2 #define OPENSSL_FIPSAPI
3 #include <openssl/opensslconf.h>
8 int main(int argc, char **argv)
10 printf("No FIPS DSA support\n");
15 #include <openssl/bn.h>
16 #include <openssl/dsa.h>
17 #include <openssl/fips.h>
18 #include <openssl/err.h>
19 #include <openssl/evp.h>
25 static int parse_mod(char *line, int *pdsa2, int *pL, int *pN,
29 char *keyword, *value;
32 p = strchr(line, ',');
44 if (!parse_line2(&keyword, &value, lbuf, line, 0))
46 if (strcmp(keyword, "L"))
51 p = strchr(line, ',');
53 p = strchr(line, ']');
57 if (!parse_line2(&keyword, &value, lbuf, line, 0))
59 if (strcmp(keyword, "N"))
65 p = strchr(line, ']');
72 if (!strcmp(p, "SHA-1"))
74 else if (!strcmp(p, "SHA-224"))
76 else if (!strcmp(p, "SHA-256"))
78 else if (!strcmp(p, "SHA-384"))
80 else if (!strcmp(p, "SHA-512"))
87 static void primes(FILE *in, FILE *out)
91 char *keyword, *value;
93 while(fgets(buf,sizeof buf,in) != NULL)
96 if (!parse_line(&keyword, &value, lbuf, buf))
98 if(!strcmp(keyword,"Prime"))
103 do_hex2bn(&pp,value);
104 fprintf(out, "result= %c" RESP_EOL,
105 BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
110 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
111 const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
112 unsigned char *seed_out,
113 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
114 int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
115 const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
116 int idx, unsigned char *seed_out,
117 int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
119 int dsa_paramgen_check_g(DSA *dsa);
121 static void pqg(FILE *in, FILE *out)
125 char *keyword, *value;
127 const EVP_MD *md = NULL;
128 BIGNUM *p = NULL, *q = NULL;
129 enum pqtype { PQG_NONE, PQG_PQ, PQG_G, PQG_GCANON}
131 int seedlen=-1, idxlen, idx = -1;
132 unsigned char seed[1024], idtmp[1024];
134 while(fgets(buf,sizeof buf,in) != NULL)
138 if (strstr(buf, "Probable"))
140 else if (strstr(buf, "Unverifiable"))
142 else if (strstr(buf, "Canonical"))
143 pqg_type = PQG_GCANON;
145 if (!parse_line(&keyword, &value, lbuf, buf))
150 if (strcmp(keyword, "Num"))
152 if(!strcmp(keyword,"[mod"))
154 if (!parse_mod(value, &dsa2, &L, &N, &md))
156 fprintf(stderr, "Mod Parse Error\n");
160 else if(!strcmp(keyword,"N")
161 || (!strcmp(keyword, "Num") && pqg_type == PQG_PQ))
170 dsa = FIPS_dsa_new();
172 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
176 fprintf(stderr, "Parameter Generation error\n");
179 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
181 &counter, &h, NULL) <= 0)
183 fprintf(stderr, "Parameter Generation error\n");
187 do_bn_print_name(out, "P",dsa->p);
188 do_bn_print_name(out, "Q",dsa->q);
190 do_bn_print_name(out, "G",dsa->g);
191 OutputValue(dsa2 ? "domain_parameter_seed" : "Seed",
192 seed, M_EVP_MD_size(md), out, 0);
195 fprintf(out, "c = %d" RESP_EOL, counter);
196 fprintf(out, "H = %lx" RESP_EOL RESP_EOL,h);
200 fprintf(out, "counter = %d" RESP_EOL RESP_EOL, counter);
204 else if(!strcmp(keyword,"P"))
206 else if(!strcmp(keyword,"Q"))
208 else if(!strcmp(keyword,"domain_parameter_seed"))
209 seedlen = hex2bin(value, seed);
210 else if(!strcmp(keyword,"firstseed"))
211 seedlen = hex2bin(value, seed);
212 else if(!strcmp(keyword,"pseed"))
213 seedlen += hex2bin(value, seed + seedlen);
214 else if(!strcmp(keyword,"qseed"))
215 seedlen += hex2bin(value, seed + seedlen);
216 else if(!strcmp(keyword,"index"))
218 idxlen = hex2bin(value, idtmp);
221 fprintf(stderr, "Index value error\n");
226 if ((idx >= 0 && pqg_type == PQG_GCANON) || (q && pqg_type == PQG_G))
229 dsa = FIPS_dsa_new();
233 if (dsa_builtin_paramgen2(dsa, L, N, md,
234 seed, seedlen, idx, NULL,
235 NULL, NULL, NULL) <= 0)
237 fprintf(stderr, "Parameter Generation error\n");
240 do_bn_print_name(out, "G",dsa->g);
247 static void pqgver(FILE *in, FILE *out)
251 char *keyword, *value;
252 BIGNUM *p = NULL, *q = NULL, *g = NULL;
253 int counter=-1, counter2;
254 unsigned long h=0, h2;
256 int dsa2, L, N, part_test = 0;
257 const EVP_MD *md = NULL;
258 int seedlen=-1, idxlen, idx = -1;
259 unsigned char seed[1024], idtmp[1024];
261 while(fgets(buf,sizeof buf,in) != NULL)
263 if (!parse_line(&keyword, &value, lbuf, buf))
274 if(!strcmp(keyword,"[mod"))
276 if (!parse_mod(value, &dsa2, &L, &N, &md))
278 fprintf(stderr, "Mod Parse Error\n");
282 else if(!strcmp(keyword,"P"))
284 else if(!strcmp(keyword,"Q"))
286 else if(!strcmp(keyword,"G"))
288 else if(!strcmp(keyword,"firstseed"))
289 seedlen = hex2bin(value, seed);
290 else if(!strcmp(keyword,"pseed"))
291 seedlen += hex2bin(value, seed + seedlen);
292 else if(!strcmp(keyword,"qseed"))
293 seedlen += hex2bin(value, seed + seedlen);
294 else if(!strcmp(keyword,"Seed")
295 || !strcmp(keyword,"domain_parameter_seed"))
297 seedlen = hex2bin(value, seed);
298 if (!dsa2 && seedlen != 20)
300 fprintf(stderr, "Seed parse length error\n");
306 else if(!strcmp(keyword,"index"))
308 idxlen = hex2bin(value, idtmp);
311 fprintf(stderr, "Index value error\n");
316 else if(!strcmp(keyword,"c"))
317 counter = atoi(buf+4);
319 if (part_test && idx < 0 && h == 0 && g)
321 dsa = FIPS_dsa_new();
325 if (dsa_paramgen_check_g(dsa))
326 fprintf(out, "Result = P" RESP_EOL);
328 fprintf(out, "Result = F" RESP_EOL);
339 else if(!strcmp(keyword,"H") || part_test)
343 if (!p || !q || (!g && !part_test))
345 fprintf(stderr, "Parse Error\n");
348 dsa = FIPS_dsa_new();
355 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
357 &counter2, &h2, NULL))
359 fprintf(stderr, "Parameter Generation error\n");
362 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
363 seed, seedlen, idx, NULL,
364 &counter2, &h2, NULL) < 0)
366 fprintf(stderr, "Parameter Generation error\n");
372 if (BN_cmp(dsa->g, g))
373 fprintf(out, "Result = F" RESP_EOL);
375 fprintf(out, "Result = P" RESP_EOL);
377 else if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) ||
379 ((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2)))))
380 fprintf(out, "Result = F" RESP_EOL);
382 fprintf(out, "Result = P" RESP_EOL);
402 /* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
403 * algorithm tests. It is an additional test to perform sanity checks on the
404 * output of the KeyPair test.
407 static int dss_paramcheck(int L, int N, BIGNUM *p, BIGNUM *q, BIGNUM *g,
411 if (BN_num_bits(p) != L)
413 if (BN_num_bits(q) != N)
415 if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
417 if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
420 if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
421 || (BN_cmp(g, BN_value_one()) <= 0)
422 || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
432 static void keyver(FILE *in, FILE *out)
436 char *keyword, *value;
437 BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
446 while(fgets(buf,sizeof buf,in) != NULL)
448 if (!parse_line(&keyword, &value, lbuf, buf))
453 if(!strcmp(keyword,"[mod"))
465 if (!parse_mod(value, &dsa2, &L, &N, NULL))
467 fprintf(stderr, "Mod Parse Error\n");
471 else if(!strcmp(keyword,"P"))
473 else if(!strcmp(keyword,"Q"))
475 else if(!strcmp(keyword,"G"))
477 else if(!strcmp(keyword,"X"))
479 else if(!strcmp(keyword,"Y"))
482 if (!p || !q || !g || !X || !Y)
484 fprintf(stderr, "Parse Error\n");
487 do_bn_print_name(out, "P",p);
488 do_bn_print_name(out, "Q",q);
489 do_bn_print_name(out, "G",g);
490 do_bn_print_name(out, "X",X);
491 do_bn_print_name(out, "Y",Y);
494 if (dss_paramcheck(L, N, p, q, g, ctx))
500 fprintf(out, "Result = F" RESP_EOL);
503 if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
504 fprintf(out, "Result = F" RESP_EOL);
506 fprintf(out, "Result = P" RESP_EOL);
524 static void keypair(FILE *in, FILE *out)
528 char *keyword, *value;
531 while(fgets(buf,sizeof buf,in) != NULL)
533 if (!parse_line(&keyword, &value, lbuf, buf))
537 if(!strcmp(keyword,"[mod"))
539 if (!parse_mod(value, &dsa2, &L, &N, NULL))
541 fprintf(stderr, "Mod Parse Error\n");
546 else if(!strcmp(keyword,"N"))
551 dsa = FIPS_dsa_new();
552 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
553 NULL, NULL, NULL, NULL))
555 fprintf(stderr, "Parameter Generation error\n");
558 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1,
559 NULL, NULL, NULL, NULL) <= 0)
561 fprintf(stderr, "Parameter Generation error\n");
564 do_bn_print_name(out, "P",dsa->p);
565 do_bn_print_name(out, "Q",dsa->q);
566 do_bn_print_name(out, "G",dsa->g);
567 fputs(RESP_EOL, out);
571 if (!DSA_generate_key(dsa))
574 do_bn_print_name(out, "X",dsa->priv_key);
575 do_bn_print_name(out, "Y",dsa->pub_key);
576 fputs(RESP_EOL, out);
582 static void siggen(FILE *in, FILE *out)
586 char *keyword, *value;
588 const EVP_MD *md = NULL;
591 while(fgets(buf,sizeof buf,in) != NULL)
593 if (!parse_line(&keyword, &value, lbuf, buf))
599 if(!strcmp(keyword,"[mod"))
601 if (!parse_mod(value, &dsa2, &L, &N, &md))
603 fprintf(stderr, "Mod Parse Error\n");
608 dsa = FIPS_dsa_new();
609 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0,
610 NULL, NULL, NULL, NULL))
612 fprintf(stderr, "Parameter Generation error\n");
615 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1,
616 NULL, NULL, NULL, NULL) <= 0)
618 fprintf(stderr, "Parameter Generation error\n");
621 do_bn_print_name(out, "P",dsa->p);
622 do_bn_print_name(out, "Q",dsa->q);
623 do_bn_print_name(out, "G",dsa->g);
624 fputs(RESP_EOL, out);
626 else if(!strcmp(keyword,"Msg"))
628 unsigned char msg[1024];
632 FIPS_md_ctx_init(&mctx);
634 n=hex2bin(value,msg);
636 if (!DSA_generate_key(dsa))
638 do_bn_print_name(out, "Y",dsa->pub_key);
640 FIPS_digestinit(&mctx, md);
641 FIPS_digestupdate(&mctx, msg, n);
642 sig = FIPS_dsa_sign_ctx(dsa, &mctx);
644 do_bn_print_name(out, "R",sig->r);
645 do_bn_print_name(out, "S",sig->s);
646 fputs(RESP_EOL, out);
647 FIPS_dsa_sig_free(sig);
648 FIPS_md_ctx_cleanup(&mctx);
655 static void sigver(FILE *in, FILE *out)
660 unsigned char msg[1024];
661 char *keyword, *value;
664 const EVP_MD *md = NULL;
665 DSA_SIG sg, *sig = &sg;
670 while(fgets(buf,sizeof buf,in) != NULL)
672 if (!parse_line(&keyword, &value, lbuf, buf))
678 if(!strcmp(keyword,"[mod"))
680 if (!parse_mod(value, &dsa2, &L, &N, &md))
682 fprintf(stderr, "Mod Parse Error\n");
687 dsa = FIPS_dsa_new();
689 else if(!strcmp(keyword,"P"))
690 dsa->p=hex2bn(value);
691 else if(!strcmp(keyword,"Q"))
692 dsa->q=hex2bn(value);
693 else if(!strcmp(keyword,"G"))
694 dsa->g=hex2bn(value);
695 else if(!strcmp(keyword,"Msg"))
696 n=hex2bin(value,msg);
697 else if(!strcmp(keyword,"Y"))
698 dsa->pub_key=hex2bn(value);
699 else if(!strcmp(keyword,"R"))
700 sig->r=hex2bn(value);
701 else if(!strcmp(keyword,"S"))
705 FIPS_md_ctx_init(&mctx);
706 sig->s=hex2bn(value);
708 FIPS_digestinit(&mctx, md);
709 FIPS_digestupdate(&mctx, msg, n);
711 r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
713 FIPS_md_ctx_cleanup(&mctx);
715 fprintf(out, "Result = %c" RESP_EOL RESP_EOL, r == 1 ? 'P' : 'F');
720 int main(int argc,char **argv)
725 in = fopen(argv[2], "r");
728 fprintf(stderr, "Error opening input file\n");
731 out = fopen(argv[3], "w");
734 fprintf(stderr, "Error opening output file\n");
745 fprintf(stderr,"%s [prime|pqg|pqgver|keypair|keyver|siggen|sigver]\n",argv[0]);
749 if(!strcmp(argv[1],"prime"))
751 else if(!strcmp(argv[1],"pqg"))
753 else if(!strcmp(argv[1],"pqgver"))
755 else if(!strcmp(argv[1],"keypair"))
757 else if(!strcmp(argv[1],"keyver"))
759 else if(!strcmp(argv[1],"siggen"))
761 else if(!strcmp(argv[1],"sigver"))
765 fprintf(stderr,"Don't know how to %s.\n",argv[1]);