Handle provable prime parameters for canonical g generation which are
[openssl.git] / fips / dsa / fips_dssvs.c
index 4610557f7b48f0e3b6ca6511a9d7653eefbc1e36..3362a33e6cb747f5a146ee81340b459c08de228f 100644 (file)
@@ -22,35 +22,77 @@ int main(int argc, char **argv)
 
 #include "fips_utl.h"
 
-static void pbn(const char *name, BIGNUM *bn)
+static int parse_mod(char *line, int *pdsa2, int *pL, int *pN,
+                               const EVP_MD **pmd)
        {
-       int len, i;
-       unsigned char *tmp;
-       len = BN_num_bytes(bn);
-       tmp = OPENSSL_malloc(len);
-       if (!tmp)
+       char lbuf[10240];
+       char *keyword, *value;
+
+       char *p;
+       p = strchr(line, ',');
+       if (!p)
                {
-               fprintf(stderr, "Memory allocation error\n");
-               return;
+               *pL = atoi(line);
+               *pdsa2 = 0;
+               *pN = 160;
+               if (pmd)
+                       *pmd = EVP_sha1();
+               return 1;
                }
-       BN_bn2bin(bn, tmp);
-       printf("%s = ", name);
-       for (i = 0; i < len; i++)
-               printf("%02X", tmp[i]);
-       fputs("\n", stdout);
-       OPENSSL_free(tmp);
-       return;
+       *pdsa2 = 1;
+       *p = 0;
+       if (!parse_line2(&keyword, &value, lbuf, line, 0))
+               return 0;
+       if (strcmp(keyword, "L"))
+               return 0;
+       *pL = atoi(value);
+       strcpy(line, p + 1);
+       if (pmd)
+               p = strchr(line, ',');
+       else
+               p = strchr(line, ']');
+       if (!p)
+               return 0;
+       *p = 0;
+       if (!parse_line2(&keyword, &value, lbuf, line, 0))
+               return 0;
+       if (strcmp(keyword, "N"))
+               return 0;
+       *pN = atoi(value);
+       if (!pmd)
+               return 1;
+       strcpy(line, p + 1);
+       p = strchr(line, ']');
+       if (!p)
+               return 0;
+       *p = 0;
+       p = line;
+       while(isspace(*p))
+               p++;
+       if (!strcmp(p, "SHA-1"))
+               *pmd = EVP_sha1();
+       else if (!strcmp(p, "SHA-224"))
+               *pmd = EVP_sha224();
+       else if (!strcmp(p, "SHA-256"))
+               *pmd = EVP_sha256();
+       else if (!strcmp(p, "SHA-384"))
+               *pmd = EVP_sha384();
+       else if (!strcmp(p, "SHA-512"))
+               *pmd = EVP_sha512();
+       else
+               return 0;
+       return 1;
        }
 
