New functions implemented

- `EC_POINT_is_on_curve`
- `i2d_EC_PUBKEY`
- `i2d_ECPrivateKey`
- `wc_ecc_point_is_on_curve`
pull/3155/head
Juliusz Sosinowicz 2020-03-25 17:26:06 +01:00
parent 88b9bf3fba
commit 1f0d6d5f31
5 changed files with 176 additions and 3 deletions

View File

@ -100,6 +100,7 @@
#include <wolfssl/wolfcrypt/hmac.h>
#include <wolfssl/wolfcrypt/random.h>
#include <wolfssl/wolfcrypt/des3.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/md4.h>
#include <wolfssl/wolfcrypt/md5.h>
#include <wolfssl/wolfcrypt/arc4.h>
@ -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;

View File

@ -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) && \

View File

@ -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)

View File

@ -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

View File

@ -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