Line data Source code
1 : /* pubkey.c - Public key encryption/decryption tests
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, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #ifdef HAVE_CONFIG_H
21 : #include <config.h>
22 : #endif
23 : #include <stdarg.h>
24 : #include <stdio.h>
25 : #include <stdlib.h>
26 : #include <string.h>
27 :
28 :
29 : #include "../src/gcrypt-int.h"
30 :
31 : #define my_isascii(c) (!((c) & 0x80))
32 : #define digitp(p) (*(p) >= '0' && *(p) <= '9')
33 : #define hexdigitp(a) (digitp (a) \
34 : || (*(a) >= 'A' && *(a) <= 'F') \
35 : || (*(a) >= 'a' && *(a) <= 'f'))
36 : #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
37 : *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
38 : #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
39 : #define DIM(v) (sizeof(v)/sizeof((v)[0]))
40 : #define DIMof(type,member) DIM(((type *)0)->member)
41 :
42 :
43 : /* Sample RSA keys, taken from basic.c. */
44 :
45 : static const char sample_private_key_1[] =
46 : "(private-key\n"
47 : " (openpgp-rsa\n"
48 : " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
49 : "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
50 : "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
51 : "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
52 : " (e #010001#)\n"
53 : " (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
54 : "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
55 : "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
56 : "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
57 : " (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
58 : "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
59 : " (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
60 : "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
61 : " (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
62 : "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
63 : " )\n"
64 : ")\n";
65 :
66 : /* The same key as above but without p, q and u to test the non CRT case. */
67 : static const char sample_private_key_1_1[] =
68 : "(private-key\n"
69 : " (openpgp-rsa\n"
70 : " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
71 : "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
72 : "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
73 : "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
74 : " (e #010001#)\n"
75 : " (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
76 : "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
77 : "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
78 : "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
79 : " )\n"
80 : ")\n";
81 :
82 : /* The same key as above but just without q to test the non CRT case. This
83 : should fail. */
84 : static const char sample_private_key_1_2[] =
85 : "(private-key\n"
86 : " (openpgp-rsa\n"
87 : " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
88 : "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
89 : "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
90 : "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
91 : " (e #010001#)\n"
92 : " (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
93 : "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
94 : "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
95 : "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
96 : " (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
97 : "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
98 : " (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
99 : "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
100 : " )\n"
101 : ")\n";
102 :
103 : static const char sample_public_key_1[] =
104 : "(public-key\n"
105 : " (rsa\n"
106 : " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
107 : "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
108 : "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
109 : "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
110 : " (e #010001#)\n"
111 : " )\n"
112 : ")\n";
113 :
114 :
115 : static int verbose;
116 : static int error_count;
117 :
118 :
119 : /* If we have a decent libgpg-error we can use some gcc attributes. */
120 : #ifdef GPGRT_ATTR_NORETURN
121 : static void die (const char *format, ...) GPGRT_ATTR_NR_PRINTF(1,2);
122 : static void fail (const char *format, ...) GPGRT_ATTR_PRINTF(1,2);
123 : static void info (const char *format, ...) GPGRT_ATTR_PRINTF(1,2);
124 : #endif /*GPGRT_ATTR_NORETURN*/
125 :
126 :
127 : static void
128 0 : die (const char *format, ...)
129 : {
130 : va_list arg_ptr ;
131 :
132 0 : va_start( arg_ptr, format ) ;
133 0 : vfprintf (stderr, format, arg_ptr );
134 0 : va_end(arg_ptr);
135 0 : if (*format && format[strlen(format)-1] != '\n')
136 0 : putc ('\n', stderr);
137 0 : exit (1);
138 : }
139 :
140 : static void
141 0 : fail (const char *format, ...)
142 : {
143 : va_list arg_ptr;
144 :
145 0 : va_start (arg_ptr, format);
146 0 : vfprintf (stderr, format, arg_ptr);
147 0 : va_end (arg_ptr);
148 0 : error_count++;
149 0 : }
150 :
151 : static void
152 0 : info (const char *format, ...)
153 : {
154 : va_list arg_ptr;
155 :
156 0 : va_start (arg_ptr, format);
157 0 : vfprintf (stderr, format, arg_ptr);
158 0 : va_end (arg_ptr);
159 0 : }
160 :
161 : static void
162 0 : show_sexp (const char *prefix, gcry_sexp_t a)
163 : {
164 : char *buf;
165 : size_t size;
166 :
167 0 : if (prefix)
168 0 : fputs (prefix, stderr);
169 0 : size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
170 0 : buf = gcry_xmalloc (size);
171 :
172 0 : gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
173 0 : fprintf (stderr, "%.*s", (int)size, buf);
174 0 : gcry_free (buf);
175 0 : }
176 :
177 : /* from ../cipher/pubkey-util.c */
178 : static gpg_err_code_t
179 4 : _gcry_pk_util_get_nbits (gcry_sexp_t list, unsigned int *r_nbits)
180 : {
181 : char buf[50];
182 : const char *s;
183 : size_t n;
184 :
185 4 : *r_nbits = 0;
186 :
187 4 : list = gcry_sexp_find_token (list, "nbits", 0);
188 4 : if (!list)
189 0 : return 0; /* No NBITS found. */
190 :
191 4 : s = gcry_sexp_nth_data (list, 1, &n);
192 4 : if (!s || n >= DIM (buf) - 1 )
193 : {
194 : /* NBITS given without a cdr. */
195 0 : gcry_sexp_release (list);
196 0 : return GPG_ERR_INV_OBJ;
197 : }
198 4 : memcpy (buf, s, n);
199 4 : buf[n] = 0;
200 4 : *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
201 4 : gcry_sexp_release (list);
202 4 : return 0;
203 : }
204 :
205 : /* Convert STRING consisting of hex characters into its binary
206 : representation and return it as an allocated buffer. The valid
207 : length of the buffer is returned at R_LENGTH. The string is
208 : delimited by end of string. The function returns NULL on
209 : error. */
210 : static void *
211 2 : data_from_hex (const char *string, size_t *r_length)
212 : {
213 : const char *s;
214 : unsigned char *buffer;
215 : size_t length;
216 :
217 2 : buffer = gcry_xmalloc (strlen(string)/2+1);
218 2 : length = 0;
219 65 : for (s=string; *s; s +=2 )
220 : {
221 63 : if (!hexdigitp (s) || !hexdigitp (s+1))
222 0 : die ("error parsing hex string `%s'\n", string);
223 63 : ((unsigned char*)buffer)[length++] = xtoi_2 (s);
224 : }
225 2 : *r_length = length;
226 2 : return buffer;
227 : }
228 :
229 :
230 : static void
231 2 : extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected)
232 : {
233 : gcry_sexp_t l1;
234 : const void *a;
235 : size_t alen;
236 : void *b;
237 : size_t blen;
238 :
239 2 : l1 = gcry_sexp_find_token (sexp, name, 0);
240 2 : a = gcry_sexp_nth_data (l1, 1, &alen);
241 2 : b = data_from_hex (expected, &blen);
242 2 : if (!a)
243 0 : fail ("parameter \"%s\" missing in key\n", name);
244 2 : else if ( alen != blen || memcmp (a, b, alen) )
245 : {
246 0 : fail ("parameter \"%s\" does not match expected value\n", name);
247 0 : if (verbose)
248 : {
249 0 : info ("expected: %s\n", expected);
250 0 : show_sexp ("sexp: ", sexp);
251 : }
252 : }
253 2 : gcry_free (b);
254 2 : gcry_sexp_release (l1);
255 2 : }
256 :
257 :
258 : static void
259 28 : check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
260 : gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
261 : {
262 : gcry_sexp_t plain1, cipher, l;
263 : gcry_mpi_t x0, x1;
264 : int rc;
265 : int have_flags;
266 :
267 : /* Extract data from plaintext. */
268 28 : l = gcry_sexp_find_token (plain0, "value", 0);
269 28 : x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
270 28 : gcry_sexp_release (l);
271 :
272 : /* Encrypt data. */
273 28 : rc = gcry_pk_encrypt (&cipher, plain0, pkey);
274 28 : if (rc)
275 0 : die ("encryption failed: %s\n", gcry_strerror (rc));
276 :
277 28 : l = gcry_sexp_find_token (cipher, "flags", 0);
278 28 : have_flags = !!l;
279 28 : gcry_sexp_release (l);
280 :
281 : /* Decrypt data. */
282 28 : rc = gcry_pk_decrypt (&plain1, cipher, skey);
283 28 : gcry_sexp_release (cipher);
284 28 : if (rc)
285 : {
286 0 : if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
287 : {
288 0 : gcry_mpi_release (x0);
289 28 : return; /* This is the expected failure code. */
290 : }
291 0 : die ("decryption failed: %s\n", gcry_strerror (rc));
292 : }
293 :
294 : /* Extract decrypted data. Note that for compatibility reasons, the
295 : output of gcry_pk_decrypt depends on whether a flags lists (even
296 : if empty) occurs in its input data. Because we passed the output
297 : of encrypt directly to decrypt, such a flag value won't be there
298 : as of today. We check it anyway. */
299 28 : l = gcry_sexp_find_token (plain1, "value", 0);
300 28 : if (l)
301 : {
302 0 : if (!have_flags)
303 0 : die ("compatibility mode of pk_decrypt broken\n");
304 0 : gcry_sexp_release (plain1);
305 0 : x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
306 0 : gcry_sexp_release (l);
307 : }
308 : else
309 : {
310 28 : if (have_flags)
311 0 : die ("compatibility mode of pk_decrypt broken\n");
312 28 : x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG);
313 28 : gcry_sexp_release (plain1);
314 : }
315 :
316 : /* Compare. */
317 28 : if (gcry_mpi_cmp (x0, x1))
318 0 : die ("data corrupted\n");
319 28 : gcry_mpi_release (x0);
320 28 : gcry_mpi_release (x1);
321 : }
322 :
323 : static void
324 14 : check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data,
325 : gpg_err_code_t decrypt_fail_code)
326 : {
327 : gcry_sexp_t plain;
328 : gcry_mpi_t x;
329 : int rc;
330 :
331 : /* Create plain text. */
332 14 : x = gcry_mpi_new (nbits_data);
333 14 : gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
334 :
335 14 : rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x);
336 14 : if (rc)
337 0 : die ("converting data for encryption failed: %s\n",
338 : gcry_strerror (rc));
339 :
340 14 : check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
341 14 : gcry_sexp_release (plain);
342 14 : gcry_mpi_release (x);
343 :
344 : /* Create plain text. */
345 14 : x = gcry_mpi_new (nbits_data);
346 14 : gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
347 :
348 14 : rc = gcry_sexp_build (&plain, NULL,
349 : "(data (flags raw no-blinding) (value %m))", x);
350 14 : gcry_mpi_release (x);
351 14 : if (rc)
352 0 : die ("converting data for encryption failed: %s\n",
353 : gcry_strerror (rc));
354 :
355 14 : check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
356 14 : gcry_sexp_release (plain);
357 14 : }
358 :
359 : static void
360 6 : get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant)
361 : {
362 : gcry_sexp_t pub_key, sec_key;
363 : int rc;
364 : static const char *secret;
365 :
366 :
367 6 : switch (secret_variant)
368 : {
369 2 : case 0: secret = sample_private_key_1; break;
370 2 : case 1: secret = sample_private_key_1_1; break;
371 2 : case 2: secret = sample_private_key_1_2; break;
372 0 : default: die ("BUG\n");
373 : }
374 :
375 6 : rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1,
376 : strlen (sample_public_key_1));
377 6 : if (!rc)
378 6 : rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret));
379 6 : if (rc)
380 0 : die ("converting sample keys failed: %s\n", gcry_strerror (rc));
381 :
382 6 : *pkey = pub_key;
383 6 : *skey = sec_key;
384 6 : }
385 :
386 : static void
387 2 : get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
388 : {
389 : gcry_sexp_t key_spec, key, pub_key, sec_key;
390 : int rc;
391 :
392 2 : rc = gcry_sexp_new (&key_spec,
393 : "(genkey (rsa (nbits 4:2048)))", 0, 1);
394 2 : if (rc)
395 0 : die ("error creating S-expression: %s\n", gcry_strerror (rc));
396 2 : rc = gcry_pk_genkey (&key, key_spec);
397 2 : gcry_sexp_release (key_spec);
398 2 : if (rc)
399 0 : die ("error generating RSA key: %s\n", gcry_strerror (rc));
400 :
401 2 : if (verbose > 1)
402 0 : show_sexp ("generated RSA key:\n", key);
403 :
404 2 : pub_key = gcry_sexp_find_token (key, "public-key", 0);
405 2 : if (! pub_key)
406 0 : die ("public part missing in key\n");
407 :
408 2 : sec_key = gcry_sexp_find_token (key, "private-key", 0);
409 2 : if (! sec_key)
410 0 : die ("private part missing in key\n");
411 :
412 2 : gcry_sexp_release (key);
413 2 : *pkey = pub_key;
414 2 : *skey = sec_key;
415 2 : }
416 :
417 :
418 : static void
419 2 : get_keys_x931_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
420 : {
421 : gcry_sexp_t key_spec, key, pub_key, sec_key;
422 : int rc;
423 :
424 2 : rc = gcry_sexp_new (&key_spec,
425 : "(genkey (rsa (nbits 4:2048)(use-x931)))", 0, 1);
426 2 : if (rc)
427 0 : die ("error creating S-expression: %s\n", gcry_strerror (rc));
428 2 : rc = gcry_pk_genkey (&key, key_spec);
429 2 : gcry_sexp_release (key_spec);
430 2 : if (rc)
431 0 : die ("error generating RSA key: %s\n", gcry_strerror (rc));
432 :
433 2 : if (verbose > 1)
434 0 : show_sexp ("generated RSA (X9.31) key:\n", key);
435 :
436 2 : pub_key = gcry_sexp_find_token (key, "public-key", 0);
437 2 : if (!pub_key)
438 0 : die ("public part missing in key\n");
439 :
440 2 : sec_key = gcry_sexp_find_token (key, "private-key", 0);
441 2 : if (!sec_key)
442 0 : die ("private part missing in key\n");
443 :
444 2 : gcry_sexp_release (key);
445 2 : *pkey = pub_key;
446 2 : *skey = sec_key;
447 2 : }
448 :
449 :
450 : static void
451 4 : get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x)
452 : {
453 : gcry_sexp_t key_spec, key, pub_key, sec_key;
454 : int rc;
455 :
456 4 : rc = gcry_sexp_new
457 : (&key_spec,
458 : (fixed_x
459 : ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))"
460 : : "(genkey (elg (nbits 3:512)))"),
461 : 0, 1);
462 :
463 4 : if (rc)
464 0 : die ("error creating S-expression: %s\n", gcry_strerror (rc));
465 4 : rc = gcry_pk_genkey (&key, key_spec);
466 4 : gcry_sexp_release (key_spec);
467 4 : if (rc)
468 0 : die ("error generating Elgamal key: %s\n", gcry_strerror (rc));
469 :
470 4 : if (verbose > 1)
471 0 : show_sexp ("generated ELG key:\n", key);
472 :
473 4 : pub_key = gcry_sexp_find_token (key, "public-key", 0);
474 4 : if (!pub_key)
475 0 : die ("public part missing in key\n");
476 :
477 4 : sec_key = gcry_sexp_find_token (key, "private-key", 0);
478 4 : if (!sec_key)
479 0 : die ("private part missing in key\n");
480 :
481 4 : gcry_sexp_release (key);
482 4 : *pkey = pub_key;
483 4 : *skey = sec_key;
484 4 : }
485 :
486 :
487 : static void
488 4 : get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key)
489 : {
490 : gcry_sexp_t key_spec, key, pub_key, sec_key;
491 : int rc;
492 :
493 4 : rc = gcry_sexp_new (&key_spec,
494 : transient_key
495 : ? "(genkey (dsa (nbits 4:2048)(transient-key)))"
496 : : "(genkey (dsa (nbits 4:2048)))",
497 : 0, 1);
498 4 : if (rc)
499 0 : die ("error creating S-expression: %s\n", gcry_strerror (rc));
500 4 : rc = gcry_pk_genkey (&key, key_spec);
501 4 : gcry_sexp_release (key_spec);
502 4 : if (rc)
503 0 : die ("error generating DSA key: %s\n", gcry_strerror (rc));
504 :
505 4 : if (verbose > 1)
506 0 : show_sexp ("generated DSA key:\n", key);
507 :
508 4 : pub_key = gcry_sexp_find_token (key, "public-key", 0);
509 4 : if (!pub_key)
510 0 : die ("public part missing in key\n");
511 :
512 4 : sec_key = gcry_sexp_find_token (key, "private-key", 0);
513 4 : if (!sec_key)
514 0 : die ("private part missing in key\n");
515 :
516 4 : gcry_sexp_release (key);
517 4 : *pkey = pub_key;
518 4 : *skey = sec_key;
519 4 : }
520 :
521 :
522 : static void
523 2 : get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
524 : {
525 : gcry_sexp_t key_spec, key, pub_key, sec_key;
526 : int rc;
527 :
528 2 : rc = gcry_sexp_new
529 : (&key_spec, "(genkey (dsa (nbits 4:2048)(use-fips186)))", 0, 1);
530 2 : if (rc)
531 0 : die ("error creating S-expression: %s\n", gcry_strerror (rc));
532 2 : rc = gcry_pk_genkey (&key, key_spec);
533 2 : gcry_sexp_release (key_spec);
534 2 : if (rc)
535 0 : die ("error generating DSA key: %s\n", gcry_strerror (rc));
536 :
537 2 : if (verbose > 1)
538 0 : show_sexp ("generated DSA key (fips 186):\n", key);
539 :
540 2 : pub_key = gcry_sexp_find_token (key, "public-key", 0);
541 2 : if (!pub_key)
542 0 : die ("public part missing in key\n");
543 :
544 2 : sec_key = gcry_sexp_find_token (key, "private-key", 0);
545 2 : if (!sec_key)
546 0 : die ("private part missing in key\n");
547 :
548 2 : gcry_sexp_release (key);
549 2 : *pkey = pub_key;
550 2 : *skey = sec_key;
551 2 : }
552 :
553 :
554 : static void
555 2 : get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
556 : {
557 : gcry_sexp_t key_spec, key, pub_key, sec_key;
558 : int rc;
559 :
560 2 : rc = gcry_sexp_new
561 : (&key_spec,
562 : "(genkey (dsa (transient-key)(domain"
563 : "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
564 : "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
565 : "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
566 : "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
567 : "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
568 : "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
569 : "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
570 : "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
571 : "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
572 : ")))", 0, 1);
573 2 : if (rc)
574 0 : die ("error creating S-expression: %s\n", gcry_strerror (rc));
575 2 : rc = gcry_pk_genkey (&key, key_spec);
576 2 : gcry_sexp_release (key_spec);
577 2 : if (rc)
578 0 : die ("error generating DSA key: %s\n", gcry_strerror (rc));
579 :
580 2 : if (verbose > 1)
581 0 : show_sexp ("generated DSA key:\n", key);
582 :
583 2 : pub_key = gcry_sexp_find_token (key, "public-key", 0);
584 2 : if (!pub_key)
585 0 : die ("public part missing in key\n");
586 :
587 2 : sec_key = gcry_sexp_find_token (key, "private-key", 0);
588 2 : if (!sec_key)
589 0 : die ("private part missing in key\n");
590 :
591 2 : gcry_sexp_release (key);
592 2 : *pkey = pub_key;
593 2 : *skey = sec_key;
594 2 : }
595 :
596 : #if 0
597 : static void
598 : get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
599 : {
600 : gcry_sexp_t key_spec, key, pub_key, sec_key;
601 : int rc;
602 :
603 : rc = gcry_sexp_new
604 : (&key_spec,
605 : "(genkey (dsa (transient-key)(use-fips186)(domain"
606 : "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
607 : "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
608 : "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
609 : "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
610 : "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
611 : "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
612 : "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
613 : "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
614 : "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
615 : ")))", 0, 1);
616 : if (rc)
617 : die ("error creating S-expression: %s\n", gcry_strerror (rc));
618 : rc = gcry_pk_genkey (&key, key_spec);
619 : gcry_sexp_release (key_spec);
620 : if (rc)
621 : die ("error generating DSA key: %s\n", gcry_strerror (rc));
622 :
623 : if (verbose > 1)
624 : show_sexp ("generated DSA key:\n", key);
625 :
626 : pub_key = gcry_sexp_find_token (key, "public-key", 0);
627 : if (!pub_key)
628 : die ("public part missing in key\n");
629 :
630 : sec_key = gcry_sexp_find_token (key, "private-key", 0);
631 : if (!sec_key)
632 : die ("private part missing in key\n");
633 :
634 : gcry_sexp_release (key);
635 : *pkey = pub_key;
636 : *skey = sec_key;
637 : }
638 : #endif /*0*/
639 :
640 : static void
641 2 : get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
642 : {
643 : gcry_sexp_t key_spec, key, pub_key, sec_key;
644 : int rc;
645 :
646 2 : rc = gcry_sexp_new
647 : (&key_spec,
648 : "(genkey"
649 : " (dsa"
650 : " (nbits 4:2048)"
651 : " (use-fips186)"
652 : " (transient-key)"
653 : " (derive-parms"
654 : " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))",
655 : 0, 1);
656 2 : if (rc)
657 0 : die ("error creating S-expression: %s\n", gcry_strerror (rc));
658 2 : rc = gcry_pk_genkey (&key, key_spec);
659 2 : gcry_sexp_release (key_spec);
660 2 : if (rc)
661 0 : die ("error generating DSA key: %s\n", gcry_strerror (rc));
662 :
663 2 : if (verbose > 1)
664 0 : show_sexp ("generated DSA key (fips 186 with seed):\n", key);
665 :
666 2 : pub_key = gcry_sexp_find_token (key, "public-key", 0);
667 2 : if (!pub_key)
668 0 : die ("public part missing in key\n");
669 :
670 2 : sec_key = gcry_sexp_find_token (key, "private-key", 0);
671 2 : if (!sec_key)
672 0 : die ("private part missing in key\n");
673 :
674 2 : gcry_sexp_release (key);
675 2 : *pkey = pub_key;
676 2 : *skey = sec_key;
677 2 : }
678 :
679 :
680 : static void
681 2 : check_run (void)
682 : {
683 : gpg_error_t err;
684 : gcry_sexp_t pkey, skey;
685 : int variant;
686 :
687 8 : for (variant=0; variant < 3; variant++)
688 : {
689 6 : if (verbose)
690 0 : fprintf (stderr, "Checking sample key (%d).\n", variant);
691 6 : get_keys_sample (&pkey, &skey, variant);
692 : /* Check gcry_pk_testkey which requires all elements. */
693 6 : err = gcry_pk_testkey (skey);
694 6 : if ((variant == 0 && err)
695 6 : || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ))
696 0 : die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err));
697 : /* Run the usual check but expect an error from variant 2. */
698 6 : check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0);
699 6 : gcry_sexp_release (pkey);
700 6 : gcry_sexp_release (skey);
701 : }
702 :
703 2 : if (verbose)
704 0 : fprintf (stderr, "Checking generated RSA key.\n");
705 2 : get_keys_new (&pkey, &skey);
706 2 : check_keys (pkey, skey, 800, 0);
707 2 : gcry_sexp_release (pkey);
708 2 : gcry_sexp_release (skey);
709 :
710 2 : if (verbose)
711 0 : fprintf (stderr, "Checking generated RSA key (X9.31).\n");
712 2 : get_keys_x931_new (&pkey, &skey);
713 2 : check_keys (pkey, skey, 800, 0);
714 2 : gcry_sexp_release (pkey);
715 2 : gcry_sexp_release (skey);
716 :
717 2 : if (verbose)
718 0 : fprintf (stderr, "Checking generated Elgamal key.\n");
719 2 : get_elg_key_new (&pkey, &skey, 0);
720 2 : check_keys (pkey, skey, 400, 0);
721 2 : gcry_sexp_release (pkey);
722 2 : gcry_sexp_release (skey);
723 :
724 2 : if (verbose)
725 0 : fprintf (stderr, "Checking passphrase generated Elgamal key.\n");
726 2 : get_elg_key_new (&pkey, &skey, 1);
727 2 : check_keys (pkey, skey, 800, 0);
728 2 : gcry_sexp_release (pkey);
729 2 : gcry_sexp_release (skey);
730 :
731 2 : if (verbose)
732 0 : fprintf (stderr, "Generating DSA key.\n");
733 2 : get_dsa_key_new (&pkey, &skey, 0);
734 : /* Fixme: Add a check function for DSA keys. */
735 2 : gcry_sexp_release (pkey);
736 2 : gcry_sexp_release (skey);
737 :
738 2 : if (!gcry_fips_mode_active ())
739 : {
740 2 : if (verbose)
741 0 : fprintf (stderr, "Generating transient DSA key.\n");
742 2 : get_dsa_key_new (&pkey, &skey, 1);
743 : /* Fixme: Add a check function for DSA keys. */
744 2 : gcry_sexp_release (pkey);
745 2 : gcry_sexp_release (skey);
746 : }
747 :
748 2 : if (verbose)
749 0 : fprintf (stderr, "Generating DSA key (FIPS 186).\n");
750 2 : get_dsa_key_fips186_new (&pkey, &skey);
751 : /* Fixme: Add a check function for DSA keys. */
752 2 : gcry_sexp_release (pkey);
753 2 : gcry_sexp_release (skey);
754 :
755 2 : if (verbose)
756 0 : fprintf (stderr, "Generating DSA key with given domain.\n");
757 2 : get_dsa_key_with_domain_new (&pkey, &skey);
758 : /* Fixme: Add a check function for DSA keys. */
759 2 : gcry_sexp_release (pkey);
760 2 : gcry_sexp_release (skey);
761 :
762 : /* We need new test vectors for get_dsa_key_fips186_with_domain_new. */
763 2 : if (verbose)
764 0 : fprintf (stderr, "Generating DSA key with given domain (FIPS 186)"
765 : " - skipped.\n");
766 : /* get_dsa_key_fips186_with_domain_new (&pkey, &skey); */
767 : /* /\* Fixme: Add a check function for DSA keys. *\/ */
768 : /* gcry_sexp_release (pkey); */
769 : /* gcry_sexp_release (skey); */
770 :
771 2 : if (verbose)
772 0 : fprintf (stderr, "Generating DSA key with given seed (FIPS 186).\n");
773 2 : get_dsa_key_fips186_with_seed_new (&pkey, &skey);
774 : /* Fixme: Add a check function for DSA keys. */
775 2 : gcry_sexp_release (pkey);
776 2 : gcry_sexp_release (skey);
777 2 : }
778 :
779 :
780 :
781 : static gcry_mpi_t
782 4 : key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name)
783 : {
784 : gcry_sexp_t l1, l2;
785 : gcry_mpi_t result;
786 :
787 4 : l1 = gcry_sexp_find_token (sexp, topname, 0);
788 4 : if (!l1)
789 0 : return NULL;
790 :
791 4 : l2 = gcry_sexp_find_token (l1, name, 0);
792 4 : if (!l2)
793 : {
794 0 : gcry_sexp_release (l1);
795 0 : return NULL;
796 : }
797 :
798 4 : result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
799 4 : gcry_sexp_release (l2);
800 4 : gcry_sexp_release (l1);
801 4 : return result;
802 : }
803 :
804 :
805 : static void
806 4 : check_x931_derived_key (int what)
807 : {
808 : static struct {
809 : const char *param;
810 : const char *expected_d;
811 : } testtable[] = {
812 : { /* First example from X9.31 (D.1.1). */
813 : "(genkey\n"
814 : " (rsa\n"
815 : " (nbits 4:1024)\n"
816 : " (rsa-use-e 1:3)\n"
817 : " (derive-parms\n"
818 : " (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n"
819 : " (Xp2 #192E8AAC41C576C822D93EA433#)\n"
820 : " (Xp #D8CD81F035EC57EFE822955149D3BFF70C53520D\n"
821 : " 769D6D76646C7A792E16EBD89FE6FC5B605A6493\n"
822 : " 39DFC925A86A4C6D150B71B9EEA02D68885F5009\n"
823 : " B98BD984#)\n"
824 : " (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n"
825 : " (Xq2 #134E4CAA16D2350A21D775C404#)\n"
826 : " (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n"
827 : " 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n"
828 : " 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n"
829 : " 321DE34A#))))\n",
830 : "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173"
831 : "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961"
832 : "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE"
833 : "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13"
834 : "241D3C4B"
835 : },
836 :
837 : { /* Second example from X9.31 (D.2.1). */
838 : "(genkey\n"
839 : " (rsa\n"
840 : " (nbits 4:1536)\n"
841 : " (rsa-use-e 1:3)\n"
842 : " (derive-parms\n"
843 : " (Xp1 #18272558B61316348297EACA74#)\n"
844 : " (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n"
845 : " (Xp #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n"
846 : " 0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n"
847 : " 60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n"
848 : " 318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n"
849 : " EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n"
850 : " (Xq1 #11FDDA6E8128DC1629F75192BA#)\n"
851 : " (Xq2 #18AB178ECA907D72472F65E480#)\n"
852 : " (Xq #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n"
853 : " CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n"
854 : " B734E3FBD15862EBC59FA0425DFA131E549136E8\n"
855 : " E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n"
856 : " EA14B9D5F2A263DC65626E4D6CEAC767#))))\n",
857 : "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1"
858 : "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2"
859 : "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383"
860 : "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9"
861 : "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C"
862 : "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0"
863 : "BBCCB9F65C83"
864 : /* Note that this example in X9.31 gives this value for D:
865 :
866 : "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44"
867 : "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8"
868 : "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E"
869 : "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7"
870 : "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270"
871 : "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342"
872 : "EF32E7D9720B"
873 :
874 : This is a bug in X9.31, obviously introduced by using
875 :
876 : d = e^{-1} mod (p-1)(q-1)
877 :
878 : instead of using the universal exponent as required by 4.1.3:
879 :
880 : d = e^{-1} mod lcm(p-1,q-1)
881 :
882 : The examples in X9.31 seem to be pretty buggy, see
883 : cipher/primegen.c for another bug. Not only that I had to
884 : spend 100 USD for the 66 pages of the document, it also took
885 : me several hours to figure out that the bugs are in the
886 : document and not in my code.
887 : */
888 : },
889 :
890 : { /* First example from NIST RSAVS (B.1.1). */
891 : "(genkey\n"
892 : " (rsa\n"
893 : " (nbits 4:1024)\n"
894 : " (rsa-use-e 1:3)\n"
895 : " (derive-parms\n"
896 : " (Xp1 #1ed3d6368e101dab9124c92ac8#)\n"
897 : " (Xp2 #16e5457b8844967ce83cab8c11#)\n"
898 : " (Xp #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n"
899 : " ab262da1dcda8194720672a4e02229a0c71f60ae\n"
900 : " c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n"
901 : " cab44595#)\n"
902 : " (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n"
903 : " (Xq2 #1f9cca85f185341516d92e82fd#)\n"
904 : " (Xq #c8387fd38fa33ddcea6a9de1b2d55410663502db\n"
905 : " c225655a9310cceac9f4cf1bce653ec916d45788\n"
906 : " f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n"
907 : " 2f389eda#))))\n",
908 : "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b"
909 : "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd"
910 : "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a"
911 : "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0"
912 : "dc7e8feb"
913 : },
914 :
915 : { /* Second example from NIST RSAVS (B.1.1). */
916 : "(genkey\n"
917 : " (rsa\n"
918 : " (nbits 4:1536)\n"
919 : " (rsa-use-e 1:3)\n"
920 : " (derive-parms\n"
921 : " (Xp1 #1e64c1af460dff8842c22b64d0#)\n"
922 : " (Xp2 #1e948edcedba84039c81f2ac0c#)\n"
923 : " (Xp #c8c67df894c882045ede26a9008ab09ea0672077\n"
924 : " d7bc71d412511cd93981ddde8f91b967da404056\n"
925 : " c39f105f7f239abdaff92923859920f6299e82b9\n"
926 : " 5bd5b8c959948f4a034d81613d6235a3953b49ce\n"
927 : " 26974eb7bb1f14843841281b363b9cdb#)\n"
928 : " (Xq1 #1f3df0f017ddd05611a97b6adb#)\n"
929 : " (Xq2 #143edd7b22d828913abf24ca4d#)\n"
930 : " (Xq #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n"
931 : " b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n"
932 : " 7552195fae8b061077e03920814d8b9cfb5a3958\n"
933 : " b3a82c2a7fc97e55db543948d3396289245336ec\n"
934 : " 9e3cb308cc655aebd766340da8921383#))))\n",
935 : "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184"
936 : "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536"
937 : "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461"
938 : "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a"
939 : "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2"
940 : "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4"
941 : "2ccf8a84835b"
942 : }
943 : };
944 : gpg_error_t err;
945 4 : gcry_sexp_t key_spec = NULL, key = NULL, pub_key = NULL, sec_key = NULL;
946 4 : gcry_mpi_t d_expected = NULL, d_have = NULL;
947 :
948 4 : if (what < 0 && what >= sizeof testtable)
949 0 : die ("invalid WHAT value\n");
950 :
951 4 : err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1);
952 4 : if (err)
953 0 : die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err));
954 :
955 : {
956 : unsigned nbits;
957 4 : err = _gcry_pk_util_get_nbits(key_spec, &nbits);
958 4 : if (err)
959 0 : die ("nbits not found\n");
960 4 : if (gcry_fips_mode_active() && nbits < 2048)
961 : {
962 0 : info("RSA key test with %d bits skipped in fips mode\n", nbits);
963 0 : goto leave;
964 : }
965 : }
966 :
967 4 : err = gcry_pk_genkey (&key, key_spec);
968 4 : gcry_sexp_release (key_spec);
969 4 : if (err)
970 : {
971 0 : fail ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));
972 0 : goto leave;
973 : }
974 :
975 4 : pub_key = gcry_sexp_find_token (key, "public-key", 0);
976 4 : if (!pub_key)
977 0 : die ("public part missing in key [%d]\n", what);
978 :
979 4 : sec_key = gcry_sexp_find_token (key, "private-key", 0);
980 4 : if (!sec_key)
981 0 : die ("private part missing in key [%d]\n", what);
982 :
983 4 : err = gcry_mpi_scan
984 4 : (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL);
985 4 : if (err)
986 0 : die ("error converting string [%d]\n", what);
987 :
988 4 : if (verbose > 1)
989 0 : show_sexp ("generated key:\n", key);
990 :
991 4 : d_have = key_param_from_sexp (sec_key, "rsa", "d");
992 4 : if (!d_have)
993 0 : die ("parameter d not found in RSA secret key [%d]\n", what);
994 4 : if (gcry_mpi_cmp (d_expected, d_have))
995 : {
996 0 : show_sexp (NULL, sec_key);
997 0 : die ("parameter d does match expected value [%d]\n", what);
998 : }
999 : leave:
1000 4 : gcry_mpi_release (d_expected);
1001 4 : gcry_mpi_release (d_have);
1002 :
1003 4 : gcry_sexp_release (key);
1004 4 : gcry_sexp_release (pub_key);
1005 4 : gcry_sexp_release (sec_key);
1006 4 : }
1007 :
1008 :
1009 :
1010 : static void
1011 1 : check_ecc_sample_key (void)
1012 : {
1013 : static const char ecc_private_key[] =
1014 : "(private-key\n"
1015 : " (ecdsa\n"
1016 : " (curve \"NIST P-256\")\n"
1017 : " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
1018 : "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n"
1019 : " (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
1020 : "))";
1021 : static const char ecc_private_key_wo_q[] =
1022 : "(private-key\n"
1023 : " (ecdsa\n"
1024 : " (curve \"NIST P-256\")\n"
1025 : " (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
1026 : "))";
1027 : static const char ecc_public_key[] =
1028 : "(public-key\n"
1029 : " (ecdsa\n"
1030 : " (curve \"NIST P-256\")\n"
1031 : " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
1032 : "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)"
1033 : "))";
1034 : static const char hash_string[] =
1035 : "(data (flags raw)\n"
1036 : " (value #00112233445566778899AABBCCDDEEFF"
1037 : /* */ "000102030405060708090A0B0C0D0E0F#))";
1038 : static const char hash2_string[] =
1039 : "(data (flags raw)\n"
1040 : " (hash sha1 #00112233445566778899AABBCCDDEEFF"
1041 : /* */ "000102030405060708090A0B0C0D0E0F"
1042 : /* */ "000102030405060708090A0B0C0D0E0F"
1043 : /* */ "00112233445566778899AABBCCDDEEFF#))";
1044 : /* hash2, but longer than curve length, so it will be truncated */
1045 : static const char hash3_string[] =
1046 : "(data (flags raw)\n"
1047 : " (hash sha1 #00112233445566778899AABBCCDDEEFF"
1048 : /* */ "000102030405060708090A0B0C0D0E0F"
1049 : /* */ "000102030405060708090A0B0C0D0E0F"
1050 : /* */ "00112233445566778899AABBCCDDEEFF"
1051 : /* */ "000102030405060708090A0B0C0D0E0F#))";
1052 :
1053 : gpg_error_t err;
1054 : gcry_sexp_t key, hash, hash2, hash3, sig, sig2;
1055 :
1056 1 : if (verbose)
1057 0 : fprintf (stderr, "Checking sample ECC key.\n");
1058 :
1059 1 : if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
1060 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1061 :
1062 1 : if ((err = gcry_sexp_new (&hash2, hash2_string, 0, 1)))
1063 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1064 :
1065 1 : if ((err = gcry_sexp_new (&hash3, hash3_string, 0, 1)))
1066 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1067 :
1068 1 : if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
1069 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1070 :
1071 1 : if ((err = gcry_pk_sign (&sig, hash, key)))
1072 0 : die ("gcry_pk_sign failed: %s", gpg_strerror (err));
1073 :
1074 1 : gcry_sexp_release (key);
1075 1 : if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
1076 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1077 :
1078 1 : if ((err = gcry_pk_verify (sig, hash, key)))
1079 0 : die ("gcry_pk_verify failed: %s", gpg_strerror (err));
1080 :
1081 : /* Verify hash truncation */
1082 1 : gcry_sexp_release (key);
1083 1 : if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
1084 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1085 :
1086 1 : if ((err = gcry_pk_sign (&sig2, hash2, key)))
1087 0 : die ("gcry_pk_sign failed: %s", gpg_strerror (err));
1088 :
1089 1 : gcry_sexp_release (sig);
1090 1 : if ((err = gcry_pk_sign (&sig, hash3, key)))
1091 0 : die ("gcry_pk_sign failed: %s", gpg_strerror (err));
1092 :
1093 1 : gcry_sexp_release (key);
1094 1 : if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
1095 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1096 :
1097 1 : if ((err = gcry_pk_verify (sig, hash2, key)))
1098 0 : die ("gcry_pk_verify failed: %s", gpg_strerror (err));
1099 :
1100 1 : if ((err = gcry_pk_verify (sig2, hash3, key)))
1101 0 : die ("gcry_pk_verify failed: %s", gpg_strerror (err));
1102 :
1103 : /* Now try signing without the Q parameter. */
1104 :
1105 1 : gcry_sexp_release (key);
1106 1 : if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
1107 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1108 :
1109 1 : gcry_sexp_release (sig);
1110 1 : if ((err = gcry_pk_sign (&sig, hash, key)))
1111 0 : die ("gcry_pk_sign without Q failed: %s", gpg_strerror (err));
1112 :
1113 1 : gcry_sexp_release (key);
1114 1 : if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
1115 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1116 :
1117 1 : if ((err = gcry_pk_verify (sig, hash, key)))
1118 0 : die ("gcry_pk_verify signed without Q failed: %s", gpg_strerror (err));
1119 :
1120 1 : gcry_sexp_release (sig);
1121 1 : gcry_sexp_release (sig2);
1122 1 : gcry_sexp_release (key);
1123 1 : gcry_sexp_release (hash);
1124 1 : gcry_sexp_release (hash2);
1125 1 : gcry_sexp_release (hash3);
1126 1 : }
1127 :
1128 :
1129 : static void
1130 1 : check_ed25519ecdsa_sample_key (void)
1131 : {
1132 : static const char ecc_private_key[] =
1133 : "(private-key\n"
1134 : " (ecc\n"
1135 : " (curve \"Ed25519\")\n"
1136 : " (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
1137 : " 156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
1138 : " (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
1139 : "))";
1140 : static const char ecc_private_key_wo_q[] =
1141 : "(private-key\n"
1142 : " (ecc\n"
1143 : " (curve \"Ed25519\")\n"
1144 : " (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
1145 : "))";
1146 : static const char ecc_public_key[] =
1147 : "(public-key\n"
1148 : " (ecc\n"
1149 : " (curve \"Ed25519\")\n"
1150 : " (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
1151 : " 156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
1152 : "))";
1153 : static const char ecc_public_key_comp[] =
1154 : "(public-key\n"
1155 : " (ecc\n"
1156 : " (curve \"Ed25519\")\n"
1157 : " (q #047b57c2c1d3ded93332b52d588dd45863478b658387413a718779c0dd1a6d95#)"
1158 : "))";
1159 : static const char hash_string[] =
1160 : "(data (flags rfc6979)\n"
1161 : " (hash sha256 #00112233445566778899AABBCCDDEEFF"
1162 : /* */ "000102030405060708090A0B0C0D0E0F#))";
1163 :
1164 : gpg_error_t err;
1165 : gcry_sexp_t key, hash, sig;
1166 :
1167 1 : if (verbose)
1168 0 : fprintf (stderr, "Checking sample Ed25519/ECDSA key.\n");
1169 :
1170 : /* Sign. */
1171 1 : if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
1172 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1173 1 : if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
1174 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1175 1 : if ((err = gcry_pk_sign (&sig, hash, key)))
1176 0 : die ("gcry_pk_sign failed: %s", gpg_strerror (err));
1177 :
1178 : /* Verify. */
1179 1 : gcry_sexp_release (key);
1180 1 : if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
1181 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1182 1 : if ((err = gcry_pk_verify (sig, hash, key)))
1183 0 : die ("gcry_pk_verify failed: %s", gpg_strerror (err));
1184 :
1185 : /* Verify again using a compressed public key. */
1186 1 : gcry_sexp_release (key);
1187 1 : if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
1188 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1189 1 : if ((err = gcry_pk_verify (sig, hash, key)))
1190 0 : die ("gcry_pk_verify failed (comp): %s", gpg_strerror (err));
1191 :
1192 : /* Sign without a Q parameter. */
1193 1 : gcry_sexp_release (key);
1194 1 : if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
1195 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1196 1 : gcry_sexp_release (sig);
1197 1 : if ((err = gcry_pk_sign (&sig, hash, key)))
1198 0 : die ("gcry_pk_sign w/o Q failed: %s", gpg_strerror (err));
1199 :
1200 : /* Verify. */
1201 1 : gcry_sexp_release (key);
1202 1 : if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
1203 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1204 1 : if ((err = gcry_pk_verify (sig, hash, key)))
1205 0 : die ("gcry_pk_verify signed w/o Q failed: %s", gpg_strerror (err));
1206 :
1207 : /* Verify again using a compressed public key. */
1208 1 : gcry_sexp_release (key);
1209 1 : if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
1210 0 : die ("line %d: %s", __LINE__, gpg_strerror (err));
1211 1 : if ((err = gcry_pk_verify (sig, hash, key)))
1212 0 : die ("gcry_pk_verify signed w/o Q failed (comp): %s", gpg_strerror (err));
1213 :
1214 1 : extract_cmp_data (sig, "r", ("a63123a783ef29b8276e08987daca4"
1215 : "655d0179e22199bf63691fd88eb64e15"));
1216 1 : extract_cmp_data (sig, "s", ("0d9b45c696ab90b96b08812b485df185"
1217 : "623ddaf5d02fa65ca5056cb6bd0f16f1"));
1218 :
1219 1 : gcry_sexp_release (sig);
1220 1 : gcry_sexp_release (key);
1221 1 : gcry_sexp_release (hash);
1222 1 : }
1223 :
1224 :
1225 : int
1226 1 : main (int argc, char **argv)
1227 : {
1228 1 : int debug = 0;
1229 : int i;
1230 :
1231 1 : if (argc > 1 && !strcmp (argv[1], "--verbose"))
1232 0 : verbose = 1;
1233 1 : else if (argc > 1 && !strcmp (argv[1], "--debug"))
1234 : {
1235 0 : verbose = 2;
1236 0 : debug = 1;
1237 : }
1238 :
1239 1 : gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
1240 1 : if (!gcry_check_version (GCRYPT_VERSION))
1241 0 : die ("version mismatch\n");
1242 1 : gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
1243 1 : if (debug)
1244 0 : gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
1245 : /* No valuable keys are create, so we can speed up our RNG. */
1246 1 : gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1247 :
1248 3 : for (i=0; i < 2; i++)
1249 2 : check_run ();
1250 :
1251 5 : for (i=0; i < 4; i++)
1252 4 : check_x931_derived_key (i);
1253 :
1254 1 : check_ecc_sample_key ();
1255 1 : if (!gcry_fips_mode_active ())
1256 1 : check_ed25519ecdsa_sample_key ();
1257 :
1258 1 : return !!error_count;
1259 : }
|