-static void primes()
+static void primes(FILE *in, FILE *out)
     {
     char buf[10240];
     char lbuf[10240];
     char *keyword, *value;
 
-    while(fgets(buf,sizeof buf,stdin) != NULL)
+    while(fgets(buf,sizeof buf,in) != NULL)
        {
-       fputs(buf,stdout);
+       fputs(buf,out);
        if (!parse_line(&keyword, &value, lbuf, buf))
                continue;
        if(!strcmp(keyword,"Prime"))
@@ -59,7 +101,7 @@ static void primes()
 
            pp=BN_new();
            do_hex2bn(&pp,value);
-           printf("result= %c\n",
+           fprintf(out, "result= %c\n",
                   BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
            }       
        }
@@ -69,109 +111,244 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
        const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
        unsigned char *seed_out,
        int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
+int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
+       const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
+       int idx, unsigned char *seed_out,
+       int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
 
-static void pqg()
+static void pqg(FILE *in, FILE *out)
     {
     char buf[1024];
     char lbuf[1024];
     char *keyword, *value;
-    int nmod=0;
-
-    while(fgets(buf,sizeof buf,stdin) != NULL)
+    int dsa2, L, N;
+    const EVP_MD *md = NULL;
+    BIGNUM *p = NULL, *q = NULL;
+    enum pqtype { PQG_NONE, PQG_PQ, PQG_G, PQG_GCANON}
+               pqg_type = PQG_NONE;
+    int seedlen=-1, idxlen, idx = -1;
+    unsigned char seed[1024], idtmp[1024];
+
+    while(fgets(buf,sizeof buf,in) != NULL)
        {
+       if (buf[0] == '[')
+               {
+               if (strstr(buf, "Probable"))
+                       pqg_type = PQG_PQ;
+               else if (strstr(buf, "Unverifiable"))
+                       pqg_type = PQG_G;
+               else if (strstr(buf, "Canonical"))
+                       pqg_type = PQG_GCANON;
+               }
        if (!parse_line(&keyword, &value, lbuf, buf))
                {
-               fputs(buf,stdout);
+               fputs(buf,out);
                continue;
                }
+       fputs(buf,out);
        if(!strcmp(keyword,"[mod"))
-           nmod=atoi(value);
-       else if(!strcmp(keyword,"N"))
+           {
+           if (!parse_mod(value, &dsa2, &L, &N, &md))
+               {
+               fprintf(stderr, "Mod Parse Error\n");
+               exit (1);
+               }
+           }
+       else if(!strcmp(keyword,"N") 
+               || (!strcmp(keyword, "Num") && pqg_type == PQG_PQ))
            {
            int n=atoi(value);
 
-           printf("[mod = %d]\n\n",nmod);
-
            while(n--)
                {
-               unsigned char seed[EVP_MAX_MD_SIZE];
                DSA *dsa;
                int counter;
                unsigned long h;
                dsa = FIPS_dsa_new();
 
-               if (!dsa_builtin_paramgen(dsa, nmod, 160, NULL, NULL, 0,
-                                       seed,&counter,&h,NULL))
+               if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
+                                               NULL, 0, seed,
+                                               &counter, &h, NULL))
+                       {
+                       fprintf(stderr, "Parameter Generation error\n");
+                       exit(1);
+                       }
+               if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
+                                               NULL, 0, -1, seed,
+                                               &counter, &h, NULL) <= 0)
+                       {
+                       fprintf(stderr, "Parameter Generation error\n");
                        exit(1);
-               pbn("P",dsa->p);
-               pbn("Q",dsa->q);
-               pbn("G",dsa->g);
-               pv("Seed",seed,20);
-               printf("c = %d\n",counter);
-               printf("H = %lx\n",h);
-               putc('\n',stdout);
+                       }
+               do_bn_print_name(out, "P",dsa->p);
+               do_bn_print_name(out, "Q",dsa->q);
+               if (!dsa2)
+                       do_bn_print_name(out, "G",dsa->g);
+               OutputValue(dsa2 ? "domain_parameter_seed" : "Seed",
+                               seed, M_EVP_MD_size(md), out, 0);
+               if (!dsa2)
+                       {
+                       fprintf(out, "c = %d\n",counter);
+                       fprintf(out, "H = %lx\n\n",h);
+                       }
+               else
+                       fputs("\n", out);
                }
            }
