Add support for memory leak checking in fips_algvs.
[openssl.git] / fips / dsa / fips_dssvs.c
index 09001615dc07e3bb655c8364e3b76bb034a3c0cc..45eefb7c63fe1ce5e05ec084a69a41f61dd4b04b 100644 (file)
@@ -41,7 +41,7 @@ static int parse_mod(char *line, int *pdsa2, int *pL, int *pN,
                }
        *pdsa2 = 1;
        *p = 0;
-       if (!parse_line(&keyword, &value, lbuf, line))
+       if (!parse_line2(&keyword, &value, lbuf, line, 0))
                return 0;
        if (strcmp(keyword, "L"))
                return 0;
@@ -54,7 +54,7 @@ static int parse_mod(char *line, int *pdsa2, int *pL, int *pN,
        if (!p)
                return 0;
        *p = 0;
-       if (!parse_line(&keyword, &value, lbuf, line))
+       if (!parse_line2(&keyword, &value, lbuf, line, 0))
                return 0;
        if (strcmp(keyword, "N"))
                return 0;
@@ -101,7 +101,7 @@ static void primes(FILE *in, FILE *out)
 
            pp=BN_new();
            do_hex2bn(&pp,value);
-           fprintf(out, "result= %c\n",
+           fprintf(out, "result= %c" RESP_EOL,
                   BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
            }       
        }
@@ -111,11 +111,13 @@ 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 bits, size_t qbits,
+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,
-       unsigned char *seed_out,
+       int idx, unsigned char *seed_out,
        int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
 
+int dsa_paramgen_check_g(DSA *dsa);
+
 static void pqg(FILE *in, FILE *out)
     {
     char buf[1024];
@@ -123,30 +125,45 @@ static void pqg(FILE *in, FILE *out)
     char *keyword, *value;
     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,out);
                continue;
                }
+       if (strcmp(keyword, "Num"))
+               fputs(buf,out);
        if(!strcmp(keyword,"[mod"))
            {
-           fputs(buf,out);
            if (!parse_mod(value, &dsa2, &L, &N, &md))
                {
                fprintf(stderr, "Mod Parse Error\n");
                exit (1);
                }
            }
-       else if(!strcmp(keyword,"N"))
+       else if(!strcmp(keyword,"N") 
+               || (!strcmp(keyword, "Num") && pqg_type == PQG_PQ))
            {
            int n=atoi(value);
 
            while(n--)
                {
-               unsigned char seed[EVP_MAX_MD_SIZE];
                DSA *dsa;
                int counter;
                unsigned long h;
@@ -160,7 +177,7 @@ static void pqg(FILE *in, FILE *out)
                        exit(1);
                        }
                if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
-                                               NULL, 0, seed,
+                                               NULL, 0, -1, seed,
                                                &counter, &h, NULL) <= 0)
                        {
                        fprintf(stderr, "Parameter Generation error\n");
@@ -169,14 +186,62 @@ static void pqg(FILE *in, FILE *out)
  
                do_bn_print_name(out, "P",dsa->p);
                do_bn_print_name(out, "Q",dsa->q);
-               do_bn_print_name(out, "G",dsa->g);
-               OutputValue("Seed",seed, M_EVP_MD_size(md), out, 0);
-               fprintf(out, "c = %d\n",counter);
-               fprintf(out, "H = %lx\n\n",h);
+               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" RESP_EOL, counter);
+                       fprintf(out, "H = %lx" RESP_EOL RESP_EOL,h);
+                       }
+               else
+                       {
+                       fprintf(out, "counter = %d" RESP_EOL RESP_EOL, counter);
+                       }
+               FIPS_dsa_free(dsa);
                }
            }
-       else
-           fputs(buf,out);
+       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;
+               }
        }
     }
 
@@ -191,8 +256,8 @@ static void pqgver(FILE *in, FILE *out)
     DSA *dsa=NULL;
     int dsa2, L, N, part_test = 0;
     const EVP_MD *md = NULL;
