09001615dc07e3bb655c8364e3b76bb034a3c0cc
[openssl.git] / fips / dsa / fips_dssvs.c
1
2 #define OPENSSL_FIPSAPI
3 #include <openssl/opensslconf.h>
4
5 #ifndef OPENSSL_FIPS
6 #include <stdio.h>
7
8 int main(int argc, char **argv)
9 {
10     printf("No FIPS DSA support\n");
11     return(0);
12 }
13 #else
14
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>
20 #include <string.h>
21 #include <ctype.h>
22
23 #include "fips_utl.h"
24
25 static int parse_mod(char *line, int *pdsa2, int *pL, int *pN,
26                                 const EVP_MD **pmd)
27         {
28         char lbuf[10240];
29         char *keyword, *value;
30
31         char *p;
32         p = strchr(line, ',');
33         if (!p)
34                 {
35                 *pL = atoi(line);
36                 *pdsa2 = 0;
37                 *pN = 160;
38                 if (pmd)
39                         *pmd = EVP_sha1();
40                 return 1;
41                 }
42         *pdsa2 = 1;
43         *p = 0;
44         if (!parse_line(&keyword, &value, lbuf, line))
45                 return 0;
46         if (strcmp(keyword, "L"))
47                 return 0;
48         *pL = atoi(value);
49         strcpy(line, p + 1);
50         if (pmd)
51                 p = strchr(line, ',');
52         else
53                 p = strchr(line, ']');
54         if (!p)
55                 return 0;
56         *p = 0;
57         if (!parse_line(&keyword, &value, lbuf, line))
58                 return 0;
59         if (strcmp(keyword, "N"))
60                 return 0;
61         *pN = atoi(value);
62         if (!pmd)
63                 return 1;
64         strcpy(line, p + 1);
65         p = strchr(line, ']');
66         if (!p)
67                 return 0;
68         *p = 0;
69         p = line;
70         while(isspace(*p))
71                 p++;
72         if (!strcmp(p, "SHA-1"))
73                 *pmd = EVP_sha1();
74         else if (!strcmp(p, "SHA-224"))
75                 *pmd = EVP_sha224();
76         else if (!strcmp(p, "SHA-256"))
77                 *pmd = EVP_sha256();
78         else if (!strcmp(p, "SHA-384"))
79                 *pmd = EVP_sha384();
80         else if (!strcmp(p, "SHA-512"))
81                 *pmd = EVP_sha512();
82         else
83                 return 0;
84         return 1;
85         }
86
87 static void primes(FILE *in, FILE *out)
88     {
89     char buf[10240];
90     char lbuf[10240];
91     char *keyword, *value;
92
93     while(fgets(buf,sizeof buf,in) != NULL)
94         {
95         fputs(buf,out);
96         if (!parse_line(&keyword, &value, lbuf, buf))
97                 continue;
98         if(!strcmp(keyword,"Prime"))
99             {
100             BIGNUM *pp;
101
102             pp=BN_new();
103             do_hex2bn(&pp,value);
104             fprintf(out, "result= %c\n",
105                    BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
106             }       
107         }
108     }
109
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 bits, size_t qbits,
115         const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
116         unsigned char *seed_out,
117         int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
118
119 static void pqg(FILE *in, FILE *out)
120     {
121     char buf[1024];
122     char lbuf[1024];
123     char *keyword, *value;
124     int dsa2, L, N;
125     const EVP_MD *md = NULL;
126
127     while(fgets(buf,sizeof buf,in) != NULL)
128         {
129         if (!parse_line(&keyword, &value, lbuf, buf))
130                 {
131                 fputs(buf,out);
132                 continue;
133                 }
134         if(!strcmp(keyword,"[mod"))
135             {
136             fputs(buf,out);
137             if (!parse_mod(value, &dsa2, &L, &N, &md))
138                 {
139                 fprintf(stderr, "Mod Parse Error\n");
140                 exit (1);
141                 }
142             }
143         else if(!strcmp(keyword,"N"))
144             {
145             int n=atoi(value);
146
147             while(n--)
148                 {
149                 unsigned char seed[EVP_MAX_MD_SIZE];
150                 DSA *dsa;
151                 int counter;
152                 unsigned long h;
153                 dsa = FIPS_dsa_new();
154
155                 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
156                                                 NULL, 0, seed,
157                                                 &counter, &h, NULL))
158                         {
159                         fprintf(stderr, "Parameter Generation error\n");
160                         exit(1);
161                         }
162                 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
163                                                 NULL, 0, seed,
164                                                 &counter, &h, NULL) <= 0)
165                         {
166                         fprintf(stderr, "Parameter Generation error\n");
167                         exit(1);
168                         }
169  
170                 do_bn_print_name(out, "P",dsa->p);
171                 do_bn_print_name(out, "Q",dsa->q);
172                 do_bn_print_name(out, "G",dsa->g);
173                 OutputValue("Seed",seed, M_EVP_MD_size(md), out, 0);
174                 fprintf(out, "c = %d\n",counter);
175                 fprintf(out, "H = %lx\n\n",h);
176                 }
177             }
178         else
179             fputs(buf,out);
180         }
181     }
182
183 static void pqgver(FILE *in, FILE *out)
184     {
185     char buf[1024];
186     char lbuf[1024];
187     char *keyword, *value;
188     BIGNUM *p = NULL, *q = NULL, *g = NULL;
189     int counter=-1, counter2;
190     unsigned long h=0, h2;
191     DSA *dsa=NULL;
192     int dsa2, L, N, part_test = 0;
193     const EVP_MD *md = NULL;
194     int seedlen=-1;
195     unsigned char seed[1024];
196
197     while(fgets(buf,sizeof buf,in) != NULL)
198         {
199         if (!parse_line(&keyword, &value, lbuf, buf))
200                 {
201                 if (p && q)
202                         {
203                         part_test = 1;
204                         goto partial;
205                         }
206                 fputs(buf,out);
207                 continue;
208                 }
209         fputs(buf, out);
210         if(!strcmp(keyword,"[mod"))
211             {
212             if (!parse_mod(value, &dsa2, &L, &N, &md))
213                 {
214                 fprintf(stderr, "Mod Parse Error\n");
215                 exit (1);
216                 }
217             }
218         else if(!strcmp(keyword,"P"))
219             p=hex2bn(value);
220         else if(!strcmp(keyword,"Q"))
221             q=hex2bn(value);
222         else if(!strcmp(keyword,"G"))
223             g=hex2bn(value);
224         else if(!strcmp(keyword,"Seed"))
225             {
226             seedlen = hex2bin(value, seed);
227             if (!dsa2 && seedlen != 20)
228                 {
229                 fprintf(stderr, "Seed parse length error\n");
230                 exit (1);
231                 }
232             }
233         else if(!strcmp(keyword,"c"))
234             counter =atoi(buf+4);
235         partial:
236         if(!strcmp(keyword,"H") || part_test)
237             {
238             if (!part_test)
239                 h = atoi(value);
240             if (!p || !q || (!g && !part_test))
241                 {
242                 fprintf(stderr, "Parse Error\n");
243                 exit (1);
244                 }
245             dsa = FIPS_dsa_new();
246             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
247                                         seed, seedlen, NULL,
248                                         &counter2, &h2, NULL))
249                         {
250                         fprintf(stderr, "Parameter Generation error\n");
251                         exit(1);
252                         }
253             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
254                                         seed, seedlen, NULL,
255                                         &counter2, &h2, NULL) < 0)
256                         {
257                         fprintf(stderr, "Parameter Generation error\n");
258                         exit(1);
259                         }
260             if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || 
261                 (!part_test &&
262                 ((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2)))))
263                 fprintf(out, "Result = F\n");
264             else
265                 fprintf(out, "Result = P\n");
266             BN_free(p);
267             BN_free(q);
268             BN_free(g);
269             p = NULL;
270             q = NULL;
271             g = NULL;
272             FIPS_dsa_free(dsa);
273             dsa = NULL;
274             if (part_test)
275                 {
276                 fputs(buf,out);
277                 part_test = 0;
278                 }
279             }
280         }
281     }
282
283 /* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
284  * algorithm tests. It is an additional test to perform sanity checks on the
285  * output of the KeyPair test.
286  */
287
288 static int dss_paramcheck(int L, int N, BIGNUM *p, BIGNUM *q, BIGNUM *g,
289                                                         BN_CTX *ctx)
290     {
291     BIGNUM *rem = NULL;
292     if (BN_num_bits(p) != L)
293         return 0;
294     if (BN_num_bits(q) != N)
295         return 0;
296     if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
297         return 0;
298     if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
299         return 0;
300     rem = BN_new();
301     if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
302         || (BN_cmp(g, BN_value_one()) <= 0)
303         || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
304         {
305         BN_free(rem);
306         return 0;
307         }
308     /* Todo: check g */
309     BN_free(rem);
310     return 1;
311     }
312
313 static void keyver(FILE *in, FILE *out)
314     {
315     char buf[1024];
316     char lbuf[1024];
317     char *keyword, *value;
318     BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
319     BIGNUM *Y2;
320     BN_CTX *ctx = NULL;
321     int dsa2, L, N;
322     int paramcheck = 0;
323
324     ctx = BN_CTX_new();
325     Y2 = BN_new();
326
327     while(fgets(buf,sizeof buf,in) != NULL)
328         {
329         if (!parse_line(&keyword, &value, lbuf, buf))
330                 {
331                 fputs(buf,out);
332                 continue;
333                 }
334         if(!strcmp(keyword,"[mod"))
335             {
336             if (p)
337                 BN_free(p);
338             p = NULL;
339             if (q)
340                 BN_free(q);
341             q = NULL;
342             if (g)
343                 BN_free(g);
344             g = NULL;
345             paramcheck = 0;
346             if (!parse_mod(value, &dsa2, &L, &N, NULL))
347                 {
348                 fprintf(stderr, "Mod Parse Error\n");
349                 exit (1);
350                 }
351             }
352         else if(!strcmp(keyword,"P"))
353             p=hex2bn(value);
354         else if(!strcmp(keyword,"Q"))
355             q=hex2bn(value);
356         else if(!strcmp(keyword,"G"))
357             g=hex2bn(value);
358         else if(!strcmp(keyword,"X"))
359             X=hex2bn(value);
360         else if(!strcmp(keyword,"Y"))
361             {
362             Y=hex2bn(value);
363             if (!p || !q || !g || !X || !Y)
364                 {
365                 fprintf(stderr, "Parse Error\n");
366                 exit (1);
367                 }
368             do_bn_print_name(out, "P",p);
369             do_bn_print_name(out, "Q",q);
370             do_bn_print_name(out, "G",g);
371             do_bn_print_name(out, "X",X);
372             do_bn_print_name(out, "Y",Y);
373             if (!paramcheck)
374                 {
375                 if (dss_paramcheck(L, N, p, q, g, ctx))
376                         paramcheck = 1;
377                 else
378                         paramcheck = -1;
379                 }
380             if (paramcheck != 1)
381                 fprintf(out, "Result = F\n");
382             else
383                 {
384                 if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
385                         fprintf(out, "Result = F\n");
386                 else
387                         fprintf(out, "Result = P\n");
388                 }
389             BN_free(X);
390             BN_free(Y);
391             X = NULL;
392             Y = NULL;
393             }
394         }
395         if (p)
396             BN_free(p);
397         if (q)
398             BN_free(q);
399         if (g)
400             BN_free(g);
401         if (Y2)
402             BN_free(Y2);
403     }
404
405 static void keypair(FILE *in, FILE *out)
406     {
407     char buf[1024];
408     char lbuf[1024];
409     char *keyword, *value;
410     int dsa2, L, N;
411
412     while(fgets(buf,sizeof buf,in) != NULL)
413         {
414         if (!parse_line(&keyword, &value, lbuf, buf))
415                 {
416                 continue;
417                 }
418         if(!strcmp(keyword,"[mod"))
419             {
420             if (!parse_mod(value, &dsa2, &L, &N, NULL))
421                 {
422                 fprintf(stderr, "Mod Parse Error\n");
423                 exit (1);
424                 }
425             fputs(buf,out);
426             }
427         else if(!strcmp(keyword,"N"))
428             {
429             DSA *dsa;
430             int n=atoi(value);
431
432             dsa = FIPS_dsa_new();
433             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
434                                                 NULL, NULL, NULL, NULL))
435                         {
436                         fprintf(stderr, "Parameter Generation error\n");
437                         exit(1);
438                         }
439             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0,
440                                                 NULL, NULL, NULL, NULL) <= 0)
441                         {
442                         fprintf(stderr, "Parameter Generation error\n");
443                         exit(1);
444                         }
445             do_bn_print_name(out, "P",dsa->p);
446             do_bn_print_name(out, "Q",dsa->q);
447             do_bn_print_name(out, "G",dsa->g);
448             fputs("\n", out);
449
450             while(n--)
451                 {
452                 if (!DSA_generate_key(dsa))
453                         exit(1);
454
455                 do_bn_print_name(out, "X",dsa->priv_key);
456                 do_bn_print_name(out, "Y",dsa->pub_key);
457                 fputs("\n", out);
458                 }
459             }
460         }
461     }
462
463 static void siggen(FILE *in, FILE *out)
464     {
465     char buf[1024];
466     char lbuf[1024];
467     char *keyword, *value;
468     int dsa2, L, N;
469     const EVP_MD *md = NULL;
470     DSA *dsa=NULL;
471
472     while(fgets(buf,sizeof buf,in) != NULL)
473         {
474         if (!parse_line(&keyword, &value, lbuf, buf))
475                 {
476                 fputs(buf,out);
477                 continue;
478                 }
479         fputs(buf,out);
480         if(!strcmp(keyword,"[mod"))
481             {
482             if (!parse_mod(value, &dsa2, &L, &N, &md))
483                 {
484                 fprintf(stderr, "Mod Parse Error\n");
485                 exit (1);
486                 }
487             if (dsa)
488                 FIPS_dsa_free(dsa);
489             dsa = FIPS_dsa_new();
490             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0,
491                                                 NULL, NULL, NULL, NULL))
492                         {
493                         fprintf(stderr, "Parameter Generation error\n");
494                         exit(1);
495                         }
496             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0,
497                                                 NULL, NULL, NULL, NULL) <= 0)
498                         {
499                         fprintf(stderr, "Parameter Generation error\n");
500                         exit(1);
501                         }
502             do_bn_print_name(out, "P",dsa->p);
503             do_bn_print_name(out, "Q",dsa->q);
504             do_bn_print_name(out, "G",dsa->g);
505             fputs("\n", out);
506             }
507         else if(!strcmp(keyword,"Msg"))
508             {
509             unsigned char msg[1024];
510             int n;
511             EVP_MD_CTX mctx;
512             DSA_SIG *sig;
513             FIPS_md_ctx_init(&mctx);
514
515             n=hex2bin(value,msg);
516
517             if (!DSA_generate_key(dsa))
518                 exit(1);
519             do_bn_print_name(out, "Y",dsa->pub_key);
520
521             FIPS_digestinit(&mctx, md);
522             FIPS_digestupdate(&mctx, msg, n);
523             sig = FIPS_dsa_sign_ctx(dsa, &mctx);
524
525             do_bn_print_name(out, "R",sig->r);
526             do_bn_print_name(out, "S",sig->s);
527             fputs("\n", out);
528             FIPS_dsa_sig_free(sig);
529             FIPS_md_ctx_cleanup(&mctx);
530             }
531         }
532         if (dsa)
533                 FIPS_dsa_free(dsa);
534     }
535
536 static void sigver(FILE *in, FILE *out)
537     {
538     DSA *dsa=NULL;
539     char buf[1024];
540     char lbuf[1024];
541     unsigned char msg[1024];
542     char *keyword, *value;
543     int n=0;
544     int dsa2, L, N;
545     const EVP_MD *md = NULL;
546     DSA_SIG sg, *sig = &sg;
547
548     sig->r = NULL;
549     sig->s = NULL;
550
551     while(fgets(buf,sizeof buf,in) != NULL)
552         {
553         if (!parse_line(&keyword, &value, lbuf, buf))
554                 {
555                 fputs(buf,out);
556                 continue;
557                 }
558         fputs(buf,out);
559         if(!strcmp(keyword,"[mod"))
560             {
561             if (!parse_mod(value, &dsa2, &L, &N, &md))
562                 {
563                 fprintf(stderr, "Mod Parse Error\n");
564                 exit (1);
565                 }
566             if (dsa)
567                 FIPS_dsa_free(dsa);
568             dsa = FIPS_dsa_new();
569             }
570         else if(!strcmp(keyword,"P"))
571             dsa->p=hex2bn(value);
572         else if(!strcmp(keyword,"Q"))
573             dsa->q=hex2bn(value);
574         else if(!strcmp(keyword,"G"))
575             dsa->g=hex2bn(value);
576         else if(!strcmp(keyword,"Msg"))
577             n=hex2bin(value,msg);
578         else if(!strcmp(keyword,"Y"))
579             dsa->pub_key=hex2bn(value);
580         else if(!strcmp(keyword,"R"))
581             sig->r=hex2bn(value);
582         else if(!strcmp(keyword,"S"))
583             {
584             EVP_MD_CTX mctx;
585             int r;
586             FIPS_md_ctx_init(&mctx);
587             sig->s=hex2bn(value);
588
589             FIPS_digestinit(&mctx, md);
590             FIPS_digestupdate(&mctx, msg, n);
591             no_err = 1;
592             r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
593             no_err = 0;
594             FIPS_md_ctx_cleanup(&mctx);
595         
596             fprintf(out, "Result = %c\n\n", r == 1 ? 'P' : 'F');
597             }
598         }
599     }
600
601 int main(int argc,char **argv)
602     {
603     FILE *in, *out;
604     if (argc == 4)
605         {
606         in = fopen(argv[2], "r");
607         if (!in)
608                 {
609                 fprintf(stderr, "Error opening input file\n");
610                 exit(1);
611                 }
612         out = fopen(argv[3], "w");
613         if (!out)
614                 {
615                 fprintf(stderr, "Error opening output file\n");
616                 exit(1);
617                 }
618         }
619     else if (argc == 2)
620         {
621         in = stdin;
622         out = stdout;
623         }
624     else
625         {
626         fprintf(stderr,"%s [prime|pqg|pqgver|keypair|keyver|siggen|sigver]\n",argv[0]);
627         exit(1);
628         }
629     fips_algtest_init();
630     if(!strcmp(argv[1],"prime"))
631         primes(in, out);
632     else if(!strcmp(argv[1],"pqg"))
633         pqg(in, out);
634     else if(!strcmp(argv[1],"pqgver"))
635         pqgver(in, out);
636     else if(!strcmp(argv[1],"keypair"))
637         keypair(in, out);
638     else if(!strcmp(argv[1],"keyver"))
639         keyver(in, out);
640     else if(!strcmp(argv[1],"siggen"))
641         siggen(in, out);
642     else if(!strcmp(argv[1],"sigver"))
643         sigver(in, out);
644     else
645         {
646         fprintf(stderr,"Don't know how to %s.\n",argv[1]);
647         exit(1);
648         }
649
650     if (argc == 4)
651         {
652         fclose(in);
653         fclose(out);
654         }
655
656     return 0;
657     }
658
659 #endif