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