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
32static int verbose;
33static int in_fips_mode;
34
35static void
36die (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
46gcry_err_code_t
47foo_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
58void
59foo_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
69void
70foo_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
80gcry_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
87int
88check_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
107void
108check_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
160int
161main (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}
188