-    int seedlen=-1;
-    unsigned char seed[1024];
+    int seedlen=-1, idxlen, idx = -1;
+    unsigned char seed[1024], idtmp[1024];
 
     while(fgets(buf,sizeof buf,in) != NULL)
        {
@@ -221,7 +286,14 @@ static void pqgver(FILE *in, FILE *out)
            q=hex2bn(value);
        else if(!strcmp(keyword,"G"))
            g=hex2bn(value);
-       else if(!strcmp(keyword,"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,"Seed")
+               || !strcmp(keyword,"domain_parameter_seed"))
            {
            seedlen = hex2bin(value, seed);
            if (!dsa2 && seedlen != 20)
@@ -229,11 +301,43 @@ static void pqgver(FILE *in, FILE *out)
                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);
+           counter = atoi(buf+4);
        partial:
-       if(!strcmp(keyword,"H") || part_test)
+       if (part_test && idx < 0 && h == 0 && g)
+           {
+           dsa = FIPS_dsa_new();
+           dsa->p = BN_dup(p);
+           dsa->q = BN_dup(q);
+           dsa->g = BN_dup(g);
+           if (dsa_paramgen_check_g(dsa))
+               fprintf(out, "Result = P" RESP_EOL);
+           else
+               fprintf(out, "Result = F" RESP_EOL);
+           BN_free(p);
+           BN_free(q);
+           BN_free(g);
+           p = NULL;
+           q = NULL;
+           g = NULL;
+           FIPS_dsa_free(dsa);
+           dsa = NULL;
+           part_test = 0;
+           }
+       else if(!strcmp(keyword,"H") || part_test)
            {
            if (!part_test)
                h = atoi(value);
@@ -243,6 +347,12 @@ static void pqgver(FILE *in, FILE *out)
                exit (1);
                }
            dsa = FIPS_dsa_new();
+           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))
@@ -251,18 +361,26 @@ static void pqgver(FILE *in, FILE *out)
                        exit(1);
                        }
            if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md,
-                                       seed, seedlen, NULL,
+                                       seed, seedlen, idx, NULL,
                                        &counter2, &h2, NULL) < 0)
                        {
                        fprintf(stderr, "Parameter Generation error\n");
                        exit(1);
                        }
-            if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || 
+           no_err = 0;
+           if (idx >= 0)
+               {
+               if (BN_cmp(dsa->g, g))
+                       fprintf(out, "Result = F" RESP_EOL);
+               else
+                       fprintf(out, "Result = P" RESP_EOL);
+               }
+            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");
+               fprintf(out, "Result = F" RESP_EOL);
            else
-               fprintf(out, "Result = P\n");
+               fprintf(out, "Result = P" RESP_EOL);
            BN_free(p);
            BN_free(q);
            BN_free(g);
@@ -273,9 +391,11 @@ static void pqgver(FILE *in, FILE *out)
            dsa = NULL;
            if (part_test)
                {
-               fputs(buf,out);
+               if (idx == -1)
+                       fputs(buf,out);
                part_test = 0;
                }
+           idx = -1;
            }
        }
     }
@@ -378,13 +498,13 @@ static void keyver(FILE *in, FILE *out)
                        paramcheck = -1;
                }
            if (paramcheck != 1)
-               fprintf(out, "Result = F\n");
+               fprintf(out, "Result = F" RESP_EOL);
            else
                {
                if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
-                       fprintf(out, "Result = F\n");
+                       fprintf(out, "Result = F" RESP_EOL);
                else
-                       fprintf(out, "Result = P\n");
+                       fprintf(out, "Result = P" RESP_EOL);
                }
            BN_free(X);
            BN_free(Y);
@@ -400,6 +520,8 @@ static void keyver(FILE *in, FILE *out)
            BN_free(g);
        if (Y2)
            BN_free(Y2);
+       if (ctx)
+           BN_CTX_free(ctx);
     }
 
 static void keypair(FILE *in, FILE *out)
