blob: df90fe094cde1cb8634c05076371dfee3275159f [file] [log] [blame] [edit]
/* 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;
}