diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 65d668c4b..eebb7935e 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -70,6 +70,18 @@ Possible ECC enable options: * signing. If the value is invalid then an error is * returned rather than generating a new 'k'. (For testing) * default: off + * WOLFSSL_ECDSA_DETERMINISTIC_K: Enables RFC6979 implementation of + * deterministic ECC signatures. The following function + * can be used to set the deterministic signing flag in the + * ecc key structure. + * int wc_ecc_set_deterministic(ecc_key* key, byte flag) + * default: off + * + * WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT: RFC6979 lists a variant that uses the + * hash directly instead of doing bits2octets(H(m)), when + * the variant macro is used the bits2octets operation on + * the hash is removed. + * default: off */ /* @@ -5479,7 +5491,8 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, } #endif /* !NO_ASN */ -#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) +#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ + defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) /* returns MP_OKAY on success */ static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key) { @@ -5522,7 +5535,8 @@ static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key) FREE_CURVE_SPECS(); return err; } -#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K */ +#endif /* WOLFSSL_ECDSA_DETERMINISTIC_K || + WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT */ #if defined(WOLFSSL_STM32_PKA) int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, @@ -5582,7 +5596,8 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng, break; } #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \ - defined(WOLFSSL_ECDSA_DETERMINISTIC_K) + defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ + defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) if (key->sign_k != NULL) { if (loop_check > 1) { err = RNG_FAILURE_E; @@ -5601,7 +5616,8 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng, #ifdef WOLFSSL_ECDSA_SET_K_ONE_LOOP loop_check = 64; #endif - #ifdef WOLFSSL_ECDSA_DETERMINISTIC_K + #if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ + defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) if (key->deterministic == 1) { /* sign_k generated earlier in function for SP calls. * Only go through the loop once and fail if error */ @@ -5708,6 +5724,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \ defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ + defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) || \ (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA))) DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); @@ -5738,7 +5755,8 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, } #endif -#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) +#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ + defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) /* generate deterministic 'k' value to be used either with SP or normal */ if (key->deterministic == 1) { if (deterministic_sign_helper(in, inlen, key)) { @@ -5755,7 +5773,8 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, #endif ) { #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) \ - || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) + || defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ + defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) mp_int* sign_k = key->sign_k; #else mp_int* sign_k = NULL; @@ -5869,7 +5888,8 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, /* load curve info */ #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \ - defined(WOLFSSL_ECDSA_DETERMINISTIC_K) + defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ + defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err); if (err == MP_OKAY) err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); @@ -6017,13 +6037,15 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, return err; } -#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) +#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ + defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) /* helper function to do HMAC operations * returns 0 on success and updates "out" buffer */ static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz, const byte* h1, word32 h1Sz, byte* x, word32 xSz, byte* oct, - byte* out, enum wc_HashType hashType, void* heap) { + byte* out, enum wc_HashType hashType, void* heap) +{ Hmac hmac; int ret, init; @@ -6135,7 +6157,7 @@ int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz, } #endif - VSz = KSz = h1len = hashSz; + VSz = KSz = h1len = xSz = hashSz; /* 3.2 b. Set V = 0x01 0x01 ... */ XMEMSET(V, 0x01, VSz); @@ -6144,7 +6166,7 @@ int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz, XMEMSET(K, 0x00, KSz); mp_init(&z1); /* always init z1 and free z1 */ - ret = mp_to_unsigned_bin(priv, x); + ret = mp_to_unsigned_bin_len(priv, x, hashSz); if (ret == 0) { qbits = mp_count_bits(order); ret = mp_read_unsigned_bin(&z1, hash, hashSz); @@ -6156,7 +6178,11 @@ int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz, mp_rshb(&z1, (hashSz * WOLFSSL_BIT_SIZE) - qbits); XMEMSET(h1, 0, WC_MAX_DIGEST_SIZE); - /* mod reduce by order using conditional subtract */ + #if !defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) + /* mod reduce by order using conditional subtract + * RFC6979 lists a variant that uses the hash directly instead of + * doing bits2octets(H(m)), when variant macro is used avoid this + * bits2octets operation */ if (mp_cmp(&z1, order) == MP_GT) { mp_sub(&z1, order, &z1); h1len = mp_unsigned_bin_size(&z1); @@ -6167,7 +6193,9 @@ int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz, ret = mp_to_unsigned_bin(&z1, h1); } } - else { + else + #endif + { /* use original hash and keep leading 0's */ h1len = hashSz; XMEMCPY(h1, hash, hashSz); diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index fa97b11fc..9fb96929b 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -489,10 +489,12 @@ struct ecc_key { #endif #if defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \ - defined(WOLFSSL_ECDSA_DETERMINISTIC_K) + defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ + defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) mp_int *sign_k; #endif -#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) +#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ + defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) byte deterministic:1; #endif @@ -598,7 +600,8 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, WOLFSSL_API int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, ecc_key* key, mp_int *r, mp_int *s); -#ifdef WOLFSSL_ECDSA_DETERMINISTIC_K +#if defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \ + defined(WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT) WOLFSSL_API int wc_ecc_set_deterministic(ecc_key* key, byte flag); WOLFSSL_API