]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/openssl/fips/dsa/fips_dssvs.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / openssl / fips / dsa / fips_dssvs.c
1 #include <openssl/opensslconf.h>
2
3 #ifndef OPENSSL_FIPS
4 #include <stdio.h>
5
6 int main(int argc, char **argv)
7 {
8     printf("No FIPS DSA support\n");
9     return(0);
10 }
11 #else
12
13 #include <openssl/bn.h>
14 #include <openssl/dsa.h>
15 #include <openssl/fips.h>
16 #include <openssl/err.h>
17 #include <openssl/evp.h>
18 #include <string.h>
19 #include <ctype.h>
20
21 #include "fips_utl.h"
22
23 static void pbn(const char *name, BIGNUM *bn)
24         {
25         int len, i;
26         unsigned char *tmp;
27         len = BN_num_bytes(bn);
28         tmp = OPENSSL_malloc(len);
29         if (!tmp)
30                 {
31                 fprintf(stderr, "Memory allocation error\n");
32                 return;
33                 }
34         BN_bn2bin(bn, tmp);
35         printf("%s = ", name);
36         for (i = 0; i < len; i++)
37                 printf("%02X", tmp[i]);
38         fputs("\n", stdout);
39         OPENSSL_free(tmp);
40         return;
41         }
42
43 static void primes()
44     {
45     char buf[10240];
46     char lbuf[10240];
47     char *keyword, *value;
48
49     while(fgets(buf,sizeof buf,stdin) != NULL)
50         {
51         fputs(buf,stdout);
52         if (!parse_line(&keyword, &value, lbuf, buf))
53                 continue;
54         if(!strcmp(keyword,"Prime"))
55             {
56             BIGNUM *pp;
57
58             pp=BN_new();
59             do_hex2bn(&pp,value);
60             printf("result= %c\n",
61                    BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
62             }       
63         }
64     }
65
66 static void pqg()
67     {
68     char buf[1024];
69     char lbuf[1024];
70     char *keyword, *value;
71     int nmod=0;
72
73     while(fgets(buf,sizeof buf,stdin) != NULL)
74         {
75         if (!parse_line(&keyword, &value, lbuf, buf))
76                 {
77                 fputs(buf,stdout);
78                 continue;
79                 }
80         if(!strcmp(keyword,"[mod"))
81             nmod=atoi(value);
82         else if(!strcmp(keyword,"N"))
83             {
84             int n=atoi(value);
85
86             printf("[mod = %d]\n\n",nmod);
87
88             while(n--)
89                 {
90                 unsigned char seed[20];
91                 DSA *dsa;
92                 int counter;
93                 unsigned long h;
94                 dsa = FIPS_dsa_new();
95
96                 if (!DSA_generate_parameters_ex(dsa, nmod,seed,0,&counter,&h,NULL))
97                         {
98                         do_print_errors();
99                         exit(1);
100                         }
101                 pbn("P",dsa->p);
102                 pbn("Q",dsa->q);
103                 pbn("G",dsa->g);
104                 pv("Seed",seed,20);
105                 printf("c = %d\n",counter);
106                 printf("H = %lx\n",h);
107                 putc('\n',stdout);
108                 }
109             }
110         else
111             fputs(buf,stdout);
112         }
113     }
114
115 static void pqgver()
116     {
117     char buf[1024];
118     char lbuf[1024];
119     char *keyword, *value;
120     BIGNUM *p = NULL, *q = NULL, *g = NULL;
121     int counter, counter2;
122     unsigned long h, h2;
123     DSA *dsa=NULL;
124     int nmod=0;
125     unsigned char seed[1024];
126
127     while(fgets(buf,sizeof buf,stdin) != NULL)
128         {
129         if (!parse_line(&keyword, &value, lbuf, buf))
130                 {
131                 fputs(buf,stdout);
132                 continue;
133                 }
134         fputs(buf, stdout);
135         if(!strcmp(keyword,"[mod"))
136             nmod=atoi(value);
137         else if(!strcmp(keyword,"P"))
138             p=hex2bn(value);
139         else if(!strcmp(keyword,"Q"))
140             q=hex2bn(value);
141         else if(!strcmp(keyword,"G"))
142             g=hex2bn(value);
143         else if(!strcmp(keyword,"Seed"))
144             {
145             int slen = hex2bin(value, seed);
146             if (slen != 20)
147                 {
148                 fprintf(stderr, "Seed parse length error\n");
149                 exit (1);
150                 }
151             }
152         else if(!strcmp(keyword,"c"))
153             counter =atoi(buf+4);
154         else if(!strcmp(keyword,"H"))
155             {
156             h = atoi(value);
157             if (!p || !q || !g)
158                 {
159                 fprintf(stderr, "Parse Error\n");
160                 exit (1);
161                 }
162             dsa = FIPS_dsa_new();
163             if (!DSA_generate_parameters_ex(dsa, nmod,seed,20 ,&counter2,&h2,NULL))
164                         {
165                         do_print_errors();
166                         exit(1);
167                         }
168             if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g)
169                 || (counter != counter2) || (h != h2))
170                 printf("Result = F\n");
171             else
172                 printf("Result = P\n");
173             BN_free(p);
174             BN_free(q);
175             BN_free(g);
176             p = NULL;
177             q = NULL;
178             g = NULL;
179             FIPS_dsa_free(dsa);
180             dsa = NULL;
181             }
182         }
183     }
184
185 /* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
186  * algorithm tests. It is an additional test to perform sanity checks on the
187  * output of the KeyPair test.
188  */
189
190 static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
191                                                         BN_CTX *ctx)
192     {
193     BIGNUM *rem = NULL;
194     if (BN_num_bits(p) != nmod)
195         return 0;
196     if (BN_num_bits(q) != 160)
197         return 0;
198     if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
199         return 0;
200     if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
201         return 0;
202     rem = BN_new();
203     if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
204         || (BN_cmp(g, BN_value_one()) <= 0)
205         || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
206         {
207         BN_free(rem);
208         return 0;
209         }
210     /* Todo: check g */
211     BN_free(rem);
212     return 1;
213     }
214
215 static void keyver()
216     {
217     char buf[1024];
218     char lbuf[1024];
219     char *keyword, *value;
220     BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
221     BIGNUM *Y2;
222     BN_CTX *ctx = NULL;
223     int nmod=0, paramcheck = 0;
224
225     ctx = BN_CTX_new();
226     Y2 = BN_new();
227
228     while(fgets(buf,sizeof buf,stdin) != NULL)
229         {
230         if (!parse_line(&keyword, &value, lbuf, buf))
231                 {
232                 fputs(buf,stdout);
233                 continue;
234                 }
235         if(!strcmp(keyword,"[mod"))
236             {
237             if (p)
238                 BN_free(p);
239             p = NULL;
240             if (q)
241                 BN_free(q);
242             q = NULL;
243             if (g)
244                 BN_free(g);
245             g = NULL;
246             paramcheck = 0;
247             nmod=atoi(value);
248             }
249         else if(!strcmp(keyword,"P"))
250             p=hex2bn(value);
251         else if(!strcmp(keyword,"Q"))
252             q=hex2bn(value);
253         else if(!strcmp(keyword,"G"))
254             g=hex2bn(value);
255         else if(!strcmp(keyword,"X"))
256             X=hex2bn(value);
257         else if(!strcmp(keyword,"Y"))
258             {
259             Y=hex2bn(value);
260             if (!p || !q || !g || !X || !Y)
261                 {
262                 fprintf(stderr, "Parse Error\n");
263                 exit (1);
264                 }
265             pbn("P",p);
266             pbn("Q",q);
267             pbn("G",g);
268             pbn("X",X);
269             pbn("Y",Y);
270             if (!paramcheck)
271                 {
272                 if (dss_paramcheck(nmod, p, q, g, ctx))
273                         paramcheck = 1;
274                 else
275                         paramcheck = -1;
276                 }
277             if (paramcheck != 1)
278                 printf("Result = F\n");
279             else
280                 {
281                 if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
282                         printf("Result = F\n");
283                 else
284                         printf("Result = P\n");
285                 }
286             BN_free(X);
287             BN_free(Y);
288             X = NULL;
289             Y = NULL;
290             }
291         }
292         if (p)
293             BN_free(p);
294         if (q)
295             BN_free(q);
296         if (g)
297             BN_free(g);
298         if (Y2)
299             BN_free(Y2);
300     }
301
302 static void keypair()
303     {
304     char buf[1024];
305     char lbuf[1024];
306     char *keyword, *value;
307     int nmod=0;
308
309     while(fgets(buf,sizeof buf,stdin) != NULL)
310         {
311         if (!parse_line(&keyword, &value, lbuf, buf))
312                 {
313                 fputs(buf,stdout);
314                 continue;
315                 }
316         if(!strcmp(keyword,"[mod"))
317             nmod=atoi(value);
318         else if(!strcmp(keyword,"N"))
319             {
320             DSA *dsa;
321             int n=atoi(value);
322
323             printf("[mod = %d]\n\n",nmod);
324             dsa = FIPS_dsa_new();
325             if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
326                 {
327                 do_print_errors();
328                 exit(1);
329                 }
330             pbn("P",dsa->p);
331             pbn("Q",dsa->q);
332             pbn("G",dsa->g);
333             putc('\n',stdout);
334
335             while(n--)
336                 {
337                 if (!DSA_generate_key(dsa))
338                         {
339                         do_print_errors();
340                         exit(1);
341                         }
342
343                 pbn("X",dsa->priv_key);
344                 pbn("Y",dsa->pub_key);
345                 putc('\n',stdout);
346                 }
347             }
348         }
349     }
350
351 static void siggen()
352     {
353     char buf[1024];
354     char lbuf[1024];
355     char *keyword, *value;
356     int nmod=0;
357     DSA *dsa=NULL;
358
359     while(fgets(buf,sizeof buf,stdin) != NULL)
360         {
361         if (!parse_line(&keyword, &value, lbuf, buf))
362                 {
363                 fputs(buf,stdout);
364                 continue;
365                 }
366         if(!strcmp(keyword,"[mod"))
367             {
368             nmod=atoi(value);
369             printf("[mod = %d]\n\n",nmod);
370             if (dsa)
371                 FIPS_dsa_free(dsa);
372             dsa = FIPS_dsa_new();
373             if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
374                 {
375                 do_print_errors();
376                 exit(1);
377                 }
378             pbn("P",dsa->p);
379             pbn("Q",dsa->q);
380             pbn("G",dsa->g);
381             putc('\n',stdout);
382             }
383         else if(!strcmp(keyword,"Msg"))
384             {
385             unsigned char msg[1024];
386             unsigned char sbuf[60];
387             unsigned int slen;
388             int n;
389             EVP_PKEY pk;
390             EVP_MD_CTX mctx;
391             DSA_SIG *sig;
392             EVP_MD_CTX_init(&mctx);
393
394             n=hex2bin(value,msg);
395             pv("Msg",msg,n);
396
397             if (!DSA_generate_key(dsa))
398                 {
399                 do_print_errors();
400                 exit(1);
401                 }
402             pk.type = EVP_PKEY_DSA;
403             pk.pkey.dsa = dsa;
404             pbn("Y",dsa->pub_key);
405
406             EVP_SignInit_ex(&mctx, EVP_dss1(), NULL);
407             EVP_SignUpdate(&mctx, msg, n);
408             EVP_SignFinal(&mctx, sbuf, &slen, &pk);
409
410             sig = DSA_SIG_new();
411             FIPS_dsa_sig_decode(sig, sbuf, slen);
412
413             pbn("R",sig->r);
414             pbn("S",sig->s);
415             putc('\n',stdout);
416             DSA_SIG_free(sig);
417             EVP_MD_CTX_cleanup(&mctx);
418             }
419         }
420         if (dsa)
421                 FIPS_dsa_free(dsa);
422     }
423
424 static void sigver()
425     {
426     DSA *dsa=NULL;
427     char buf[1024];
428     char lbuf[1024];
429     unsigned char msg[1024];
430     char *keyword, *value;
431     int nmod=0, n=0;
432     DSA_SIG sg, *sig = &sg;
433
434     sig->r = NULL;
435     sig->s = NULL;
436
437     while(fgets(buf,sizeof buf,stdin) != NULL)
438         {
439         if (!parse_line(&keyword, &value, lbuf, buf))
440                 {
441                 fputs(buf,stdout);
442                 continue;
443                 }
444         if(!strcmp(keyword,"[mod"))
445             {
446             nmod=atoi(value);
447             if(dsa)
448                 FIPS_dsa_free(dsa);
449             dsa=FIPS_dsa_new();
450             }
451         else if(!strcmp(keyword,"P"))
452             dsa->p=hex2bn(value);
453         else if(!strcmp(keyword,"Q"))
454             dsa->q=hex2bn(value);
455         else if(!strcmp(keyword,"G"))
456             {
457             dsa->g=hex2bn(value);
458
459             printf("[mod = %d]\n\n",nmod);
460             pbn("P",dsa->p);
461             pbn("Q",dsa->q);
462             pbn("G",dsa->g);
463             putc('\n',stdout);
464             }
465         else if(!strcmp(keyword,"Msg"))
466             {
467             n=hex2bin(value,msg);
468             pv("Msg",msg,n);
469             }
470         else if(!strcmp(keyword,"Y"))
471             dsa->pub_key=hex2bn(value);
472         else if(!strcmp(keyword,"R"))
473             sig->r=hex2bn(value);
474         else if(!strcmp(keyword,"S"))
475             {
476             EVP_MD_CTX mctx;
477             EVP_PKEY pk;
478             unsigned char sigbuf[60];
479             unsigned int slen;
480             int r;
481             EVP_MD_CTX_init(&mctx);
482             pk.type = EVP_PKEY_DSA;
483             pk.pkey.dsa = dsa;
484             sig->s=hex2bn(value);
485         
486             pbn("Y",dsa->pub_key);
487             pbn("R",sig->r);
488             pbn("S",sig->s);
489
490             slen = FIPS_dsa_sig_encode(sigbuf, sig);
491             EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL);
492             EVP_VerifyUpdate(&mctx, msg, n);
493             r = EVP_VerifyFinal(&mctx, sigbuf, slen, &pk);
494             EVP_MD_CTX_cleanup(&mctx);
495         
496             printf("Result = %c\n", r == 1 ? 'P' : 'F');
497             putc('\n',stdout);
498             }
499         }
500     }
501
502 int main(int argc,char **argv)
503     {
504     if(argc != 2)
505         {
506         fprintf(stderr,"%s [prime|pqg|pqgver|keypair|siggen|sigver]\n",argv[0]);
507         exit(1);
508         }
509     if(!FIPS_mode_set(1))
510         {
511         do_print_errors();
512         exit(1);
513         }
514     if(!strcmp(argv[1],"prime"))
515         primes();
516     else if(!strcmp(argv[1],"pqg"))
517         pqg();
518     else if(!strcmp(argv[1],"pqgver"))
519         pqgver();
520     else if(!strcmp(argv[1],"keypair"))
521         keypair();
522     else if(!strcmp(argv[1],"keyver"))
523         keyver();
524     else if(!strcmp(argv[1],"siggen"))
525         siggen();
526     else if(!strcmp(argv[1],"sigver"))
527         sigver();
528     else
529         {
530         fprintf(stderr,"Don't know how to %s.\n",argv[1]);
531         exit(1);
532         }
533
534     return 0;
535     }
536
537 #endif