Skip to content

Commit b3e9e51

Browse files
extra sanity check for hash of all 0's
1 parent a057975 commit b3e9e51

5 files changed

Lines changed: 95 additions & 36 deletions

File tree

tests/api/test_evp_cipher.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2195,7 +2195,7 @@ int test_wolfssl_EVP_sm4_ecb(void)
21952195
};
21962196
byte cipherText[sizeof(plainText) + SM4_BLOCK_SIZE];
21972197
byte decryptedText[sizeof(plainText) + SM4_BLOCK_SIZE];
2198-
EVP_CIPHER_CTX* ctx;
2198+
EVP_CIPHER_CTX* ctx = NULL;
21992199
int outSz;
22002200

22012201
XMEMSET(key, 0, sizeof(key));
@@ -2251,7 +2251,7 @@ int test_wolfssl_EVP_sm4_cbc(void)
22512251
};
22522252
byte cipherText[sizeof(plainText) + SM4_BLOCK_SIZE];
22532253
byte decryptedText[sizeof(plainText) + SM4_BLOCK_SIZE];
2254-
EVP_CIPHER_CTX* ctx;
2254+
EVP_CIPHER_CTX* ctx = NULL;
22552255
int outSz;
22562256

22572257
XMEMSET(key, 0, sizeof(key));
@@ -2319,7 +2319,7 @@ int test_wolfssl_EVP_sm4_ctr(void)
23192319
byte plainText[] = {0xDE, 0xAD, 0xBE, 0xEF};
23202320
byte cipherText[sizeof(plainText)];
23212321
byte decryptedText[sizeof(plainText)];
2322-
EVP_CIPHER_CTX* ctx;
2322+
EVP_CIPHER_CTX* ctx = NULL;
23232323
int outSz;
23242324

23252325
XMEMSET(key, 0, sizeof(key));

tests/api/test_evp_pkey.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,9 +1592,25 @@ static int test_wolfSSL_EVP_PKEY_sign_verify(int keyType)
15921592
ExpectIntEQ(EVP_PKEY_verify(
15931593
ctx_verify, sig, siglen, hash, SHA256_DIGEST_LENGTH),
15941594
WOLFSSL_SUCCESS);
1595-
ExpectIntEQ(EVP_PKEY_verify(
1596-
ctx_verify, sig, siglen, zero, SHA256_DIGEST_LENGTH),
1597-
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
1595+
1596+
if (keyType == EVP_PKEY_EC) {
1597+
#ifdef WC_TEST_NO_ECC_SIGN_VERIFY_ZERO_DIGEST
1598+
/* wolfSSL differs from OpenSSL in that it treats a hash of all 0's as a
1599+
* fatal error and does not attempt to verify */
1600+
ExpectIntEQ(EVP_PKEY_verify(
1601+
ctx_verify, sig, siglen, zero, SHA256_DIGEST_LENGTH),
1602+
WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR));
1603+
#else
1604+
ExpectIntEQ(EVP_PKEY_verify(
1605+
ctx_verify, sig, siglen, zero, SHA256_DIGEST_LENGTH),
1606+
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
1607+
#endif
1608+
}
1609+
else {
1610+
ExpectIntEQ(EVP_PKEY_verify(
1611+
ctx_verify, sig, siglen, zero, SHA256_DIGEST_LENGTH),
1612+
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
1613+
}
15981614

15991615
#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
16001616
!defined(HAVE_SELFTEST)

wolfcrypt/src/ecc.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7272,6 +7272,10 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
72727272
ecc_key* key, mp_int *r, mp_int *s)
72737273
{
72747274
int err = 0;
7275+
#ifndef WC_ALLOW_ECC_ZERO_HASH
7276+
byte hashIsZero = 0;
7277+
word32 zIdx;
7278+
#endif
72757279
#if !defined(WOLFSSL_SP_MATH)
72767280
mp_int* e;
72777281
#if !defined(WOLFSSL_ASYNC_CRYPT) || !defined(HAVE_CAVIUM_V)
@@ -7298,6 +7302,14 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
72987302
return BAD_LENGTH_E;
72997303
}
73007304

7305+
#ifndef WC_ALLOW_ECC_ZERO_HASH
7306+
/* reject all 0's hash */
7307+
for (zIdx = 0; zIdx < inlen; zIdx++)
7308+
hashIsZero |= in[zIdx];
7309+
if (hashIsZero == 0)
7310+
return ECC_BAD_ARG_E;
7311+
#endif
7312+
73017313
/* is this a private key? */
73027314
if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
73037315
return ECC_BAD_ARG_E;
@@ -9274,6 +9286,10 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
92749286
#else
92759287
int err;
92769288
word32 keySz = 0;
9289+
#ifndef WC_ALLOW_ECC_ZERO_HASH
9290+
byte hashIsZero = 0;
9291+
word32 zIdx;
9292+
#endif
92779293
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
92789294
byte sigRS[ATECC_KEY_SIZE*2];
92799295
#elif defined(WOLFSSL_CRYPTOCELL)
@@ -9303,6 +9319,14 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
93039319
return BAD_LENGTH_E;
93049320
}
93059321

9322+
#ifndef WC_ALLOW_ECC_ZERO_HASH
9323+
/* reject all 0's hash */
9324+
for (zIdx = 0; zIdx < hashlen; zIdx++)
9325+
hashIsZero |= hash[zIdx];
9326+
if (hashIsZero == 0)
9327+
return ECC_BAD_ARG_E;
9328+
#endif
9329+
93069330
/* default to invalid signature */
93079331
*res = 0;
93089332

