Add support for memory leak checking in fips_algvs.
[openssl.git] / fips / ecdh / fips_ecdhvs.c
index c3ee1743691e414ca596bd8ee318a55b893c7e1c..a30e335e2b9fddf35ab476ee1e56f32858af714c 100644 (file)
@@ -76,7 +76,7 @@ int main(int argc, char **argv)
 
 #include "fips_utl.h"
 
-static const EVP_MD *parse_md(char *line)
+static const EVP_MD *eparse_md(char *line)
        {
        char *p;
        if (line[0] != '[' || line[1] != 'E')
@@ -106,18 +106,9 @@ static const EVP_MD *parse_md(char *line)
                return NULL;
        }
 
-static int lookup_curve(char *cname)
+static int lookup_curve2(char *cname)
        {
        char *p;
-       p = strchr(cname, ':');
-       if (!p)
-               {
-               fprintf(stderr, "Parse error: missing :\n");
-               return NID_undef;
-               }
-       cname = p + 1;
-       while(isspace(*cname))
-               cname++;
        p = strchr(cname, ']');
        if (!p)
                {
@@ -161,6 +152,21 @@ static int lookup_curve(char *cname)
        return NID_undef;
        }
 
+static int lookup_curve(char *cname)
+       {
+       char *p;
+       p = strchr(cname, ':');
+       if (!p)
+               {
+               fprintf(stderr, "Parse error: missing :\n");
+               return NID_undef;
+               }
+       cname = p + 1;
+       while(isspace(*cname))
+               cname++;
+       return lookup_curve2(cname);
+       }
+
 static EC_POINT *make_peer(EC_GROUP *group, BIGNUM *x, BIGNUM *y)
        {
        EC_POINT *peer;
@@ -190,13 +196,14 @@ static EC_POINT *make_peer(EC_GROUP *group, BIGNUM *x, BIGNUM *y)
        return NULL;
        }
 
-static int ec_print_pubkey(FILE *out, EC_KEY *key)
+static int ec_print_key(FILE *out, EC_KEY *key, int add_e, int exout)
        {
        const EC_POINT *pt;
        const EC_GROUP *grp;
        const EC_METHOD *meth;
        int rv;
        BIGNUM *tx, *ty;
+       const BIGNUM *d = NULL;
        BN_CTX *ctx;
        ctx = BN_CTX_new();
        if (!ctx)
@@ -207,6 +214,8 @@ static int ec_print_pubkey(FILE *out, EC_KEY *key)
                return 0;
        grp = EC_KEY_get0_group(key);
        pt = EC_KEY_get0_public_key(key);
+       if (exout)
+               d = EC_KEY_get0_private_key(key);
        meth = EC_GROUP_method_of(grp);
        if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field)
                rv = EC_POINT_get_affine_coordinates_GFp(grp, pt, tx, ty, ctx);
@@ -220,8 +229,20 @@ static int ec_print_pubkey(FILE *out, EC_KEY *key)
                rv = EC_POINT_get_affine_coordinates_GF2m(grp, pt, tx, ty, ctx);
 #endif
 
-       do_bn_print_name(out, "QeIUTx", tx);
-       do_bn_print_name(out, "QeIUTy", ty);
+       if (add_e)
+               {
+               do_bn_print_name(out, "QeIUTx", tx);
+               do_bn_print_name(out, "QeIUTy", ty);
+               if (d)
+                       do_bn_print_name(out, "QeIUTd", d);
+               }
+       else
+               {
+               do_bn_print_name(out, "QIUTx", tx);
+               do_bn_print_name(out, "QIUTy", ty);
+               if (d)
+                       do_bn_print_name(out, "QIUTd", d);
+               }
 
        BN_CTX_free(ctx);
 
@@ -244,9 +265,10 @@ static void ec_output_Zhash(FILE *out, int exout, EC_GROUP *group,
        peerkey = make_peer(group, cx, cy);
        if (rhash == NULL)
                {
-               rhashlen = M_EVP_MD_size(md);
+               if (md)
+                       rhashlen = M_EVP_MD_size(md);
                EC_KEY_generate_key(ec);
-               ec_print_pubkey(out, ec);
+               ec_print_key(out, ec, md ? 1 : 0, exout);
                }
        else
                {
@@ -258,22 +280,32 @@ static void ec_output_Zhash(FILE *out, int exout, EC_GROUP *group,
        if (!Z)
                exit(1);
        ECDH_compute_key(Z, Zlen, peerkey, ec, 0);
-       if (exout)
-               OutputValue("Z", Z, Zlen, out, 0);
-       FIPS_digest(Z, Zlen, chash, NULL, md);
-       OutputValue(rhash ? "IUTHashZZ" : "HashZZ", chash, rhashlen, out, 0);
-       if (rhash)
+       if (md)
                {
-               fprintf(out, "Result = %s\n",
+               if (exout)
+                       OutputValue("Z", Z, Zlen, out, 0);
+               FIPS_digest(Z, Zlen, chash, NULL, md);
+               OutputValue(rhash ? "IUTHashZZ" : "HashZZ",
+                                               chash, rhashlen, out, 0);
+               if (rhash)
+                       {
+                       fprintf(out, "Result = %s\n",
                                memcmp(chash, rhash, rhashlen) ? "F" : "P");
+                       }
                }
+       else
+               OutputValue("ZIUT", Z, Zlen, out, 0);
        OPENSSL_cleanse(Z, Zlen);
        OPENSSL_free(Z);
        EC_KEY_free(ec);
        EC_POINT_free(peerkey);
        }
                
-int main(int argc,char **argv)
+#ifdef FIPS_ALGVS
+int fips_ecdhvs_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
        {
        char **args = argv + 1;
        int argn = argc - 1;
@@ -287,6 +319,7 @@ int main(int argc,char **argv)
        EC_GROUP *group = NULL;
        char *keyword = NULL, *value = NULL;
        int do_verify = -1, exout = 0;
+       int rv = 1;
 
        int curve_nids[5] = {0,0,0,0,0};
        int param_set = -1;
@@ -372,21 +405,31 @@ int main(int argc,char **argv)
                        curve_nids[param_set] = nid;
                        }
 
+               if (strlen(buf) > 4 && buf[0] == '[' && buf[2] == '-')
+                       {
+                       int nid = lookup_curve2(buf + 1);
+                       if (nid == NID_undef)
+                               goto parse_error;
+                       if (group)
+                               EC_GROUP_free(group);
+                       group = EC_GROUP_new_by_curve_name(nid);
+                       }
+
                if (strlen(buf) > 6 && !strncmp(buf, "[E", 2))
                        {
-                       md = parse_md(buf);
+                       md = eparse_md(buf);
                        if (md == NULL)
                                goto parse_error;
                        continue;
                        }
                if (!parse_line(&keyword, &value, lbuf, buf))
                        continue;
-               if (!strcmp(keyword, "QeCAVSx"))
+               if (!strcmp(keyword, "QeCAVSx") || !strcmp(keyword, "QCAVSx"))
                        {
                        if (!do_hex2bn(&cx, value))
                                goto parse_error;
                        }
-               else if (!strcmp(keyword, "QeCAVSy"))
+               else if (!strcmp(keyword, "QeCAVSy") || !strcmp(keyword, "QCAVSy"))
                        {
                        if (!do_hex2bn(&cy, value))
                                goto parse_error;
@@ -421,10 +464,23 @@ int main(int argc,char **argv)
                                        md, rhash, rhashlen);
                        }
                }
-       return 0;
+       rv = 0;
        parse_error:
-       fprintf(stderr, "Error Parsing request file\n");
-       exit(1);
+       if (id)
+               BN_free(id);
+       if (ix)
+               BN_free(ix);
+       if (iy)
+               BN_free(iy);
+       if (cx)
+               BN_free(cx);
+       if (cy)
+               BN_free(cy);
+       if (group)
+               EC_GROUP_free(group);
+       if (rv)
+               fprintf(stderr, "Error Parsing request file\n");
+       return rv;
        }
 
 #endif