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.h" 30 31/* Sample RSA keys, taken from basic.c. */ 32 33static const char sample_private_key_1[] = 34"(private-key\n" 35" (openpgp-rsa\n" 36" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" 37 "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" 38 "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" 39 "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" 40" (e #010001#)\n" 41" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" 42 "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" 43 "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" 44 "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" 45" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" 46 "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n" 47" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" 48 "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n" 49" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" 50 "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n" 51" )\n" 52")\n"; 53 54/* The same key as above but without p, q and u to test the non CRT case. */ 55static const char sample_private_key_1_1[] = 56"(private-key\n" 57" (openpgp-rsa\n" 58" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" 59 "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" 60 "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" 61 "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" 62" (e #010001#)\n" 63" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" 64 "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" 65 "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" 66 "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" 67" )\n" 68")\n"; 69 70/* The same key as above but just without q to test the non CRT case. This 71 should fail. */ 72static const char sample_private_key_1_2[] = 73"(private-key\n" 74" (openpgp-rsa\n" 75" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" 76 "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" 77 "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" 78 "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" 79" (e #010001#)\n" 80" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" 81 "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" 82 "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" 83 "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" 84" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" 85 "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n" 86" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" 87 "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n" 88" )\n" 89")\n"; 90 91static const char sample_public_key_1[] = 92"(public-key\n" 93" (rsa\n" 94" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" 95 "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" 96 "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" 97 "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" 98" (e #010001#)\n" 99" )\n" 100")\n"; 101 102 103static int verbose; 104 105static void 106die (const char *format, ...) 107{ 108 va_list arg_ptr ; 109 110 va_start( arg_ptr, format ) ; 111 vfprintf (stderr, format, arg_ptr ); 112 va_end(arg_ptr); 113 exit (1); 114} 115 116static void 117show_sexp (const char *prefix, gcry_sexp_t a) 118{ 119 char *buf; 120 size_t size; 121 122 if (prefix) 123 fputs (prefix, stderr); 124 size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); 125 buf = gcry_xmalloc (size); 126 127 gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); 128 fprintf (stderr, "%.*s", (int)size, buf); 129 gcry_free (buf); 130} 131 132 133static void 134check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey, 135 gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code) 136{ 137 gcry_sexp_t plain1, cipher, l; 138 gcry_mpi_t x0, x1; 139 int rc; 140 int have_flags; 141 142 /* Extract data from plaintext. */ 143 l = gcry_sexp_find_token (plain0, "value", 0); 144 x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG); 145 146 /* Encrypt data. */ 147 rc = gcry_pk_encrypt (&cipher, plain0, pkey); 148 if (rc) 149 die ("encryption failed: %s\n", gcry_strerror (rc)); 150 151 l = gcry_sexp_find_token (cipher, "flags", 0); 152 have_flags = !!l; 153 gcry_sexp_release (l); 154 155 /* Decrypt data. */ 156 rc = gcry_pk_decrypt (&plain1, cipher, skey); 157 gcry_sexp_release (cipher); 158 if (rc) 159 { 160 if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code) 161 return; /* This is the expected failure code. */ 162 die ("decryption failed: %s\n", gcry_strerror (rc)); 163 } 164 165 /* Extract decrypted data. Note that for compatibility reasons, the 166 output of gcry_pk_decrypt depends on whether a flags lists (even 167 if empty) occurs in its input data. Because we passed the output 168 of encrypt directly to decrypt, such a flag value won't be there 169 as of today. We check it anyway. */ 170 l = gcry_sexp_find_token (plain1, "value", 0); 171 if (l) 172 { 173 if (!have_flags) 174 die ("compatibility mode of pk_decrypt broken\n"); 175 gcry_sexp_release (plain1); 176 x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG); 177 gcry_sexp_release (l); 178 } 179 else 180 { 181 if (have_flags) 182 die ("compatibility mode of pk_decrypt broken\n"); 183 x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG); 184 gcry_sexp_release (plain1); 185 } 186 187 /* Compare. */ 188 if (gcry_mpi_cmp (x0, x1)) 189 die ("data corrupted\n"); 190} 191 192static void 193check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data, 194 gpg_err_code_t decrypt_fail_code) 195{ 196 gcry_sexp_t plain; 197 gcry_mpi_t x; 198 int rc; 199 200 /* Create plain text. */ 201 x = gcry_mpi_new (nbits_data); 202 gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM); 203 204 rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x); 205 if (rc) 206 die ("converting data for encryption failed: %s\n", 207 gcry_strerror (rc)); 208 209 check_keys_crypt (pkey, skey, plain, decrypt_fail_code); 210 gcry_sexp_release (plain); 211 gcry_mpi_release (x); 212 213 /* Create plain text. */ 214 x = gcry_mpi_new (nbits_data); 215 gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM); 216 217 rc = gcry_sexp_build (&plain, NULL, 218 "(data (flags raw no-blinding) (value %m))", x); 219 if (rc) 220 die ("converting data for encryption failed: %s\n", 221 gcry_strerror (rc)); 222 223 check_keys_crypt (pkey, skey, plain, decrypt_fail_code); 224 gcry_sexp_release (plain); 225} 226 227static void 228get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant) 229{ 230 gcry_sexp_t pub_key, sec_key; 231 int rc; 232 static const char *secret; 233 234 235 switch (secret_variant) 236 { 237 case 0: secret = sample_private_key_1; break; 238 case 1: secret = sample_private_key_1_1; break; 239 case 2: secret = sample_private_key_1_2; break; 240 default: die ("BUG\n"); 241 } 242 243 rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1, 244 strlen (sample_public_key_1)); 245 if (!rc) 246 rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret)); 247 if (rc) 248 die ("converting sample keys failed: %s\n", gcry_strerror (rc)); 249 250 *pkey = pub_key; 251 *skey = sec_key; 252} 253 254static void 255get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) 256{ 257 gcry_sexp_t key_spec, key, pub_key, sec_key; 258 int rc; 259 260 rc = gcry_sexp_new (&key_spec, 261 "(genkey (rsa (nbits 4:1024)))", 0, 1); 262 if (rc) 263 die ("error creating S-expression: %s\n", gcry_strerror (rc)); 264 rc = gcry_pk_genkey (&key, key_spec); 265 gcry_sexp_release (key_spec); 266 if (rc) 267 die ("error generating RSA key: %s\n", gcry_strerror (rc)); 268 269 if (verbose > 1) 270 show_sexp ("generated RSA key:\n", key); 271 272 pub_key = gcry_sexp_find_token (key, "public-key", 0); 273 if (! pub_key) 274 die ("public part missing in key\n"); 275 276 sec_key = gcry_sexp_find_token (key, "private-key", 0); 277 if (! sec_key) 278 die ("private part missing in key\n"); 279 280 gcry_sexp_release (key); 281 *pkey = pub_key; 282 *skey = sec_key; 283} 284 285 286static void 287get_keys_x931_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) 288{ 289 gcry_sexp_t key_spec, key, pub_key, sec_key; 290 int rc; 291 292 rc = gcry_sexp_new (&key_spec, 293 "(genkey (rsa (nbits 4:1024)(use-x931)))", 0, 1); 294 if (rc) 295 die ("error creating S-expression: %s\n", gcry_strerror (rc)); 296 rc = gcry_pk_genkey (&key, key_spec); 297 gcry_sexp_release (key_spec); 298 if (rc) 299 die ("error generating RSA key: %s\n", gcry_strerror (rc)); 300 301 if (verbose > 1) 302 show_sexp ("generated RSA (X9.31) key:\n", key); 303 304 pub_key = gcry_sexp_find_token (key, "public-key", 0); 305 if (!pub_key) 306 die ("public part missing in key\n"); 307 308 sec_key = gcry_sexp_find_token (key, "private-key", 0); 309 if (!sec_key) 310 die ("private part missing in key\n"); 311 312 gcry_sexp_release (key); 313 *pkey = pub_key; 314 *skey = sec_key; 315} 316 317 318static void 319get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x) 320{ 321 gcry_sexp_t key_spec, key, pub_key, sec_key; 322 int rc; 323 324 rc = gcry_sexp_new 325 (&key_spec, 326 (fixed_x 327 ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))" 328 : "(genkey (elg (nbits 3:512)))"), 329 0, 1); 330 331 if (rc) 332 die ("error creating S-expression: %s\n", gcry_strerror (rc)); 333 rc = gcry_pk_genkey (&key, key_spec); 334 gcry_sexp_release (key_spec); 335 if (rc) 336 die ("error generating Elgamal key: %s\n", gcry_strerror (rc)); 337 338 if (verbose > 1) 339 show_sexp ("generated ELG key:\n", key); 340 341 pub_key = gcry_sexp_find_token (key, "public-key", 0); 342 if (!pub_key) 343 die ("public part missing in key\n"); 344 345 sec_key = gcry_sexp_find_token (key, "private-key", 0); 346 if (!sec_key) 347 die ("private part missing in key\n"); 348 349 gcry_sexp_release (key); 350 *pkey = pub_key; 351 *skey = sec_key; 352} 353 354 355static void 356get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key) 357{ 358 gcry_sexp_t key_spec, key, pub_key, sec_key; 359 int rc; 360 361 rc = gcry_sexp_new (&key_spec, 362 transient_key 363 ? "(genkey (dsa (nbits 4:1024)(transient-key)))" 364 : "(genkey (dsa (nbits 4:1024)))", 365 0, 1); 366 if (rc) 367 die ("error creating S-expression: %s\n", gcry_strerror (rc)); 368 rc = gcry_pk_genkey (&key, key_spec); 369 gcry_sexp_release (key_spec); 370 if (rc) 371 die ("error generating DSA key: %s\n", gcry_strerror (rc)); 372 373 if (verbose > 1) 374 show_sexp ("generated DSA key:\n", key); 375 376 pub_key = gcry_sexp_find_token (key, "public-key", 0); 377 if (!pub_key) 378 die ("public part missing in key\n"); 379 380 sec_key = gcry_sexp_find_token (key, "private-key", 0); 381 if (!sec_key) 382 die ("private part missing in key\n"); 383 384 gcry_sexp_release (key); 385 *pkey = pub_key; 386 *skey = sec_key; 387} 388 389 390static void 391get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) 392{ 393 gcry_sexp_t key_spec, key, pub_key, sec_key; 394 int rc; 395 396 rc = gcry_sexp_new 397 (&key_spec, "(genkey (dsa (nbits 4:1024)(use-fips186)))", 0, 1); 398 if (rc) 399 die ("error creating S-expression: %s\n", gcry_strerror (rc)); 400 rc = gcry_pk_genkey (&key, key_spec); 401 gcry_sexp_release (key_spec); 402 if (rc) 403 die ("error generating DSA key: %s\n", gcry_strerror (rc)); 404 405 if (verbose > 1) 406 show_sexp ("generated DSA key (fips 186):\n", key); 407 408 pub_key = gcry_sexp_find_token (key, "public-key", 0); 409 if (!pub_key) 410 die ("public part missing in key\n"); 411 412 sec_key = gcry_sexp_find_token (key, "private-key", 0); 413 if (!sec_key) 414 die ("private part missing in key\n"); 415 416 gcry_sexp_release (key); 417 *pkey = pub_key; 418 *skey = sec_key; 419} 420 421 422static void 423get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) 424{ 425 gcry_sexp_t key_spec, key, pub_key, sec_key; 426 int rc; 427 428 rc = gcry_sexp_new 429 (&key_spec, 430 "(genkey (dsa (transient-key)(domain" 431 "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" 432 "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" 433 "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" 434 "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" 435 "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" 436 "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" 437 "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" 438 "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" 439 "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" 440 ")))", 0, 1); 441 if (rc) 442 die ("error creating S-expression: %s\n", gcry_strerror (rc)); 443 rc = gcry_pk_genkey (&key, key_spec); 444 gcry_sexp_release (key_spec); 445 if (rc) 446 die ("error generating DSA key: %s\n", gcry_strerror (rc)); 447 448 if (verbose > 1) 449 show_sexp ("generated DSA key:\n", key); 450 451 pub_key = gcry_sexp_find_token (key, "public-key", 0); 452 if (!pub_key) 453 die ("public part missing in key\n"); 454 455 sec_key = gcry_sexp_find_token (key, "private-key", 0); 456 if (!sec_key) 457 die ("private part missing in key\n"); 458 459 gcry_sexp_release (key); 460 *pkey = pub_key; 461 *skey = sec_key; 462} 463 464static void 465get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) 466{ 467 gcry_sexp_t key_spec, key, pub_key, sec_key; 468 int rc; 469 470 rc = gcry_sexp_new 471 (&key_spec, 472 "(genkey (dsa (transient-key)(use-fips186)(domain" 473 "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" 474 "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" 475 "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" 476 "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" 477 "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" 478 "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" 479 "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" 480 "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" 481 "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" 482 ")))", 0, 1); 483 if (rc) 484 die ("error creating S-expression: %s\n", gcry_strerror (rc)); 485 rc = gcry_pk_genkey (&key, key_spec); 486 gcry_sexp_release (key_spec); 487 if (rc) 488 die ("error generating DSA key: %s\n", gcry_strerror (rc)); 489 490 if (verbose > 1) 491 show_sexp ("generated DSA key:\n", key); 492 493 pub_key = gcry_sexp_find_token (key, "public-key", 0); 494 if (!pub_key) 495 die ("public part missing in key\n"); 496 497 sec_key = gcry_sexp_find_token (key, "private-key", 0); 498 if (!sec_key) 499 die ("private part missing in key\n"); 500 501 gcry_sexp_release (key); 502 *pkey = pub_key; 503 *skey = sec_key; 504} 505 506 507static void 508get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) 509{ 510 gcry_sexp_t key_spec, key, pub_key, sec_key; 511 int rc; 512 513 rc = gcry_sexp_new 514 (&key_spec, 515 "(genkey" 516 " (dsa" 517 " (nbits 4:1024)" 518 " (use-fips186)" 519 " (transient-key)" 520 " (derive-parms" 521 " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))", 522 0, 1); 523 if (rc) 524 die ("error creating S-expression: %s\n", gcry_strerror (rc)); 525 rc = gcry_pk_genkey (&key, key_spec); 526 gcry_sexp_release (key_spec); 527 if (rc) 528 die ("error generating DSA key: %s\n", gcry_strerror (rc)); 529 530 if (verbose > 1) 531 show_sexp ("generated DSA key (fips 186 with seed):\n", key); 532 533 pub_key = gcry_sexp_find_token (key, "public-key", 0); 534 if (!pub_key) 535 die ("public part missing in key\n"); 536 537 sec_key = gcry_sexp_find_token (key, "private-key", 0); 538 if (!sec_key) 539 die ("private part missing in key\n"); 540 541 gcry_sexp_release (key); 542 *pkey = pub_key; 543 *skey = sec_key; 544} 545 546 547static void 548check_run (void) 549{ 550 gpg_error_t err; 551 gcry_sexp_t pkey, skey; 552 int variant; 553 554 for (variant=0; variant < 3; variant++) 555 { 556 if (verbose) 557 fprintf (stderr, "Checking sample key (%d).\n", variant); 558 get_keys_sample (&pkey, &skey, variant); 559 /* Check gcry_pk_testkey which requires all elements. */ 560 err = gcry_pk_testkey (skey); 561 if ((variant == 0 && err) 562 || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ)) 563 die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err)); 564 /* Run the usual check but expect an error from variant 2. */ 565 check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0); 566 gcry_sexp_release (pkey); 567 gcry_sexp_release (skey); 568 } 569 570 if (verbose) 571 fprintf (stderr, "Checking generated RSA key.\n"); 572 get_keys_new (&pkey, &skey); 573 check_keys (pkey, skey, 800, 0); 574 gcry_sexp_release (pkey); 575 gcry_sexp_release (skey); 576 577 if (verbose) 578 fprintf (stderr, "Checking generated RSA key (X9.31).\n"); 579 get_keys_x931_new (&pkey, &skey); 580 check_keys (pkey, skey, 800, 0); 581 gcry_sexp_release (pkey); 582 gcry_sexp_release (skey); 583 584 if (verbose) 585 fprintf (stderr, "Checking generated Elgamal key.\n"); 586 get_elg_key_new (&pkey, &skey, 0); 587 check_keys (pkey, skey, 400, 0); 588 gcry_sexp_release (pkey); 589 gcry_sexp_release (skey); 590 591 if (verbose) 592 fprintf (stderr, "Checking passphrase generated Elgamal key.\n"); 593 get_elg_key_new (&pkey, &skey, 1); 594 check_keys (pkey, skey, 800, 0); 595 gcry_sexp_release (pkey); 596 gcry_sexp_release (skey); 597 598 if (verbose) 599 fprintf (stderr, "Generating DSA key.\n"); 600 get_dsa_key_new (&pkey, &skey, 0); 601 /* Fixme: Add a check function for DSA keys. */ 602 gcry_sexp_release (pkey); 603 gcry_sexp_release (skey); 604 605 if (!gcry_fips_mode_active ()) 606 { 607 if (verbose) 608 fprintf (stderr, "Generating transient DSA key.\n"); 609 get_dsa_key_new (&pkey, &skey, 1); 610 /* Fixme: Add a check function for DSA keys. */ 611 gcry_sexp_release (pkey); 612 gcry_sexp_release (skey); 613 } 614 615 if (verbose) 616 fprintf (stderr, "Generating DSA key (FIPS 186).\n"); 617 get_dsa_key_fips186_new (&pkey, &skey); 618 /* Fixme: Add a check function for DSA keys. */ 619 gcry_sexp_release (pkey); 620 gcry_sexp_release (skey); 621 622 if (verbose) 623 fprintf (stderr, "Generating DSA key with given domain.\n"); 624 get_dsa_key_with_domain_new (&pkey, &skey); 625 /* Fixme: Add a check function for DSA keys. */ 626 gcry_sexp_release (pkey); 627 gcry_sexp_release (skey); 628 629 if (verbose) 630 fprintf (stderr, "Generating DSA key with given domain (FIPS 186).\n"); 631 get_dsa_key_fips186_with_domain_new (&pkey, &skey); 632 /* Fixme: Add a check function for DSA keys. */ 633 gcry_sexp_release (pkey); 634 gcry_sexp_release (skey); 635 636 if (verbose) 637 fprintf (stderr, "Generating DSA key with given seed (FIPS 186).\n"); 638 get_dsa_key_fips186_with_seed_new (&pkey, &skey); 639 /* Fixme: Add a check function for DSA keys. */ 640 gcry_sexp_release (pkey); 641 gcry_sexp_release (skey); 642} 643 644 645 646static gcry_mpi_t 647key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name) 648{ 649 gcry_sexp_t l1, l2; 650 gcry_mpi_t result; 651 652 l1 = gcry_sexp_find_token (sexp, topname, 0); 653 if (!l1) 654 return NULL; 655 656 l2 = gcry_sexp_find_token (l1, name, 0); 657 if (!l2) 658 { 659 gcry_sexp_release (l1); 660 return NULL; 661 } 662 663 result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); 664 gcry_sexp_release (l2); 665 gcry_sexp_release (l1); 666 return result; 667} 668 669 670static void 671check_x931_derived_key (int what) 672{ 673 static struct { 674 const char *param; 675 const char *expected_d; 676 } testtable[] = { 677 { /* First example from X9.31 (D.1.1). */ 678 "(genkey\n" 679 " (rsa\n" 680 " (nbits 4:1024)\n" 681 " (rsa-use-e 1:3)\n" 682 " (derive-parms\n" 683 " (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n" 684 " (Xp2 #192E8AAC41C576C822D93EA433#)\n" 685 " (Xp #D8CD81F035EC57EFE822955149D3BFF70C53520D\n" 686 " 769D6D76646C7A792E16EBD89FE6FC5B605A6493\n" 687 " 39DFC925A86A4C6D150B71B9EEA02D68885F5009\n" 688 " B98BD984#)\n" 689 " (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n" 690 " (Xq2 #134E4CAA16D2350A21D775C404#)\n" 691 " (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n" 692 " 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n" 693 " 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n" 694 " 321DE34A#))))\n", 695 "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173" 696 "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961" 697 "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE" 698 "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13" 699 "241D3C4B" 700 }, 701 702 { /* Second example from X9.31 (D.2.1). */ 703 "(genkey\n" 704 " (rsa\n" 705 " (nbits 4:1536)\n" 706 " (rsa-use-e 1:3)\n" 707 " (derive-parms\n" 708 " (Xp1 #18272558B61316348297EACA74#)\n" 709 " (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n" 710 " (Xp #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n" 711 " 0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n" 712 " 60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n" 713 " 318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n" 714 " EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n" 715 " (Xq1 #11FDDA6E8128DC1629F75192BA#)\n" 716 " (Xq2 #18AB178ECA907D72472F65E480#)\n" 717 " (Xq #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n" 718 " CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n" 719 " B734E3FBD15862EBC59FA0425DFA131E549136E8\n" 720 " E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n" 721 " EA14B9D5F2A263DC65626E4D6CEAC767#))))\n", 722 "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1" 723 "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2" 724 "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383" 725 "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9" 726 "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C" 727 "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0" 728 "BBCCB9F65C83" 729 /* Note that this example in X9.31 gives this value for D: 730 731 "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44" 732 "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8" 733 "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E" 734 "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7" 735 "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270" 736 "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342" 737 "EF32E7D9720B" 738 739 This is a bug in X9.31, obviously introduced by using 740 741 d = e^{-1} mod (p-1)(q-1) 742 743 instead of using the universal exponent as required by 4.1.3: 744 745 d = e^{-1} mod lcm(p-1,q-1) 746 747 The examples in X9.31 seem to be pretty buggy, see 748 cipher/primegen.c for another bug. Not only that I had to 749 spend 100 USD for the 66 pages of the document, it also took 750 me several hours to figure out that the bugs are in the 751 document and not in my code. 752 */ 753 }, 754 755 { /* First example from NIST RSAVS (B.1.1). */ 756 "(genkey\n" 757 " (rsa\n" 758 " (nbits 4:1024)\n" 759 " (rsa-use-e 1:3)\n" 760 " (derive-parms\n" 761 " (Xp1 #1ed3d6368e101dab9124c92ac8#)\n" 762 " (Xp2 #16e5457b8844967ce83cab8c11#)\n" 763 " (Xp #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n" 764 " ab262da1dcda8194720672a4e02229a0c71f60ae\n" 765 " c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n" 766 " cab44595#)\n" 767 " (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n" 768 " (Xq2 #1f9cca85f185341516d92e82fd#)\n" 769 " (Xq #c8387fd38fa33ddcea6a9de1b2d55410663502db\n" 770 " c225655a9310cceac9f4cf1bce653ec916d45788\n" 771 " f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n" 772 " 2f389eda#))))\n", 773 "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b" 774 "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd" 775 "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a" 776 "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0" 777 "dc7e8feb" 778 }, 779 780 { /* Second example from NIST RSAVS (B.1.1). */ 781 "(genkey\n" 782 " (rsa\n" 783 " (nbits 4:1536)\n" 784 " (rsa-use-e 1:3)\n" 785 " (derive-parms\n" 786 " (Xp1 #1e64c1af460dff8842c22b64d0#)\n" 787 " (Xp2 #1e948edcedba84039c81f2ac0c#)\n" 788 " (Xp #c8c67df894c882045ede26a9008ab09ea0672077\n" 789 " d7bc71d412511cd93981ddde8f91b967da404056\n" 790 " c39f105f7f239abdaff92923859920f6299e82b9\n" 791 " 5bd5b8c959948f4a034d81613d6235a3953b49ce\n" 792 " 26974eb7bb1f14843841281b363b9cdb#)\n" 793 " (Xq1 #1f3df0f017ddd05611a97b6adb#)\n" 794 " (Xq2 #143edd7b22d828913abf24ca4d#)\n" 795 " (Xq #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n" 796 " b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n" 797 " 7552195fae8b061077e03920814d8b9cfb5a3958\n" 798 " b3a82c2a7fc97e55db543948d3396289245336ec\n" 799 " 9e3cb308cc655aebd766340da8921383#))))\n", 800 "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184" 801 "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536" 802 "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461" 803 "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a" 804 "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2" 805 "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4" 806 "2ccf8a84835b" 807 } 808 }; 809 gpg_error_t err; 810 gcry_sexp_t key_spec, key, pub_key, sec_key; 811 gcry_mpi_t d_expected, d_have; 812 813 if (what < 0 && what >= sizeof testtable) 814 die ("invalid WHAT value\n"); 815 816 err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1); 817 if (err) 818 die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err)); 819 820 err = gcry_pk_genkey (&key, key_spec); 821 gcry_sexp_release (key_spec); 822 if (err) 823 die ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err)); 824 825 pub_key = gcry_sexp_find_token (key, "public-key", 0); 826 if (!pub_key) 827 die ("public part missing in key [%d]\n", what); 828 829 sec_key = gcry_sexp_find_token (key, "private-key", 0); 830 if (!sec_key) 831 die ("private part missing in key [%d]\n", what); 832 833 err = gcry_mpi_scan 834 (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL); 835 if (err) 836 die ("error converting string [%d]\n", what); 837 838 if (verbose > 1) 839 show_sexp ("generated key:\n", key); 840 841 d_have = key_param_from_sexp (sec_key, "rsa", "d"); 842 if (!d_have) 843 die ("parameter d not found in RSA secret key [%d]\n", what); 844 if (gcry_mpi_cmp (d_expected, d_have)) 845 { 846 show_sexp (NULL, sec_key); 847 die ("parameter d does match expected value [%d]\n", what); 848 } 849 gcry_mpi_release (d_expected); 850 gcry_mpi_release (d_have); 851 852 gcry_sexp_release (key); 853 gcry_sexp_release (pub_key); 854 gcry_sexp_release (sec_key); 855} 856 857 858 859 860int 861main (int argc, char **argv) 862{ 863 int debug = 0; 864 int i; 865 866 if (argc > 1 && !strcmp (argv[1], "--verbose")) 867 verbose = 1; 868 else if (argc > 1 && !strcmp (argv[1], "--debug")) 869 { 870 verbose = 2; 871 debug = 1; 872 } 873 874 gcry_control (GCRYCTL_DISABLE_SECMEM, 0); 875 if (!gcry_check_version (GCRYPT_VERSION)) 876 die ("version mismatch\n"); 877 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); 878 if (debug) 879 gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); 880 /* No valuable keys are create, so we can speed up our RNG. */ 881 gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); 882 883 for (i=0; i < 2; i++) 884 check_run (); 885 886 for (i=0; i < 4; i++) 887 check_x931_derived_key (i); 888 889 return 0; 890} 891