Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,9 @@ WC_DILITHIUM_FIXED_ARRAY
WC_DISABLE_RADIX_ZERO_PAD
WC_FLAG_DONT_USE_AESNI
WC_FORCE_LINUXKM_FORTIFY_SOURCE
WC_HASH_CUSTOM_MAX_BLOCK_SIZE
WC_HASH_CUSTOM_MAX_DIGEST_SIZE
WC_HASH_CUSTOM_MIN_DIGEST_SIZE
WC_NO_ASYNC_SLEEP
WC_NO_RNG_SIMPLE
WC_NO_STATIC_ASSERT
Expand All @@ -651,9 +654,6 @@ WC_RSA_NONBLOCK
WC_RSA_NONBLOCK_TIME
WC_RSA_NO_FERMAT_CHECK
WC_RWLOCK_OPS_INLINE
WC_SHA384
WC_SHA384_DIGEST_SIZE
WC_SHA512
WC_SKIP_INCLUDED_C_FILES
WC_SSIZE_TYPE
WC_STRICT_SIG
Expand Down
7 changes: 7 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
#include <wolfssl/error-ssl.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/dh.h>
#include <wolfssl/wolfcrypt/hash.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
Expand Down Expand Up @@ -5720,6 +5721,12 @@ int EccVerify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* out,
}
#endif

/* Check hash length */
if ((outSz > WC_MAX_DIGEST_SIZE) ||
(outSz < WC_MIN_DIGEST_SIZE)) {
return BAD_LENGTH_E;
}

(void)ssl;
(void)keyBufInfo;

Expand Down
16 changes: 16 additions & 0 deletions src/pk_ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -5264,6 +5264,14 @@ int wolfSSL_ECDSA_do_verify(const unsigned char *dgst, int dLen,
ret = WOLFSSL_FATAL_ERROR;
}

/* Check hash length */
if ((ret == 1) &&
((dLen > WC_MAX_DIGEST_SIZE) ||
(dLen < WC_MIN_DIGEST_SIZE))) {
WOLFSSL_MSG("wolfSSL_ECDSA_do_verify Bad digest size");
ret = WOLFSSL_FATAL_ERROR;
}

/* Ensure internal EC key is set from external. */
if ((ret == 1) && (key->inSet == 0)) {
WOLFSSL_MSG("No EC key internal set, do it");
Expand Down Expand Up @@ -5388,6 +5396,14 @@ int wolfSSL_ECDSA_verify(int type, const unsigned char *digest, int digestSz,
ret = 0;
}

/* Check hash length */
if ((ret == 1) &&
((digestSz > WC_MAX_DIGEST_SIZE) ||
(digestSz < WC_MIN_DIGEST_SIZE))) {
WOLFSSL_MSG("wolfSSL_ECDSA_verify Bad digest size");
ret = 0;
}

/* Verify signature using digest and key. */
if ((ret == 1) && (wc_ecc_verify_hash(sig, (word32)sigSz, digest,
(word32)digestSz, &verify, (ecc_key*)key->internal) != 0)) {
Expand Down
4 changes: 2 additions & 2 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -12284,9 +12284,9 @@ static int test_wc_CheckCertSigPubKey(void)
ExpectIntEQ(wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, keyDer, 0,
RSAk), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

/* Wrong aglo. */
/* Wrong algo. */
ExpectIntEQ(wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, keyDer,
keyDerSz, ECDSAk), WC_NO_ERR_TRACE(ASN_PARSE_E));
keyDerSz, ECDSAk), WC_NO_ERR_TRACE(ASN_SIG_OID_E));

wc_FreeDecodedCert(&decoded);
if (cert_der != NULL)
Expand Down
28 changes: 25 additions & 3 deletions tests/api/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,32 @@
#define HEAP_HINT NULL
#endif

#include <wolfssl/wolfcrypt/hash.h>

#define TEST_STRING "Everyone gets Friday off."
#define TEST_STRING_SZ 25

#if defined(WC_FIPS_186_5_PLUS)
#define TEST_STRING "WC_FIPS_186_5_PLUS test test"
#define TEST_STRING_SZ 28
#elif defined(WC_FIPS_186_4_PLUS) || defined(HAVE_SELFTEST)
#define TEST_STRING "WC_FIPS_186_4_PLUS test.."
#define TEST_STRING_SZ 25
#elif WC_MIN_DIGEST_SIZE <= 25
#define TEST_STRING "Everyone gets Friday off."
#define TEST_STRING_SZ 25
#elif WC_MIN_DIGEST_SIZE <= 28
#define TEST_STRING "Everyone works the weekends."
#define TEST_STRING_SZ 28
#elif WC_MIN_DIGEST_SIZE <= 32
#define TEST_STRING "Everyone works through the night"
#define TEST_STRING_SZ 32
#elif WC_MIN_DIGEST_SIZE <= 48
#define TEST_STRING "Everyone gets to summer in Tuscany with Chianti."
#define TEST_STRING_SZ 48
#elif WC_MIN_DIGEST_SIZE <= 64
#define TEST_STRING "Everyone works from Christmas Eve, clear through New Year's Day."
#define TEST_STRING_SZ 64
#else
#error WC_MIN_DIGEST_SIZE value not supported by unit test.
#endif

