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
1 change: 1 addition & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,7 @@ WC_ASYNC_NO_SHA384
WC_ASYNC_NO_SHA512
WC_ASYNC_NO_X25519
WC_ASYNC_THREAD_BIND
WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS
WC_CACHE_RESISTANT_BASE64_TABLE
WC_DILITHIUM_FIXED_ARRAY
WC_DISABLE_RADIX_ZERO_PAD
Expand Down
27 changes: 17 additions & 10 deletions doc/dox_comments/header_files/cmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,11 @@ int wc_AesCmacGenerate(byte* out, word32* outSz,
\ingroup CMAC
\brief Single shot function for validating a CMAC
\return 0 on success
\param check CMAC value to verify
\param checkSz size of check buffer
\return BAD_FUNC_ARG if parameters are invalid
\return MAC_CMP_FAILED_E if the supplied tag does not match
\param check Expected MAC value to verify
\param checkSz size of expected MAC value; must be in
[\c WC_CMAC_TAG_MIN_SZ, \c WC_AES_BLOCK_SIZE]
\param in input data to process
\param inSz size of input data
\param key key pointer
Expand Down Expand Up @@ -211,10 +214,8 @@ int wc_CMAC_Grow(Cmac* cmac, const byte* in, int inSz);
\ingroup CMAC
\brief Single shot AES-CMAC generation with extended parameters
including heap and device ID.

\return 0 on success
\return BAD_FUNC_ARG if parameters are invalid

\param cmac Pointer to Cmac structure (can be NULL for one-shot)
\param out Buffer to store MAC output
\param outSz Pointer to output size (in/out)
Expand Down Expand Up @@ -249,14 +250,13 @@ int wc_AesCmacGenerate_ex(Cmac *cmac, byte* out, word32* outSz,
\ingroup CMAC
\brief Single shot AES-CMAC verification with extended parameters
including heap and device ID.

\return 0 on success
\return BAD_FUNC_ARG if parameters are invalid
\return MAC_CMP_FAILED_E if MAC verification fails

\param cmac Pointer to Cmac structure (can be NULL for one-shot)
\param cmac Pointer to Cmac structure
\param check Expected MAC value to verify
\param checkSz Size of expected MAC
\param checkSz Size of expected MAC; must be in
[\c WC_CMAC_TAG_MIN_SZ, \c WC_AES_BLOCK_SIZE]
\param in Input data to authenticate
\param inSz Length of input data
\param key AES key
Expand All @@ -267,17 +267,24 @@ int wc_AesCmacGenerate_ex(Cmac *cmac, byte* out, word32* outSz,

_Example_
\code
byte mac[AES_BLOCK_SIZE];
Cmac cmac;
Comment thread
kareem-wolfssl marked this conversation as resolved.
byte mac[WC_AES_BLOCK_SIZE];
byte key[16], msg[64];
int ret;

int ret = wc_AesCmacVerify_ex(NULL, mac, sizeof(mac), msg,
ret = wc_InitCmac_ex(&cmac, key, sizeof(key), WC_CMAC_AES, NULL,
NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_AesCmacVerify_ex(&cmac, mac, sizeof(mac), msg,
sizeof(msg), key, sizeof(key),
NULL, INVALID_DEVID);
}
if (ret == MAC_CMP_FAILED_E) {
// MAC verification failed
}
\endcode

\sa wc_InitCmac_ex
\sa wc_AesCmacVerify
\sa wc_AesCmacGenerate_ex
*/
Expand Down
5 changes: 4 additions & 1 deletion src/tls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -6139,7 +6139,10 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
ssl->options.sendVerify = SEND_BLANK_CERT;
#else
WOLFSSL_MSG("Certificate required but none set on client");
SendAlert(ssl, alert_fatal, illegal_parameter);
/* RFC 8446 Section 4.4.2.4: send certificate_required when a
* peer (here, the client) cannot provide a certificate that the
* other peer required. */
SendAlert(ssl, alert_fatal, certificate_required);
WOLFSSL_ERROR_VERBOSE(NO_CERT_ERROR);
return NO_CERT_ERROR;
#endif
Expand Down
41 changes: 41 additions & 0 deletions tests/api/test_cmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,47 @@ int test_wc_AesCmacGenerate(void)
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_AesCmacVerify(mac, macSz, NULL, msgSz, key, keySz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));

ExpectIntEQ(wc_AesCmacVerify(mac, 1, msg, msgSz, key, keySz),
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_AesCmacVerify(mac, WC_CMAC_TAG_MIN_SZ - 1, msg, msgSz,
key, keySz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
ExpectIntEQ(wc_AesCmacVerify(mac, WC_AES_BLOCK_SIZE + 1, msg, msgSz,
key, keySz), WC_NO_ERR_TRACE(BAD_FUNC_ARG));

/* Truncated tags within the supported range must verify correctly when
* the generator was asked to produce the same length */
{
byte truncMac[WC_AES_BLOCK_SIZE];
word32 truncSz;
word32 lengths[] = { WC_CMAC_TAG_MIN_SZ, 8, WC_AES_BLOCK_SIZE - 1 };
word32 lengthsSz = (word32)(sizeof(lengths)/sizeof(lengths[0]));
word32 li;
Comment thread
kareem-wolfssl marked this conversation as resolved.
for (li = 0; li < lengthsSz; li++) {
XMEMSET(truncMac, 0, sizeof(truncMac));
truncSz = lengths[li];
ExpectIntEQ(wc_AesCmacGenerate(truncMac, &truncSz, msg, msgSz,
key, keySz), 0);
ExpectIntEQ(truncSz, lengths[li]);
ExpectIntEQ(wc_AesCmacVerify(truncMac, truncSz, msg, msgSz,
key, keySz), 0);
/* Flipping a bit in the truncated tag must yield
* MAC_CMP_FAILED_E, not silent success from comparing a too
* short prefix. */
truncMac[0] ^= 0x01;
ExpectIntEQ(wc_AesCmacVerify(truncMac, truncSz, msg, msgSz,
key, keySz), WC_NO_ERR_TRACE(MAC_CMP_FAILED_E));
}
}

/* A full-length tag that does not match must return MAC_CMP_FAILED_E. */
{
byte badMac[WC_AES_BLOCK_SIZE];
XMEMCPY(badMac, mac, WC_AES_BLOCK_SIZE);
badMac[0] ^= 0x01;
ExpectIntEQ(wc_AesCmacVerify(badMac, WC_AES_BLOCK_SIZE, msg, msgSz,
key, keySz), WC_NO_ERR_TRACE(MAC_CMP_FAILED_E));
}
#endif
return EXPECT_RESULT();

Expand Down
23 changes: 16 additions & 7 deletions wolfcrypt/src/cmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,24 +574,32 @@ int wc_AesCmacVerify_ex(Cmac* cmac,
{
int ret = 0;
byte a[WC_AES_BLOCK_SIZE];
word32 aSz = sizeof(a);
word32 aSz;
int compareRet;

if (cmac == NULL || check == NULL || checkSz == 0 ||
(in == NULL && inSz != 0)) {
if (cmac == NULL || check == NULL || checkSz < WC_CMAC_TAG_MIN_SZ ||
checkSz > WC_AES_BLOCK_SIZE || (in == NULL && inSz != 0)) {
return BAD_FUNC_ARG;
}

XMEMSET(a, 0, aSz);
aSz = checkSz;
XMEMSET(a, 0, sizeof(a));
ret = wc_AesCmacGenerate_ex(cmac,
a, &aSz,
in, inSz,
key, keySz,
heap,
devId);
/* aSz is passed by reference to wc_AesCmacGenerate_ex, which on the
* WOLF_CRYPTO_CB path forwards it to a user-supplied callback that may
* write back any value. Reject anything that does not match the user
* provided length. */
if (ret == 0 && aSz != checkSz) {
ret = BAD_STATE_E;
}
if (ret == 0) {
compareRet = ConstantCompare(check, a, (int)min(checkSz, aSz));
ret = compareRet ? 1 : 0;
compareRet = ConstantCompare(check, a, (int)aSz);
ret = compareRet ? MAC_CMP_FAILED_E : 0;
}

return ret;
Expand All @@ -605,7 +613,8 @@ int wc_AesCmacVerify(const byte* check, word32 checkSz,
int ret = 0;
WC_DECLARE_VAR(cmac, Cmac, 1, 0);

if (check == NULL || checkSz == 0 || (in == NULL && inSz > 0) ||
if (check == NULL || checkSz < WC_CMAC_TAG_MIN_SZ ||
checkSz > WC_AES_BLOCK_SIZE || (in == NULL && inSz > 0) ||
key == NULL || keySz == 0) {
return BAD_FUNC_ARG;
}
Expand Down
20 changes: 18 additions & 2 deletions wolfssl/wolfcrypt/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -4202,7 +4202,8 @@ extern void uITRON4_free(void *p) ;
#if defined(HAVE_CURVE25519) && !defined(CURVE25519_SMALL) && \
!defined(FREESCALE_LTC_ECC) && !defined(WOLFSSL_ARMASM) && \
(!defined(USE_INTEL_SPEEDUP) || defined(NO_CURVED25519_X64)) && \
!defined(WOLFSSL_CURVE25519_BLINDING) && !defined(NO_CURVE25519_BLINDING)
!defined(WOLFSSL_CURVE25519_BLINDING) && !defined(NO_CURVE25519_BLINDING) \
&& !defined(WC_NO_RNG)
#define WOLFSSL_CURVE25519_BLINDING
#endif

Expand All @@ -4212,7 +4213,8 @@ extern void uITRON4_free(void *p) ;
#if (defined(USE_FAST_MATH) && !defined(TFM_TIMING_RESISTANT)) || \
(defined(HAVE_ECC) && !defined(ECC_TIMING_RESISTANT)) || \
(!defined(NO_RSA) && !defined(WC_RSA_BLINDING) && !defined(HAVE_FIPS) && \
!defined(WC_NO_RNG))
!defined(WC_NO_RNG) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) && \
!defined(WOLFSSL_RSA_VERIFY_ONLY))

#if !defined(_MSC_VER) && !defined(__TASKING__)
#warning "For timing resistance / side-channel attack prevention consider using harden options"
Expand All @@ -4222,6 +4224,20 @@ extern void uITRON4_free(void *p) ;
#endif
#endif

/* WC_NO_RNG silently removes RSA blinding, as blinding depends on the RNG.
* Refuse to build until the conflict is resolved or the loss of hardening is
* explicitly acknowledged via WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS. */
#if defined(WC_NO_RNG) && ((defined(WC_RSA_BLINDING) && !defined(NO_RSA) && \
!defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
(defined(HAVE_CURVE25519) && defined(WOLFSSL_CURVE25519_BLINDING)) || \
(defined(HAVE_ECC) && defined(WOLFSSL_ECC_BLIND_K))) && \
!defined(WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS)
#error "Blinding is enabled but the RNG is disabled. Either remove \
WC_NO_RNG to enable the RNG, disable blinding by removing WC_RSA_BLINDING/\
WOLFSSL_CURVE25519_BLINDING/WOLFSSL_ECC_BLIND_K, or acknowledge the loss of \
blinding by defining WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS."
#endif
Comment thread
kareem-wolfssl marked this conversation as resolved.

#ifdef OPENSSL_COEXIST
/* make sure old names are disabled */
#ifndef NO_OLD_SSL_NAMES
Expand Down
Loading