@@ -436,7 +558,7 @@ static void keypair(FILE *in, FILE *out)
                        fprintf(stderr, "Parameter Generation error\n");
                        exit(1);
                        }
-           if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0,
+           if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, NULL, NULL, 0, -1,
                                                NULL, NULL, NULL, NULL) <= 0)
                        {
                        fprintf(stderr, "Parameter Generation error\n");
@@ -445,7 +567,7 @@ static void keypair(FILE *in, FILE *out)
            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);
+           fputs(RESP_EOL, out);
 
            while(n--)
                {
@@ -454,8 +576,10 @@ static void keypair(FILE *in, FILE *out)
 
                do_bn_print_name(out, "X",dsa->priv_key);
                do_bn_print_name(out, "Y",dsa->pub_key);
-               fputs("\n", out);
+               fputs(RESP_EOL, out);
                }
+           if (dsa)
+               FIPS_dsa_free(dsa);
            }
        }
     }
@@ -493,7 +617,7 @@ static void siggen(FILE *in, FILE *out)
                        fprintf(stderr, "Parameter Generation error\n");
                        exit(1);
                        }
-           if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0,
+           if (dsa2 && dsa_builtin_paramgen2(dsa, L, N, md, NULL, 0, -1,
                                                NULL, NULL, NULL, NULL) <= 0)
                        {
                        fprintf(stderr, "Parameter Generation error\n");
@@ -502,7 +626,7 @@ static void siggen(FILE *in, FILE *out)
            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);
+           fputs(RESP_EOL, out);
            }
        else if(!strcmp(keyword,"Msg"))
            {
@@ -524,13 +648,13 @@ static void siggen(FILE *in, FILE *out)
 
            do_bn_print_name(out, "R",sig->r);
            do_bn_print_name(out, "S",sig->s);
-           fputs("\n", out);
+           fputs(RESP_EOL, out);
            FIPS_dsa_sig_free(sig);
            FIPS_md_ctx_cleanup(&mctx);
            }
        }
-       if (dsa)
-               FIPS_dsa_free(dsa);
+    if (dsa)
+       FIPS_dsa_free(dsa);
     }
 
 static void sigver(FILE *in, FILE *out)
@@ -568,15 +692,15 @@ static void sigver(FILE *in, FILE *out)
            dsa = FIPS_dsa_new();
            }
        else if(!strcmp(keyword,"P"))
-           dsa->p=hex2bn(value);
+           do_hex2bn(&dsa->p, value);
        else if(!strcmp(keyword,"Q"))
-           dsa->q=hex2bn(value);
+           do_hex2bn(&dsa->q, value);
        else if(!strcmp(keyword,"G"))
-           dsa->g=hex2bn(value);
+           do_hex2bn(&dsa->g, value);
        else if(!strcmp(keyword,"Msg"))
            n=hex2bin(value,msg);
        else if(!strcmp(keyword,"Y"))
-           dsa->pub_key=hex2bn(value);
+           do_hex2bn(&dsa->pub_key, value);
        else if(!strcmp(keyword,"R"))
            sig->r=hex2bn(value);
        else if(!strcmp(keyword,"S"))
@@ -592,13 +716,29 @@ static void sigver(FILE *in, FILE *out)
            r = FIPS_dsa_verify_ctx(dsa, &mctx, sig);
            no_err = 0;
            FIPS_md_ctx_cleanup(&mctx);
+           if (sig->s)
+               {
+               BN_free(sig->s);
+               sig->s = NULL;
+               }
+           if (sig->r)
+               {
+               BN_free(sig->r);
+               sig->r = NULL;
+               }
        
-           fprintf(out, "Result = %c\n\n", r == 1 ? 'P' : 'F');
+           fprintf(out, "Result = %c" RESP_EOL RESP_EOL, r == 1 ? 'P' : 'F');
            }
        }
+       if (dsa)
+           FIPS_dsa_free(dsa);
     }
 
-int main(int argc,char **argv)
+#ifdef FIPS_ALGVS
+int fips_dssvs_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
     {
     FILE *in, *out;
     if (argc == 4)