-       else
-           fputs(buf,stdout);
+       else if(!strcmp(keyword,"P"))
+           p=hex2bn(value);
+       else if(!strcmp(keyword,"Q"))
+           q=hex2bn(value);
+       else if(!strcmp(keyword,"domain_parameter_seed"))
+           seedlen = hex2bin(value, seed);
+       else if(!strcmp(keyword,"firstseed"))
+           seedlen = hex2bin(value, seed);
+       else if(!strcmp(keyword,"pseed"))
+           seedlen += hex2bin(value, seed + seedlen);
+       else if(!strcmp(keyword,"qseed"))
+           seedlen += hex2bin(value, seed + seedlen);
+       else if(!strcmp(keyword,"index"))
+           {
+           idxlen = hex2bin(value, idtmp);
+            if (idxlen != 1)
+               {
+               fprintf(stderr, "Index value error\n");
+               exit (1);
+               }
+           idx = idtmp[0];
+           }
+       if ((idx >= 0 && pqg_type == PQG_GCANON) || (q && pqg_type == PQG_G))
+               {
+               DSA *dsa;
+               dsa = FIPS_dsa_new();
+               dsa->p = p;
+               dsa->q = q;
+               p = q = NULL;
+               if (dsa_builtin_paramgen2(dsa, L, N, md,
+                                               seed, seedlen, idx, NULL,
+                                               NULL, NULL, NULL) <= 0)
+                       {
+                       fprintf(stderr, "Parameter Generation error\n");
+                       exit(1);
+                       }
+               do_bn_print_name(out, "G",dsa->g);
+               FIPS_dsa_free(dsa);
+               idx = -1;
+               }
        }
     }
 
-static void pqgver()
+static void pqgver(FILE *in, FILE *out)
     {
     char buf[1024];
     char lbuf[1024];
     char *keyword, *value;
     BIGNUM *p = NULL, *q = NULL, *g = NULL;
-    int counter, counter2;
-    unsigned long h, h2;
+    int counter=-1, counter2;
+    unsigned long h=0, h2;
     DSA *dsa=NULL;
-    int nmod=0;
-    unsigned char seed[1024];
+    int dsa2, L, N, part_test = 0;
+    const EVP_MD *md = NULL;
+    int seedlen=-1, idxlen, idx = -1;
+    unsigned char seed[1024], idtmp[1024];
 
-    while(fgets(buf,sizeof buf,stdin) != NULL)
+    while(fgets(buf,sizeof buf,in) != NULL)
        {
        if (!parse_line(&keyword, &value, lbuf, buf))
                {
-               fputs(buf,stdout);
+               if (p && q)
+                       {
+                       part_test = 1;
+                       goto partial;
+                       }
+               fputs(buf,out);
                continue;
                }
-       fputs(buf, stdout);
+       fputs(buf, out);
        if(!strcmp(keyword,"[mod"))
-           nmod=atoi(value);
+           {
+           if (!parse_mod(value, &dsa2, &L, &N, &md))
+               {
+               fprintf(stderr, "Mod Parse Error\n");
+               exit (1);
+               }
+           }
        else if(!strcmp(keyword,"P"))
            p=hex2bn(value);
        else if(!strcmp(keyword,"Q"))
            q=hex2bn(value);
        else if(!strcmp(keyword,"G"))
            g=hex2bn(value);
-       else if(!strcmp(keyword,"Seed"))
+       else if(!strcmp(keyword,"Seed")
+               || !strcmp(keyword,"domain_parameter_seed"))
            {
-           int slen = hex2bin(value, seed);
-           if (slen != 20)
+           seedlen = hex2bin(value, seed);
+           if (!dsa2 && seedlen != 20)
                {
                fprintf(stderr, "Seed parse length error\n");
                exit (1);
                }
+           if (idx > 0)
+               part_test = 1;
+           }
+       else if(!strcmp(keyword,"index"))
+           {
+           idxlen = hex2bin(value, idtmp);
+            if (idxlen != 1)
+               {
+               fprintf(stderr, "Index value error\n");
+               exit (1);
+               }
+           idx = idtmp[0];
            }
        else if(!strcmp(keyword,"c"))
-           counter =atoi(buf+4);
-       else if(!strcmp(keyword,"H"))
+           counter = atoi(buf+4);
+       partial:
+       if(!strcmp(keyword,"H") || part_test)
            {
-           h = atoi(value);
-           if (!p || !q || !g)
+           if (!part_test)
+               h = atoi(value);
+           if (!p || !q || (!g && !part_test))
                {
                fprintf(stderr, "Parse Error\n");
                exit (1);
                }
            dsa = FIPS_dsa_new();
-           if (!DSA_generate_parameters_ex(dsa, nmod,seed,20 ,&counter2,&h2,NULL))
+           if (idx >= 0)
+               {
+               dsa->p = BN_dup(p);
+               dsa->q = BN_dup(q);
+               }
+           no_err = 1;
+           if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md,
+                                       seed, seedlen, NULL,
+                                       &counter2, &h2, NULL))
+                       {
+                       fprintf(stderr, "Parameter Generation error\n");
                        exit(1);
-            if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g)
-               || (counter != counter2) || (h != h2))
-               printf("Result = F\n");
+                       }
+           if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
+                                       seed, seedlen, idx, NULL,
+                                       &counter2, &h2, NULL) < 0)
+                       {
+                       fprintf(stderr, "Parameter Generation error\n");
+                       exit(1);
+                       }
+           no_err = 0;
+           if (idx >= 0)
+               {
+               if (BN_cmp(dsa->g, g))
+                       fprintf(out, "Result = F\n");
+               else
+                       fprintf(out, "Result = P\n");
+               }
+            else if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || 
+               (!part_test &&
+               ((BN_cmp(dsa->g, g) || (counter != counter2) || (h != h2)))))
+               fprintf(out, "Result = F\n");
            else
