| /* register.c - Test for registering of additional cipher modules. |
| * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. |
| * |
| * This file is part of Libgcrypt. |
| * |
| * Libgcrypt is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU Lesser General Public License as |
| * published by the Free Software Foundation; either version 2.1 of |
| * the License, or (at your option) any later version. |
| * |
| * Libgcrypt is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif |
| #include <stdarg.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <assert.h> |
| |
| #include "../src/gcrypt.h" |
| |
| static int verbose; |
| static int in_fips_mode; |
| |
| static void |
| die (const char *format, ...) |
| { |
| va_list arg_ptr ; |
| |
| va_start( arg_ptr, format ) ; |
| vfprintf (stderr, format, arg_ptr ); |
| va_end(arg_ptr); |
| exit (1); |
| } |
| |
| gcry_err_code_t |
| foo_setkey (void *c, const unsigned char *key, unsigned keylen) |
| { |
| (void)c; |
| (void)key; |
| (void)keylen; |
| |
| return 0; |
| } |
| |
| #define FOO_BLOCKSIZE 16 |
| |
| void |
| foo_encrypt (void *c, unsigned char *outbuf, const unsigned char *inbuf) |
| { |
| int i; |
| |
| (void)c; |
| |
| for (i = 0; i < FOO_BLOCKSIZE; i++) |
| outbuf[i] = inbuf[i] ^ 0x42; |
| } |
| |
| void |
| foo_decrypt (void *c, unsigned char *outbuf, const unsigned char *inbuf) |
| { |
| int i; |
| |
| (void)c; |
| |
| for (i = 0; i < FOO_BLOCKSIZE; i++) |
| outbuf[i] = inbuf[i] ^ 0x42; |
| } |
| |
| gcry_cipher_spec_t cipher_spec_foo = |
| { |
| "FOO", NULL, NULL, 16, 0, 0, |
| foo_setkey, foo_encrypt, foo_decrypt, |
| NULL, NULL, |
| }; |
| |
| int |
| check_list (int algorithm) |
| { |
| gcry_error_t err = GPG_ERR_NO_ERROR; |
| int *list, list_length; |
| int i, ret = 0; |
| |
| err = gcry_cipher_list (NULL, &list_length); |
| assert (! err); |
| list = malloc (sizeof (int) * list_length); |
| assert (list); |
| err = gcry_cipher_list (list, &list_length); |
| |
| for (i = 0; i < list_length && (! ret); i++) |
| if (list[i] == algorithm) |
| ret = 1; |
| |
| return ret; |
| } |
| |
| void |
| check_run (void) |
| { |
| int err, algorithm; |
| gcry_cipher_hd_t h; |
| char plain[16] = "Heil Discordia!"; |
| char encrypted[16], decrypted[16]; |
| gcry_module_t module; |
| int ret; |
| |
| err = gcry_cipher_register (&cipher_spec_foo, &algorithm, &module); |
| if (in_fips_mode) |
| { |
| if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) |
| die ("register cipher failed in fips mode: %s\n", gpg_strerror (err)); |
| return; |
| } |
| else |
| { |
| if (err) |
| die ("register cipher failed: %s\n", gpg_strerror (err)); |
| } |
| |
| err = gcry_cipher_open (&h, algorithm, GCRY_CIPHER_MODE_CBC, 0); |
| if (err) |
| die ("gcry_cipher_open failed: %s\n", gpg_strerror (err)); |
| |
| err = gcry_cipher_encrypt (h, |
| (unsigned char *) encrypted, sizeof (encrypted), |
| (unsigned char *) plain, sizeof (plain)); |
| assert (! err); |
| assert (memcmp ((void *) plain, (void *) encrypted, sizeof (plain))); |
| |
| err = gcry_cipher_reset (h); |
| assert (! err); |
| |
| err = gcry_cipher_decrypt (h, |
| (unsigned char *) decrypted, sizeof (decrypted), |
| (unsigned char *) encrypted, sizeof (encrypted)); |
| assert (! err); |
| assert (! memcmp ((void *) plain, (void *) decrypted, sizeof (plain))); |
| |
| ret = check_list (algorithm); |
| assert (ret); |
| |
| gcry_cipher_close (h); |
| |
| gcry_cipher_unregister (module); |
| |
| ret = check_list (algorithm); |
| assert (! ret); |
| } |
| |
| int |
| main (int argc, char **argv) |
| { |
| int debug = 0; |
| int i = 1; |
| |
| if (argc > 1 && !strcmp (argv[1], "--verbose")) |
| verbose = 1; |
| else if (argc > 1 && !strcmp (argv[1], "--debug")) |
| verbose = debug = 1; |
| |
| gcry_control (GCRYCTL_DISABLE_SECMEM, 0); |
| if (!gcry_check_version (GCRYPT_VERSION)) |
| die ("version mismatch\n"); |
| gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); |
| if (debug) |
| gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); |
| |
| if ( gcry_control (GCRYCTL_FIPS_MODE_P, 0) ) |
| in_fips_mode = 1; |
| |
| for (; i > 0; i--) |
| check_run (); |
| |
| /* In fips mode we let the Makefile skip this test because a PASS |
| would not make much sense with all egistering disabled. */ |
| return in_fips_mode? 77:0; |
| } |