diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index f7fb835fa..aac9fe657 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -6299,7 +6299,7 @@ int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz, byte *x = NULL; mp_int *z1 = NULL; #endif - word32 xSz, VSz, KSz, h1len; + word32 xSz, VSz, KSz, h1len, qLen; byte intOct; if (hash == NULL || k == NULL || order == NULL) { @@ -6366,7 +6366,7 @@ int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz, #endif VSz = KSz = hashSz; - xSz = h1len = mp_unsigned_bin_size(order); + qLen = xSz = h1len = mp_unsigned_bin_size(order); /* 3.2 b. Set V = 0x01 0x01 ... */ XMEMSET(V, 0x01, VSz); @@ -6375,7 +6375,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_len(priv, x, xSz); + ret = mp_to_unsigned_bin_len(priv, x, qLen); if (ret == 0) { qbits = mp_count_bits(order); ret = mp_read_unsigned_bin(z1, hash, hashSz); @@ -6440,7 +6440,6 @@ int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz, /* 3.2 step h. loop through the next steps until a valid value is found */ if (ret == 0 ) { - word32 qLen = (qbits+7)/8; int err; intOct = 0x00; @@ -6473,10 +6472,10 @@ int wc_ecc_gen_deterministic_k(const byte* hash, word32 hashSz, ret = mp_read_unsigned_bin(k, x, xSz); } - if ((ret == 0) && ((int)(VSz * WOLFSSL_BIT_SIZE) != qbits)) { + if ((ret == 0) && ((int)(xSz * WOLFSSL_BIT_SIZE) != qbits)) { /* handle odd case where shift of 'k' is needed with RFC 6979 * k = bits2int(T) in section 3.2 h.3 */ - mp_rshb(k, (VSz * WOLFSSL_BIT_SIZE) - qbits); + mp_rshb(k, (xSz * WOLFSSL_BIT_SIZE) - qbits); } /* 3.2 step h.3 the key should be smaller than the order of base diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 80c8322ef..1e953fd5d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -20945,6 +20945,85 @@ done: wc_ecc_free(&key); return ret; } + +#if defined(HAVE_ECC521) +/* KAT from RFC6979 */ +static int ecc512_test_deterministic_k(WC_RNG* rng) +{ + int ret; + ecc_key key; + byte sig[ECC_MAX_SIG_SIZE]; + word32 sigSz; + unsigned char msg[] = "sample"; + unsigned char hash[32]; + + const char* dIUT = + "0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75C" + "AA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83" + "538"; + const char* QIUTx = + "1894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD3" + "71123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F502" + "3A4"; + const char* QIUTy = + "0493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A2" + "8A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDF" + "CF5"; + const char* expRstr = + "1511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659" + "D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E" + "1A7"; + const char* expSstr = + "04A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916" + "E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7E" + "CFC"; + mp_int r,s, expR, expS; + + mp_init_multi(&r, &s, &expR, &expS, NULL, NULL); + ret = wc_ecc_init_ex(&key, HEAP_HINT, devId); + if (ret != 0) { + return ret; + } + ret = wc_ecc_import_raw(&key, QIUTx, QIUTy, dIUT, "SECP521R1"); + if (ret != 0) { + goto done; + } + + ret = wc_Hash(WC_HASH_TYPE_SHA256, msg, + (word32)XSTRLEN((const char*)msg), hash, sizeof(hash)); + if (ret != 0) { + goto done; + } + + ret = wc_ecc_set_deterministic(&key, 1); + if (ret != 0) { + goto done; + } + + sigSz = sizeof(sig); + do { + #if defined(WOLFSSL_ASYNC_CRYPT) + ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); + #endif + if (ret == 0) + ret = wc_ecc_sign_hash_ex(hash, sizeof(hash), rng, &key, &r, &s); + } while (ret == WC_PENDING_E); + if (ret != 0) { + goto done; + } + TEST_SLEEP(); + + mp_read_radix(&expR, expRstr, MP_RADIX_HEX); + mp_read_radix(&expS, expSstr, MP_RADIX_HEX); + if (mp_cmp(&r, &expR) != MP_EQ) { + ret = -1; + } + +done: + wc_ecc_free(&key); + return ret; +} +#endif /* HAVE_ECC521 */ #endif /* WOLFSSL_PUBLIC_MP */ #endif @@ -23891,6 +23970,13 @@ WOLFSSL_TEST_SUBROUTINE int ecc_test(void) printf("ecc384_test_deterministic_k failed! %d\n", ret); goto done; } + #if defined(HAVE_ECC521) + ret = ecc512_test_deterministic_k(&rng); + if (ret != 0) { + printf("ecc512_test_deterministic_k failed! %d\n", ret); + goto done; + } + #endif #endif #endif