-               printf("Result = P\n");
+               fprintf(out, "Result = P\n");
            BN_free(p);
            BN_free(q);
            BN_free(g);
@@ -180,6 +357,13 @@ static void pqgver()
            g = NULL;
            FIPS_dsa_free(dsa);
            dsa = NULL;
+           if (part_test)
+               {
+               if (idx == -1)
+                       fputs(buf,out);
+               part_test = 0;
+               }
+           idx = -1;
            }
        }
     }
@@ -189,13 +373,13 @@ static void pqgver()
  * output of the KeyPair test.
  */
 
-static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
+static int dss_paramcheck(int L, int N, BIGNUM *p, BIGNUM *q, BIGNUM *g,
                                                        BN_CTX *ctx)
     {
     BIGNUM *rem = NULL;
-    if (BN_num_bits(p) != nmod)
+    if (BN_num_bits(p) != L)
        return 0;
-    if (BN_num_bits(q) != 160)
+    if (BN_num_bits(q) != N)
        return 0;
     if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
        return 0;
@@ -214,7 +398,7 @@ static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
     return 1;
     }
 
-static void keyver()
+static void keyver(FILE *in, FILE *out)
     {
     char buf[1024];
     char lbuf[1024];
@@ -222,16 +406,17 @@ static void keyver()
     BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
     BIGNUM *Y2;
     BN_CTX *ctx = NULL;
-    int nmod=0, paramcheck = 0;
+    int dsa2, L, N;
+    int paramcheck = 0;
 
     ctx = BN_CTX_new();
     Y2 = BN_new();
 
-    while(fgets(buf,sizeof buf,stdin) != NULL)
+    while(fgets(buf,sizeof buf,in) != NULL)
        {
        if (!parse_line(&keyword, &value, lbuf, buf))
                {
-               fputs(buf,stdout);
+               fputs(buf,out);
                continue;
                }
        if(!strcmp(keyword,"[mod"))
@@ -246,7 +431,11 @@ static void keyver()
                BN_free(g);
            g = NULL;
            paramcheck = 0;
-           nmod=atoi(value);
+           if (!parse_mod(value, &dsa2, &L, &N, NULL))
+               {
+               fprintf(stderr, "Mod Parse Error\n");
+               exit (1);
+               }
            }
        else if(!strcmp(keyword,"P"))
            p=hex2bn(value);
@@ -264,26 +453,26 @@ static void keyver()
                fprintf(stderr, "Parse Error\n");
                exit (1);
                }
