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