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
174 changes: 106 additions & 68 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,41 @@ 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 +213,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 +223,34 @@ 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,41 +294,53 @@ 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 */
}
ret = 0;
#endif
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) {
return BAD_STATE_E;
if (cmac->bufferSz == AES_BLOCK_SIZE) {
subKey = cmac->k1;
}
remainder = AES_BLOCK_SIZE - cmac->bufferSz;
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);
}

if (remainder == 0) {
remainder = AES_BLOCK_SIZE;
cmac->buffer[AES_BLOCK_SIZE - remainder] = 0x80;
subKey = cmac->k2;
}
if (remainder > 1) {
XMEMSET(cmac->buffer + AES_BLOCK_SIZE - remainder, 0, remainder);
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);
}

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;
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */
default :
ret = BAD_FUNC_ARG;
}

return 0;
return ret;
}

int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) {
Expand All @@ -314,7 +353,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 +373,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 @@ -498,5 +535,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 */
32 changes: 29 additions & 3 deletions wolfcrypt/src/cryptocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ static const char* GetAlgoTypeStr(int algo)
case WC_ALGO_TYPE_RNG: return "RNG";
case WC_ALGO_TYPE_SEED: return "Seed";
case WC_ALGO_TYPE_HMAC: return "HMAC";
case WC_ALGO_TYPE_CMAC: return "CMAC";
}
return NULL;
}
Expand All @@ -104,6 +105,7 @@ static const char* GetPkTypeStr(int pk)
}
return NULL;
}
#if !defined(NO_AES) || !defined(NO_DES3)
static const char* GetCipherTypeStr(int cipher)
{
switch (cipher) {
Expand All @@ -119,6 +121,7 @@ static const char* GetCipherTypeStr(int cipher)
}
return NULL;
}
#endif /* !NO_AES || !NO_DES3 */
static const char* GetHashTypeStr(int hash)
{
switch (hash) {
Expand All @@ -141,6 +144,16 @@ static const char* GetHashTypeStr(int hash)
return NULL;
}

#ifdef WOLFSSL_CMAC
static const char* GetCmacTypeStr(int type)
{
switch (type) {
case WC_CMAC_AES: return "AES";
philljj marked this conversation as resolved.
Show resolved Hide resolved
}
return NULL;
}
#endif /* WOLFSSL_CMAC */

#ifndef NO_RSA
static const char* GetRsaType(int type)
{
Expand Down Expand Up @@ -186,12 +199,14 @@ WOLFSSL_API void wc_CryptoCb_InfoString(wc_CryptoInfo* info)
GetPkTypeStr(info->pk.type), info->pk.type);
}
}
#if !defined(NO_AES) || !defined(NO_DES3)
else if (info->algo_type == WC_ALGO_TYPE_CIPHER) {
printf("Crypto CB: %s %s (%d) (%p ctx)\n",
GetAlgoTypeStr(info->algo_type),
GetCipherTypeStr(info->cipher.type),
info->cipher.type, info->cipher.ctx);
}
#endif /* !NO_AES || !NO_DES3 */
else if (info->algo_type == WC_ALGO_TYPE_HASH) {
printf("Crypto CB: %s %s (%d) (%p ctx) %s\n",
GetAlgoTypeStr(info->algo_type),
Expand All @@ -206,6 +221,17 @@ WOLFSSL_API void wc_CryptoCb_InfoString(wc_CryptoInfo* info)
info->hmac.macType, info->hmac.hmac,
(info->hmac.in != NULL) ? "Update" : "Final");
}
#ifdef WOLFSSL_CMAC
else if (info->algo_type == WC_ALGO_TYPE_CMAC) {
printf("Crypto CB: %s %s (%d) (%p ctx) %s %s %s\n",
GetAlgoTypeStr(info->algo_type),
GetCmacTypeStr(info->cmac.type),
info->cmac.type, info->cmac.cmac,
(info->cmac.key != NULL) ? "Init " : "",
(info->cmac.in != NULL) ? "Update " : "",
(info->cmac.out != NULL) ? "Final" : "");
}
#endif
#ifdef WOLF_CRYPTO_CB_CMD
else if (info->algo_type == WC_ALGO_TYPE_NONE) {
printf("Crypto CB: %s %s (%d)\n",
Expand Down Expand Up @@ -1775,7 +1801,8 @@ int wc_CryptoCb_RandomSeed(OS_Seed* os, byte* seed, word32 sz)
return wc_CryptoCb_TranslateErrorCode(ret);
}
#endif /* !WC_NO_RNG */
#ifdef WOLFSSL_CMAC

#if defined(WOLFSSL_CMAC)
int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz,
const byte* in, word32 inSz, byte* out, word32* outSz, int type,
void* ctx)
Expand All @@ -1791,7 +1818,6 @@ int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz,
/* locate first callback and try using it */
dev = wc_CryptoCb_FindDeviceByIndex(0);
}

if (dev && dev->cb) {
wc_CryptoInfo cryptoInfo;
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
Expand All @@ -1812,7 +1838,7 @@ int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz,

return wc_CryptoCb_TranslateErrorCode(ret);
}
#endif
#endif /* WOLFSSL_CMAC && !NO_AES */
philljj marked this conversation as resolved.
Show resolved Hide resolved

/* returns the default dev id for the current build */
int wc_CryptoCb_DefaultDevID(void)
Expand Down
Loading