-           pbn("P",p);
-           pbn("Q",q);
-           pbn("G",g);
-           pbn("X",X);
-           pbn("Y",Y);
+           do_bn_print_name(out, "P",p);
+           do_bn_print_name(out, "Q",q);
+           do_bn_print_name(out, "G",g);
+           do_bn_print_name(out, "X",X);
+           do_bn_print_name(out, "Y",Y);
            if (!paramcheck)
                {
-               if (dss_paramcheck(nmod, p, q, g, ctx))
+               if (dss_paramcheck(L, N, p, q, g, ctx))
                        paramcheck = 1;
                else
                        paramcheck = -1;
                }
            if (paramcheck != 1)
-               printf("Result = F\n");
+               fprintf(out, "Result = F\n");
            else
                {
                if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
-                       printf("Result = F\n");
+                       fprintf(out, "Result = F\n");
                else
-                       printf("Result = P\n");
+                       fprintf(out, "Result = P\n");
                }
            BN_free(X);
            BN_free(Y);
@@ -301,77 +490,107 @@ static void keyver()
            BN_free(Y2);
     }
 
-static void keypair()
+static void keypair(FILE *in, FILE *out)
     {
     char buf[1024];
     char lbuf[1024];
     char *keyword, *value;
-    int nmod=0;
+    int dsa2, L, N;
 
-    while(fgets(buf,sizeof buf,stdin) != NULL)
+    while(fgets(buf,sizeof buf,in) != NULL)
        {
        if (!parse_line(&keyword, &value, lbuf, buf))
                {
-               fputs(buf,stdout);
                continue;
                }
        if(!strcmp(keyword,"[mod"))
-           nmod=atoi(value);
+           {
+           if (!parse_mod(value, &dsa2, &L, &N, NULL))
+               {
+               fprintf(stderr, "Mod Parse Error\n");
+               exit (1);
+               }
+           fputs(buf,out);
+           }
        else if(!strcmp(keyword,"N"))
            {
            DSA *dsa;
            int n=atoi(value);
 
-           printf("[mod = %d]\n\n",nmod);
            dsa = FIPS_dsa_new();
-           if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
-               exit(1);
-           pbn("P",dsa->p);
-           pbn("Q",dsa->q);
-           pbn("G",dsa->g);
-           putc('\n',stdout);
+           if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, NULL, NULL, 0,
+                                               NULL, NULL, NULL, NULL))
+                       {
+                       fprintf(stderr, "Parameter Generation error\n");
+                       exit(1);
+                       }
+           if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1,
+                                               NULL, NULL, NULL, NULL) <= 0)
+                       {
+                       fprintf(stderr, "Parameter Generation error\n");
+                       exit(1);
+                       }
+           do_bn_print_name(out, "P",dsa->p);
+           do_bn_print_name(out, "Q",dsa->q);
+           do_bn_print_name(out, "G",dsa->g);
+           fputs("\n", out);
 
            while(n--)
                {
                if (!DSA_generate_key(dsa))
                        exit(1);
 
-               pbn("X",dsa->priv_key);
-               pbn("Y",dsa->pub_key);
-               putc('\n',stdout);
+               do_bn_print_name(out, "X",dsa->priv_key);
+               do_bn_print_name(out, "Y",dsa->pub_key);
+               fputs("\n", out);
                }
            }
        }
     }
 
