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