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 static void pqg(FILE *in, FILE *out)
123 char *keyword, *value;
125 const EVP_MD *md = NULL;
126 BIGNUM *p = NULL, *q = NULL;
127 enum pqtype { PQG_NONE, PQG_PQ, PQG_G, PQG_GCANON}
129 int seedlen=-1, idxlen, idx = -1;
130 unsigned char seed[1024], idtmp[1024];
132 while(fgets(buf,sizeof buf,in) != NULL)
136 if (strstr(buf, "Probable"))
138 else if (strstr(buf, "Unverifiable"))
140 else if (strstr(buf, "Canonical"))
141 pqg_type = PQG_GCANON;
143 if (!parse_line(&keyword, &value, lbuf, buf))
148 if (strcmp(keyword, "Num"))
150 if(!strcmp(keyword,"[mod"))
152 if (!parse_mod(value, &dsa2, &L, &N, &md))
154 fprintf(stderr, "Mod Parse Error\n");
158 else if(!strcmp(keyword,"N")
159 || (!strcmp(keyword, "Num") && pqg_type == PQG_PQ))
168 dsa = FIPS_dsa_new();
170 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
174 fprintf(stderr, "Parameter Generation error\n");
177 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
179 &counter, &h, NULL) <= 0)
181 fprintf(stderr, "Parameter Generation error\n");
185 do_bn_print_name(out, "P",dsa->p);
186 do_bn_print_name(out, "Q",dsa->q);
188 do_bn_print_name(out, "G",dsa->g);
189 OutputValue(dsa2 ? "domain_parameter_seed" : "Seed",
190 seed, M_EVP_MD_size(md), out, 0);
193 fprintf(out, "c = %d" RESP_EOL, counter);
194 fprintf(out, "H = %lx" RESP_EOL RESP_EOL,h);
198 fprintf(out, "counter = %d" RESP_EOL RESP_EOL, counter);
202 else if(!strcmp(keyword,"P"))
204 else if(!strcmp(keyword,"Q"))
206 else if(!strcmp(keyword,"domain_parameter_seed"))
207 seedlen = hex2bin(value, seed);
208 else if(!strcmp(keyword,"firstseed"))
209 seedlen = hex2bin(value, seed);
210 else if(!strcmp(keyword,"pseed"))
211 seedlen += hex2bin(value, seed + seedlen);
212 else if(!strcmp(keyword,"qseed"))
213 seedlen += hex2bin(value, seed + seedlen);
214 else if(!strcmp(keyword,"index"))
216 idxlen = hex2bin(value, idtmp);
219 fprintf(stderr, "Index value error\n");
224 if ((idx >= 0 && pqg_type == PQG_GCANON) || (q && pqg_type == PQG_G))
227 dsa = FIPS_dsa_new();
231 if (dsa_builtin_paramgen2(dsa, L, N, md,
232 seed, seedlen, idx, NULL,
233 NULL, NULL, NULL) <= 0)
235 fprintf(stderr, "Parameter Generation error\n");
238 do_bn_print_name(out, "G",dsa->g);
245 static void pqgver(FILE *in, FILE *out)
249 char *keyword, *value;
250 BIGNUM *p = NULL, *q = NULL, *g = NULL;
251 int counter=-1, counter2;
252 unsigned long h=0, h2;
254 int dsa2, L, N, part_test = 0;
255 const EVP_MD *md = NULL;
256 int seedlen=-1, idxlen, idx = -1;
257 unsigned char seed[1024], idtmp[1024];
259 while(fgets(buf,sizeof buf,in) != NULL)
261 if (!parse_line(&keyword, &value, lbuf, buf))
272 if(!strcmp(keyword,"[mod"))
274 if (!parse_mod(value, &dsa2, &L, &N, &md))
276 fprintf(stderr, "Mod Parse Error\n");
280 else if(!strcmp(keyword,"P"))
282 else if(!strcmp(keyword,"Q"))
284 else if(!strcmp(keyword,"G"))
286 else if(!strcmp(keyword,"firstseed"))
287 seedlen = hex2bin(value, seed);
288 else if(!strcmp(keyword,"pseed"))
289 seedlen += hex2bin(value, seed + seedlen);
290 else if(!strcmp(keyword,"qseed"))
291 seedlen += hex2bin(value, seed + seedlen);
292 else if(!strcmp(keyword,"Seed")
293 || !strcmp(keyword,"domain_parameter_seed"))
295 seedlen = hex2bin(value, seed);
296 if (!dsa2 && seedlen != 20)
298 fprintf(stderr, "Seed parse length error\n");
304 else if(!strcmp(keyword,"index"))
306 idxlen = hex2bin(value, idtmp);
309 fprintf(stderr, "Index value error\n");
314 else if(!strcmp(keyword,"c"))
315 counter = atoi(buf+4);
317 if(!strcmp(keyword,"H") || part_test)
321 if (!p || !q || (!g && !part_test))
323 fprintf(stderr, "Parse Error\n");
326 dsa = FIPS_dsa_new();
333 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
335 &counter2, &h2, NULL))
337 fprintf(stderr, "Parameter Generation error\n");
340 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
341 seed, seedlen, idx, NULL,
342 &counter2, &h2, NULL) < 0)
344 fprintf(stderr, "Parameter Generation error\n");
350 if (BN_cmp(dsa->g, g))
351 fprintf(out, "Result = F" RESP_EOL);
353 fprintf(out, "Result = P" RESP_EOL);
355 else if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) ||
357 ((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2)))))
358 fprintf(out, "Result = F" RESP_EOL);
360 fprintf(out, "Result = P" RESP_EOL);
380 /* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
381 * algorithm tests. It is an additional test to perform sanity checks on the
382 * output of the KeyPair test.
385 static int dss_paramcheck(int L, int N, BIGNUM *p, BIGNUM *q, BIGNUM *g,
389 if (BN_num_bits(p) != L)
391 if (BN_num_bits(q) != N)
393 if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
395 if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
398 if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
399 || (BN_cmp(g, BN_value_one()) <= 0)
400 || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
410 static void keyver(FILE *in, FILE *out)
414 char *keyword, *value;
415 BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
424 while(fgets(buf,sizeof buf,in) != NULL)
426 if (!parse_line(&keyword, &value, lbuf, buf))
431 if(!strcmp(keyword,"[mod"))
443 if (!parse_mod(value, &dsa2, &L, &N, NULL))
445 fprintf(stderr, "Mod Parse Error\n");
449 else if(!strcmp(keyword,"P"))
451 else if(!strcmp(keyword,"Q"))
453 else if(!strcmp(keyword,"G"))
455 else if(!strcmp(keyword,"X"))
457 else if(!strcmp(keyword,"Y"))
460 if (!p || !q || !g || !X || !Y)
462 fprintf(stderr, "Parse Error\n");
465 do_bn_print_name(out, "P",p);
466 do_bn_print_name(out, "Q",q);
467 do_bn_print_name(out, "G",g);
468 do_bn_print_name(out, "X",X);
469 do_bn_print_name(out, "Y",Y);
472 if (dss_paramcheck(L, N, p, q, g, ctx))
478 fprintf(out, "Result = F" RESP_EOL);
481 if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
482 fprintf(out, "Result = F" RESP_EOL);
484 fprintf(out, "Result = P" RESP_EOL);
502 static void keypair(FILE *in, FILE *out)
506 char *keyword, *value;
509 while(fgets(buf,sizeof buf,in) != NULL)
511 if (!parse_line(&keyword, &value, lbuf, buf))
515 if(!strcmp(keyword,"[mod"))
517 if (!parse_mod(value, &dsa2, &L, &N, NULL))
519 fprintf(stderr, "Mod Parse Error\n");
524 else if(!strcmp(keyword,"N"))
529 dsa = FIPS_dsa_new();
530 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
531 NULL, NULL, NULL, NULL))
533 fprintf(stderr, "Parameter Generation error\n");
536 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1,
537 NULL, NULL, NULL, NULL) <= 0)
539 fprintf(stderr, "Parameter Generation error\n");
542 do_bn_print_name(out, "P",dsa->p);
543 do_bn_print_name(out, "Q",dsa->q);
544 do_bn_print_name(out, "G",dsa->g);
545 fputs(RESP_EOL, out);
549 if (!DSA_generate_key(dsa))
552 do_bn_print_name(out, "X",dsa->priv_key);
553 do_bn_print_name(out, "Y",dsa->pub_key);
554 fputs(RESP_EOL, out);
560 static void siggen(FILE *in, FILE *out)
564 char *keyword, *value;
566 const EVP_MD *md = NULL;
569 while(fgets(buf,sizeof buf,in) != NULL)
571 if (!parse_line(&keyword, &value, lbuf, buf))
577 if(!strcmp(keyword,"[mod"))
579 if (!parse_mod(value, &dsa2, &L, &N, &md))
581 fprintf(stderr, "Mod Parse Error\n");
586 dsa = FIPS_dsa_new();
587 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0,
588 NULL, NULL, NULL, NULL))
590 fprintf(stderr, "Parameter Generation error\n");
593 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1,
594 NULL, NULL, NULL, NULL) <= 0)
596 fprintf(stderr, "Parameter Generation error\n");
599 do_bn_print_name(out, "P",dsa->p);
600 do_bn_print_name(out, "Q",dsa->q);
601 do_bn_print_name(out, "G",dsa->g);
602 fputs(RESP_EOL, out);
604 else if(!strcmp(keyword,"Msg"))
606 unsigned char msg[1024];
610 FIPS_md_ctx_init(&mctx);
612 n=hex2bin(value,msg);
614 if (!DSA_generate_key(dsa))
616 do_bn_print_name(out, "Y",dsa->pub_key);
618 FIPS_digestinit(&mctx, md);
619 FIPS_digestupdate(&mctx, msg, n);
620 sig = FIPS_dsa_sign_ctx(dsa, &mctx);
622 do_bn_print_name(out, "R",sig->r);
623 do_bn_print_name(out, "S",sig->s);
624 fputs(RESP_EOL, out);
625 FIPS_dsa_sig_free(sig);
626 FIPS_md_ctx_cleanup(&mctx);
633 static void sigver(FILE *in, FILE *out)
638 unsigned char msg[1024];
639 char *keyword, *value;
642 const EVP_MD *md = NULL;
643 DSA_SIG sg, *sig = &sg;
648 while(fgets(buf,sizeof buf,in) != NULL)
650 if (!parse_line(&keyword, &value, lbuf, buf))
656 if(!strcmp(keyword,"[mod"))
658 if (!parse_mod(value, &dsa2, &L, &N, &md))
660 fprintf(stderr, "Mod Parse Error\n");
665 dsa = FIPS_dsa_new();
667 else if(!strcmp(keyword,"P"))
668 dsa->p=hex2bn(value);
669 else if(!strcmp(keyword,"Q"))
670 dsa->q=hex2bn(value);
671 else if(!strcmp(keyword,"G"))
672 dsa->g=hex2bn(value);
673 else if(!strcmp(keyword,"Msg"))
674 n=hex2bin(value,msg);
675 else if(!strcmp(keyword,"Y"))
676 dsa->pub_key=hex2bn(value);
677 else if(!strcmp(keyword,"R"))
678 sig->r=hex2bn(value);
679 else if(!strcmp(keyword,"S"))
683 FIPS_md_ctx_init(&mctx);
684 sig->s=hex2bn(value);
686 FIPS_digestinit(&mctx, md);
687 FIPS_digestupdate(&mctx, msg, n);
689 r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
691 FIPS_md_ctx_cleanup(&mctx);
693 fprintf(out, "Result = %c" RESP_EOL RESP_EOL, r == 1 ? 'P' : 'F');
698 int main(int argc,char **argv)
703 in = fopen(argv[2], "r");
706 fprintf(stderr, "Error opening input file\n");
709 out = fopen(argv[3], "w");
712 fprintf(stderr, "Error opening output file\n");
723 fprintf(stderr,"%s [prime|pqg|pqgver|keypair|keyver|siggen|sigver]\n",argv[0]);
727 if(!strcmp(argv[1],"prime"))
729 else if(!strcmp(argv[1],"pqg"))
731 else if(!strcmp(argv[1],"pqgver"))
733 else if(!strcmp(argv[1],"keypair"))
735 else if(!strcmp(argv[1],"keyver"))
737 else if(!strcmp(argv[1],"siggen"))
739 else if(!strcmp(argv[1],"sigver"))
743 fprintf(stderr,"Don't know how to %s.\n",argv[1]);