ghash-x86_64.pl: optimize for upcoming Atom.
[openssl.git] / fips / ecdh / fips_ecdhvs.c
index d459fbd986fecf724cd484f0dbb416fd406c9b90..a1422868b37b69f62ac618a82f02754c3c2145ef 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')
@@ -196,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, int add_e)
+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)
@@ -213,6 +214,8 @@ static int ec_print_pubkey(FILE *out, EC_KEY *key, int add_e)
                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);
@@ -230,11 +233,15 @@ static int ec_print_pubkey(FILE *out, EC_KEY *key, int 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);
@@ -254,6 +261,7 @@ static void ec_output_Zhash(FILE *out, int exout, EC_GROUP *group,
        unsigned char chash[EVP_MAX_MD_SIZE];
        int Zlen;
        ec = EC_KEY_new();
+       EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH);
        EC_KEY_set_group(ec, group);
        peerkey = make_peer(group, cx, cy);
        if (rhash == NULL)
@@ -261,7 +269,7 @@ static void ec_output_Zhash(FILE *out, int exout, EC_GROUP *group,
                if (md)
                        rhashlen = M_EVP_MD_size(md);
                EC_KEY_generate_key(ec);
-               ec_print_pubkey(out, ec, md ? 1 : 0);
+               ec_print_key(out, ec, md ? 1 : 0, exout);
                }
        else
                {
@@ -294,7 +302,11 @@ static void ec_output_Zhash(FILE *out, int exout, EC_GROUP *group,
        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;
@@ -308,6 +320,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;
@@ -401,11 +414,16 @@ int main(int argc,char **argv)
                        if (group)
                                EC_GROUP_free(group);
                        group = EC_GROUP_new_by_curve_name(nid);
+                       if (!group)
+                               {
+                               fprintf(stderr, "ERROR: unsupported curve %s\n", buf + 1);
+                               return 1;
+                               }
                        }
 
                if (strlen(buf) > 6 && !strncmp(buf, "[E", 2))
                        {
-                       md = parse_md(buf);
+                       md = eparse_md(buf);
                        if (md == NULL)
                                goto parse_error;
                        continue;
@@ -452,10 +470,27 @@ 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 (in && in != stdin)
+               fclose(in);
+       if (out && out != stdout)
+               fclose(out);
+       if (rv)
+               fprintf(stderr, "Error Parsing request file\n");
+       return rv;
        }
 
 #endif