ff7f8139b3e2022114f00c388484dd2004dc993c
[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, part_test = 0;
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                 if (p && q)
225                         {
226                         part_test = 1;
227                         goto partial;
228                         }
229                 fputs(buf,stdout);
230                 continue;
231                 }
232         fputs(buf, stdout);
233         if(!strcmp(keyword,"[mod"))
234             {
235             if (!parse_mod(value, &dsa2, &L, &N, &md))
236                 {
237                 fprintf(stderr, "Mod Parse Error\n");
238                 exit (1);
239                 }
240             }
241         else if(!strcmp(keyword,"P"))
242             p=hex2bn(value);
243         else if(!strcmp(keyword,"Q"))
244             q=hex2bn(value);
245         else if(!strcmp(keyword,"G"))
246             g=hex2bn(value);
247         else if(!strcmp(keyword,"Seed"))
248             {
249             seedlen = hex2bin(value, seed);
250             if (!dsa2 && seedlen != 20)
251                 {
252                 fprintf(stderr, "Seed parse length error\n");
253                 exit (1);
254                 }
255             }
256         else if(!strcmp(keyword,"c"))
257             counter =atoi(buf+4);
258         partial:
259         if(!strcmp(keyword,"H") || part_test)
260             {
261             if (!part_test)
262                 h = atoi(value);
263             if (!p || !q || (!g && !part_test))
264                 {
265                 fprintf(stderr, "Parse Error\n");
266                 exit (1);
267                 }
268             dsa = FIPS_dsa_new();
269             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
270                                         seed, seedlen, NULL,
271                                         &counter2, &h2, NULL))
272                         {
273                         fprintf(stderr, "Parameter Generation error\n");
274                         exit(1);
275                         }
276             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
277                                         seed, seedlen, NULL,
278                                         &counter2, &h2, NULL) < 0)
279                         {
280                         fprintf(stderr, "Parameter Generation error\n");
281                         exit(1);
282                         }
283             if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || 
284                 (!part_test &&
285                 ((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2)))))
286                 printf("Result = F\n");
287             else
288                 printf("Result = P\n");
289             BN_free(p);
290             BN_free(q);
291             BN_free(g);
292             p = NULL;
293             q = NULL;
294             g = NULL;
295             FIPS_dsa_free(dsa);
296             dsa = NULL;
297             if (part_test)
298                 {
299                 fputs(buf,stdout);
300                 part_test = 0;
301                 }
302             }
303         }
304     }
305
306 /* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
307  * algorithm tests. It is an additional test to perform sanity checks on the
308  * output of the KeyPair test.
309  */
310
311 static int dss_paramcheck(int L, int N, BIGNUM *p, BIGNUM *q, BIGNUM *g,
312                                                         BN_CTX *ctx)
313     {
314     BIGNUM *rem = NULL;
315     if (BN_num_bits(p) != L)
316         return 0;
317     if (BN_num_bits(q) != N)
318         return 0;
319     if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
320         return 0;
321     if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
322         return 0;
323     rem = BN_new();
324     if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
325         || (BN_cmp(g, BN_value_one()) <= 0)
326         || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
327         {
328         BN_free(rem);
329         return 0;
330         }
331     /* Todo: check g */
332     BN_free(rem);
333     return 1;
334     }
335
336 static void keyver()
337     {
338     char buf[1024];
339     char lbuf[1024];
340     char *keyword, *value;
341     BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
342     BIGNUM *Y2;
343     BN_CTX *ctx = NULL;
344     int dsa2, L, N;
345     int paramcheck = 0;
346
347     ctx = BN_CTX_new();
348     Y2 = BN_new();
349
350     while(fgets(buf,sizeof buf,stdin) != NULL)
351         {
352         if (!parse_line(&keyword, &value, lbuf, buf))
353                 {
354                 fputs(buf,stdout);
355                 continue;
356                 }
357         if(!strcmp(keyword,"[mod"))
358             {
359             if (p)
360                 BN_free(p);
361             p = NULL;
362             if (q)
363                 BN_free(q);
364             q = NULL;
365             if (g)
366                 BN_free(g);
367             g = NULL;
368             paramcheck = 0;
369             if (!parse_mod(value, &dsa2, &L, &N, NULL))
370                 {
371                 fprintf(stderr, "Mod Parse Error\n");
372                 exit (1);
373                 }
374             }
375         else if(!strcmp(keyword,"P"))
376             p=hex2bn(value);
377         else if(!strcmp(keyword,"Q"))
378             q=hex2bn(value);
379         else if(!strcmp(keyword,"G"))
380             g=hex2bn(value);
381         else if(!strcmp(keyword,"X"))
382             X=hex2bn(value);
383         else if(!strcmp(keyword,"Y"))
384             {
385             Y=hex2bn(value);
386             if (!p || !q || !g || !X || !Y)
387                 {
388                 fprintf(stderr, "Parse Error\n");
389                 exit (1);
390                 }
391             pbn("P",p);
392             pbn("Q",q);
393             pbn("G",g);
394             pbn("X",X);
395             pbn("Y",Y);
396             if (!paramcheck)
397                 {
398                 if (dss_paramcheck(L, N, p, q, g, ctx))
399                         paramcheck = 1;
400                 else
401                         paramcheck = -1;
402                 }
403             if (paramcheck != 1)
404                 printf("Result = F\n");
405             else
406                 {
407                 if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
408                         printf("Result = F\n");
409                 else
410                         printf("Result = P\n");
411                 }
412             BN_free(X);
413             BN_free(Y);
414             X = NULL;
415             Y = NULL;
416             }
417         }
418         if (p)
419             BN_free(p);
420         if (q)
421             BN_free(q);
422         if (g)
423             BN_free(g);
424         if (Y2)
425             BN_free(Y2);
426     }
427
428 static void keypair()
429     {
430     char buf[1024];
431     char lbuf[1024];
432     char *keyword, *value;
433     int dsa2, L, N;
434
435     while(fgets(buf,sizeof buf,stdin) != NULL)
436         {
437         if (!parse_line(&keyword, &value, lbuf, buf))
438                 {
439                 continue;
440                 }
441         if(!strcmp(keyword,"[mod"))
442             {
443             if (!parse_mod(value, &dsa2, &L, &N, NULL))
444                 {
445                 fprintf(stderr, "Mod Parse Error\n");
446                 exit (1);
447                 }
448             fputs(buf,stdout);
449             }
450         else if(!strcmp(keyword,"N"))
451             {
452             DSA *dsa;
453             int n=atoi(value);
454
455             dsa = FIPS_dsa_new();
456             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
457                                                 NULL, NULL, NULL, NULL))
458                         {
459                         fprintf(stderr, "Parameter Generation error\n");
460                         exit(1);
461                         }
462             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0,
463                                                 NULL, NULL, NULL, NULL) <= 0)
464                         {
465                         fprintf(stderr, "Parameter Generation error\n");
466                         exit(1);
467                         }
468             pbn("P",dsa->p);
469             pbn("Q",dsa->q);
470             pbn("G",dsa->g);
471             putc('\n',stdout);
472
473             while(n--)
474                 {
475                 if (!DSA_generate_key(dsa))
476                         exit(1);
477
478                 pbn("X",dsa->priv_key);
479                 pbn("Y",dsa->pub_key);
480                 putc('\n',stdout);
481                 }
482             }
483         }
484     }
485
486 static void siggen()
487     {
488     char buf[1024];
489     char lbuf[1024];
490     char *keyword, *value;
491     int dsa2, L, N;
492     const EVP_MD *md = NULL;
493     DSA *dsa=NULL;
494
495     while(fgets(buf,sizeof buf,stdin) != NULL)
496         {
497         if (!parse_line(&keyword, &value, lbuf, buf))
498                 {
499                 fputs(buf,stdout);
500                 continue;
501                 }
502         fputs(buf,stdout);
503         if(!strcmp(keyword,"[mod"))
504             {
505             if (!parse_mod(value, &dsa2, &L, &N, &md))
506                 {
507                 fprintf(stderr, "Mod Parse Error\n");
508                 exit (1);
509                 }
510             if (dsa)
511                 FIPS_dsa_free(dsa);
512             dsa = FIPS_dsa_new();
513             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0,
514                                                 NULL, NULL, NULL, NULL))
515                         {
516                         fprintf(stderr, "Parameter Generation error\n");
517                         exit(1);
518                         }
519             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0,
520                                                 NULL, NULL, NULL, NULL) <= 0)
521                         {
522                         fprintf(stderr, "Parameter Generation error\n");
523                         exit(1);
524                         }
525             pbn("P",dsa->p);
526             pbn("Q",dsa->q);
527             pbn("G",dsa->g);
528             putc('\n',stdout);
529             }
530         else if(!strcmp(keyword,"Msg"))
531             {
532             unsigned char msg[1024];
533             int n;
534             EVP_MD_CTX mctx;
535             DSA_SIG *sig;
536             FIPS_md_ctx_init(&mctx);
537
538             n=hex2bin(value,msg);
539
540             if (!DSA_generate_key(dsa))
541                 exit(1);
542             pbn("Y",dsa->pub_key);
543
544             FIPS_digestinit(&mctx, md);
545             FIPS_digestupdate(&mctx, msg, n);
546             sig = FIPS_dsa_sign_ctx(dsa, &mctx);
547
548             pbn("R",sig->r);
549             pbn("S",sig->s);
550             putc('\n',stdout);
551             FIPS_dsa_sig_free(sig);
552             FIPS_md_ctx_cleanup(&mctx);
553             }
554         }
555         if (dsa)
556                 FIPS_dsa_free(dsa);
557     }
558
559 static void sigver()
560     {
561     DSA *dsa=NULL;
562     char buf[1024];
563     char lbuf[1024];
564     unsigned char msg[1024];
565     char *keyword, *value;
566     int n=0;
567     int dsa2, L, N;
568     const EVP_MD *md = NULL;
569     DSA_SIG sg, *sig = &sg;
570
571     sig->r = NULL;
572     sig->s = NULL;
573
574     while(fgets(buf,sizeof buf,stdin) != NULL)
575         {
576         if (!parse_line(&keyword, &value, lbuf, buf))
577                 {
578                 fputs(buf,stdout);
579                 continue;
580                 }
581         fputs(buf,stdout);
582         if(!strcmp(keyword,"[mod"))
583             {
584             if (!parse_mod(value, &dsa2, &L, &N, &md))
585                 {
586                 fprintf(stderr, "Mod Parse Error\n");
587                 exit (1);
588                 }
589             if (dsa)
590                 FIPS_dsa_free(dsa);
591             dsa = FIPS_dsa_new();
592             }
593         else if(!strcmp(keyword,"P"))
594             dsa->p=hex2bn(value);
595         else if(!strcmp(keyword,"Q"))
596             dsa->q=hex2bn(value);
597         else if(!strcmp(keyword,"G"))
598             dsa->g=hex2bn(value);
599         else if(!strcmp(keyword,"Msg"))
600             n=hex2bin(value,msg);
601         else if(!strcmp(keyword,"Y"))
602             dsa->pub_key=hex2bn(value);
603         else if(!strcmp(keyword,"R"))
604             sig->r=hex2bn(value);
605         else if(!strcmp(keyword,"S"))
606             {
607             EVP_MD_CTX mctx;
608             int r;
609             FIPS_md_ctx_init(&mctx);
610             sig->s=hex2bn(value);
611
612             FIPS_digestinit(&mctx, md);
613             FIPS_digestupdate(&mctx, msg, n);
614             no_err = 1;
615             r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
616             no_err = 0;
617             FIPS_md_ctx_cleanup(&mctx);
618         
619             printf("Result = %c\n", r == 1 ? 'P' : 'F');
620             putc('\n',stdout);
621             }
622         }
623     }
624
625 int main(int argc,char **argv)
626     {
627     if(argc != 2)
628         {
629         fprintf(stderr,"%s [prime|pqg|pqgver|keypair|keyver|siggen|sigver]\n",argv[0]);
630         exit(1);
631         }
632     fips_set_error_print();
633     if(!FIPS_mode_set(1))
634         exit(1);
635     if(!strcmp(argv[1],"prime"))
636         primes();
637     else if(!strcmp(argv[1],"pqg"))
638         pqg();
639     else if(!strcmp(argv[1],"pqgver"))
640         pqgver();
641     else if(!strcmp(argv[1],"keypair"))
642         keypair();
643     else if(!strcmp(argv[1],"keyver"))
644         keyver();
645     else if(!strcmp(argv[1],"siggen"))
646         siggen();
647     else if(!strcmp(argv[1],"sigver"))
648         sigver();
649     else
650         {
651         fprintf(stderr,"Don't know how to %s.\n",argv[1]);
652         exit(1);
653         }
654
655     return 0;
656     }
657
658 #endif