-static void siggen()
+static void siggen(FILE *in, FILE *out)
     {
     char buf[1024];
     char lbuf[1024];
     char *keyword, *value;
-    int nmod=0;
+    int dsa2, L, N;
+    const EVP_MD *md = NULL;
     DSA *dsa=NULL;
 
-    while(fgets(buf,sizeof buf,stdin) != NULL)
+    while(fgets(buf,sizeof buf,in) != NULL)
        {
        if (!parse_line(&keyword, &value, lbuf, buf))
                {
-               fputs(buf,stdout);
+               fputs(buf,out);
                continue;
                }
+       fputs(buf,out);
        if(!strcmp(keyword,"[mod"))
            {
-           nmod=atoi(value);
-           printf("[mod = %d]\n\n",nmod);
+           if (!parse_mod(value, &dsa2, &L, &N, &md))
+               {
+               fprintf(stderr, "Mod Parse Error\n");
+               exit (1);
+               }
            if (dsa)
                FIPS_dsa_free(dsa);
            dsa = FIPS_dsa_new();
-           if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
-               exit(1);
-           pbn("P",dsa->p);
-           pbn("Q",dsa->q);
-           pbn("G",dsa->g);
-           putc('\n',stdout);
+           if (!dsa2 && !dsa_builtin_paramgen(dsa, L, N, md, NULL, 0,
+                                               NULL, NULL, NULL, NULL))
+                       {
+                       fprintf(stderr, "Parameter Generation error\n");
+                       exit(1);
+                       }
+           if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1,
+                                               NULL, NULL, NULL, NULL) <= 0)
+                       {
+                       fprintf(stderr, "Parameter Generation error\n");
+                       exit(1);
+                       }
+           do_bn_print_name(out, "P",dsa->p);
+           do_bn_print_name(out, "Q",dsa->q);
+           do_bn_print_name(out, "G",dsa->g);
+           fputs("\n", out);
            }
        else if(!strcmp(keyword,"Msg"))
            {
@@ -379,76 +598,71 @@ static void siggen()
            int n;
            EVP_MD_CTX mctx;
            DSA_SIG *sig;
-           EVP_MD_CTX_init(&mctx);
+           FIPS_md_ctx_init(&mctx);
 
            n=hex2bin(value,msg);
-           pv("Msg",msg,n);
 
            if (!DSA_generate_key(dsa))
                exit(1);
-           pbn("Y",dsa->pub_key);
+           do_bn_print_name(out, "Y",dsa->pub_key);
 
-           EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL);
-           EVP_DigestUpdate(&mctx, msg, n);
+           FIPS_digestinit(&mctx, md);
+           FIPS_digestupdate(&mctx, msg, n);
            sig = FIPS_dsa_sign_ctx(dsa, &mctx);
 
-           pbn("R",sig->r);
-           pbn("S",sig->s);
-           putc('\n',stdout);
-           DSA_SIG_free(sig);
-           EVP_MD_CTX_cleanup(&mctx);
+           do_bn_print_name(out, "R",sig->r);
+           do_bn_print_name(out, "S",sig->s);
+           fputs("\n", out);
+           FIPS_dsa_sig_free(sig);
+           FIPS_md_ctx_cleanup(&mctx);
            }
        }
        if (dsa)
                FIPS_dsa_free(dsa);
     }
 
