mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #754 from wolfSSL/ecc_cdh
Added ECC Cofactor DH (ECC-CDH) supportpull/756/head v3.10.3
commit
3837173f93
|
@ -347,7 +347,8 @@ int Base64_Encode_NoNl(const byte* in, word32 inLen, byte* out, word32* outLen)
|
|||
#endif /* defined(WOLFSSL_BASE64_ENCODE) */
|
||||
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS)
|
||||
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) \
|
||||
|| defined(HAVE_ECC_CDH)
|
||||
|
||||
static
|
||||
const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
|
|
|
@ -35,6 +35,7 @@ Possible ECC enable options:
|
|||
* HAVE_ECC_SIGN: ECC sign default: on
|
||||
* HAVE_ECC_VERIFY: ECC verify default: on
|
||||
* HAVE_ECC_DHE: ECC build shared secret default: on
|
||||
* HAVE_ECC_CDH: ECC cofactor DH shared secret default: off
|
||||
* HAVE_ECC_KEY_IMPORT: ECC Key import default: on
|
||||
* HAVE_ECC_KEY_EXPORT: ECC Key export default: on
|
||||
* ECC_SHAMIR: Enables Shamir calc method default: on
|
||||
|
@ -2578,14 +2579,39 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
|
|||
int err;
|
||||
ecc_point* result = NULL;
|
||||
word32 x = 0;
|
||||
mp_int* k = &private_key->k;
|
||||
#ifdef HAVE_ECC_CDH
|
||||
mp_int k_lcl;
|
||||
|
||||
/* if cofactor flag has been set */
|
||||
if (private_key->flags & WC_ECC_FLAG_COFACTOR) {
|
||||
mp_digit cofactor = (mp_digit)private_key->dp->cofactor;
|
||||
/* only perform cofactor calc if not equal to 1 */
|
||||
if (cofactor != 1) {
|
||||
k = &k_lcl;
|
||||
if (mp_init(k) != MP_OKAY)
|
||||
return MEMORY_E;
|
||||
/* multiply cofactor times private key "k" */
|
||||
err = mp_mul_d(&private_key->k, cofactor, k);
|
||||
if (err != MP_OKAY) {
|
||||
mp_clear(k);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* make new point */
|
||||
result = wc_ecc_new_point_h(private_key->heap);
|
||||
if (result == NULL) {
|
||||
#ifdef HAVE_ECC_CDH
|
||||
if (k == &k_lcl)
|
||||
mp_clear(k);
|
||||
#endif
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
err = wc_ecc_mulmod_ex(&private_key->k, point, result,
|
||||
err = wc_ecc_mulmod_ex(k, point, result,
|
||||
curve->Af, curve->prime, 1, private_key->heap);
|
||||
if (err == MP_OKAY) {
|
||||
x = mp_unsigned_bin_size(curve->prime);
|
||||
|
@ -2602,6 +2628,10 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
|
|||
*outlen = x;
|
||||
|
||||
wc_ecc_del_point_h(result, private_key->heap);
|
||||
#ifdef HAVE_ECC_CDH
|
||||
if (k == &k_lcl)
|
||||
mp_clear(k);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -2693,6 +2723,7 @@ int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
|
|||
#endif /* !WOLFSSL_ATECC508A */
|
||||
#endif /* HAVE_ECC_DHE */
|
||||
|
||||
|
||||
#ifndef WOLFSSL_ATECC508A
|
||||
/* return 1 if point is at infinity, 0 if not, < 0 on error */
|
||||
int wc_ecc_point_is_at_infinity(ecc_point* p)
|
||||
|
@ -3024,6 +3055,14 @@ int wc_ecc_init(ecc_key* key)
|
|||
return wc_ecc_init_ex(key, NULL, INVALID_DEVID);
|
||||
}
|
||||
|
||||
int wc_ecc_set_flags(ecc_key* key, word32 flags)
|
||||
{
|
||||
if (key == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
key->flags |= flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ECC_SIGN
|
||||
|
||||
|
@ -4861,6 +4900,7 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
|||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMSET(key, 0, sizeof(ecc_key));
|
||||
/* set curve type and index */
|
||||
err = wc_ecc_set_curve(key, 0, curve_id);
|
||||
if (err != 0) {
|
||||
|
|
|
@ -2254,6 +2254,12 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c)
|
|||
return MP_OKAY;
|
||||
}
|
||||
|
||||
int mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
|
||||
{
|
||||
fp_mul_d(a, b, c);
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
/* d = a * b (mod c) */
|
||||
int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
|
||||
{
|
||||
|
|
|
@ -8198,6 +8198,63 @@ static int ecc_test_vector(int keySize)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ECC_CDH
|
||||
static int ecc_test_cdh_vectors(void)
|
||||
{
|
||||
int ret;
|
||||
ecc_key pub_key, priv_key;
|
||||
byte sharedA[32] = {0}, sharedB[32] = {0};
|
||||
word32 x, z;
|
||||
|
||||
const char* QCAVSx = "700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287";
|
||||
const char* QCAVSy = "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac";
|
||||
const char* dIUT = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534";
|
||||
const char* QIUTx = "ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b230";
|
||||
const char* QIUTy = "28af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141";
|
||||
const char* ZIUT = "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b";
|
||||
|
||||
/* setup private and public keys */
|
||||
ret = wc_ecc_init(&pub_key);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
ret = wc_ecc_init(&priv_key);
|
||||
if (ret != 0) {
|
||||
wc_ecc_free(&pub_key);
|
||||
goto done;
|
||||
}
|
||||
wc_ecc_set_flags(&pub_key, WC_ECC_FLAG_COFACTOR);
|
||||
wc_ecc_set_flags(&priv_key, WC_ECC_FLAG_COFACTOR);
|
||||
ret = wc_ecc_import_raw(&pub_key, QCAVSx, QCAVSy, NULL, "SECP256R1");
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
ret = wc_ecc_import_raw(&priv_key, QIUTx, QIUTy, dIUT, "SECP256R1");
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
|
||||
/* compute ECC Cofactor shared secret */
|
||||
x = sizeof(sharedA);
|
||||
ret = wc_ecc_shared_secret(&priv_key, &pub_key, sharedA, &x);
|
||||
if (ret != 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* read in expected Z */
|
||||
z = sizeof(sharedB);
|
||||
ret = Base16_Decode((const byte*)ZIUT, (word32)XSTRLEN(ZIUT), sharedB, &z);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
|
||||
/* compare results */
|
||||
if (x != z || XMEMCMP(sharedA, sharedB, x)) {
|
||||
ERROR_OUT(-1007, done);
|
||||
}
|
||||
|
||||
done:
|
||||
wc_ecc_free(&priv_key);
|
||||
wc_ecc_free(&pub_key);
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_ECC_CDH */
|
||||
#endif /* HAVE_ECC_VECTOR_TEST */
|
||||
|
||||
#ifdef WOLFSSL_KEY_GEN
|
||||
|
@ -8343,6 +8400,33 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount,
|
|||
ERROR_OUT(-1005, done);
|
||||
#endif /* HAVE_ECC_DHE */
|
||||
|
||||
#ifdef HAVE_ECC_CDH
|
||||
/* add cofactor flag */
|
||||
wc_ecc_set_flags(&userA, WC_ECC_FLAG_COFACTOR);
|
||||
wc_ecc_set_flags(&userB, WC_ECC_FLAG_COFACTOR);
|
||||
|
||||
x = sizeof(sharedA);
|
||||
ret = wc_ecc_shared_secret(&userA, &userB, sharedA, &x);
|
||||
if (ret != 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
y = sizeof(sharedB);
|
||||
ret = wc_ecc_shared_secret(&userB, &userA, sharedB, &y);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
|
||||
if (y != x)
|
||||
ERROR_OUT(-1006, done);
|
||||
|
||||
if (XMEMCMP(sharedA, sharedB, x))
|
||||
ERROR_OUT(-1007, done);
|
||||
|
||||
/* remove cofactor flag */
|
||||
wc_ecc_set_flags(&userA, 0);
|
||||
wc_ecc_set_flags(&userB, 0);
|
||||
#endif /* HAVE_ECC_CDH */
|
||||
|
||||
#ifdef HAVE_ECC_KEY_EXPORT
|
||||
x = sizeof(exportBuf);
|
||||
ret = wc_ecc_export_x963(&userA, exportBuf, &x);
|
||||
|
@ -8579,6 +8663,13 @@ int ecc_test(void)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ECC_CDH
|
||||
ret = ecc_test_cdh_vectors();
|
||||
if (ret != 0) {
|
||||
printf("ecc_test_cdh_vectors failed! %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
done:
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@ WOLFSSL_API int Base64_Decode(const byte* in, word32 inLen, byte* out,
|
|||
word32* outLen);
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS)
|
||||
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_FIPS) \
|
||||
|| defined(HAVE_ECC_CDH)
|
||||
WOLFSSL_API
|
||||
int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen);
|
||||
WOLFSSL_API
|
||||
|
|
|
@ -248,6 +248,13 @@ typedef struct {
|
|||
#endif
|
||||
} ecc_point;
|
||||
|
||||
/* ECC Flags */
|
||||
enum {
|
||||
WC_ECC_FLAG_NONE = 0x00,
|
||||
#ifdef HAVE_ECC_CDH
|
||||
WC_ECC_FLAG_COFACTOR = 0x01,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* An ECC Key */
|
||||
typedef struct ecc_key {
|
||||
|
@ -256,6 +263,7 @@ typedef struct ecc_key {
|
|||
this curve if -1, this key is using user supplied
|
||||
curve in dp */
|
||||
int state;
|
||||
word32 flags;
|
||||
const ecc_set_type* dp; /* domain parameters, either points to NIST
|
||||
curves (idx >= 0) or user supplied */
|
||||
void* heap; /* heap hint */
|
||||
|
@ -327,6 +335,8 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId);
|
|||
WOLFSSL_API
|
||||
void wc_ecc_free(ecc_key* key);
|
||||
WOLFSSL_API
|
||||
int wc_ecc_set_flags(ecc_key* key, word32 flags);
|
||||
WOLFSSL_API
|
||||
void wc_ecc_fp_free(void);
|
||||
|
||||
WOLFSSL_API
|
||||
|
|
|
@ -622,6 +622,7 @@ int mp_sub (mp_int * a, mp_int * b, mp_int * c);
|
|||
int mp_add_d (mp_int * a, mp_digit b, mp_int * c);
|
||||
|
||||
int mp_mul (mp_int * a, mp_int * b, mp_int * c);
|
||||
int mp_mul_d (mp_int * a, mp_digit b, mp_int * c);
|
||||
int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d);
|
||||
int mp_submod (mp_int* a, mp_int* b, mp_int* c, mp_int* d);
|
||||
int mp_addmod (mp_int* a, mp_int* b, mp_int* c, mp_int* d);
|
||||
|
|
Loading…
Reference in New Issue