Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to separate CMAC and AES conditional compiles. Correct update. #8007

Merged
merged 9 commits into from
Sep 25, 2024
197 changes: 122 additions & 75 deletions wolfcrypt/src/cmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#include <wolfssl/wolfcrypt/hash.h>
#endif

#if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
#if defined(WOLFSSL_CMAC)

#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
Expand Down Expand Up @@ -80,7 +80,7 @@ int wc_CMAC_Grow(Cmac* cmac, const byte* in, int inSz)
}
#endif /* WOLFSSL_HASH_KEEP */


#if !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
/* Used by AES-SIV. See aes.c. */
void ShiftAndXorRb(byte* out, byte* in)
{
Expand All @@ -100,6 +100,7 @@ void ShiftAndXorRb(byte* out, byte* in)
}
}
}
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */

/* returns 0 on success */
int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
Expand Down Expand Up @@ -146,30 +147,40 @@ int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
return BAD_FUNC_ARG;
}

ret = wc_AesInit(&cmac->aes, heap, devId);

#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
cmac->useSWCrypt = useSW;
if (cmac->useSWCrypt == 1) {
cmac->aes.useSWCrypt = 1;
}
#endif
switch (type) {
#if !defined (NO_AES) && defined(WOLFSSL_AES_DIRECT)
case WC_CMAC_AES:
cmac->type = WC_CMAC_AES;
ret = wc_AesInit(&cmac->aes, heap, devId);

if (ret == 0) {
ret = wc_AesSetKey(&cmac->aes, key, keySz, NULL, AES_ENCRYPTION);
}
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
cmac->useSWCrypt = useSW;
if (cmac->useSWCrypt == 1) {
cmac->aes.useSWCrypt = 1;
}
#endif

if (ret == 0) {
byte l[AES_BLOCK_SIZE];
if (ret == 0) {
ret = wc_AesSetKey(&cmac->aes, key, keySz, NULL, AES_ENCRYPTION);
}

XMEMSET(l, 0, AES_BLOCK_SIZE);
ret = wc_AesEncryptDirect(&cmac->aes, l, l);
if (ret == 0) {
ShiftAndXorRb(cmac->k1, l);
ShiftAndXorRb(cmac->k2, cmac->k1);
ForceZero(l, AES_BLOCK_SIZE);
byte l[AES_BLOCK_SIZE];

XMEMSET(l, 0, AES_BLOCK_SIZE);
ret = wc_AesEncryptDirect(&cmac->aes, l, l);
if (ret == 0) {
ShiftAndXorRb(cmac->k1, l);
ShiftAndXorRb(cmac->k2, cmac->k1);
ForceZero(l, AES_BLOCK_SIZE);
}
}
break;
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */
default:
return BAD_FUNC_ARG;
}

return ret;
}

Expand Down Expand Up @@ -201,7 +212,7 @@ int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz)
#endif
{
ret = wc_CryptoCb_Cmac(cmac, NULL, 0, in, inSz,
NULL, NULL, 0, NULL);
NULL, NULL, cmac->type, NULL);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
/* fall-through when unavailable */
Expand All @@ -211,26 +222,35 @@ int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz)
/* Clear CRYPTOCB_UNAVAILABLE return code */
ret = 0;

while ((ret == 0) && (inSz != 0)) {
word32 add = min(inSz, AES_BLOCK_SIZE - cmac->bufferSz);
XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);

cmac->bufferSz += add;
in += add;
inSz -= add;

if (cmac->bufferSz == AES_BLOCK_SIZE && inSz != 0) {
if (cmac->totalSz != 0) {
xorbuf(cmac->buffer, cmac->digest, AES_BLOCK_SIZE);
}
ret = wc_AesEncryptDirect(&cmac->aes, cmac->digest, cmac->buffer);
if (ret == 0) {
cmac->totalSz += AES_BLOCK_SIZE;
cmac->bufferSz = 0;
switch (cmac->type) {
#if !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
case WC_CMAC_AES:
{
while ((ret == 0) && (inSz != 0)) {
word32 add = min(inSz, AES_BLOCK_SIZE - cmac->bufferSz);
XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);

cmac->bufferSz += add;
in += add;
inSz -= add;

if (cmac->bufferSz == AES_BLOCK_SIZE && inSz != 0) {
if (cmac->totalSz != 0) {
xorbuf(cmac->buffer, cmac->digest, AES_BLOCK_SIZE);
}
ret = wc_AesEncryptDirect(&cmac->aes, cmac->digest,
cmac->buffer);
if (ret == 0) {
cmac->totalSz += AES_BLOCK_SIZE;
cmac->bufferSz = 0;
}
}
}
}; break;
philljj marked this conversation as resolved.
Show resolved Hide resolved
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */
default:
ret = BAD_FUNC_ARG;
}

return ret;
}

