A whole bunch of changes to eventually support
[libgcrypt.git] / tests / register.c
1 /* register.c - Test for registering of additional cipher modules.
2  *      Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29
30 #include "../src/gcrypt.h"
31
32 static int verbose;
33 static int in_fips_mode;
34
35 static void
36 die (const char *format, ...)
37 {
38   va_list arg_ptr ;
39
40   va_start( arg_ptr, format ) ;
41   vfprintf (stderr, format, arg_ptr );
42   va_end(arg_ptr);
43   exit (1);
44 }
45
46 gcry_err_code_t
47 foo_setkey (void *c, const unsigned char *key, unsigned keylen)
48 {
49   (void)c;
50   (void)key;
51   (void)keylen;
52
53   return 0;
54 }
55
56 #define FOO_BLOCKSIZE 16
57
58 void
59 foo_encrypt (void *c, unsigned char *outbuf, const unsigned char *inbuf)
60 {
61   int i;
62
63   (void)c;
64
65   for (i = 0; i < FOO_BLOCKSIZE; i++)
66     outbuf[i] = inbuf[i] ^ 0x42;
67 }
68
69 void
70 foo_decrypt (void *c, unsigned char *outbuf, const unsigned char *inbuf)
71 {
72   int i;
73
74   (void)c;
75
76   for (i = 0; i < FOO_BLOCKSIZE; i++)
77     outbuf[i] = inbuf[i] ^ 0x42;
78 }
79
80 gcry_cipher_spec_t cipher_spec_foo =
81   {
82     "FOO", NULL, NULL, 16, 0, 0,
83     foo_setkey, foo_encrypt, foo_decrypt,
84     NULL, NULL,
85   };
86
87 int
88 check_list (int algorithm)
89 {
90   gcry_error_t err = GPG_ERR_NO_ERROR;
91   int *list, list_length;
92   int i, ret = 0;
93
94   err = gcry_cipher_list (NULL, &list_length);
95   assert (! err);
96   list = malloc (sizeof (int) * list_length);
97   assert (list);
98   err = gcry_cipher_list (list, &list_length);
99   
100   for (i = 0; i < list_length && (! ret); i++)
101     if (list[i] == algorithm)
102       ret = 1;
103
104   return ret;
105 }
106
107 void
108 check_run (void)
109 {
110   int err, algorithm;
111   gcry_cipher_hd_t h;
112   char plain[16] = "Heil Discordia!";
113   char encrypted[16], decrypted[16];
114   gcry_module_t module;
115   int ret;
116
117   err = gcry_cipher_register (&cipher_spec_foo, &algorithm, &module);
118   if (in_fips_mode)
119     {
120       if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
121         die ("register cipher failed in fips mode: %s\n", gpg_strerror (err));
122       return;
123     }
124   else
125     {
126       if (err)
127         die ("register cipher failed: %s\n", gpg_strerror (err));
128     }
129
130   err = gcry_cipher_open (&h, algorithm, GCRY_CIPHER_MODE_CBC, 0);
131   if (err)
132     die ("gcry_cipher_open failed: %s\n", gpg_strerror (err));
133
134   err = gcry_cipher_encrypt (h,
135                              (unsigned char *) encrypted, sizeof (encrypted),
136                              (unsigned char *) plain, sizeof (plain));
137   assert (! err);
138   assert (memcmp ((void *) plain, (void *) encrypted, sizeof (plain)));
139
140   err = gcry_cipher_reset (h);
141   assert (! err);
142
143   err = gcry_cipher_decrypt (h,
144                              (unsigned char *) decrypted, sizeof (decrypted),
145                              (unsigned char *) encrypted, sizeof (encrypted));
146   assert (! err);
147   assert (! memcmp ((void *) plain, (void *) decrypted, sizeof (plain)));
148
149   ret = check_list (algorithm);
150   assert (ret);
151
152   gcry_cipher_close (h);
153
154   gcry_cipher_unregister (module);
155
156   ret = check_list (algorithm);
157   assert (! ret);
158 }
159
160 int
161 main (int argc, char **argv)
162 {
163   int debug = 0;
164   int i = 1;
165
166   if (argc > 1 && !strcmp (argv[1], "--verbose"))
167     verbose = 1;
168   else if (argc > 1 && !strcmp (argv[1], "--debug"))
169     verbose = debug = 1;
170
171   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
172   if (!gcry_check_version (GCRYPT_VERSION))
173     die ("version mismatch\n");
174   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
175   if (debug)
176     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
177
178   if ( gcry_control (GCRYCTL_FIPS_MODE_P, 0) )
179     in_fips_mode = 1;
180
181   for (; i > 0; i--)
182     check_run ();
183
184   /* In fips mode we let the Makefile skip this test because a PASS
185      would not make much sense with all egistering disabled. */
186   return in_fips_mode? 77:0; 
187 }