Added ECC Cofactor DH (ECC-CDH) support with new “wc_ecc_cdh()” and “wc_ecc_cdh_ex()” API’s. Enable using “HAVE_ECC_CDH” define.
This commit is contained in:
parent
c022614e07
commit
39607984f7
@ -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
|
||||
@ -2693,6 +2694,122 @@ int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
|
||||
#endif /* !WOLFSSL_ATECC508A */
|
||||
#endif /* HAVE_ECC_DHE */
|
||||
|
||||
|
||||
#ifdef HAVE_ECC_CDH
|
||||
/*
|
||||
Elliptic Curve Cryptography Cofactor Diffie-Hellman (ECC CDH)
|
||||
|
||||
A shared secret Z is computed using the domain parameters:
|
||||
(q, FR, a, b{, SEED}, G, n, h), the other party’s public key,
|
||||
and one’s own private key.
|
||||
|
||||
Input:
|
||||
1. (q, FR, a, b{, SEED}, G, n, h): Domain parameters,
|
||||
2. dA : One’s own private key, and
|
||||
3. QB : The other party’s public key.
|
||||
*/
|
||||
|
||||
int wc_ecc_cdh_ex(ecc_key* private_key, ecc_point* public_point,
|
||||
byte* out, word32 *outlen)
|
||||
{
|
||||
int err;
|
||||
int cofactor;
|
||||
ecc_point* result = NULL;
|
||||
mp_int k_lcl;
|
||||
mp_int* k;
|
||||
word32 x = 0;
|
||||
DECLARE_CURVE_SPECS(2)
|
||||
|
||||
if (private_key == NULL || public_point == NULL || out == NULL ||
|
||||
outlen == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* type valid? */
|
||||
if (private_key->type != ECC_PRIVATEKEY) {
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
|
||||
/* load curve info */
|
||||
cofactor = private_key->dp->cofactor;
|
||||
err = wc_ecc_curve_load(private_key->dp, &curve,
|
||||
(ECC_CURVE_FIELD_PRIME | ECC_CURVE_FIELD_AF));
|
||||
if (err != MP_OKAY) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* multiple cofactor times private key "k" */
|
||||
if (cofactor != 1) {
|
||||
k = &k_lcl;
|
||||
if (mp_init(k) != MP_OKAY) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
mp_set_int(k, cofactor);
|
||||
mp_mul(k, &private_key->k, k);
|
||||
}
|
||||
else {
|
||||
k = &private_key->k;
|
||||
}
|
||||
|
||||
/* make new point */
|
||||
result = wc_ecc_new_point_h(private_key->heap);
|
||||
if (result == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
/* multiple public and private points */
|
||||
err = wc_ecc_mulmod_ex(k, public_point, result,
|
||||
curve->Af, curve->prime, 1, private_key->heap);
|
||||
if (err == MP_OKAY) {
|
||||
x = mp_unsigned_bin_size(curve->prime);
|
||||
if (*outlen < x) {
|
||||
err = BUFFER_E;
|
||||
}
|
||||
}
|
||||
|
||||
/* return output */
|
||||
if (err == MP_OKAY) {
|
||||
XMEMSET(out, 0, x);
|
||||
err = mp_to_unsigned_bin(result->x,
|
||||
out + (x - mp_unsigned_bin_size(result->x)));
|
||||
}
|
||||
*outlen = x;
|
||||
|
||||
/* clean up */
|
||||
wc_ecc_del_point_h(result, private_key->heap);
|
||||
if (cofactor != 1) {
|
||||
mp_clear(k);
|
||||
}
|
||||
wc_ecc_curve_free(curve);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int wc_ecc_cdh(ecc_key* private_key, ecc_key* public_key,
|
||||
byte* out, word32* outlen)
|
||||
{
|
||||
if (private_key == NULL || public_key == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Verify domain params supplied */
|
||||
if (wc_ecc_is_valid_idx(private_key->idx) == 0 ||
|
||||
wc_ecc_is_valid_idx(public_key->idx) == 0) {
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
|
||||
/* Verify curve id matches */
|
||||
if (private_key->dp->id != public_key->dp->id) {
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
|
||||
return wc_ecc_cdh_ex(private_key, &public_key->pubkey, out, outlen);
|
||||
}
|
||||
|
||||
#endif /* HAVE_ECC_CDH */
|
||||
|
||||
|
||||
#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)
|
||||
|
@ -8343,6 +8343,25 @@ 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
|
||||
x = sizeof(sharedA);
|
||||
ret = wc_ecc_cdh(&userA, &userB, sharedA, &x);
|
||||
if (ret != 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
y = sizeof(sharedB);
|
||||
ret = wc_ecc_cdh(&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);
|
||||
#endif /* HAVE_ECC_CDH */
|
||||
|
||||
#ifdef HAVE_ECC_KEY_EXPORT
|
||||
x = sizeof(exportBuf);
|
||||
ret = wc_ecc_export_x963(&userA, exportBuf, &x);
|
||||
|
@ -302,6 +302,15 @@ int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
|
||||
#define wc_ecc_shared_secret_ssh wc_ecc_shared_secret_ex /* For backwards compat */
|
||||
#endif /* HAVE_ECC_DHE */
|
||||
|
||||
#ifdef HAVE_ECC_CDH
|
||||
WOLFSSL_API
|
||||
int wc_ecc_cdh(ecc_key* private_key, ecc_key* public_key,
|
||||
byte* out, word32* outlen);
|
||||
WOLFSSL_API
|
||||
int wc_ecc_cdh_ex(ecc_key* private_key, ecc_point* public_point,
|
||||
byte* out, word32 *outlen);
|
||||
#endif /* HAVE_ECC_CDH */
|
||||
|
||||
#ifdef HAVE_ECC_SIGN
|
||||
WOLFSSL_API
|
||||
int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||
|
Loading…
x
Reference in New Issue
Block a user