-static void sigver()
+static void sigver(FILE *in, FILE *out)
     {
     DSA *dsa=NULL;
     char buf[1024];
     char lbuf[1024];
     unsigned char msg[1024];
     char *keyword, *value;
-    int nmod=0, n=0;
+    int n=0;
+    int dsa2, L, N;
+    const EVP_MD *md = NULL;
     DSA_SIG sg, *sig = &sg;
 
     sig->r = NULL;
     sig->s = NULL;
 
-    while(fgets(buf,sizeof buf,stdin) != NULL)
+    while(fgets(buf,sizeof buf,in) != NULL)
        {
        if (!parse_line(&keyword, &value, lbuf, buf))
                {
-               fputs(buf,stdout);
+               fputs(buf,out);
                continue;
                }
+       fputs(buf,out);
        if(!strcmp(keyword,"[mod"))
            {
-           nmod=atoi(value);
-           if(dsa)
+           if (!parse_mod(value, &dsa2, &L, &N, &md))
+               {
+               fprintf(stderr, "Mod Parse Error\n");
+               exit (1);
+               }
+           if (dsa)
                FIPS_dsa_free(dsa);
-           dsa=FIPS_dsa_new();
+           dsa = FIPS_dsa_new();
            }
        else if(!strcmp(keyword,"P"))
            dsa->p=hex2bn(value);
        else if(!strcmp(keyword,"Q"))
            dsa->q=hex2bn(value);
        else if(!strcmp(keyword,"G"))
-           {
            dsa->g=hex2bn(value);
-
-           printf("[mod = %d]\n\n",nmod);
-           pbn("P",dsa->p);
-           pbn("Q",dsa->q);
-           pbn("G",dsa->g);
-           putc('\n',stdout);
-           }
        else if(!strcmp(keyword,"Msg"))
-           {
            n=hex2bin(value,msg);
-           pv("Msg",msg,n);
-           }
        else if(!strcmp(keyword,"Y"))
            dsa->pub_key=hex2bn(value);
        else if(!strcmp(keyword,"R"))
@@ -457,55 +671,76 @@ static void sigver()
            {
            EVP_MD_CTX mctx;
            int r;
-           EVP_MD_CTX_init(&mctx);
+           FIPS_md_ctx_init(&mctx);
            sig->s=hex2bn(value);
-       
-           pbn("Y",dsa->pub_key);
-           pbn("R",sig->r);
-           pbn("S",sig->s);
-           EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL);
-           EVP_DigestUpdate(&mctx, msg, n);
+
+           FIPS_digestinit(&mctx, md);
+           FIPS_digestupdate(&mctx, msg, n);
            no_err = 1;
            r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
            no_err = 0;
-           EVP_MD_CTX_cleanup(&mctx);
+           FIPS_md_ctx_cleanup(&mctx);
        
-           printf("Result = %c\n", r == 1 ? 'P' : 'F');
-           putc('\n',stdout);
+           fprintf(out, "Result = %c\n\n", r == 1 ? 'P' : 'F');
            }
        }
     }
 
 int main(int argc,char **argv)
     {
-    if(argc != 2)
+    FILE *in, *out;
+    if (argc == 4)
        {
-       fprintf(stderr,"%s [prime|pqg|pqgver|keypair|siggen|sigver]\n",argv[0]);
-       exit(1);
+       in = fopen(argv[2], "r");
+       if (!in)
+               {
+               fprintf(stderr, "Error opening input file\n");
+               exit(1);
+               }
+       out = fopen(argv[3], "w");
+       if (!out)
+               {
+               fprintf(stderr, "Error opening output file\n");
+               exit(1);
+               }
+       }
+    else if (argc == 2)
+       {
+       in = stdin;
+       out = stdout;
        }
-    fips_set_error_print();
-    if(!FIPS_mode_set(1))
+    else
+       {
+       fprintf(stderr,"%s [prime|pqg|pqgver|keypair|keyver|siggen|sigver]\n",argv[0]);
        exit(1);
+       }
+    fips_algtest_init();
     if(!strcmp(argv[1],"prime"))
-       primes();
+       primes(in, out);
     else if(!strcmp(argv[1],"pqg"))
-       pqg();
+       pqg(in, out);
     else if(!strcmp(argv[1],"pqgver"))
-       pqgver();
+       pqgver(in, out);
     else if(!strcmp(argv[1],"keypair"))
-       keypair();
+       keypair(in, out);
     else if(!strcmp(argv[1],"keyver"))
-       keyver();
+       keyver(in, out);
     else if(!strcmp(argv[1],"siggen"))
-       siggen();
+       siggen(in, out);
     else if(!strcmp(argv[1],"sigver"))
-       sigver();
+       sigver(in, out);
     else
        {
        fprintf(stderr,"Don't know how to %s.\n",argv[1]);
        exit(1);
        }
 
+    if (argc == 4)
+       {
+       fclose(in);
+       fclose(out);
+       }
+
     return 0;
     }