New function EC_KEY_set_affine_coordinates() this performs all the
authorDr. Stephen Henson <steve@openssl.org>
Mon, 24 Jan 2011 16:07:40 +0000 (16:07 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 24 Jan 2011 16:07:40 +0000 (16:07 +0000)
NIST PKV tests.

crypto/ec/ec.h
crypto/ec/ec_err.c
crypto/ec/ec_key.c

index fb42dae..6409eee 100644 (file)
@@ -806,6 +806,15 @@ int EC_KEY_generate_key(EC_KEY *key);
  */
 int EC_KEY_check_key(const EC_KEY *key);
 
+/** Sets a public key from affine coordindates performing
+ *  neccessary NIST PKV tests.
+ *  \param  key  the EC_KEY object
+ *  \param  x    public key x coordinate
+ *  \param  y    public key y coordinate
+ *  \return 1 on success and 0 otherwise.
+ */
+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y);
+
 
 /********************************************************************/
 /*        de- and encoding functions for SEC1 ECPrivateKey          */
@@ -1021,6 +1030,7 @@ void ERR_load_EC_strings(void);
 #define EC_F_EC_KEY_NEW                                         182
 #define EC_F_EC_KEY_PRINT                               180
 #define EC_F_EC_KEY_PRINT_FP                            181
+#define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES   229
 #define EC_F_EC_POINTS_MAKE_AFFINE                      136
 #define EC_F_EC_POINT_ADD                               112
 #define EC_F_EC_POINT_CMP                               113
@@ -1066,6 +1076,7 @@ void ERR_load_EC_strings(void);
 #define EC_R_ASN1_UNKNOWN_FIELD                                 116
 #define EC_R_BIGNUM_OUT_OF_RANGE                        144
 #define EC_R_BUFFER_TOO_SMALL                           100
+#define EC_R_COORDINATES_OUT_OF_RANGE                   146
 #define EC_R_D2I_ECPKPARAMETERS_FAILURE                         117
 #define EC_R_DECODE_ERROR                               142
 #define EC_R_DISCRIMINANT_IS_ZERO                       118
index 1f8cbf5..a05e44c 100644 (file)
@@ -158,6 +158,7 @@ static ERR_STRING_DATA EC_str_functs[]=
 {ERR_FUNC(EC_F_EC_KEY_NEW),    "EC_KEY_new"},
 {ERR_FUNC(EC_F_EC_KEY_PRINT),  "EC_KEY_print"},
 {ERR_FUNC(EC_F_EC_KEY_PRINT_FP),       "EC_KEY_print_fp"},
+{ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES),      "EC_KEY_set_public_key_affine_coordinates"},
 {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
 {ERR_FUNC(EC_F_EC_POINT_ADD),  "EC_POINT_add"},
 {ERR_FUNC(EC_F_EC_POINT_CMP),  "EC_POINT_cmp"},
@@ -206,6 +207,7 @@ static ERR_STRING_DATA EC_str_reasons[]=
 {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD)     ,"asn1 unknown field"},
 {ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE)    ,"bignum out of range"},
 {ERR_REASON(EC_R_BUFFER_TOO_SMALL)       ,"buffer too small"},
+{ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE),"coordinates out of range"},
 {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
 {ERR_REASON(EC_R_DECODE_ERROR)           ,"decode error"},
 {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO)   ,"discriminant is zero"},
index 86e6cec..a9e780d 100644 (file)
@@ -310,7 +310,7 @@ int EC_KEY_check_key(const EC_KEY *eckey)
                ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
                goto err;
                }
-       
+
        if ((ctx = BN_CTX_new()) == NULL)
                goto err;
        if ((point = EC_POINT_new(eckey->group)) == NULL)
@@ -371,6 +371,81 @@ err:
        return(ok);
        }
 
+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y)
+       {
+       BN_CTX *ctx = NULL;
+       BIGNUM *tx, *ty;
+       EC_POINT *point = NULL;
+       int ok = 0, tmp_nid, is_char_two = 0;
+
+       if (!key || !key->group || !x || !y)
+               {
+               ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+                                               ERR_R_PASSED_NULL_PARAMETER);
+               return 0;
+               }
+       ctx = BN_CTX_new();
+       if (!ctx)
+               goto err;
+
+       point = EC_POINT_new(key->group);
+
+       if (!point)
+               goto err;
+
+       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);
+
+       if (is_char_two)
+               {
+               if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
+                                                               x, y, ctx))
+                       goto err;
+               if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
+                                                               tx, ty, ctx))
+                       goto err;
+               }
+       else
+               {
+               if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
+                                                               x, y, ctx))
+                       goto err;
+               if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
+                                                               tx, ty, ctx))
+                       goto err;
+               }
+       /* Check if retrieved coordinates match originals: if not values
+        * are out of range.
+        */
+       if (BN_cmp(x, tx) || BN_cmp(y, ty))
+               {
+               ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+                       EC_R_COORDINATES_OUT_OF_RANGE);
+               goto err;
+               }
+
+       if (!EC_KEY_set_public_key(key, point))
+               goto err;
+
+       if (EC_KEY_check_key(key) == 0)
+               goto err;
+
+       ok = 1;
+
+       err:
+       if (ctx)
+               BN_CTX_free(ctx);
+       if (point)
+               EC_POINT_free(point);
+       return ok;
+
+       }
+
 const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
        {
        return key->group;