6a0b40fc4119dae2eb507c6f178b88a1a88cf5d4
[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_line2(&keyword, &value, lbuf, line, 0))
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_line2(&keyword, &value, lbuf, line, 0))
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 static void primes(FILE *in, FILE *out)
88     {
89     char buf[10240];
90     char lbuf[10240];
91     char *keyword, *value;
92
93     while(fgets(buf,sizeof buf,in) != NULL)
94         {
95         fputs(buf,out);
96         if (!parse_line(&keyword, &value, lbuf, buf))
97                 continue;
98         if(!strcmp(keyword,"Prime"))
99             {
100             BIGNUM *pp;
101
102             pp=BN_new();
103             do_hex2bn(&pp,value);
104             fprintf(out, "result= %c" RESP_EOL,
105                    BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
106             }       
107         }
108     }
109
110 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
111         const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
112         unsigned char *seed_out,
113         int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
114 int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
115         const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
116         int idx, unsigned char *seed_out,
117         int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
118
119 int dsa_paramgen_check_g(DSA *dsa);
120
121 static void pqg(FILE *in, FILE *out)
122     {
123     char buf[1024];
124     char lbuf[1024];
125     char *keyword, *value;
126     int dsa2, L, N;
127     const EVP_MD *md = NULL;
128     BIGNUM *p = NULL, *q = NULL;
129     enum pqtype { PQG_NONE, PQG_PQ, PQG_G, PQG_GCANON}
130                 pqg_type = PQG_NONE;
131     int seedlen=-1, idxlen, idx = -1;
132     unsigned char seed[1024], idtmp[1024];
133
134     while(fgets(buf,sizeof buf,in) != NULL)
135         {
136         if (buf[0] == '[')
137                 {
138                 if (strstr(buf, "Probable"))
139                         pqg_type = PQG_PQ;
140                 else if (strstr(buf, "Unverifiable"))
141                         pqg_type = PQG_G;
142                 else if (strstr(buf, "Canonical"))
143                         pqg_type = PQG_GCANON;
144                 }
145         if (!parse_line(&keyword, &value, lbuf, buf))
146                 {
147                 fputs(buf,out);
148                 continue;
149                 }
150         if (strcmp(keyword, "Num"))
151                 fputs(buf,out);
152         if(!strcmp(keyword,"[mod"))
153             {
154             if (!parse_mod(value, &dsa2, &L, &N, &md))
155                 {
156                 fprintf(stderr, "Mod Parse Error\n");
157                 exit (1);
158                 }
159             }
160         else if(!strcmp(keyword,"N") 
161                 || (!strcmp(keyword, "Num") && pqg_type == PQG_PQ))
162             {
163             int n=atoi(value);
164
165             while(n--)
166                 {
167                 DSA *dsa;
168                 int counter;
169                 unsigned long h;
170                 dsa = FIPS_dsa_new();
171
172                 if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
173                                                 NULL, 0, seed,
174                                                 &counter, &h, NULL))
175                         {
176                         fprintf(stderr, "Parameter Generation error\n");
177                         exit(1);
178                         }
179                 if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
180                                                 NULL, 0, -1, seed,
181                                                 &counter, &h, NULL) <= 0)
182                         {
183                         fprintf(stderr, "Parameter Generation error\n");
184                         exit(1);
185                         }
186  
187                 do_bn_print_name(out, "P",dsa->p);
188                 do_bn_print_name(out, "Q",dsa->q);
189                 if (!dsa2)
190                         do_bn_print_name(out, "G",dsa->g);
191                 OutputValue(dsa2 ? "domain_parameter_seed" : "Seed",
192                                 seed, M_EVP_MD_size(md), out, 0);
193                 if (!dsa2)
194                         {
195                         fprintf(out, "c = %d" RESP_EOL, counter);
196                         fprintf(out, "H = %lx" RESP_EOL RESP_EOL,h);
197                         }
198                 else
199                         {
200                         fprintf(out, "counter = %d" RESP_EOL RESP_EOL, counter);
201                         }
202                 FIPS_dsa_free(dsa);
203                 }
204             }
205         else if(!strcmp(keyword,"P"))
206             p=hex2bn(value);
207         else if(!strcmp(keyword,"Q"))
208             q=hex2bn(value);
209         else if(!strcmp(keyword,"domain_parameter_seed"))
210             seedlen = hex2bin(value, seed);
211         else if(!strcmp(keyword,"firstseed"))
212             seedlen = hex2bin(value, seed);
213         else if(!strcmp(keyword,"pseed"))
214             seedlen += hex2bin(value, seed + seedlen);
215         else if(!strcmp(keyword,"qseed"))
216             seedlen += hex2bin(value, seed + seedlen);
217         else if(!strcmp(keyword,"index"))
218             {
219             idxlen = hex2bin(value, idtmp);
220             if (idxlen != 1)
221                 {
222                 fprintf(stderr, "Index value error\n");
223                 exit (1);
224                 }
225             idx = idtmp[0];
226             }
227         if ((idx >= 0 && pqg_type == PQG_GCANON) || (q && pqg_type == PQG_G))
228                 {
229                 DSA *dsa;
230                 dsa = FIPS_dsa_new();
231                 dsa->p = p;
232                 dsa->q = q;
233                 p = q = NULL;
234                 if (dsa_builtin_paramgen2(dsa, L, N, md,
235                                                 seed, seedlen, idx, NULL,
236                                                 NULL, NULL, NULL) <= 0)
237                         {
238                         fprintf(stderr, "Parameter Generation error\n");
239                         exit(1);
240                         }
241                 do_bn_print_name(out, "G",dsa->g);
242                 FIPS_dsa_free(dsa);
243                 idx = -1;
244                 }
245         }
246     }
247
248 static void pqgver(FILE *in, FILE *out)
249     {
250     char buf[1024];
251     char lbuf[1024];
252     char *keyword, *value;
253     BIGNUM *p = NULL, *q = NULL, *g = NULL;
254     int counter=-1, counter2;
255     unsigned long h=0, h2;
256     DSA *dsa=NULL;
257     int dsa2, L, N, part_test = 0;
258     const EVP_MD *md = NULL;
259     int seedlen=-1, idxlen, idx = -1;
260     unsigned char seed[1024], idtmp[1024];
261
262     while(fgets(buf,sizeof buf,in) != NULL)
263         {
264         if (!parse_line(&keyword, &value, lbuf, buf))
265                 {
266                 if (p && q)
267                         {
268                         part_test = 1;
269                         goto partial;
270                         }
271                 fputs(buf,out);
272                 continue;
273                 }
274         fputs(buf, out);
275         if(!strcmp(keyword,"[mod"))
276             {
277             if (!parse_mod(value, &dsa2, &L, &N, &md))
278                 {
279                 fprintf(stderr, "Mod Parse Error\n");
280                 exit (1);
281                 }
282             }
283         else if(!strcmp(keyword,"P"))
284             p=hex2bn(value);
285         else if(!strcmp(keyword,"Q"))
286             q=hex2bn(value);
287         else if(!strcmp(keyword,"G"))
288             g=hex2bn(value);
289         else if(!strcmp(keyword,"firstseed"))
290             seedlen = hex2bin(value, seed);
291         else if(!strcmp(keyword,"pseed"))
292             seedlen += hex2bin(value, seed + seedlen);
293         else if(!strcmp(keyword,"qseed"))
294             seedlen += hex2bin(value, seed + seedlen);
295         else if(!strcmp(keyword,"Seed")
296                 || !strcmp(keyword,"domain_parameter_seed"))
297             {
298             seedlen = hex2bin(value, seed);
299             if (!dsa2 && seedlen != 20)
300                 {
301                 fprintf(stderr, "Seed parse length error\n");
302                 exit (1);
303                 }
304             if (idx > 0)
305                 part_test = 1;
306             }
307         else if(!strcmp(keyword,"index"))
308             {
309             idxlen = hex2bin(value, idtmp);
310             if (idxlen != 1)
311                 {
312                 fprintf(stderr, "Index value error\n");
313                 exit (1);
314                 }
315             idx = idtmp[0];
316             }
317         else if(!strcmp(keyword,"c"))
318             counter = atoi(buf+4);
319         partial:
320         if (part_test && idx < 0 && h == 0 && g)
321             {
322             dsa = FIPS_dsa_new();
323             dsa->p = BN_dup(p);
324             dsa->q = BN_dup(q);
325             dsa->g = BN_dup(g);
326             if (dsa_paramgen_check_g(dsa))
327                 fprintf(out, "Result = P" RESP_EOL);
328             else
329                 fprintf(out, "Result = F" RESP_EOL);
330             BN_free(p);
331             BN_free(q);
332             BN_free(g);
333             p = NULL;
334             q = NULL;
335             g = NULL;
336             FIPS_dsa_free(dsa);
337             dsa = NULL;
338             part_test = 0;
339             }
340         else if(!strcmp(keyword,"H") || part_test)
341             {
342             if (!part_test)
343                 h = atoi(value);
344             if (!p || !q || (!g && !part_test))
345                 {
346                 fprintf(stderr, "Parse Error\n");
347                 exit (1);
348                 }
349             dsa = FIPS_dsa_new();
350             if (idx >= 0)
351                 {
352                 dsa->p = BN_dup(p);
353                 dsa->q = BN_dup(q);
354                 }
355             no_err = 1;
356             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
357                                         seed, seedlen, NULL,
358                                         &counter2, &h2, NULL))
359                         {
360                         fprintf(stderr, "Parameter Generation error\n");
361                         exit(1);
362                         }
363             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
364                                         seed, seedlen, idx, NULL,
365                                         &counter2, &h2, NULL) < 0)
366                         {
367                         fprintf(stderr, "Parameter Generation error\n");
368                         exit(1);
369                         }
370             no_err = 0;
371             if (idx >= 0)
372                 {
373                 if (BN_cmp(dsa->g, g))
374                         fprintf(out, "Result = F" RESP_EOL);
375                 else
376                         fprintf(out, "Result = P" RESP_EOL);
377                 }
378             else if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || 
379                 (!part_test &&
380                 ((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2)))))
381                 fprintf(out, "Result = F" RESP_EOL);
382             else
383                 fprintf(out, "Result = P" RESP_EOL);
384             BN_free(p);
385             BN_free(q);
386             BN_free(g);
387             p = NULL;
388             q = NULL;
389             g = NULL;
390             FIPS_dsa_free(dsa);
391             dsa = NULL;
392             if (part_test)
393                 {
394                 if (idx == -1)
395                         fputs(buf,out);
396                 part_test = 0;
397                 }
398             idx = -1;
399             }
400         }
401     }
402
403 /* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
404  * algorithm tests. It is an additional test to perform sanity checks on the
405  * output of the KeyPair test.
406  */
407
408 static int dss_paramcheck(int L, int N, BIGNUM *p, BIGNUM *q, BIGNUM *g,
409                                                         BN_CTX *ctx)
410     {
411     BIGNUM *rem = NULL;
412     if (BN_num_bits(p) != L)
413         return 0;
414     if (BN_num_bits(q) != N)
415         return 0;
416     if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
417         return 0;
418     if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
419         return 0;
420     rem = BN_new();
421     if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
422         || (BN_cmp(g, BN_value_one()) <= 0)
423         || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
424         {
425         BN_free(rem);
426         return 0;
427         }
428     /* Todo: check g */
429     BN_free(rem);
430     return 1;
431     }
432
433 static void keyver(FILE *in, FILE *out)
434     {
435     char buf[1024];
436     char lbuf[1024];
437     char *keyword, *value;
438     BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
439     BIGNUM *Y2;
440     BN_CTX *ctx = NULL;
441     int dsa2, L, N;
442     int paramcheck = 0;
443
444     ctx = BN_CTX_new();
445     Y2 = BN_new();
446
447     while(fgets(buf,sizeof buf,in) != NULL)
448         {
449         if (!parse_line(&keyword, &value, lbuf, buf))
450                 {
451                 fputs(buf,out);
452                 continue;
453                 }
454         if(!strcmp(keyword,"[mod"))
455             {
456             if (p)
457                 BN_free(p);
458             p = NULL;
459             if (q)
460                 BN_free(q);
461             q = NULL;
462             if (g)
463                 BN_free(g);
464             g = NULL;
465             paramcheck = 0;
466             if (!parse_mod(value, &dsa2, &L, &N, NULL))
467                 {
468                 fprintf(stderr, "Mod Parse Error\n");
469                 exit (1);
470                 }
471             }
472         else if(!strcmp(keyword,"P"))
473             p=hex2bn(value);
474         else if(!strcmp(keyword,"Q"))
475             q=hex2bn(value);
476         else if(!strcmp(keyword,"G"))
477             g=hex2bn(value);
478         else if(!strcmp(keyword,"X"))
479             X=hex2bn(value);
480         else if(!strcmp(keyword,"Y"))
481             {
482             Y=hex2bn(value);
483             if (!p || !q || !g || !X || !Y)
484                 {
485                 fprintf(stderr, "Parse Error\n");
486                 exit (1);
487                 }
488             do_bn_print_name(out, "P",p);
489             do_bn_print_name(out, "Q",q);
490             do_bn_print_name(out, "G",g);
491             do_bn_print_name(out, "X",X);
492             do_bn_print_name(out, "Y",Y);
493             if (!paramcheck)
494                 {
495                 if (dss_paramcheck(L, N, p, q, g, ctx))
496                         paramcheck = 1;
497                 else
498                         paramcheck = -1;
499                 }
500             if (paramcheck != 1)
501                 fprintf(out, "Result = F" RESP_EOL);
502             else
503                 {
504                 if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
505                         fprintf(out, "Result = F" RESP_EOL);
506                 else
507                         fprintf(out, "Result = P" RESP_EOL);
508                 }
509             BN_free(X);
510             BN_free(Y);
511             X = NULL;
512             Y = NULL;
513             }
514         }
515         if (p)
516             BN_free(p);
517         if (q)
518             BN_free(q);
519         if (g)
520             BN_free(g);
521         if (Y2)
522             BN_free(Y2);
523         if (ctx)
524             BN_CTX_free(ctx);
525     }
526
527 static void keypair(FILE *in, FILE *out)
528     {
529     char buf[1024];
530     char lbuf[1024];
531     char *keyword, *value;
532     int dsa2, L, N;
533
534     while(fgets(buf,sizeof buf,in) != NULL)
535         {
536         if (!parse_line(&keyword, &value, lbuf, buf))
537                 {
538                 continue;
539                 }
540         if(!strcmp(keyword,"[mod"))
541             {
542             if (!parse_mod(value, &dsa2, &L, &N, NULL))
543                 {
544                 fprintf(stderr, "Mod Parse Error\n");
545                 exit (1);
546                 }
547             fputs(buf,out);
548             }
549         else if(!strcmp(keyword,"N"))
550             {
551             DSA *dsa;
552             int n=atoi(value);
553
554             dsa = FIPS_dsa_new();
555             if (!dsa)
556                 {
557                 fprintf(stderr, "DSA allocation error\n");
558                 exit(1);
559                 }
560             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
561                                                 NULL, NULL, NULL, NULL))
562                         {
563                         fprintf(stderr, "Parameter Generation error\n");
564                         exit(1);
565                         }
566             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1,
567                                                 NULL, NULL, NULL, NULL) <= 0)
568                         {
569                         fprintf(stderr, "Parameter Generation error\n");
570                         exit(1);
571                         }
572             do_bn_print_name(out, "P",dsa->p);
573             do_bn_print_name(out, "Q",dsa->q);
574             do_bn_print_name(out, "G",dsa->g);
575             fputs(RESP_EOL, out);
576
577             while(n--)
578                 {
579                 if (!DSA_generate_key(dsa))
580                         exit(1);
581
582                 do_bn_print_name(out, "X",dsa->priv_key);
583                 do_bn_print_name(out, "Y",dsa->pub_key);
584                 fputs(RESP_EOL, out);
585                 }
586             FIPS_dsa_free(dsa);
587             }
588         }
589     }
590
591 static void siggen(FILE *in, FILE *out)
592     {
593     char buf[1024];
594     char lbuf[1024];
595     char *keyword, *value;
596     int dsa2, L, N;
597     const EVP_MD *md = NULL;
598     DSA *dsa=NULL;
599
600     while(fgets(buf,sizeof buf,in) != NULL)
601         {
602         if (!parse_line(&keyword, &value, lbuf, buf))
603                 {
604                 fputs(buf,out);
605                 continue;
606                 }
607         fputs(buf,out);
608         if(!strcmp(keyword,"[mod"))
609             {
610             if (!parse_mod(value, &dsa2, &L, &N, &md))
611                 {
612                 fprintf(stderr, "Mod Parse Error\n");
613                 exit (1);
614                 }
615             if (dsa)
616                 FIPS_dsa_free(dsa);
617             dsa = FIPS_dsa_new();
618             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0,
619                                                 NULL, NULL, NULL, NULL))
620                         {
621                         fprintf(stderr, "Parameter Generation error\n");
622                         exit(1);
623                         }
624             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1,
625                                                 NULL, NULL, NULL, NULL) <= 0)
626                         {
627                         fprintf(stderr, "Parameter Generation error\n");
628                         exit(1);
629                         }
630             do_bn_print_name(out, "P",dsa->p);
631             do_bn_print_name(out, "Q",dsa->q);
632             do_bn_print_name(out, "G",dsa->g);
633             fputs(RESP_EOL, out);
634             }
635         else if(!strcmp(keyword,"Msg"))
636             {
637             unsigned char msg[1024];
638             int n;
639             DSA_SIG *sig;
640
641             n=hex2bin(value,msg);
642
643             if (!DSA_generate_key(dsa))
644                 exit(1);
645             do_bn_print_name(out, "Y",dsa->pub_key);
646
647             sig = FIPS_dsa_sign(dsa, msg, n, md);
648
649             do_bn_print_name(out, "R",sig->r);
650             do_bn_print_name(out, "S",sig->s);
651             fputs(RESP_EOL, out);
652             FIPS_dsa_sig_free(sig);
653             }
654         }
655     if (dsa)
656         FIPS_dsa_free(dsa);
657     }
658
659 static void sigver(FILE *in, FILE *out)
660     {
661     DSA *dsa=NULL;
662     char buf[1024];
663     char lbuf[1024];
664     unsigned char msg[1024];
665     char *keyword, *value;
666     int n=0;
667     int dsa2, L, N;
668     const EVP_MD *md = NULL;
669     DSA_SIG sg, *sig = &sg;
670
671     sig->r = NULL;
672     sig->s = NULL;
673
674     while(fgets(buf,sizeof buf,in) != NULL)
675         {
676         if (!parse_line(&keyword, &value, lbuf, buf))
677                 {
678                 fputs(buf,out);
679                 continue;
680                 }
681         fputs(buf,out);
682         if(!strcmp(keyword,"[mod"))
683             {
684             if (!parse_mod(value, &dsa2, &L, &N, &md))
685                 {
686                 fprintf(stderr, "Mod Parse Error\n");
687                 exit (1);
688                 }
689             if (dsa)
690                 FIPS_dsa_free(dsa);
691             dsa = FIPS_dsa_new();
692             }
693         else if(!strcmp(keyword,"P"))
694             do_hex2bn(&dsa->p, value);
695         else if(!strcmp(keyword,"Q"))
696             do_hex2bn(&dsa->q, value);
697         else if(!strcmp(keyword,"G"))
698             do_hex2bn(&dsa->g, value);
699         else if(!strcmp(keyword,"Msg"))
700             n=hex2bin(value,msg);
701         else if(!strcmp(keyword,"Y"))
702             do_hex2bn(&dsa->pub_key, value);
703         else if(!strcmp(keyword,"R"))
704             sig->r=hex2bn(value);
705         else if(!strcmp(keyword,"S"))
706             {
707             int r;
708             sig->s=hex2bn(value);
709
710             no_err = 1;
711             r = FIPS_dsa_verify(dsa, msg, n, md, sig);
712             no_err = 0;
713             if (sig->s)
714                 {
715                 BN_free(sig->s);
716                 sig->s = NULL;
717                 }
718             if (sig->r)
719                 {
720                 BN_free(sig->r);
721                 sig->r = NULL;
722                 }
723         
724             fprintf(out, "Result = %c" RESP_EOL RESP_EOL, r == 1 ? 'P' : 'F');
725             }
726         }
727         if (dsa)
728             FIPS_dsa_free(dsa);
729     }
730
731 #ifdef FIPS_ALGVS
732 int fips_dssvs_main(int argc, char **argv)
733 #else
734 int main(int argc, char **argv)
735 #endif
736     {
737     FILE *in, *out;
738     if (argc == 4)
739         {
740         in = fopen(argv[2], "r");
741         if (!in)
742                 {
743                 fprintf(stderr, "Error opening input file\n");
744                 exit(1);
745                 }
746         out = fopen(argv[3], "w");
747         if (!out)
748                 {
749                 fprintf(stderr, "Error opening output file\n");
750                 exit(1);
751                 }
752         }
753     else if (argc == 2)
754         {
755         in = stdin;
756         out = stdout;
757         }
758     else
759         {
760         fprintf(stderr,"%s [prime|pqg|pqgver|keypair|keyver|siggen|sigver]\n",argv[0]);
761         exit(1);
762         }
763     fips_algtest_init();
764     if(!strcmp(argv[1],"prime"))
765         primes(in, out);
766     else if(!strcmp(argv[1],"pqg"))
767         pqg(in, out);
768     else if(!strcmp(argv[1],"pqgver"))
769         pqgver(in, out);
770     else if(!strcmp(argv[1],"keypair"))
771         keypair(in, out);
772     else if(!strcmp(argv[1],"keyver"))
773         keyver(in, out);
774     else if(!strcmp(argv[1],"siggen"))
775         siggen(in, out);
776     else if(!strcmp(argv[1],"sigver"))
777         sigver(in, out);
778     else
779         {
780         fprintf(stderr,"Don't know how to %s.\n",argv[1]);
781         exit(1);
782         }
783
784     if (argc == 4)
785         {
786         fclose(in);
787         fclose(out);
788         }
789
790     return 0;
791     }
792
793 #endif