diff --git a/src/ssl.c b/src/ssl.c index bfd5f86c3..63a0792db 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -32946,6 +32946,47 @@ int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out) return (int)len; } +#ifdef HAVE_ECC_KEY_IMPORT +WOLFSSL_EC_KEY *wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY **key, const unsigned char **in, + long len) +{ + WOLFSSL_EC_KEY *eckey = NULL; + WOLFSSL_ENTER("wolfSSL_d2i_ECPrivateKey"); + + if (!in || !*in || len <= 0) { + WOLFSSL_MSG("wolfSSL_d2i_ECPrivateKey Bad arguments"); + return NULL; + } + + if (!(eckey = wolfSSL_EC_KEY_new())) { + WOLFSSL_MSG("wolfSSL_EC_KEY_new error"); + return NULL; + } + + if (wc_ecc_import_private_key(*in, len, NULL, 0, (ecc_key*)eckey->internal) != MP_OKAY) { + WOLFSSL_MSG("wc_ecc_import_private_key error"); + goto error; + } + + eckey->inSet = 1; + + if (SetECKeyExternal(eckey) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECKeyExternal error"); + goto error; + } + + if (key) { + *key = eckey; + } + + return eckey; + +error: + wolfSSL_EC_KEY_free(eckey); + return NULL; +} +#endif /* HAVE_ECC_KEY_IMPORT */ + int wolfSSL_i2d_ECPrivateKey(const WOLFSSL_EC_KEY *in, unsigned char **out) { int len; @@ -33199,6 +33240,70 @@ int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ !defined(HAVE_SELFTEST) #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2)) +int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, + const WOLFSSL_EC_POINT *p1, + const WOLFSSL_EC_POINT *p2, WOLFSSL_BN_CTX *ctx) +{ + mp_int a, prime; + mp_digit mp = 0; + int ret = WOLFSSL_FAILURE; + + (void)ctx; + + if (!group || !r || !p1 || !p2) { + WOLFSSL_MSG("wolfSSL_EC_POINT_add error"); + return WOLFSSL_FAILURE; + } + + if (setupPoint(r) != WOLFSSL_SUCCESS || + setupPoint(p1) != WOLFSSL_SUCCESS || + setupPoint(p2) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("setupPoint error"); + return WOLFSSL_FAILURE; + } + + /* read the curve prime and a */ + if (mp_init_multi(&prime, &a, NULL, NULL, NULL, NULL) != MP_OKAY) { + WOLFSSL_MSG("mp_init_multi error"); + goto cleanup; + } + + if (mp_read_radix(&a, ecc_sets[group->curve_idx].Af, MP_RADIX_HEX) + != MP_OKAY) { + WOLFSSL_MSG("mp_read_radix a error"); + goto cleanup; + } + + if (mp_read_radix(&prime, ecc_sets[group->curve_idx].prime, MP_RADIX_HEX) + != MP_OKAY) { + WOLFSSL_MSG("mp_read_radix prime error"); + goto cleanup; + } + + if (mp_montgomery_setup(&prime, &mp) != MP_OKAY) { + WOLFSSL_MSG("mp_montgomery_setup nqm error"); + goto cleanup; + } + + if (ecc_projective_add_point((ecc_point*)p1->internal, (ecc_point*)p2->internal, + (ecc_point*)r->internal, &a, &prime, mp) + != MP_OKAY) { + WOLFSSL_MSG("wc_ecc_mulmod nqm error"); + goto cleanup; + } + + if (ecc_map((ecc_point*)r->internal, &prime, mp) != MP_OKAY) { + WOLFSSL_MSG("ecc_map nqm error"); + goto cleanup; + } + + ret = WOLFSSL_SUCCESS; +cleanup: + mp_clear(&a); + mp_clear(&prime); + return ret; +} + /* Calculate the value: generator * n + q * m * return code compliant with OpenSSL : * 1 if success, 0 if error @@ -33342,6 +33447,43 @@ cleanup: #endif /* !defined(WOLFSSL_ATECC508A) && defined(ECC_SHAMIR) && * !defined(HAVE_SELFTEST) */ +/* (x, y) -> (x, -y) */ +int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *a, + WOLFSSL_BN_CTX *ctx) +{ + ecc_point* p; + mp_int prime; + + (void)ctx; + + WOLFSSL_ENTER("wolfSSL_EC_POINT_invert"); + + if (!group || !a || setupPoint(a) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + + p = (ecc_point*)a->internal; + + + /* read the curve prime and a */ + if (mp_init_multi(&prime, NULL, NULL, NULL, NULL, NULL) != MP_OKAY) { + WOLFSSL_MSG("mp_init_multi error"); + return WOLFSSL_FAILURE; + } + + if (mp_sub(&prime, p->y, p->y) != MP_OKAY) { + WOLFSSL_MSG("mp_sub error"); + return WOLFSSL_FAILURE; + } + + if (SetECPointExternal(a) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECPointExternal error"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *p) { WOLFSSL_ENTER("wolfSSL_EC_POINT_clear_free"); diff --git a/tests/api.c b/tests/api.c index e823d30d6..45c61b6e4 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1946,6 +1946,7 @@ static void test_wolfSSL_EC(void) #ifndef HAVE_SELFTEST /* perform point multiplication */ + AssertIntEQ(EC_POINT_add(group, new_point, new_point, Gxy, ctx), WOLFSSL_SUCCESS); AssertIntEQ(EC_POINT_mul(group, new_point, Gx, Gxy, k, ctx), WOLFSSL_SUCCESS); AssertIntEQ(BN_is_zero(new_point->X), 0); AssertIntEQ(BN_is_zero(new_point->Y), 0); @@ -1992,6 +1993,9 @@ static void test_wolfSSL_EC(void) /* Test copying */ AssertIntEQ(EC_POINT_copy(new_point, set_point), 1); + /* Test inverting */ + AssertIntEQ(EC_POINT_invert(group, new_point, ctx), 1); + AssertPtrEq(EC_POINT_point2bn(group, set_point, POINT_CONVERSION_UNCOMPRESSED, set_point_bn, ctx), set_point_bn); @@ -2135,8 +2139,10 @@ static void test_EC_i2d(void) { #ifdef HAVE_ECC EC_KEY *key; + EC_KEY *copy; int len; unsigned char *buf = NULL; + const unsigned char *tmp = NULL; AssertNotNull(key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); AssertIntEQ(EC_KEY_generate_key(key), 1); @@ -2150,8 +2156,12 @@ static void test_EC_i2d(void) AssertIntGT((len = i2d_ECPrivateKey(key, NULL)), 0); AssertIntEQ(i2d_ECPrivateKey(key, &buf), len); + tmp = buf; + AssertNotNull(d2i_ECPrivateKey(©, &tmp, len)); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); EC_KEY_free(key); + EC_KEY_free(copy); #endif /* HAVE_ECC */ } diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 4f5c0841c..477e06ea3 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -148,6 +148,9 @@ int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, WOLFSSL_API int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out); WOLFSSL_API +WOLFSSL_EC_KEY *wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY **key, const unsigned char **in, + long len); +WOLFSSL_API int wolfSSL_i2d_ECPrivateKey(const WOLFSSL_EC_KEY *in, unsigned char **out); WOLFSSL_API void wolfSSL_EC_KEY_set_conv_form(WOLFSSL_EC_KEY *eckey, char form); @@ -236,11 +239,18 @@ int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, const WOLFSSL_BIGNUM *y, WOLFSSL_BN_CTX *ctx); WOLFSSL_API +int wolfSSL_EC_POINT_add(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, + const WOLFSSL_EC_POINT *p1, + const WOLFSSL_EC_POINT *p2, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx); WOLFSSL_API +int wolfSSL_EC_POINT_invert(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *a, + WOLFSSL_BN_CTX *ctx); +WOLFSSL_API void wolfSSL_EC_POINT_clear_free(WOLFSSL_EC_POINT *point); WOLFSSL_API int wolfSSL_EC_POINT_cmp(const WOLFSSL_EC_GROUP *group, @@ -300,7 +310,9 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, wolfSSL_EC_POINT_get_affine_coordinates_GFp #define EC_POINT_set_affine_coordinates_GFp \ wolfSSL_EC_POINT_set_affine_coordinates_GFp +#define EC_POINT_add wolfSSL_EC_POINT_add #define EC_POINT_mul wolfSSL_EC_POINT_mul +#define EC_POINT_invert wolfSSL_EC_POINT_invert #define EC_POINT_clear_free wolfSSL_EC_POINT_clear_free #define EC_POINT_cmp wolfSSL_EC_POINT_cmp #define EC_POINT_copy wolfSSL_EC_POINT_copy @@ -316,6 +328,7 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_POINT_is_on_curve wolfSSL_EC_POINT_is_on_curve #define i2o_ECPublicKey wolfSSL_i2o_ECPublicKey #define i2d_EC_PUBKEY wolfSSL_i2o_ECPublicKey +#define d2i_ECPrivateKey wolfSSL_d2i_ECPrivateKey #define i2d_ECPrivateKey wolfSSL_i2d_ECPrivateKey #define EC_KEY_set_conv_form wolfSSL_EC_KEY_set_conv_form