Expand All @@ -244,16 +264,23 @@ int wc_CmacFree(Cmac* cmac)
* wc_CmacFinal() not called. */
XFREE(cmac->msg, cmac->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
wc_AesFree(&cmac->aes);
switch (cmac->type) {
#if !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
case WC_CMAC_AES:
wc_AesFree(&cmac->aes);
break;
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */
default:
/* Nothing to do */
(void)cmac;
}
ForceZero(cmac, sizeof(Cmac));
return 0;
}

int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
{
int ret = 0;
const byte* subKey;
word32 remainder;

if (cmac == NULL || out == NULL || outSz == NULL) {
return BAD_FUNC_ARG;
Expand All @@ -267,44 +294,64 @@ int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
if (cmac->devId != INVALID_DEVID)
#endif
{
ret = wc_CryptoCb_Cmac(cmac, NULL, 0, NULL, 0, out, outSz, 0, NULL);
ret = wc_CryptoCb_Cmac(cmac, NULL, 0, NULL, 0, out, outSz, cmac->type,
NULL);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
/* fall-through when unavailable */
}
#endif

if (cmac->bufferSz == AES_BLOCK_SIZE) {
subKey = cmac->k1;
}
else {
/* ensure we will have a valid remainder value */
if (cmac->bufferSz > AES_BLOCK_SIZE) {
return BAD_STATE_E;
}
remainder = AES_BLOCK_SIZE - cmac->bufferSz;

if (remainder == 0) {
remainder = AES_BLOCK_SIZE;
}
if (remainder > 1) {
XMEMSET(cmac->buffer + AES_BLOCK_SIZE - remainder, 0, remainder);
}
/* Clear CRYPTOCB_UNAVAILABLE return code */
ret = 0;

cmac->buffer[AES_BLOCK_SIZE - remainder] = 0x80;
subKey = cmac->k2;
/* fall-through when unavailable */
}
xorbuf(cmac->buffer, cmac->digest, AES_BLOCK_SIZE);
xorbuf(cmac->buffer, subKey, AES_BLOCK_SIZE);
ret = wc_AesEncryptDirect(&cmac->aes, cmac->digest, cmac->buffer);
#endif
if (ret == 0) {
XMEMCPY(out, cmac->digest, *outSz);
switch (cmac->type) {
#if !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
case WC_CMAC_AES:
{
const byte* subKey;
word32 remainder;

if (cmac->bufferSz == AES_BLOCK_SIZE) {
subKey = cmac->k1;
}
else {
/* ensure we will have a valid remainder value */
if (cmac->bufferSz > AES_BLOCK_SIZE) {
ret = BAD_STATE_E;
break;
}
remainder = AES_BLOCK_SIZE - cmac->bufferSz;

if (remainder == 0) {
remainder = AES_BLOCK_SIZE;
}
if (remainder > 1) {
XMEMSET(cmac->buffer + AES_BLOCK_SIZE - remainder, 0,
remainder);
}

cmac->buffer[AES_BLOCK_SIZE - remainder] = 0x80;
subKey = cmac->k2;
}
xorbuf(cmac->buffer, cmac->digest, AES_BLOCK_SIZE);
xorbuf(cmac->buffer, subKey, AES_BLOCK_SIZE);
ret = wc_AesEncryptDirect(&cmac->aes, cmac->digest, cmac->buffer);
if (ret == 0) {
XMEMCPY(out, cmac->digest, *outSz);
}
}; break;
philljj marked this conversation as resolved.
Show resolved Hide resolved
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */
default:
ret = BAD_FUNC_ARG;
}
}

return 0;
return ret;
}

int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) {
int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz)
{
int ret = 0;

if (cmac == NULL)
Expand All @@ -314,7 +361,7 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) {
return ret;
}


#if !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
int wc_AesCmacGenerate_ex(Cmac* cmac,
byte* out, word32* outSz,
const byte* in, word32 inSz,
Expand All @@ -334,8 +381,6 @@ int wc_AesCmacGenerate_ex(Cmac* cmac,
if (devId != INVALID_DEVID)
#endif
{
cmac->devCtx = NULL;

ret = wc_CryptoCb_Cmac(cmac, key, keySz, in, inSz, out, outSz,
WC_CMAC_AES, NULL);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
Expand Down Expand Up @@ -432,7 +477,8 @@ int wc_AesCmacVerify_ex(Cmac* cmac,
word32 aSz = sizeof(a);
int compareRet;

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

Expand Down Expand Up @@ -498,5 +544,6 @@ int wc_AesCmacVerify(const byte* check, word32 checkSz,

return ret;
}
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */

#endif /* WOLFSSL_CMAC && NO_AES && WOLFSSL_AES_DIRECT */
#endif /* WOLFSSL_CMAC */
Loading