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:
David Garske 2017-02-16 13:17:08 -08:00
parent c022614e07
commit 39607984f7
3 changed files with 145 additions and 0 deletions
wolfcrypt
wolfssl/wolfcrypt

@ -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 partys public key,
and ones own private key.
Input:
1. (q, FR, a, b{, SEED}, G, n, h): Domain parameters,
2. dA : Ones own private key, and
3. QB : The other partys 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,