wolfcrypt/test/test.c

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36736,9 +36736,12 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif
3673636736
#if !defined(ECC_TIMING_RESISTANT) || (defined(ECC_TIMING_RESISTANT) && \
3673736737
!defined(WC_NO_RNG) && !defined(WOLFSSL_KCAPI_ECC))
3673836738
#ifdef HAVE_ECC_SIGN
36739-
/* some hardware doesn't support sign/verify of all zero digest */
36740-
#if !defined(WC_TEST_NO_ECC_SIGN_VERIFY_ZERO_DIGEST)
36741-
/* test DSA sign hash with zeros */
36739+
/* WC_TEST_NO_ECC_SIGN_VERIFY_ZERO_DIGEST: build rejects all-zero digest,
36740+
* so test expects failure. */
36741+
#ifdef WOLFSSL_SM2
36742+
if (curve_id != ECC_SM2P256V1)
36743+
#endif
36744+
{
3674236745
for (i = 0; i < (int)ECC_DIGEST_SIZE; i++) {
3674336746
digest[i] = 0;
3674436747
}
@@ -36752,29 +36755,47 @@ static wc_test_ret_t ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerif
3675236755
ret = wc_ecc_sign_hash(digest, ECC_DIGEST_SIZE, sig, &x, rng,
3675336756
userA);
3675436757
} while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
36758+
#ifdef WC_TEST_NO_ECC_SIGN_VERIFY_ZERO_DIGEST
36759+
if (ret == 0) {
36760+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
36761+
}
36762+
else {
36763+
ret = 0;
36764+
}
36765+
#else
3675536766
if (ret != 0)
3675636767
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
36768+
#endif
3675736769
TEST_SLEEP();
3675836770

3675936771
#ifdef HAVE_ECC_VERIFY
36760-
for (i=0; i<testVerifyCount; i++) {
36761-
verify = 0;
36762-
do {
36763-
#if defined(WOLFSSL_ASYNC_CRYPT)
36764-
ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
36765-
#endif
36766-
if (ret == 0)
36767-
ret = wc_ecc_verify_hash(sig, x, digest, ECC_DIGEST_SIZE,
36768-
&verify, userA);
36769-
} while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
36770-
if (ret != 0)
36771-
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
36772-
if (verify != 1)
36773-
ERROR_OUT(WC_TEST_RET_ENC_NC, done);
36774-
TEST_SLEEP();
36772+
verify = 0;
36773+
do {
36774+
#if defined(WOLFSSL_ASYNC_CRYPT)
36775+
ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
36776+
#endif
36777+
if (ret == 0)
36778+
ret = wc_ecc_verify_hash(sig, x, digest, ECC_DIGEST_SIZE,
36779+
&verify, userA);
36780+
} while (ret == WC_NO_ERR_TRACE(WC_PENDING_E));
36781+
#ifdef WC_TEST_NO_ECC_SIGN_VERIFY_ZERO_DIGEST
36782+
if (ret == 0) {
36783+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
3677536784
}
36785+
else {
36786+
ret = 0;
36787+
}
36788+
if (verify == 1)
36789+
ERROR_OUT(WC_TEST_RET_ENC_NC, done);
36790+
#else
36791+
if (ret != 0)
36792+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done);
36793+
if (verify != 1)
36794+
ERROR_OUT(WC_TEST_RET_ENC_NC, done);
36795+
#endif
36796+
TEST_SLEEP();
3677636797
#endif /* HAVE_ECC_VERIFY */
36777-
#endif /* !WC_TEST_NO_ECC_SIGN_VERIFY_ZERO_DIGEST */
36798+
}
3677836799

3677936800
/* test DSA sign hash with sequence (0,1,2,3,4,...) */
3678036801
for (i = 0; i < (int)ECC_DIGEST_SIZE; i++) {

wolfssl/wolfcrypt/settings.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3513,13 +3513,16 @@ extern void uITRON4_free(void *p) ;
35133513
#undef NO_DH
35143514
#endif
35153515

3516-
/* CryptoCell defines */
3517-
#ifdef WOLFSSL_CRYPTOCELL
3518-
#if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN)
3519-
/* Don't attempt to sign/verify an all-zero digest in wolfCrypt tests */
3516+
#ifdef HAVE_ECC
3517+
/* defined for all ECC non FIPS builds and for FIPS v7+, unless the user
3518+
* explicitly opts in to allowing an all-zero digest with
3519+
* WC_ALLOW_ECC_ZERO_HASH or is building with HAVE_SELFTEST */
3520+
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GT(7,0)) && \
3521+
!defined(HAVE_SELFTEST) && !defined(WC_ALLOW_ECC_ZERO_HASH)
3522+
/* sign/verify of an all-zero digest in wolfCrypt rejected */
35203523
#define WC_TEST_NO_ECC_SIGN_VERIFY_ZERO_DIGEST
3521-
#endif /* HAVE_ECC && HAVE_ECC_SIGN */
3522-
#endif
3524+
#endif
3525+
#endif /* HAVE_ECC */
35233526

35243527
/* Asynchronous Crypto */
35253528
#ifdef WOLFSSL_ASYNC_CRYPT
@@ -3546,11 +3549,6 @@ extern void uITRON4_free(void *p) ;
35463549
#define ECC_CACHE_CURVE
35473550
#endif
35483551

3549-
#if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN)
3550-
/* Don't attempt to sign/verify an all-zero digest in wolfCrypt tests */
3551-
#define WC_TEST_NO_ECC_SIGN_VERIFY_ZERO_DIGEST
3552-
#endif /* HAVE_ECC && HAVE_ECC_SIGN */
3553-
35543552
#endif /* WOLFSSL_ASYNC_CRYPT */
35553553
#ifndef WC_ASYNC_DEV_SIZE
35563554
#define WC_ASYNC_DEV_SIZE 0

0 commit comments

Comments
 (0)