e2f2297f00762a43396be1c369c86d4c00208725
[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 (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
556                                                 NULL, NULL, NULL, NULL))
557                         {
558                         fprintf(stderr, "Parameter Generation error\n");
559                         exit(1);
560                         }
561             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1,
562                                                 NULL, NULL, NULL, NULL) <= 0)
563                         {
564                         fprintf(stderr, "Parameter Generation error\n");
565                         exit(1);
566                         }
567             do_bn_print_name(out, "P",dsa->p);
568             do_bn_print_name(out, "Q",dsa->q);
569             do_bn_print_name(out, "G",dsa->g);
570             fputs(RESP_EOL, out);
571
572             while(n--)
573                 {
574                 if (!DSA_generate_key(dsa))
575                         exit(1);
576
577                 do_bn_print_name(out, "X",dsa->priv_key);
578                 do_bn_print_name(out, "Y",dsa->pub_key);
579                 fputs(RESP_EOL, out);
580                 }
581             if (dsa)
582                 FIPS_dsa_free(dsa);
583             }
584         }
585     }
586
587 static void siggen(FILE *in, FILE *out)
588     {
589     char buf[1024];
590     char lbuf[1024];
591     char *keyword, *value;
592     int dsa2, L, N;
593     const EVP_MD *md = NULL;
594     DSA *dsa=NULL;
595
596     while(fgets(buf,sizeof buf,in) != NULL)
597         {
598         if (!parse_line(&keyword, &value, lbuf, buf))
599                 {
600                 fputs(buf,out);
601                 continue;
602                 }
603         fputs(buf,out);
604         if(!strcmp(keyword,"[mod"))
605             {
606             if (!parse_mod(value, &dsa2, &L, &N, &md))
607                 {
608                 fprintf(stderr, "Mod Parse Error\n");
609                 exit (1);
610                 }
611             if (dsa)
612                 FIPS_dsa_free(dsa);
613             dsa = FIPS_dsa_new();
614             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0,
615                                                 NULL, NULL, NULL, NULL))
616                         {
617                         fprintf(stderr, "Parameter Generation error\n");
618                         exit(1);
619                         }
620             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1,
621                                                 NULL, NULL, NULL, NULL) <= 0)
622                         {
623                         fprintf(stderr, "Parameter Generation error\n");
624                         exit(1);
625                         }
626             do_bn_print_name(out, "P",dsa->p);
627             do_bn_print_name(out, "Q",dsa->q);
628             do_bn_print_name(out, "G",dsa->g);
629             fputs(RESP_EOL, out);
630             }
631         else if(!strcmp(keyword,"Msg"))
632             {
633             unsigned char msg[1024];
634             int n;
635             DSA_SIG *sig;
636
637             n=hex2bin(value,msg);
638
639             if (!DSA_generate_key(dsa))
640                 exit(1);
641             do_bn_print_name(out, "Y",dsa->pub_key);
642
643             sig = FIPS_dsa_sign(dsa, msg, n, md);
644
645             do_bn_print_name(out, "R",sig->r);
646             do_bn_print_name(out, "S",sig->s);
647             fputs(RESP_EOL, out);
648             FIPS_dsa_sig_free(sig);
649             }
650         }
651     if (dsa)
652         FIPS_dsa_free(dsa);
653     }
654
655 static void sigver(FILE *in, FILE *out)
656     {
657     DSA *dsa=NULL;
658     char buf[1024];
659     char lbuf[1024];
660     unsigned char msg[1024];
661     char *keyword, *value;
662     int n=0;
663     int dsa2, L, N;
664     const EVP_MD *md = NULL;
665     DSA_SIG sg, *sig = &sg;
666
667     sig->r = NULL;
668     sig->s = NULL;
669
670     while(fgets(buf,sizeof buf,in) != NULL)
671         {
672         if (!parse_line(&keyword, &value, lbuf, buf))
673                 {
674                 fputs(buf,out);
675                 continue;
676                 }
677         fputs(buf,out);
678         if(!strcmp(keyword,"[mod"))
679             {
680             if (!parse_mod(value, &dsa2, &L, &N, &md))
681                 {
682                 fprintf(stderr, "Mod Parse Error\n");
683                 exit (1);
684                 }
685             if (dsa)
686                 FIPS_dsa_free(dsa);
687             dsa = FIPS_dsa_new();
688             }
689         else if(!strcmp(keyword,"P"))
690             do_hex2bn(&dsa->p, value);
691         else if(!strcmp(keyword,"Q"))
692             do_hex2bn(&dsa->q, value);
693         else if(!strcmp(keyword,"G"))
694             do_hex2bn(&dsa->g, value);
695         else if(!strcmp(keyword,"Msg"))
696             n=hex2bin(value,msg);
697         else if(!strcmp(keyword,"Y"))
698             do_hex2bn(&dsa->pub_key, value);
699         else if(!strcmp(keyword,"R"))
700             sig->r=hex2bn(value);
701         else if(!strcmp(keyword,"S"))
702             {
703             int r;
704             sig->s=hex2bn(value);
705
706             no_err = 1;
707             r = FIPS_dsa_verify(dsa, msg, n, md, sig);
708             no_err = 0;
709             if (sig->s)
710                 {
711                 BN_free(sig->s);
712                 sig->s = NULL;
713                 }
714             if (sig->r)
715                 {
716                 BN_free(sig->r);
717                 sig->r = NULL;
718                 }
719         
720             fprintf(out, "Result = %c" RESP_EOL RESP_EOL, r == 1 ? 'P' : 'F');
721             }
722         }
723         if (dsa)
724             FIPS_dsa_free(dsa);
725     }
726
727 #ifdef FIPS_ALGVS
728 int fips_dssvs_main(int argc, char **argv)
729 #else
730 int main(int argc, char **argv)
731 #endif
732     {
733     FILE *in, *out;
734     if (argc == 4)
735         {
736         in = fopen(argv[2], "r");
737         if (!in)
738                 {
739                 fprintf(stderr, "Error opening input file\n");
740                 exit(1);
741                 }
742         out = fopen(argv[3], "w");
743         if (!out)
744                 {
745                 fprintf(stderr, "Error opening output file\n");
746                 exit(1);
747                 }
748         }
749     else if (argc == 2)
750         {
751         in = stdin;
752         out = stdout;
753         }
754     else
755         {
756         fprintf(stderr,"%s [prime|pqg|pqgver|keypair|keyver|siggen|sigver]\n",argv[0]);
757         exit(1);
758         }
759     fips_algtest_init();
760     if(!strcmp(argv[1],"prime"))
761         primes(in, out);
762     else if(!strcmp(argv[1],"pqg"))
763         pqg(in, out);
764     else if(!strcmp(argv[1],"pqgver"))
765         pqgver(in, out);
766     else if(!strcmp(argv[1],"keypair"))
767         keypair(in, out);
768     else if(!strcmp(argv[1],"keyver"))
769         keyver(in, out);
770     else if(!strcmp(argv[1],"siggen"))
771         siggen(in, out);
772     else if(!strcmp(argv[1],"sigver"))
773         sigver(in, out);
774     else
775         {
776         fprintf(stderr,"Don't know how to %s.\n",argv[1]);
777         exit(1);
778         }
779
780     if (argc == 4)
781         {
782         fclose(in);
783         fclose(out);
784         }
785
786     return 0;
787     }
788
789 #endif