Skip to content

Commit

Permalink
Add EC_POINT_hex2point
Browse files Browse the repository at this point in the history
  • Loading branch information
kojo1 committed Feb 1, 2024
1 parent 3db58af commit 791c9e7
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 16 deletions.
117 changes: 113 additions & 4 deletions src/pk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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.
*
Expand Down
25 changes: 18 additions & 7 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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));
Expand All @@ -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);
Expand Down
11 changes: 6 additions & 5 deletions wolfssl/openssl/ec.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 791c9e7

Please sign in to comment.