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);
205 else if(!strcmp(keyword,"P"))
207 else if(!strcmp(keyword,"Q"))
209 else if(!strcmp(keyword,"domain_parameter_seed"))
210 seedlen = hex2bin(value, seed);
211 else if(!strcmp(keyword,"firstseed"))
212 seedlen = hex2bin(value, seed);
213 else if(!strcmp(keyword,"pseed"))
214 seedlen += hex2bin(value, seed + seedlen);
215 else if(!strcmp(keyword,"qseed"))
216 seedlen += hex2bin(value, seed + seedlen);
217 else if(!strcmp(keyword,"index"))
219 idxlen = hex2bin(value, idtmp);
222 fprintf(stderr, "Index value error\n");
227 if ((idx >= 0 && pqg_type == PQG_GCANON) || (q && pqg_type == PQG_G))
230 dsa = FIPS_dsa_new();
234 if (dsa_builtin_paramgen2(dsa, L, N, md,
235 seed, seedlen, idx, NULL,
236 NULL, NULL, NULL) <= 0)
238 fprintf(stderr, "Parameter Generation error\n");
241 do_bn_print_name(out, "G",dsa->g);
248 static void pqgver(FILE *in, FILE *out)
252 char *keyword, *value;
253 BIGNUM *p = NULL, *q = NULL, *g = NULL;
254 int counter=-1, counter2;
255 unsigned long h=0, h2;
257 int dsa2, L, N, part_test = 0;
258 const EVP_MD *md = NULL;
259 int seedlen=-1, idxlen, idx = -1;
260 unsigned char seed[1024], idtmp[1024];
262 while(fgets(buf,sizeof buf,in) != NULL)
264 if (!parse_line(&keyword, &value, lbuf, buf))
275 if(!strcmp(keyword,"[mod"))
277 if (!parse_mod(value, &dsa2, &L, &N, &md))
279 fprintf(stderr, "Mod Parse Error\n");
283 else if(!strcmp(keyword,"P"))
285 else if(!strcmp(keyword,"Q"))
287 else if(!strcmp(keyword,"G"))
289 else if(!strcmp(keyword,"firstseed"))
290 seedlen = hex2bin(value, seed);
291 else if(!strcmp(keyword,"pseed"))
292 seedlen += hex2bin(value, seed + seedlen);
293 else if(!strcmp(keyword,"qseed"))
294 seedlen += hex2bin(value, seed + seedlen);
295 else if(!strcmp(keyword,"Seed")
296 || !strcmp(keyword,"domain_parameter_seed"))
298 seedlen = hex2bin(value, seed);
299 if (!dsa2 && seedlen != 20)
301 fprintf(stderr, "Seed parse length error\n");
307 else if(!strcmp(keyword,"index"))
309 idxlen = hex2bin(value, idtmp);
312 fprintf(stderr, "Index value error\n");
317 else if(!strcmp(keyword,"c"))
318 counter = atoi(buf+4);
320 if (part_test && idx < 0 && h == 0 && g)
322 dsa = FIPS_dsa_new();
326 if (dsa_paramgen_check_g(dsa))
327 fprintf(out, "Result = P" RESP_EOL);
329 fprintf(out, "Result = F" RESP_EOL);
340 else if(!strcmp(keyword,"H") || part_test)
344 if (!p || !q || (!g && !part_test))
346 fprintf(stderr, "Parse Error\n");
349 dsa = FIPS_dsa_new();
356 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
358 &counter2, &h2, NULL))
360 fprintf(stderr, "Parameter Generation error\n");
363 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
364 seed, seedlen, idx, NULL,
365 &counter2, &h2, NULL) < 0)
367 fprintf(stderr, "Parameter Generation error\n");
373 if (BN_cmp(dsa->g, g))
374 fprintf(out, "Result = F" RESP_EOL);
376 fprintf(out, "Result = P" RESP_EOL);
378 else if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) ||
380 ((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2)))))
381 fprintf(out, "Result = F" RESP_EOL);
383 fprintf(out, "Result = P" RESP_EOL);
403 /* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
404 * algorithm tests. It is an additional test to perform sanity checks on the
405 * output of the KeyPair test.
408 static int dss_paramcheck(int L, int N, BIGNUM *p, BIGNUM *q, BIGNUM *g,
412 if (BN_num_bits(p) != L)
414 if (BN_num_bits(q) != N)
416 if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
418 if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
421 if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
422 || (BN_cmp(g, BN_value_one()) <= 0)
423 || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
433 static void keyver(FILE *in, FILE *out)
437 char *keyword, *value;
438 BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
447 while(fgets(buf,sizeof buf,in) != NULL)
449 if (!parse_line(&keyword, &value, lbuf, buf))
454 if(!strcmp(keyword,"[mod"))
466 if (!parse_mod(value, &dsa2, &L, &N, NULL))
468 fprintf(stderr, "Mod Parse Error\n");
472 else if(!strcmp(keyword,"P"))
474 else if(!strcmp(keyword,"Q"))
476 else if(!strcmp(keyword,"G"))
478 else if(!strcmp(keyword,"X"))
480 else if(!strcmp(keyword,"Y"))
483 if (!p || !q || !g || !X || !Y)
485 fprintf(stderr, "Parse Error\n");
488 do_bn_print_name(out, "P",p);
489 do_bn_print_name(out, "Q",q);
490 do_bn_print_name(out, "G",g);
491 do_bn_print_name(out, "X",X);
492 do_bn_print_name(out, "Y",Y);
495 if (dss_paramcheck(L, N, p, q, g, ctx))
501 fprintf(out, "Result = F" RESP_EOL);
504 if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
505 fprintf(out, "Result = F" RESP_EOL);
507 fprintf(out, "Result = P" RESP_EOL);
527 static void keypair(FILE *in, FILE *out)
531 char *keyword, *value;
534 while(fgets(buf,sizeof buf,in) != NULL)
536 if (!parse_line(&keyword, &value, lbuf, buf))
540 if(!strcmp(keyword,"[mod"))
542 if (!parse_mod(value, &dsa2, &L, &N, NULL))
544 fprintf(stderr, "Mod Parse Error\n");
549 else if(!strcmp(keyword,"N"))
554 dsa = FIPS_dsa_new();
555 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
556 NULL, NULL, NULL, NULL))
558 fprintf(stderr, "Parameter Generation error\n");
561 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1,
562 NULL, NULL, NULL, NULL) <= 0)
564 fprintf(stderr, "Parameter Generation error\n");
567 do_bn_print_name(out, "P",dsa->p);
568 do_bn_print_name(out, "Q",dsa->q);
569 do_bn_print_name(out, "G",dsa->g);
570 fputs(RESP_EOL, out);
574 if (!DSA_generate_key(dsa))
577 do_bn_print_name(out, "X",dsa->priv_key);
578 do_bn_print_name(out, "Y",dsa->pub_key);
579 fputs(RESP_EOL, out);
587 static void siggen(FILE *in, FILE *out)
591 char *keyword, *value;
593 const EVP_MD *md = NULL;
596 while(fgets(buf,sizeof buf,in) != NULL)
598 if (!parse_line(&keyword, &value, lbuf, buf))
604 if(!strcmp(keyword,"[mod"))
606 if (!parse_mod(value, &dsa2, &L, &N, &md))
608 fprintf(stderr, "Mod Parse Error\n");
613 dsa = FIPS_dsa_new();
614 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0,
615 NULL, NULL, NULL, NULL))
617 fprintf(stderr, "Parameter Generation error\n");
620 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1,
621 NULL, NULL, NULL, NULL) <= 0)
623 fprintf(stderr, "Parameter Generation error\n");
626 do_bn_print_name(out, "P",dsa->p);
627 do_bn_print_name(out, "Q",dsa->q);
628 do_bn_print_name(out, "G",dsa->g);
629 fputs(RESP_EOL, out);
631 else if(!strcmp(keyword,"Msg"))
633 unsigned char msg[1024];
637 n=hex2bin(value,msg);
639 if (!DSA_generate_key(dsa))
641 do_bn_print_name(out, "Y",dsa->pub_key);
643 sig = FIPS_dsa_sign(dsa, msg, n, md);
645 do_bn_print_name(out, "R",sig->r);
646 do_bn_print_name(out, "S",sig->s);
647 fputs(RESP_EOL, out);
648 FIPS_dsa_sig_free(sig);
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 do_hex2bn(&dsa->p, value);
691 else if(!strcmp(keyword,"Q"))
692 do_hex2bn(&dsa->q, value);
693 else if(!strcmp(keyword,"G"))
694 do_hex2bn(&dsa->g, value);
695 else if(!strcmp(keyword,"Msg"))
696 n=hex2bin(value,msg);
697 else if(!strcmp(keyword,"Y"))
698 do_hex2bn(&dsa->pub_key, value);
699 else if(!strcmp(keyword,"R"))
700 sig->r=hex2bn(value);
701 else if(!strcmp(keyword,"S"))
704 sig->s=hex2bn(value);
707 r = FIPS_dsa_verify(dsa, msg, n, md, sig);
720 fprintf(out, "Result = %c" RESP_EOL RESP_EOL, r == 1 ? 'P' : 'F');
728 int fips_dssvs_main(int argc, char **argv)
730 int main(int argc, char **argv)
736 in = fopen(argv[2], "r");
739 fprintf(stderr, "Error opening input file\n");
742 out = fopen(argv[3], "w");
745 fprintf(stderr, "Error opening output file\n");
756 fprintf(stderr,"%s [prime|pqg|pqgver|keypair|keyver|siggen|sigver]\n",argv[0]);
760 if(!strcmp(argv[1],"prime"))
762 else if(!strcmp(argv[1],"pqg"))
764 else if(!strcmp(argv[1],"pqgver"))
766 else if(!strcmp(argv[1],"keypair"))
768 else if(!strcmp(argv[1],"keyver"))
770 else if(!strcmp(argv[1],"siggen"))
772 else if(!strcmp(argv[1],"sigver"))
776 fprintf(stderr,"Don't know how to %s.\n",argv[1]);