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 { 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 43static 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 66static 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,NULL)) 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 115static 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,NULL)) 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 190static 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 215static 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 302static 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 351static 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 424static 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 502int 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 538