#ifndef ONEK_BUF
#define ONEK_BUF 1024
Expand Down
117 changes: 117 additions & 0 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -16109,6 +16109,118 @@ static int DecodeDsaAsn1Sig(const byte* sig, word32 sigSz, byte* sigCpy,
}
#endif

/* The certificate's signatureAlgorithm (sigOID) must match the issuer's
* key type (keyOID). sigOID picks the pre-hash; keyOID picks the
* verifier. They need to agree or the verifier gets the wrong input. */
static int SigOidMatchesKeyOid(word32 sigOID, word32 keyOID)
{
switch (keyOID) {
#ifndef NO_RSA
case RSAk:
switch (sigOID) {
case CTC_MD2wRSA:
case CTC_MD5wRSA:
case CTC_SHAwRSA:
case CTC_SHA224wRSA:
case CTC_SHA256wRSA:
case CTC_SHA384wRSA:
case CTC_SHA512wRSA:
case CTC_SHA3_224wRSA:
case CTC_SHA3_256wRSA:
case CTC_SHA3_384wRSA:
case CTC_SHA3_512wRSA:
case CTC_RSASSAPSS:
return 1;
}
return 0;
#ifdef WC_RSA_PSS
case RSAPSSk:
return (sigOID == CTC_RSASSAPSS);
#endif
#endif
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
case DSAk:
switch (sigOID) {
case CTC_SHAwDSA:
case CTC_SHA256wDSA:
return 1;
}
return 0;
#endif
#if defined(HAVE_ECC) && defined(HAVE_ECC_VERIFY)
case ECDSAk:
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
case SM2k:
#endif
switch (sigOID) {
case CTC_SHAwECDSA:
case CTC_SHA224wECDSA:
case CTC_SHA256wECDSA:
case CTC_SHA384wECDSA:
case CTC_SHA512wECDSA:
case CTC_SHA3_224wECDSA:
case CTC_SHA3_256wECDSA:
case CTC_SHA3_384wECDSA:
case CTC_SHA3_512wECDSA:
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3)
case CTC_SM3wSM2:
#endif
return 1;
}
return 0;
#endif
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
case ED25519k:
return (sigOID == CTC_ED25519);
#endif
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
case ED448k:
return (sigOID == CTC_ED448);
#endif
#if defined(HAVE_FALCON)
case FALCON_LEVEL1k:
return (sigOID == CTC_FALCON_LEVEL1);
case FALCON_LEVEL5k:
return (sigOID == CTC_FALCON_LEVEL5);
#endif
#if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_VERIFY) && \
!defined(WOLFSSL_DILITHIUM_NO_ASN1)
#ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT
case DILITHIUM_LEVEL2k:
return (sigOID == CTC_DILITHIUM_LEVEL2);
case DILITHIUM_LEVEL3k:
return (sigOID == CTC_DILITHIUM_LEVEL3);
case DILITHIUM_LEVEL5k:
return (sigOID == CTC_DILITHIUM_LEVEL5);
#endif
case ML_DSA_LEVEL2k:
return (sigOID == CTC_ML_DSA_LEVEL2);
case ML_DSA_LEVEL3k:
return (sigOID == CTC_ML_DSA_LEVEL3);
case ML_DSA_LEVEL5k:
return (sigOID == CTC_ML_DSA_LEVEL5);
#endif
#if defined(HAVE_SPHINCS)
case SPHINCS_FAST_LEVEL1k:
return (sigOID == CTC_SPHINCS_FAST_LEVEL1);
case SPHINCS_FAST_LEVEL3k:
return (sigOID == CTC_SPHINCS_FAST_LEVEL3);
case SPHINCS_FAST_LEVEL5k:
return (sigOID == CTC_SPHINCS_FAST_LEVEL5);
case SPHINCS_SMALL_LEVEL1k:
return (sigOID == CTC_SPHINCS_SMALL_LEVEL1);
case SPHINCS_SMALL_LEVEL3k:
return (sigOID == CTC_SPHINCS_SMALL_LEVEL3);
case SPHINCS_SMALL_LEVEL5k:
return (sigOID == CTC_SPHINCS_SMALL_LEVEL5);
#endif
}

/* Default to reject unknown key types */
(void)sigOID;
return 0;
}

/* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */
int ConfirmSignature(SignatureCtx* sigCtx,
const byte* buf, word32 bufSz,
Expand Down Expand Up @@ -16177,6 +16289,11 @@ int ConfirmSignature(SignatureCtx* sigCtx,

case SIG_STATE_HASH:
{
if (!SigOidMatchesKeyOid(sigOID, keyOID)) {
WOLFSSL_MSG("sigOID incompatible with issuer keyOID");
ERROR_OUT(ASN_SIG_OID_E, exit_cs);
}

#if !defined(NO_RSA) && defined(WC_RSA_PSS)
if (sigOID == RSAPSSk) {
word32 fakeSigOID = 0;
Expand Down
11 changes: 9 additions & 2 deletions wolfcrypt/src/dilithium.c
Original file line number Diff line number Diff line change
Expand Up @@ -9273,8 +9273,9 @@ static int dilithium_sign_ctx_hash_with_seed(dilithium_key* key,
byte oidMsgHash[DILITHIUM_HASH_OID_LEN + WC_MAX_DIGEST_SIZE];
word32 oidMsgHashLen = 0;

if ((ret == 0) && (hashLen > WC_MAX_DIGEST_SIZE)) {
ret = BUFFER_E;
/* Check that the input hash length is valid. */
if ((int)hashLen != wc_HashGetDigestSize((enum wc_HashType)hashAlg)) {
ret = BAD_LENGTH_E;
}

if (ret == 0) {
Expand Down Expand Up @@ -9944,6 +9945,12 @@ static int dilithium_verify_ctx_hash(dilithium_key* key, const byte* ctx,
if (key == NULL) {
ret = BAD_FUNC_ARG;
}
/* Check that the input hash length is valid. */
if ((ret == 0) &&
((int)hashLen != wc_HashGetDigestSize((enum wc_HashType)hashAlg)))
{
ret = BAD_LENGTH_E;
}

if (ret == 0) {
/* Step 6: Hash public key. */
Expand Down
17 changes: 17 additions & 0 deletions wolfcrypt/src/dsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <wolfssl/wolfcrypt/wolfmath.h>
#include <wolfssl/wolfcrypt/sha.h>
#include <wolfssl/wolfcrypt/dsa.h>
#include <wolfssl/wolfcrypt/hash.h>

#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
Expand Down Expand Up @@ -689,6 +690,12 @@ int wc_DsaSign_ex(const byte* digest, word32 digestSz, byte* out, DsaKey* key,
if (digest == NULL || out == NULL || key == NULL || rng == NULL)
return BAD_FUNC_ARG;

if ((digestSz > WC_MAX_DIGEST_SIZE) ||
(digestSz < WC_MIN_DIGEST_SIZE))
{
return BAD_LENGTH_E;
}

SAVE_VECTOR_REGISTERS(return _svr_ret;);

do {
Expand Down Expand Up @@ -1022,6 +1029,16 @@ int wc_DsaVerify_ex(const byte* digest, word32 digestSz, const byte* sig,
if (digest == NULL || sig == NULL || key == NULL || answer == NULL)
return BAD_FUNC_ARG;

/* Note the min allowed digestSz here is WC_SHA_DIGEST_SIZE, not
* WC_MIN_DIGEST_SIZE, to allow verify-only legacy DSA operations, as
* expressly allowed under FIPS 186-5, FIPS 140-3, and SP 800-131A.
*/
if ((digestSz > WC_MAX_DIGEST_SIZE) ||
(digestSz < WC_SHA_DIGEST_SIZE))
{
return BAD_LENGTH_E;
}

do {
#ifdef WOLFSSL_SMALL_STACK
w = (mp_int *)XMALLOC(sizeof *w, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
Expand Down
25 changes: 19 additions & 6 deletions wolfcrypt/src/ecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ ECC Curve Sizes:

#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/hash.h>

#ifdef WOLFSSL_HAVE_SP_ECC
#include <wolfssl/wolfcrypt/sp.h>
Expand All @@ -223,10 +224,6 @@ ECC Curve Sizes:
#include <wolfssl/wolfcrypt/aes.h>
#endif

#ifdef HAVE_X963_KDF
#include <wolfssl/wolfcrypt/hash.h>
#endif

#ifdef WOLF_CRYPTO_CB
#include <wolfssl/wolfcrypt/cryptocb.h>
#endif
Expand Down Expand Up @@ -6778,7 +6775,9 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
if (in == NULL || out == NULL || outlen == NULL || key == NULL) {
return ECC_BAD_ARG_E;
}
if (inlen > WC_MAX_DIGEST_SIZE) {
if ((inlen > WC_MAX_DIGEST_SIZE) ||
(inlen < WC_MIN_DIGEST_SIZE))
{
return BAD_LENGTH_E;
}

Expand Down Expand Up @@ -7299,6 +7298,11 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
return ECC_BAD_ARG_E;
}
if ((inlen > WC_MAX_DIGEST_SIZE) ||
(inlen < WC_MIN_DIGEST_SIZE))
{
return BAD_LENGTH_E;
}

/* is this a private key? */
if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
Expand Down Expand Up @@ -8576,7 +8580,10 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
return ECC_BAD_ARG_E;
}
if (hashlen > WC_MAX_DIGEST_SIZE) {

/* Check hash length */
if ((hashlen > WC_MAX_DIGEST_SIZE) ||
(hashlen < WC_MIN_DIGEST_SIZE)) {
return BAD_LENGTH_E;
}

Expand Down Expand Up @@ -9284,6 +9291,12 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL)
return ECC_BAD_ARG_E;

/* Check hash length */
if ((hashlen > WC_MAX_DIGEST_SIZE) ||
(hashlen < WC_MIN_DIGEST_SIZE)) {
return BAD_LENGTH_E;
}

/* default to invalid signature */
*res = 0;

Expand Down
Loading
Loading