EC_KEY_METHOD keygen support.
[openssl.git] / crypto / ec / ec_key.c
index 07c33fe733db60152b429508e0ee21a15181bbe0..477d4a26ba9606c3fba9534608e13c05164ae7d1 100644 (file)
  * contributed to the OpenSSL project.
  */
 
+#include <internal/cryptlib.h>
 #include <string.h>
 #include "ec_lcl.h"
 #include <openssl/err.h>
 
 EC_KEY *EC_KEY_new(void)
 {
-    EC_KEY *ret = OPENSSL_malloc(sizeof(*ret));
-
-    if (ret == NULL) {
-        ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE);
-        return (NULL);
-    }
-
-    ret->version = 1;
-    ret->flags = 0;
-    ret->group = NULL;
-    ret->pub_key = NULL;
-    ret->priv_key = NULL;
-    ret->enc_flag = 0;
-    ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
-    ret->references = 1;
-    ret->method_data = NULL;
-    return (ret);
+    return EC_KEY_new_method(NULL);
 }
 
 EC_KEY *EC_KEY_new_by_curve_name(int nid)
@@ -218,15 +203,22 @@ int EC_KEY_up_ref(EC_KEY *r)
 
 int EC_KEY_generate_key(EC_KEY *eckey)
 {
-    int ok = 0;
-    BN_CTX *ctx = NULL;
-    BIGNUM *priv_key = NULL, *order = NULL;
-    EC_POINT *pub_key = NULL;
-
     if (!eckey || !eckey->group) {
         ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
         return 0;
     }
+    if (eckey->meth->keygen)
+        return eckey->meth->keygen(eckey);
+    ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
+    return 0;
+}
+
+int ossl_ec_key_gen(EC_KEY *eckey)
+{
+    int ok = 0;
+    BN_CTX *ctx = NULL;
+    BIGNUM *priv_key = NULL, *order = NULL;
+    EC_POINT *pub_key = NULL;
 
     if ((order = BN_new()) == NULL)
         goto err;
@@ -296,7 +288,7 @@ int EC_KEY_check_key(const EC_KEY *eckey)
         goto err;
 
     /* testing whether the pub_key is on the elliptic curve */
-    if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) {
+    if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
         ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
         goto err;
     }
@@ -346,7 +338,10 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
     BN_CTX *ctx = NULL;
     BIGNUM *tx, *ty;
     EC_POINT *point = NULL;
-    int ok = 0, tmp_nid, is_char_two = 0;
+    int ok = 0;
+#ifndef OPENSSL_NO_EC2M
+    int tmp_nid, is_char_two = 0;
+#endif
 
     if (!key || !key->group || !x || !y) {
         ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
@@ -354,22 +349,23 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
         return 0;
     }
     ctx = BN_CTX_new();
-    if (!ctx)
+    if (ctx == NULL)
         goto err;
 
     point = EC_POINT_new(key->group);
 
-    if (!point)
+    if (point == NULL)
         goto err;
 
+    tx = BN_CTX_get(ctx);
+    ty = BN_CTX_get(ctx);
+
+#ifndef OPENSSL_NO_EC2M
     tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));
 
     if (tmp_nid == NID_X9_62_characteristic_two_field)
         is_char_two = 1;
 
-    tx = BN_CTX_get(ctx);
-    ty = BN_CTX_get(ctx);
-#ifndef OPENSSL_NO_EC2M
     if (is_char_two) {
         if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
                                                   x, y, ctx))