From 791c9e7aba235de3917bbf43bfd8cb4b3403a79b Mon Sep 17 00:00:00 2001 From: Takashi Kojo Date: Tue, 30 Jan 2024 14:53:37 +0900 Subject: [PATCH 1/2] Add EC_POINT_hex2point --- src/pk.c | 117 +++++++++++++++++++++++++++++++++++++++++-- tests/api.c | 25 ++++++--- wolfssl/openssl/ec.h | 11 ++-- 3 files changed, 137 insertions(+), 16 deletions(-) diff --git a/src/pk.c b/src/pk.c index dfc362f699..ba03fdeb5e 100644 --- a/src/pk.c +++ b/src/pk.c @@ -9711,7 +9711,6 @@ void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *point) #endif } -#ifndef HAVE_SELFTEST /* Convert EC point to hex string that as either uncompressed or compressed. * * ECC point compression types were not included in selftest ecc.h @@ -9788,12 +9787,12 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, * odd. */ hex[0] = mp_isodd((mp_int*)point->Y->internal) ? - ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN; + 0x03 : 0x02; /* No y-ordinate. */ } else { /* Put in uncompressed format byte. */ - hex[0] = ECC_POINT_UNCOMP; + hex[0] = 0x04; /* Calculate offset as leading zeros not encoded. */ i = 1 + 2 * sz - mp_unsigned_bin_size((mp_int*)point->Y->internal); /* Put in y-ordinate after x-ordinate. */ @@ -9824,7 +9823,117 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, return hex; } -#endif /* HAVE_SELFTEST */ +static size_t hex_to_bytes(const char *hex, unsigned char *output, size_t sz) +{ + word32 i; + for (i = 0; i < sz; i++) + { + signed char ch1, ch2; + ch1 = HexCharToByte(hex[i * 2]); + ch2 = HexCharToByte(hex[i * 2 + 1]); + if ((ch1 < 0) || (ch2 < 0)) + { + WOLFSSL_MSG("hex_to_bytes: syntax error"); + return 0; + } + output[i] = (unsigned char)((ch1 << 4) + ch2); + } + return sz; +} + +WOLFSSL_EC_POINT*wolfSSL_EC_POINT_hex2point(const EC_GROUP *group, + const char *hex, WOLFSSL_EC_POINT*p, WOLFSSL_BN_CTX *ctx) +{ + /* for uncompressed mode */ + size_t str_sz; + BIGNUM *Gx = NULL; + BIGNUM *Gy = NULL; + char *strGx = NULL; + + /* for compressed mode */ + int key_sz; + byte *octGx = NULL; + + #define P_ALLOC 1 + int p_alloc = 0; + int ret; + + WOLFSSL_ENTER("wolfSSL_EC_POINT_hex2point"); + + if (group == NULL || hex == NULL || ctx == NULL) + return NULL; + + if (p == NULL) { + if ((p = wolfSSL_EC_POINT_new(group)) == NULL) { + WOLFSSL_MSG("wolfSSL_EC_POINT_new"); + goto err; + } + p_alloc = P_ALLOC; + } + + if (hex[0] == '0' && hex[1] == '4') { /* uncompressed mode */ + str_sz = ((wolfSSL_EC_GROUP_get_degree(group) + 7) / 8) * 2; + strGx = (char *)XMALLOC(str_sz + 1, NULL, DYNAMIC_TYPE_ECC); + if (strGx == NULL) { + WOLFSSL_MSG("malloc error"); + goto err; + } + + XMEMSET(strGx, 0x0, str_sz + 1); + XMEMCPY(strGx, hex + 2, str_sz); + + if (BN_hex2bn(&Gx, strGx) == 0) + goto err; + + if (BN_hex2bn(&Gy, hex + 2 + str_sz) == 0) + goto err; + + ret = wolfSSL_EC_POINT_set_affine_coordinates_GFp + (group, p, Gx, Gy, ctx); + + if (ret != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp"); + goto err; + } + } + else if (hex[0] == '0' && (hex[1] == '2' || hex[1] == '3')) { + /* compressed mode */ + key_sz = ((wolfSSL_EC_GROUP_get_degree(group) + 7) / 8); + octGx = (byte *)XMALLOC(key_sz + 1, NULL, DYNAMIC_TYPE_ECC); + if (octGx == NULL) { + WOLFSSL_MSG("EEC_KEY_get_byte_size, XMALLOC"); + goto err; + } + octGx[0] = 0x03; + if (hex_to_bytes(hex + 2, octGx + 1, XSTRLEN(hex + 2) / 2) + != XSTRLEN(hex + 2) / 2) { + goto err; + } + if (wolfSSL_ECPoint_d2i(octGx, key_sz + 1, group, p) + != WOLFSSL_SUCCESS) { + goto err; + } + } + else + goto err; + + XFREE(strGx, NULL, DYNAMIC_TYPE_ECC); + XFREE(octGx, NULL, DYNAMIC_TYPE_ECC); + wolfSSL_BN_free(Gx); + wolfSSL_BN_free(Gy); + return p; + +err: + XFREE(strGx, NULL, DYNAMIC_TYPE_ECC); + XFREE(octGx, NULL, DYNAMIC_TYPE_ECC); + wolfSSL_BN_free(Gx); + wolfSSL_BN_free(Gy); + if (p_alloc) { + EC_POINT_free(p); + } + return NULL; + +} /* Encode the EC point as an uncompressed point in DER. * diff --git a/tests/api.c b/tests/api.c index d9c75f6752..270e852562 100644 --- a/tests/api.c +++ b/tests/api.c @@ -59640,6 +59640,7 @@ static int test_wolfSSL_EC_POINT(void) EC_POINT* Gxy = NULL; EC_POINT* new_point = NULL; EC_POINT* set_point = NULL; + EC_POINT* get_point = NULL; EC_POINT* infinity = NULL; BIGNUM* k = NULL; BIGNUM* Gx = NULL; @@ -59657,6 +59658,14 @@ static int test_wolfSSL_EC_POINT(void) "77037D812DEB33A0F4A13945D898C296"; const char* kGy = "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16" "2BCE33576B315ECECBB6406837BF51F5"; + const char* uncompG + = "046B17D1F2E12C4247F8BCE6E563A440F2" + "77037D812DEB33A0F4A13945D898C296" + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16" + "2BCE33576B315ECECBB6406837BF51F5"; + const char* compG + = "036B17D1F2E12C4247F8BCE6E563A440F2" + "77037D812DEB33A0F4A13945D898C296"; #ifndef HAVE_SELFTEST EC_POINT *tmp = NULL; @@ -59665,10 +59674,6 @@ static int test_wolfSSL_EC_POINT(void) unsigned char* buf = NULL; unsigned char bufInf[1] = { 0x00 }; - const char* uncompG = "046B17D1F2E12C4247F8BCE6E563A440F2" - "77037D812DEB33A0F4A13945D898C296" - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16" - "2BCE33576B315ECECBB6406837BF51F5"; const unsigned char binUncompG[] = { 0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, @@ -59686,8 +59691,6 @@ static int test_wolfSSL_EC_POINT(void) 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, }; - const char* compG = "036B17D1F2E12C4247F8BCE6E563A440F2" - "77037D812DEB33A0F4A13945D898C296"; #ifdef HAVE_COMP_KEY const unsigned char binCompG[] = { 0x03, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, @@ -59912,7 +59915,6 @@ static int test_wolfSSL_EC_POINT(void) #endif XFREE(hexStr, NULL, DYNAMIC_TYPE_ECC); -#ifndef HAVE_SELFTEST /* Test point to hex */ ExpectNull(EC_POINT_point2hex(NULL, NULL, POINT_CONVERSION_UNCOMPRESSED, ctx)); @@ -59929,13 +59931,22 @@ static int test_wolfSSL_EC_POINT(void) hexStr = EC_POINT_point2hex(group, Gxy, POINT_CONVERSION_UNCOMPRESSED, ctx); ExpectNotNull(hexStr); ExpectStrEQ(hexStr, uncompG); + AssertNotNull(get_point = EC_POINT_hex2point(group, hexStr, NULL, ctx)); + AssertIntEQ(EC_POINT_cmp(group, Gxy, get_point, ctx), 0); XFREE(hexStr, NULL, DYNAMIC_TYPE_ECC); hexStr = EC_POINT_point2hex(group, Gxy, POINT_CONVERSION_COMPRESSED, ctx); ExpectNotNull(hexStr); ExpectStrEQ(hexStr, compG); + #ifdef HAVE_COMP_KEY + AssertNotNull(get_point = EC_POINT_hex2point + (group, hexStr, get_point, ctx)); + AssertIntEQ(EC_POINT_cmp(group, Gxy, get_point, ctx), 0); + #endif XFREE(hexStr, NULL, DYNAMIC_TYPE_ECC); + EC_POINT_free(get_point); +#ifndef HAVE_SELFTEST /* Test point to oct */ ExpectIntEQ(EC_POINT_point2oct(NULL, NULL, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, ctx), 0); diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 23ef5e9a29..7a77210c65 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -306,12 +306,14 @@ WOLFSSL_API int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group, const WOLFSSL_EC_POINT *a); -#ifndef HAVE_SELFTEST WOLFSSL_API char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, const WOLFSSL_EC_POINT* point, int form, WOLFSSL_BN_CTX* ctx); -#endif +WOLFSSL_API +WOLFSSL_EC_POINT *wolfSSL_EC_POINT_hex2point + (const WOLFSSL_EC_GROUP *group, const char *hex, + WOLFSSL_EC_POINT *p, WOLFSSL_BN_CTX *ctx); #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) @@ -395,9 +397,8 @@ typedef WOLFSSL_EC_BUILTIN_CURVE EC_builtin_curve; #define EC_KEY_set_conv_form wolfSSL_EC_KEY_set_conv_form #define EC_KEY_get_conv_form wolfSSL_EC_KEY_get_conv_form -#ifndef HAVE_SELFTEST - #define EC_POINT_point2hex wolfSSL_EC_POINT_point2hex -#endif +#define EC_POINT_point2hex wolfSSL_EC_POINT_point2hex +#define EC_POINT_hex2point wolfSSL_EC_POINT_hex2point #define EC_POINT_dump wolfSSL_EC_POINT_dump #define EC_get_builtin_curves wolfSSL_EC_get_builtin_curves From bc2b184c98e9ede9e27de327ad4a8c1a1a996f79 Mon Sep 17 00:00:00 2001 From: Takashi Kojo Date: Tue, 21 May 2024 08:33:33 +0900 Subject: [PATCH 2/2] Add EC_POINT_hex2point: zd #17090 --- src/pk.c | 55 ++++++++++++++++++++++--------------------------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/src/pk.c b/src/pk.c index ba03fdeb5e..e3a16ddde5 100644 --- a/src/pk.c +++ b/src/pk.c @@ -32,6 +32,12 @@ #ifdef HAVE_ECC #include + #ifdef HAVE_SELFTEST + /* point compression types. */ + #define ECC_POINT_COMP_EVEN 0x02 + #define ECC_POINT_COMP_ODD 0x03 + #define ECC_POINT_UNCOMP 0x04 + #endif #endif #ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV /* FIPS build has replaced ecc.h. */ @@ -9787,12 +9793,12 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, * odd. */ hex[0] = mp_isodd((mp_int*)point->Y->internal) ? - 0x03 : 0x02; + ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN; /* No y-ordinate. */ } else { /* Put in uncompressed format byte. */ - hex[0] = 0x04; + hex[0] = ECC_POINT_UNCOMP; /* Calculate offset as leading zeros not encoded. */ i = 1 + 2 * sz - mp_unsigned_bin_size((mp_int*)point->Y->internal); /* Put in y-ordinate after x-ordinate. */ @@ -9826,13 +9832,11 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, static size_t hex_to_bytes(const char *hex, unsigned char *output, size_t sz) { word32 i; - for (i = 0; i < sz; i++) - { + for (i = 0; i < sz; i++) { signed char ch1, ch2; ch1 = HexCharToByte(hex[i * 2]); ch2 = HexCharToByte(hex[i * 2 + 1]); - if ((ch1 < 0) || (ch2 < 0)) - { + if ((ch1 < 0) || (ch2 < 0)) { WOLFSSL_MSG("hex_to_bytes: syntax error"); return 0; } @@ -9841,20 +9845,19 @@ static size_t hex_to_bytes(const char *hex, unsigned char *output, size_t sz) return sz; } -WOLFSSL_EC_POINT*wolfSSL_EC_POINT_hex2point(const EC_GROUP *group, +WOLFSSL_EC_POINT* wolfSSL_EC_POINT_hex2point(const EC_GROUP *group, const char *hex, WOLFSSL_EC_POINT*p, WOLFSSL_BN_CTX *ctx) { /* for uncompressed mode */ size_t str_sz; BIGNUM *Gx = NULL; BIGNUM *Gy = NULL; - char *strGx = NULL; + char strGx[MAX_ECC_BYTES * 2 + 1]; - /* for compressed mode */ + /* for compressed mode */ int key_sz; - byte *octGx = NULL; + byte *octGx = (byte *)strGx; /* octGx[MAX_ECC_BYTES] */ - #define P_ALLOC 1 int p_alloc = 0; int ret; @@ -9868,24 +9871,20 @@ WOLFSSL_EC_POINT*wolfSSL_EC_POINT_hex2point(const EC_GROUP *group, WOLFSSL_MSG("wolfSSL_EC_POINT_new"); goto err; } - p_alloc = P_ALLOC; + p_alloc = 1; } + key_sz = (wolfSSL_EC_GROUP_get_degree(group) + 7) / 8; if (hex[0] == '0' && hex[1] == '4') { /* uncompressed mode */ - str_sz = ((wolfSSL_EC_GROUP_get_degree(group) + 7) / 8) * 2; - strGx = (char *)XMALLOC(str_sz + 1, NULL, DYNAMIC_TYPE_ECC); - if (strGx == NULL) { - WOLFSSL_MSG("malloc error"); - goto err; - } + str_sz = key_sz * 2; XMEMSET(strGx, 0x0, str_sz + 1); XMEMCPY(strGx, hex + 2, str_sz); - if (BN_hex2bn(&Gx, strGx) == 0) + if (wolfSSL_BN_hex2bn(&Gx, strGx) == 0) goto err; - if (BN_hex2bn(&Gy, hex + 2 + str_sz) == 0) + if (wolfSSL_BN_hex2bn(&Gy, hex + 2 + str_sz) == 0) goto err; ret = wolfSSL_EC_POINT_set_affine_coordinates_GFp @@ -9897,16 +9896,10 @@ WOLFSSL_EC_POINT*wolfSSL_EC_POINT_hex2point(const EC_GROUP *group, } } else if (hex[0] == '0' && (hex[1] == '2' || hex[1] == '3')) { + size_t sz = XSTRLEN(hex + 2) / 2; /* compressed mode */ - key_sz = ((wolfSSL_EC_GROUP_get_degree(group) + 7) / 8); - octGx = (byte *)XMALLOC(key_sz + 1, NULL, DYNAMIC_TYPE_ECC); - if (octGx == NULL) { - WOLFSSL_MSG("EEC_KEY_get_byte_size, XMALLOC"); - goto err; - } - octGx[0] = 0x03; - if (hex_to_bytes(hex + 2, octGx + 1, XSTRLEN(hex + 2) / 2) - != XSTRLEN(hex + 2) / 2) { + octGx[0] = ECC_POINT_COMP_ODD; + if (hex_to_bytes(hex + 2, octGx + 1, sz) != sz) { goto err; } if (wolfSSL_ECPoint_d2i(octGx, key_sz + 1, group, p) @@ -9917,15 +9910,11 @@ WOLFSSL_EC_POINT*wolfSSL_EC_POINT_hex2point(const EC_GROUP *group, else goto err; - XFREE(strGx, NULL, DYNAMIC_TYPE_ECC); - XFREE(octGx, NULL, DYNAMIC_TYPE_ECC); wolfSSL_BN_free(Gx); wolfSSL_BN_free(Gy); return p; err: - XFREE(strGx, NULL, DYNAMIC_TYPE_ECC); - XFREE(octGx, NULL, DYNAMIC_TYPE_ECC); wolfSSL_BN_free(Gx); wolfSSL_BN_free(Gy); if (p_alloc) {