fips_dssvs.c revision 296465
1#include <openssl/opensslconf.h> 2 3#ifndef OPENSSL_FIPS 4# include <stdio.h> 5 6int main(int argc, char **argv) 7{ 8 printf("No FIPS DSA support\n"); 9 return (0); 10} 11#else 12 13# include <openssl/bn.h> 14# include <openssl/dsa.h> 15# include <openssl/fips.h> 16# include <openssl/err.h> 17# include <openssl/evp.h> 18# include <string.h> 19# include <ctype.h> 20 21# include "fips_utl.h" 22 23static void pbn(const char *name, BIGNUM *bn) 24{ 25 int len, i; 26 unsigned char *tmp; 27 len = BN_num_bytes(bn); 28 tmp = OPENSSL_malloc(len); 29 if (!tmp) { 30 fprintf(stderr, "Memory allocation error\n"); 31 return; 32 } 33 BN_bn2bin(bn, tmp); 34 printf("%s = ", name); 35 for (i = 0; i < len; i++) 36 printf("%02X", tmp[i]); 37 fputs("\n", stdout); 38 OPENSSL_free(tmp); 39 return; 40} 41 42static void primes() 43{ 44 char buf[10240]; 45 char lbuf[10240]; 46 char *keyword, *value; 47 48 while (fgets(buf, sizeof buf, stdin) != NULL) { 49 fputs(buf, stdout); 50 if (!parse_line(&keyword, &value, lbuf, buf)) 51 continue; 52 if (!strcmp(keyword, "Prime")) { 53 BIGNUM *pp; 54 55 pp = BN_new(); 56 do_hex2bn(&pp, value); 57 printf("result= %c\n", 58 BN_is_prime_ex(pp, 20, NULL, NULL) ? 'P' : 'F'); 59 } 60 } 61} 62 63static void pqg() 64{ 65 char buf[1024]; 66 char lbuf[1024]; 67 char *keyword, *value; 68 int nmod = 0; 69 70 while (fgets(buf, sizeof buf, stdin) != NULL) { 71 if (!parse_line(&keyword, &value, lbuf, buf)) { 72 fputs(buf, stdout); 73 continue; 74 } 75 if (!strcmp(keyword, "[mod")) 76 nmod = atoi(value); 77 else if (!strcmp(keyword, "N")) { 78 int n = atoi(value); 79 80 printf("[mod = %d]\n\n", nmod); 81 82 while (n--) { 83 unsigned char seed[20]; 84 DSA *dsa; 85 int counter; 86 unsigned long h; 87 dsa = FIPS_dsa_new(); 88 89 if (!DSA_generate_parameters_ex 90 (dsa, nmod, seed, 0, &counter, &h, NULL)) { 91 do_print_errors(); 92 exit(1); 93 } 94 pbn("P", dsa->p); 95 pbn("Q", dsa->q); 96 pbn("G", dsa->g); 97 pv("Seed", seed, 20); 98 printf("c = %d\n", counter); 99 printf("H = %lx\n", h); 100 putc('\n', stdout); 101 } 102 } else 103 fputs(buf, stdout); 104 } 105} 106 107static void pqgver() 108{ 109 char buf[1024]; 110 char lbuf[1024]; 111 char *keyword, *value; 112 BIGNUM *p = NULL, *q = NULL, *g = NULL; 113 int counter, counter2; 114 unsigned long h, h2; 115 DSA *dsa = NULL; 116 int nmod = 0; 117 unsigned char seed[1024]; 118 119 while (fgets(buf, sizeof buf, stdin) != NULL) { 120 if (!parse_line(&keyword, &value, lbuf, buf)) { 121 fputs(buf, stdout); 122 continue; 123 } 124 fputs(buf, stdout); 125 if (!strcmp(keyword, "[mod")) 126 nmod = atoi(value); 127 else if (!strcmp(keyword, "P")) 128 p = hex2bn(value); 129 else if (!strcmp(keyword, "Q")) 130 q = hex2bn(value); 131 else if (!strcmp(keyword, "G")) 132 g = hex2bn(value); 133 else if (!strcmp(keyword, "Seed")) { 134 int slen = hex2bin(value, seed); 135 if (slen != 20) { 136 fprintf(stderr, "Seed parse length error\n"); 137 exit(1); 138 } 139 } else if (!strcmp(keyword, "c")) 140 counter = atoi(buf + 4); 141 else if (!strcmp(keyword, "H")) { 142 h = atoi(value); 143 if (!p || !q || !g) { 144 fprintf(stderr, "Parse Error\n"); 145 exit(1); 146 } 147 dsa = FIPS_dsa_new(); 148 if (!DSA_generate_parameters_ex 149 (dsa, nmod, seed, 20, &counter2, &h2, NULL)) { 150 do_print_errors(); 151 exit(1); 152 } 153 if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g) 154 || (counter != counter2) || (h != h2)) 155 printf("Result = F\n"); 156 else 157 printf("Result = P\n"); 158 BN_free(p); 159 BN_free(q); 160 BN_free(g); 161 p = NULL; 162 q = NULL; 163 g = NULL; 164 FIPS_dsa_free(dsa); 165 dsa = NULL; 166 } 167 } 168} 169 170/* 171 * Keypair verification routine. NB: this isn't part of the standard 172 * FIPS140-2 algorithm tests. It is an additional test to perform sanity 173 * checks on the output of the KeyPair test. 174 */ 175 176static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g, 177 BN_CTX *ctx) 178{ 179 BIGNUM *rem = NULL; 180 if (BN_num_bits(p) != nmod) 181 return 0; 182 if (BN_num_bits(q) != 160) 183 return 0; 184 if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1) 185 return 0; 186 if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1) 187 return 0; 188 rem = BN_new(); 189 if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem) 190 || (BN_cmp(g, BN_value_one()) <= 0) 191 || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem)) { 192 BN_free(rem); 193 return 0; 194 } 195 /* Todo: check g */ 196 BN_free(rem); 197 return 1; 198} 199 200static void keyver() 201{ 202 char buf[1024]; 203 char lbuf[1024]; 204 char *keyword, *value; 205 BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL; 206 BIGNUM *Y2; 207 BN_CTX *ctx = NULL; 208 int nmod = 0, paramcheck = 0; 209 210 ctx = BN_CTX_new(); 211 Y2 = BN_new(); 212 213 while (fgets(buf, sizeof buf, stdin) != NULL) { 214 if (!parse_line(&keyword, &value, lbuf, buf)) { 215 fputs(buf, stdout); 216 continue; 217 } 218 if (!strcmp(keyword, "[mod")) { 219 if (p) 220 BN_free(p); 221 p = NULL; 222 if (q) 223 BN_free(q); 224 q = NULL; 225 if (g) 226 BN_free(g); 227 g = NULL; 228 paramcheck = 0; 229 nmod = atoi(value); 230 } else if (!strcmp(keyword, "P")) 231 p = hex2bn(value); 232 else if (!strcmp(keyword, "Q")) 233 q = hex2bn(value); 234 else if (!strcmp(keyword, "G")) 235 g = hex2bn(value); 236 else if (!strcmp(keyword, "X")) 237 X = hex2bn(value); 238 else if (!strcmp(keyword, "Y")) { 239 Y = hex2bn(value); 240 if (!p || !q || !g || !X || !Y) { 241 fprintf(stderr, "Parse Error\n"); 242 exit(1); 243 } 244 pbn("P", p); 245 pbn("Q", q); 246 pbn("G", g); 247 pbn("X", X); 248 pbn("Y", Y); 249 if (!paramcheck) { 250 if (dss_paramcheck(nmod, p, q, g, ctx)) 251 paramcheck = 1; 252 else 253 paramcheck = -1; 254 } 255 if (paramcheck != 1) 256 printf("Result = F\n"); 257 else { 258 if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y)) 259 printf("Result = F\n"); 260 else 261 printf("Result = P\n"); 262 } 263 BN_free(X); 264 BN_free(Y); 265 X = NULL; 266 Y = NULL; 267 } 268 } 269 if (p) 270 BN_free(p); 271 if (q) 272 BN_free(q); 273 if (g) 274 BN_free(g); 275 if (Y2) 276 BN_free(Y2); 277} 278 279static void keypair() 280{ 281 char buf[1024]; 282 char lbuf[1024]; 283 char *keyword, *value; 284 int nmod = 0; 285 286 while (fgets(buf, sizeof buf, stdin) != NULL) { 287 if (!parse_line(&keyword, &value, lbuf, buf)) { 288 fputs(buf, stdout); 289 continue; 290 } 291 if (!strcmp(keyword, "[mod")) 292 nmod = atoi(value); 293 else if (!strcmp(keyword, "N")) { 294 DSA *dsa; 295 int n = atoi(value); 296 297 printf("[mod = %d]\n\n", nmod); 298 dsa = FIPS_dsa_new(); 299 if (!DSA_generate_parameters_ex 300 (dsa, nmod, NULL, 0, NULL, NULL, NULL)) { 301 do_print_errors(); 302 exit(1); 303 } 304 pbn("P", dsa->p); 305 pbn("Q", dsa->q); 306 pbn("G", dsa->g); 307 putc('\n', stdout); 308 309 while (n--) { 310 if (!DSA_generate_key(dsa)) { 311 do_print_errors(); 312 exit(1); 313 } 314 315 pbn("X", dsa->priv_key); 316 pbn("Y", dsa->pub_key); 317 putc('\n', stdout); 318 } 319 } 320 } 321} 322 323static void siggen() 324{ 325 char buf[1024]; 326 char lbuf[1024]; 327 char *keyword, *value; 328 int nmod = 0; 329 DSA *dsa = NULL; 330 331 while (fgets(buf, sizeof buf, stdin) != NULL) { 332 if (!parse_line(&keyword, &value, lbuf, buf)) { 333 fputs(buf, stdout); 334 continue; 335 } 336 if (!strcmp(keyword, "[mod")) { 337 nmod = atoi(value); 338 printf("[mod = %d]\n\n", nmod); 339 if (dsa) 340 FIPS_dsa_free(dsa); 341 dsa = FIPS_dsa_new(); 342 if (!DSA_generate_parameters_ex 343 (dsa, nmod, NULL, 0, NULL, NULL, NULL)) { 344 do_print_errors(); 345 exit(1); 346 } 347 pbn("P", dsa->p); 348 pbn("Q", dsa->q); 349 pbn("G", dsa->g); 350 putc('\n', stdout); 351 } else if (!strcmp(keyword, "Msg")) { 352 unsigned char msg[1024]; 353 unsigned char sbuf[60]; 354 unsigned int slen; 355 int n; 356 EVP_PKEY pk; 357 EVP_MD_CTX mctx; 358 DSA_SIG *sig; 359 EVP_MD_CTX_init(&mctx); 360 361 n = hex2bin(value, msg); 362 pv("Msg", msg, n); 363 364 if (!DSA_generate_key(dsa)) { 365 do_print_errors(); 366 exit(1); 367 } 368 pk.type = EVP_PKEY_DSA; 369 pk.pkey.dsa = dsa; 370 pbn("Y", dsa->pub_key); 371 372 EVP_SignInit_ex(&mctx, EVP_dss1(), NULL); 373 EVP_SignUpdate(&mctx, msg, n); 374 EVP_SignFinal(&mctx, sbuf, &slen, &pk); 375 376 sig = DSA_SIG_new(); 377 FIPS_dsa_sig_decode(sig, sbuf, slen); 378 379 pbn("R", sig->r); 380 pbn("S", sig->s); 381 putc('\n', stdout); 382 DSA_SIG_free(sig); 383 EVP_MD_CTX_cleanup(&mctx); 384 } 385 } 386 if (dsa) 387 FIPS_dsa_free(dsa); 388} 389 390static void sigver() 391{ 392 DSA *dsa = NULL; 393 char buf[1024]; 394 char lbuf[1024]; 395 unsigned char msg[1024]; 396 char *keyword, *value; 397 int nmod = 0, n = 0; 398 DSA_SIG sg, *sig = &sg; 399 400 sig->r = NULL; 401 sig->s = NULL; 402 403 while (fgets(buf, sizeof buf, stdin) != NULL) { 404 if (!parse_line(&keyword, &value, lbuf, buf)) { 405 fputs(buf, stdout); 406 continue; 407 } 408 if (!strcmp(keyword, "[mod")) { 409 nmod = atoi(value); 410 if (dsa) 411 FIPS_dsa_free(dsa); 412 dsa = FIPS_dsa_new(); 413 } else if (!strcmp(keyword, "P")) 414 dsa->p = hex2bn(value); 415 else if (!strcmp(keyword, "Q")) 416 dsa->q = hex2bn(value); 417 else if (!strcmp(keyword, "G")) { 418 dsa->g = hex2bn(value); 419 420 printf("[mod = %d]\n\n", nmod); 421 pbn("P", dsa->p); 422 pbn("Q", dsa->q); 423 pbn("G", dsa->g); 424 putc('\n', stdout); 425 } else if (!strcmp(keyword, "Msg")) { 426 n = hex2bin(value, msg); 427 pv("Msg", msg, n); 428 } else if (!strcmp(keyword, "Y")) 429 dsa->pub_key = hex2bn(value); 430 else if (!strcmp(keyword, "R")) 431 sig->r = hex2bn(value); 432 else if (!strcmp(keyword, "S")) { 433 EVP_MD_CTX mctx; 434 EVP_PKEY pk; 435 unsigned char sigbuf[60]; 436 unsigned int slen; 437 int r; 438 EVP_MD_CTX_init(&mctx); 439 pk.type = EVP_PKEY_DSA; 440 pk.pkey.dsa = dsa; 441 sig->s = hex2bn(value); 442 443 pbn("Y", dsa->pub_key); 444 pbn("R", sig->r); 445 pbn("S", sig->s); 446 447 slen = FIPS_dsa_sig_encode(sigbuf, sig); 448 EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL); 449 EVP_VerifyUpdate(&mctx, msg, n); 450 r = EVP_VerifyFinal(&mctx, sigbuf, slen, &pk); 451 EVP_MD_CTX_cleanup(&mctx); 452 453 printf("Result = %c\n", r == 1 ? 'P' : 'F'); 454 putc('\n', stdout); 455 } 456 } 457} 458 459int main(int argc, char **argv) 460{ 461 if (argc != 2) { 462 fprintf(stderr, "%s [prime|pqg|pqgver|keypair|siggen|sigver]\n", 463 argv[0]); 464 exit(1); 465 } 466 if (!FIPS_mode_set(1)) { 467 do_print_errors(); 468 exit(1); 469 } 470 if (!strcmp(argv[1], "prime")) 471 primes(); 472 else if (!strcmp(argv[1], "pqg")) 473 pqg(); 474 else if (!strcmp(argv[1], "pqgver")) 475 pqgver(); 476 else if (!strcmp(argv[1], "keypair")) 477 keypair(); 478 else if (!strcmp(argv[1], "keyver")) 479 keyver(); 480 else if (!strcmp(argv[1], "siggen")) 481 siggen(); 482 else if (!strcmp(argv[1], "sigver")) 483 sigver(); 484 else { 485 fprintf(stderr, "Don't know how to %s.\n", argv[1]); 486 exit(1); 487 } 488 489 return 0; 490} 491 492#endif 493