From 1f0d6d5f311d4ab08022d87c932ea6fb977a3822 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 25 Mar 2020 17:26:06 +0100 Subject: [PATCH] New functions implemented - `EC_POINT_is_on_curve` - `i2d_EC_PUBKEY` - `i2d_ECPrivateKey` - `wc_ecc_point_is_on_curve` --- src/ssl.c | 83 ++++++++++++++++++++++++++++++++++++++++- tests/api.c | 56 ++++++++++++++++++++++++++- wolfcrypt/src/ecc.c | 29 ++++++++++++++ wolfssl/openssl/ec.h | 9 +++++ wolfssl/wolfcrypt/ecc.h | 2 + 5 files changed, 176 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index aa7ea4c63..f6e3a0bee 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -100,6 +100,7 @@ #include #include #include + #include #include #include #include @@ -32894,10 +32895,14 @@ int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out) return WOLFSSL_FAILURE; } +#ifdef HAVE_COMP_KEY /* Default to compressed form if not set */ form = in->form == POINT_CONVERSION_UNCOMPRESSED ? POINT_CONVERSION_UNCOMPRESSED: POINT_CONVERSION_COMPRESSED; +#else + form = POINT_CONVERSION_UNCOMPRESSED; +#endif len = wolfSSL_EC_POINT_point2oct(in->group, in->pub_key, form, NULL, 0, NULL); @@ -32930,11 +32935,62 @@ int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *in, unsigned char **out) return (int)len; } +int wolfSSL_i2d_ECPrivateKey(const WOLFSSL_EC_KEY *in, unsigned char **out) +{ + int len; + byte* buf = NULL; + WOLFSSL_ENTER("wolfSSL_i2d_ECPrivateKey"); + + if (!in) { + WOLFSSL_MSG("wolfSSL_i2d_ECPrivateKey Bad arguments"); + return WOLFSSL_FAILURE; + } + + if (!in->inSet && SetECKeyInternal((WOLFSSL_EC_KEY*)in) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECKeyInternal error"); + return WOLFSSL_FAILURE; + } + + if ((len = wc_ecc_size((ecc_key*)in->internal)) <= 0) { + WOLFSSL_MSG("wc_ecc_size error"); + return WOLFSSL_FAILURE; + } + + if (out) { + if (!(buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { + WOLFSSL_MSG("tmp buffer malloc error"); + return WOLFSSL_FAILURE; + } + + if (wc_ecc_export_private_only((ecc_key*)in->internal, buf, + (word32*)&len) != MP_OKAY) { + WOLFSSL_MSG("wc_ecc_export_private_only error"); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFSSL_FAILURE; + } + + if (*out) { + XMEMCPY(*out, buf, len); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + else { + *out = buf; + } + } + + return len; +} + void wolfSSL_EC_KEY_set_conv_form(WOLFSSL_EC_KEY *eckey, char form) { - if (eckey && (form == POINT_CONVERSION_COMPRESSED || - form == POINT_CONVERSION_UNCOMPRESSED)) { + if (eckey && (form == POINT_CONVERSION_COMPRESSED +#ifdef HAVE_COMP_KEY + || form == POINT_CONVERSION_COMPRESSED +#endif + )) { eckey->form = form; + } else { + WOLFSSL_MSG("Incorrect form or HAVE_COMP_KEY not compiled in"); } } @@ -32976,6 +33032,29 @@ WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group, } #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ +#ifdef USE_ECC_B_PARAM +int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *point, + WOLFSSL_BN_CTX *ctx) +{ + (void)ctx; + WOLFSSL_ENTER("wolfSSL_EC_POINT_is_on_curve"); + + if (!group || !point) { + WOLFSSL_MSG("Invalid arguments"); + return WOLFSSL_FAILURE; + } + + if (!point->inSet && SetECPointInternal((WOLFSSL_EC_POINT*)point)) { + WOLFSSL_MSG("SetECPointInternal error"); + return WOLFSSL_FAILURE; + } + + return wc_ecc_point_is_on_curve((ecc_point*)point->internal, group->curve_idx) + == MP_OKAY ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} +#endif /* USE_ECC_B_PARAM */ + WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group) { WOLFSSL_EC_POINT *p; diff --git a/tests/api.c b/tests/api.c index 61f175062..597cb46a0 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1963,6 +1963,13 @@ static void test_wolfSSL_EC(void) AssertIntEQ(BN_is_zero(new_point->Z), 0); #endif + /* check if point X coordinate is zero */ + AssertIntEQ(BN_is_zero(new_point->X), 0); + +#ifdef USE_ECC_B_PARAM + AssertIntEQ(EC_POINT_is_on_curve(group, new_point, ctx), 1); +#endif /* USE_ECC_B_PARAM */ + /* Force non-affine coordinates */ AssertIntEQ(BN_add(new_point->Z, (WOLFSSL_BIGNUM*)BN_value_one(), (WOLFSSL_BIGNUM*)BN_value_one()), 1); @@ -2121,6 +2128,30 @@ static void test_wolfSSL_ECDSA_SIG(void) #endif /* HAVE_ECC */ } +static void test_EC_i2d(void) +{ +#ifdef HAVE_ECC + EC_KEY *key; + int len; + unsigned char *buf = NULL; + + AssertNotNull(key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); + AssertIntEQ(EC_KEY_generate_key(key), 1); + + AssertIntGT((len = i2d_EC_PUBKEY(key, NULL)), 0); + AssertIntEQ(i2d_EC_PUBKEY(key, &buf), len); + + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + buf = NULL; + + AssertIntGT((len = i2d_ECPrivateKey(key, NULL)), 0); + AssertIntEQ(i2d_ECPrivateKey(key, &buf), len); + + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + EC_KEY_free(key); +#endif /* HAVE_ECC */ +} + static void test_ECDSA_size_sign(void) { #if defined(HAVE_ECC) && !defined(NO_ECC256) && !defined(NO_ECC_SECP) @@ -20056,7 +20087,8 @@ static int test_wc_ecc_del_point (void) /* * Testing wc_ecc_point_is_at_infinity(), wc_ecc_export_point_der(), - * wc_ecc_import_point_der(), wc_ecc_copy_point(), and wc_ecc_cmp_point() + * wc_ecc_import_point_der(), wc_ecc_copy_point(), wc_ecc_point_is_on_curve(), + * and wc_ecc_cmp_point() */ static int test_wc_ecc_pointFns (void) { @@ -20219,6 +20251,27 @@ static int test_wc_ecc_pointFns (void) printf(resultFmt, ret == 0 ? passed : failed); +#ifdef USE_ECC_B_PARAM + printf(testingFmt, "wc_ecc_point_is_on_curve()"); + /* On curve if ret == 0 */ + if (ret == 0) { + ret = wc_ecc_point_is_on_curve(point, idx); + } + /* Test bad args. */ + if (ret == 0) { + ret = wc_ecc_point_is_on_curve(NULL, idx); + if (ret == BAD_FUNC_ARG) { + ret = wc_ecc_point_is_on_curve(point, 1000); + } + if (ret == ECC_BAD_ARG_E) { + ret = 0; + } else if (ret == 0) { + ret = WOLFSSL_FATAL_ERROR; + } + } + printf(resultFmt, ret == 0 ? passed : failed); +#endif /* USE_ECC_B_PARAM */ + /* Free */ wc_ecc_del_point(point); wc_ecc_del_point(cpypt); @@ -35933,6 +35986,7 @@ void ApiTest(void) test_ECDSA_size_sign(); test_ED25519(); test_ED448(); + test_EC_i2d(); #endif #if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && \ !defined(HAVE_SELFTEST) && \ diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index fec7903bf..33c609409 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -3893,6 +3893,35 @@ int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point, #endif /* !WOLFSSL_ATECC508A && !WOLFSSL_CRYPTOCELL */ #endif /* HAVE_ECC_DHE */ +#ifdef USE_ECC_B_PARAM +/* Checks if a point p lies on the curve with index curve_idx */ +int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx) +{ + int err; + DECLARE_CURVE_SPECS(curve, 3); + + if (p == NULL) + return BAD_FUNC_ARG; + + /* is the IDX valid ? */ + if (wc_ecc_is_valid_idx(curve_idx) != 1) { + return ECC_BAD_ARG_E; + } + + ALLOC_CURVE_SPECS(3); + err = wc_ecc_curve_load(wc_ecc_get_curve_params(curve_idx), &curve, + ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF | + ECC_CURVE_FIELD_BF); + if (err == MP_OKAY) { + err = wc_ecc_is_point(p, curve->Af, curve->Bf, curve->prime); + } + + wc_ecc_curve_free(curve); + FREE_CURVE_SPECS(); + + return err; +} +#endif /* USE_ECC_B_PARAM */ #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ !defined(WOLFSSL_CRYPTOCELL) diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 1f11593fe..283151d58 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -148,12 +148,18 @@ 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 +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); WOLFSSL_API WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group, const WOLFSSL_EC_POINT *p, char form, WOLFSSL_BIGNUM *in, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API +int wolfSSL_EC_POINT_is_on_curve(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *point, + WOLFSSL_BN_CTX *ctx); WOLFSSL_API int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, @@ -304,7 +310,10 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_POINT_point2oct wolfSSL_EC_POINT_point2oct #define EC_POINT_oct2point wolfSSL_EC_POINT_oct2point #define EC_POINT_point2bn wolfSSL_EC_POINT_point2bn +#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 i2d_ECPrivateKey wolfSSL_i2d_ECPrivateKey #define EC_KEY_set_conv_form wolfSSL_EC_KEY_set_conv_form #ifndef HAVE_SELFTEST diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 930b96199..087577dbd 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -592,6 +592,8 @@ WOLFSSL_API int wc_ecc_cmp_point(ecc_point* a, ecc_point *b); WOLFSSL_API int wc_ecc_point_is_at_infinity(ecc_point *p); +WOLFSSL_API +int wc_ecc_point_is_on_curve(ecc_point *p, int curve_idx); #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) WOLFSSL_API