Add usage messages.
[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                 }
203             }
204         else if(!strcmp(keyword,"P"))
205             p=hex2bn(value);
206         else if(!strcmp(keyword,"Q"))
207             q=hex2bn(value);
208         else if(!strcmp(keyword,"domain_parameter_seed"))
209             seedlen = hex2bin(value, seed);
210         else if(!strcmp(keyword,"firstseed"))
211             seedlen = hex2bin(value, seed);
212         else if(!strcmp(keyword,"pseed"))
213             seedlen += hex2bin(value, seed + seedlen);
214         else if(!strcmp(keyword,"qseed"))
215             seedlen += hex2bin(value, seed + seedlen);
216         else if(!strcmp(keyword,"index"))
217             {
218             idxlen = hex2bin(value, idtmp);
219             if (idxlen != 1)
220                 {
221                 fprintf(stderr, "Index value error\n");
222                 exit (1);
223                 }
224             idx = idtmp[0];
225             }
226         if ((idx >= 0 && pqg_type == PQG_GCANON) || (q && pqg_type == PQG_G))
227                 {
228                 DSA *dsa;
229                 dsa = FIPS_dsa_new();
230                 dsa->p = p;
231                 dsa->q = q;
232                 p = q = NULL;
233                 if (dsa_builtin_paramgen2(dsa, L, N, md,
234                                                 seed, seedlen, idx, NULL,
235                                                 NULL, NULL, NULL) <= 0)
236                         {
237                         fprintf(stderr, "Parameter Generation error\n");
238                         exit(1);
239                         }
240                 do_bn_print_name(out, "G",dsa->g);
241                 FIPS_dsa_free(dsa);
242                 idx = -1;
243                 }
244         }
245     }
246
247 static void pqgver(FILE *in, FILE *out)
248     {
249     char buf[1024];
250     char lbuf[1024];
251     char *keyword, *value;
252     BIGNUM *p = NULL, *q = NULL, *g = NULL;
253     int counter=-1, counter2;
254     unsigned long h=0, h2;
255     DSA *dsa=NULL;
256     int dsa2, L, N, part_test = 0;
257     const EVP_MD *md = NULL;
258     int seedlen=-1, idxlen, idx = -1;
259     unsigned char seed[1024], idtmp[1024];
260
261     while(fgets(buf,sizeof buf,in) != NULL)
262         {
263         if (!parse_line(&keyword, &value, lbuf, buf))
264                 {
265                 if (p && q)
266                         {
267                         part_test = 1;
268                         goto partial;
269                         }
270                 fputs(buf,out);
271                 continue;
272                 }
273         fputs(buf, out);
274         if(!strcmp(keyword,"[mod"))
275             {
276             if (!parse_mod(value, &dsa2, &L, &N, &md))
277                 {
278                 fprintf(stderr, "Mod Parse Error\n");
279                 exit (1);
280                 }
281             }
282         else if(!strcmp(keyword,"P"))
283             p=hex2bn(value);
284         else if(!strcmp(keyword,"Q"))
285             q=hex2bn(value);
286         else if(!strcmp(keyword,"G"))
287             g=hex2bn(value);
288         else if(!strcmp(keyword,"firstseed"))
289             seedlen = hex2bin(value, seed);
290         else if(!strcmp(keyword,"pseed"))
291             seedlen += hex2bin(value, seed + seedlen);
292         else if(!strcmp(keyword,"qseed"))
293             seedlen += hex2bin(value, seed + seedlen);
294         else if(!strcmp(keyword,"Seed")
295                 || !strcmp(keyword,"domain_parameter_seed"))
296             {
297             seedlen = hex2bin(value, seed);
298             if (!dsa2 && seedlen != 20)
299                 {
300                 fprintf(stderr, "Seed parse length error\n");
301                 exit (1);
302                 }
303             if (idx > 0)
304                 part_test = 1;
305             }
306         else if(!strcmp(keyword,"index"))
307             {
308             idxlen = hex2bin(value, idtmp);
309             if (idxlen != 1)
310                 {
311                 fprintf(stderr, "Index value error\n");
312                 exit (1);
313                 }
314             idx = idtmp[0];
315             }
316         else if(!strcmp(keyword,"c"))
317             counter = atoi(buf+4);
318         partial:
319         if (part_test && idx < 0 && h == 0 && g)
320             {
321             dsa = FIPS_dsa_new();
322             dsa->p = BN_dup(p);
323             dsa->q = BN_dup(q);
324             dsa->g = BN_dup(g);
325             if (dsa_paramgen_check_g(dsa))
326                 fprintf(out, "Result = P" RESP_EOL);
327             else
328                 fprintf(out, "Result = F" RESP_EOL);
329             BN_free(p);
330             BN_free(q);
331             BN_free(g);
332             p = NULL;
333             q = NULL;
334             g = NULL;
335             FIPS_dsa_free(dsa);
336             dsa = NULL;
337             part_test = 0;
338             }
339         else if(!strcmp(keyword,"H") || part_test)
340             {
341             if (!part_test)
342                 h = atoi(value);
343             if (!p || !q || (!g && !part_test))
344                 {
345                 fprintf(stderr, "Parse Error\n");
346                 exit (1);
347                 }
348             dsa = FIPS_dsa_new();
349             if (idx >= 0)
350                 {
351                 dsa->p = BN_dup(p);
352                 dsa->q = BN_dup(q);
353                 }
354             no_err = 1;
355             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
356                                         seed, seedlen, NULL,
357                                         &counter2, &h2, NULL))
358                         {
359                         fprintf(stderr, "Parameter Generation error\n");
360                         exit(1);
361                         }
362             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
363                                         seed, seedlen, idx, NULL,
364                                         &counter2, &h2, NULL) < 0)
365                         {
366                         fprintf(stderr, "Parameter Generation error\n");
367                         exit(1);
368                         }
369             no_err = 0;
370             if (idx >= 0)
371                 {
372                 if (BN_cmp(dsa->g, g))
373                         fprintf(out, "Result = F" RESP_EOL);
374                 else
375                         fprintf(out, "Result = P" RESP_EOL);
376                 }
377             else if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || 
378                 (!part_test &&
379                 ((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2)))))
380                 fprintf(out, "Result = F" RESP_EOL);
381             else
382                 fprintf(out, "Result = P" RESP_EOL);
383             BN_free(p);
384             BN_free(q);
385             BN_free(g);
386             p = NULL;
387             q = NULL;
388             g = NULL;
389             FIPS_dsa_free(dsa);
390             dsa = NULL;
391             if (part_test)
392                 {
393                 if (idx == -1)
394                         fputs(buf,out);
395                 part_test = 0;
396                 }
397             idx = -1;
398             }
399         }
400     }
401
402 /* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
403  * algorithm tests. It is an additional test to perform sanity checks on the
404  * output of the KeyPair test.
405  */
406
407 static int dss_paramcheck(int L, int N, BIGNUM *p, BIGNUM *q, BIGNUM *g,
408                                                         BN_CTX *ctx)
409     {
410     BIGNUM *rem = NULL;
411     if (BN_num_bits(p) != L)
412         return 0;
413     if (BN_num_bits(q) != N)
414         return 0;
415     if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
416         return 0;
417     if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
418         return 0;
419     rem = BN_new();
420     if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
421         || (BN_cmp(g, BN_value_one()) <= 0)
422         || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
423         {
424         BN_free(rem);
425         return 0;
426         }
427     /* Todo: check g */
428     BN_free(rem);
429     return 1;
430     }
431
432 static void keyver(FILE *in, FILE *out)
433     {
434     char buf[1024];
435     char lbuf[1024];
436     char *keyword, *value;
437     BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
438     BIGNUM *Y2;
439     BN_CTX *ctx = NULL;
440     int dsa2, L, N;
441     int paramcheck = 0;
442
443     ctx = BN_CTX_new();
444     Y2 = BN_new();
445
446     while(fgets(buf,sizeof buf,in) != NULL)
447         {
448         if (!parse_line(&keyword, &value, lbuf, buf))
449                 {
450                 fputs(buf,out);
451                 continue;
452                 }
453         if(!strcmp(keyword,"[mod"))
454             {
455             if (p)
456                 BN_free(p);
457             p = NULL;
458             if (q)
459                 BN_free(q);
460             q = NULL;
461             if (g)
462                 BN_free(g);
463             g = NULL;
464             paramcheck = 0;
465             if (!parse_mod(value, &dsa2, &L, &N, NULL))
466                 {
467                 fprintf(stderr, "Mod Parse Error\n");
468                 exit (1);
469                 }
470             }
471         else if(!strcmp(keyword,"P"))
472             p=hex2bn(value);
473         else if(!strcmp(keyword,"Q"))
474             q=hex2bn(value);
475         else if(!strcmp(keyword,"G"))
476             g=hex2bn(value);
477         else if(!strcmp(keyword,"X"))
478             X=hex2bn(value);
479         else if(!strcmp(keyword,"Y"))
480             {
481             Y=hex2bn(value);
482             if (!p || !q || !g || !X || !Y)
483                 {
484                 fprintf(stderr, "Parse Error\n");
485                 exit (1);
486                 }
487             do_bn_print_name(out, "P",p);
488             do_bn_print_name(out, "Q",q);
489             do_bn_print_name(out, "G",g);
490             do_bn_print_name(out, "X",X);
491             do_bn_print_name(out, "Y",Y);
492             if (!paramcheck)
493                 {
494                 if (dss_paramcheck(L, N, p, q, g, ctx))
495                         paramcheck = 1;
496                 else
497                         paramcheck = -1;
498                 }
499             if (paramcheck != 1)
500                 fprintf(out, "Result = F" RESP_EOL);
501             else
502                 {
503                 if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
504                         fprintf(out, "Result = F" RESP_EOL);
505                 else
506                         fprintf(out, "Result = P" RESP_EOL);
507                 }
508             BN_free(X);
509             BN_free(Y);
510             X = NULL;
511             Y = NULL;
512             }
513         }
514         if (p)
515             BN_free(p);
516         if (q)
517             BN_free(q);
518         if (g)
519             BN_free(g);
520         if (Y2)
521             BN_free(Y2);
522     }
523
524 static void keypair(FILE *in, FILE *out)
525     {
526     char buf[1024];
527     char lbuf[1024];
528     char *keyword, *value;
529     int dsa2, L, N;
530
531     while(fgets(buf,sizeof buf,in) != NULL)
532         {
533         if (!parse_line(&keyword, &value, lbuf, buf))
534                 {
535                 continue;
536                 }
537         if(!strcmp(keyword,"[mod"))
538             {
539             if (!parse_mod(value, &dsa2, &L, &N, NULL))
540                 {
541                 fprintf(stderr, "Mod Parse Error\n");
542                 exit (1);
543                 }
544             fputs(buf,out);
545             }
546         else if(!strcmp(keyword,"N"))
547             {
548             DSA *dsa;
549             int n=atoi(value);
550
551             dsa = FIPS_dsa_new();
552             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
553                                                 NULL, NULL, NULL, NULL))
554                         {
555                         fprintf(stderr, "Parameter Generation error\n");
556                         exit(1);
557                         }
558             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1,
559                                                 NULL, NULL, NULL, NULL) <= 0)
560                         {
561                         fprintf(stderr, "Parameter Generation error\n");
562                         exit(1);
563                         }
564             do_bn_print_name(out, "P",dsa->p);
565             do_bn_print_name(out, "Q",dsa->q);
566             do_bn_print_name(out, "G",dsa->g);
567             fputs(RESP_EOL, out);
568
569             while(n--)
570                 {
571                 if (!DSA_generate_key(dsa))
572                         exit(1);
573
574                 do_bn_print_name(out, "X",dsa->priv_key);
575                 do_bn_print_name(out, "Y",dsa->pub_key);
576                 fputs(RESP_EOL, out);
577                 }
578             }
579         }
580     }
581
582 static void siggen(FILE *in, FILE *out)
583     {
584     char buf[1024];
585     char lbuf[1024];
586     char *keyword, *value;
587     int dsa2, L, N;
588     const EVP_MD *md = NULL;
589     DSA *dsa=NULL;
590
591     while(fgets(buf,sizeof buf,in) != NULL)
592         {
593         if (!parse_line(&keyword, &value, lbuf, buf))
594                 {
595                 fputs(buf,out);
596                 continue;
597                 }
598         fputs(buf,out);
599         if(!strcmp(keyword,"[mod"))
600             {
601             if (!parse_mod(value, &dsa2, &L, &N, &md))
602                 {
603                 fprintf(stderr, "Mod Parse Error\n");
604                 exit (1);
605                 }
606             if (dsa)
607                 FIPS_dsa_free(dsa);
608             dsa = FIPS_dsa_new();
609             if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0,
610                                                 NULL, NULL, NULL, NULL))
611                         {
612                         fprintf(stderr, "Parameter Generation error\n");
613                         exit(1);
614                         }
615             if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1,
616                                                 NULL, NULL, NULL, NULL) <= 0)
617                         {
618                         fprintf(stderr, "Parameter Generation error\n");
619                         exit(1);
620                         }
621             do_bn_print_name(out, "P",dsa->p);
622             do_bn_print_name(out, "Q",dsa->q);
623             do_bn_print_name(out, "G",dsa->g);
624             fputs(RESP_EOL, out);
625             }
626         else if(!strcmp(keyword,"Msg"))
627             {
628             unsigned char msg[1024];
629             int n;
630             EVP_MD_CTX mctx;
631             DSA_SIG *sig;
632             FIPS_md_ctx_init(&mctx);
633
634             n=hex2bin(value,msg);
635
636             if (!DSA_generate_key(dsa))
637                 exit(1);
638             do_bn_print_name(out, "Y",dsa->pub_key);
639
640             FIPS_digestinit(&mctx, md);
641             FIPS_digestupdate(&mctx, msg, n);
642             sig = FIPS_dsa_sign_ctx(dsa, &mctx);
643
644             do_bn_print_name(out, "R",sig->r);
645             do_bn_print_name(out, "S",sig->s);
646             fputs(RESP_EOL, out);
647             FIPS_dsa_sig_free(sig);
648             FIPS_md_ctx_cleanup(&mctx);
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             dsa->p=hex2bn(value);
691         else if(!strcmp(keyword,"Q"))
692             dsa->q=hex2bn(value);
693         else if(!strcmp(keyword,"G"))
694             dsa->g=hex2bn(value);
695         else if(!strcmp(keyword,"Msg"))
696             n=hex2bin(value,msg);
697         else if(!strcmp(keyword,"Y"))
698             dsa->pub_key=hex2bn(value);
699         else if(!strcmp(keyword,"R"))
700             sig->r=hex2bn(value);
701         else if(!strcmp(keyword,"S"))
702             {
703             EVP_MD_CTX mctx;
704             int r;
705             FIPS_md_ctx_init(&mctx);
706             sig->s=hex2bn(value);
707
708             FIPS_digestinit(&mctx, md);
709             FIPS_digestupdate(&mctx, msg, n);
710             no_err = 1;
711             r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
712             no_err = 0;
713             FIPS_md_ctx_cleanup(&mctx);
714         
715             fprintf(out, "Result = %c" RESP_EOL RESP_EOL, r == 1 ? 'P' : 'F');
716             }
717         }
718     }
719
720 int main(int argc,char **argv)
721     {
722     FILE *in, *out;
723     if (argc == 4)
724         {
725         in = fopen(argv[2], "r");
726         if (!in)
727                 {
728                 fprintf(stderr, "Error opening input file\n");
729                 exit(1);
730                 }
731         out = fopen(argv[3], "w");
732         if (!out)
733                 {
734                 fprintf(stderr, "Error opening output file\n");
735                 exit(1);
736                 }
737         }
738     else if (argc == 2)
739         {
740         in = stdin;
741         out = stdout;
742         }
743     else
744         {
745         fprintf(stderr,"%s [prime|pqg|pqgver|keypair|keyver|siggen|sigver]\n",argv[0]);
746         exit(1);
747         }
748     fips_algtest_init();
749     if(!strcmp(argv[1],"prime"))
750         primes(in, out);
751     else if(!strcmp(argv[1],"pqg"))
752         pqg(in, out);
753     else if(!strcmp(argv[1],"pqgver"))
754         pqgver(in, out);
755     else if(!strcmp(argv[1],"keypair"))
756         keypair(in, out);
757     else if(!strcmp(argv[1],"keyver"))
758         keyver(in, out);
759     else if(!strcmp(argv[1],"siggen"))
760         siggen(in, out);
761     else if(!strcmp(argv[1],"sigver"))
762         sigver(in, out);
763     else
764         {
765         fprintf(stderr,"Don't know how to %s.\n",argv[1]);
766         exit(1);
767         }
768
769     if (argc == 4)
770         {
771         fclose(in);
772         fclose(out);
773         }
774
775     return 0;
776     }
777
778 #endif