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