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