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