Skip to content
Merged
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
161 changes: 140 additions & 21 deletions wolfcrypt/src/cmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void ShiftAndXorRb(byte* out, byte* in)
int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
int type, void* unused, void* heap, int devId)
{
int ret;
int ret = 0;
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
byte useSW = 0;
#endif
Expand Down Expand Up @@ -196,10 +196,12 @@ int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz)
if (ret != CRYPTOCB_UNAVAILABLE)
return ret;
/* fall-through when unavailable */
ret = 0; /* reset error code */
}
#endif

/* Clear CRYPTOCB_UNAVAILABLE return code */
ret = 0;

while (inSz != 0) {
word32 add = min(inSz, AES_BLOCK_SIZE - cmac->bufferSz);
XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);
Expand Down Expand Up @@ -242,7 +244,7 @@ int wc_CmacFree(Cmac* cmac)

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

Expand Down Expand Up @@ -296,7 +298,7 @@ int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
}

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

if (cmac == NULL)
return BAD_FUNC_ARG;
Expand All @@ -305,11 +307,70 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) {
return ret;
}


int wc_AesCmacGenerate_ex(Cmac* cmac,
byte* out, word32* outSz,
const byte* in, word32 inSz,
const byte* key, word32 keySz,
void* heap, int devId)
{
int ret = 0;

if (cmac == NULL) {
return BAD_FUNC_ARG;
}

#ifdef WOLF_CRYPTO_CB
/* Set devId regardless of value (invalid or not) */
cmac->devId = devId;
#ifndef WOLF_CRYPTO_CB_FIND
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 != CRYPTOCB_UNAVAILABLE)
return ret;

/* Clear CRYPTOCB_UNAVAILABLE return code */
ret = 0;

/* fall-through when unavailable */
}
#endif

if ( ((out == NULL) && (outSz != NULL) && (*outSz > 0))
|| (in == NULL && inSz > 0)
|| (key == NULL && keySz > 0)) {
return BAD_FUNC_ARG;
}

/* Init step is optional */
if (key != NULL) {
ret = wc_InitCmac_ex(cmac, key, keySz, WC_CMAC_AES, NULL, heap, devId);
}
if (ret == 0) {
ret = wc_CmacUpdate(cmac, in, inSz);
/* Ensure we are freed and zeroed if not calling wc_CmacFinal */
if (ret != 0) {
Comment thread
billphipps marked this conversation as resolved.
Outdated
(void)wc_CmacFree(cmac);
}
}
if (ret == 0) {
ret = wc_CmacFinal(cmac, out, outSz);
}

return ret;
}


int wc_AesCmacGenerate(byte* out, word32* outSz,
const byte* in, word32 inSz,
const byte* key, word32 keySz)
{
int ret;
int ret = 0;
#ifdef WOLFSSL_SMALL_STACK
Cmac *cmac;
#else
Expand All @@ -326,21 +387,22 @@ int wc_AesCmacGenerate(byte* out, word32* outSz,
return MEMORY_E;
}
#endif

#ifdef WOLFSSL_CHECK_MEM_ZERO
XMEMSET(((unsigned char *)cmac) + sizeof(Aes), 0xff,
Comment thread
bigbrett marked this conversation as resolved.
Outdated
sizeof(Cmac) - sizeof(Aes));
/* Aes part is checked by wc_AesFree. */
wc_MemZero_Add("wc_AesCmacGenerate cmac",
wc_MemZero_Add("wc_AesCmacGenerate_ex cmac",
((unsigned char *)cmac) + sizeof(Aes), sizeof(Cmac) - sizeof(Aes));
#endif

ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
if (ret == 0) {
ret = wc_CmacUpdate(cmac, in, inSz);
}
if (ret == 0) {
ret = wc_CmacFinal(cmac, out, outSz);
}
ret = wc_AesCmacGenerate_ex(cmac,
out, outSz,
in, inSz,
key, keySz,
NULL,
INVALID_DEVID);


#ifdef WOLFSSL_SMALL_STACK
if (cmac) {
Expand All @@ -354,28 +416,85 @@ int wc_AesCmacGenerate(byte* out, word32* outSz,
}


int wc_AesCmacVerify(const byte* check, word32 checkSz,
const byte* in, word32 inSz,
const byte* key, word32 keySz)
int wc_AesCmacVerify_ex(Cmac* cmac,
const byte* check, word32 checkSz,
const byte* in, word32 inSz,
const byte* key, word32 keySz,
void* heap, int devId)
{
int ret;
int ret = 0;
byte a[AES_BLOCK_SIZE];
word32 aSz = sizeof(a);
int compareRet;

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

XMEMSET(a, 0, aSz);
ret = wc_AesCmacGenerate(a, &aSz, in, inSz, key, keySz);
compareRet = ConstantCompare(check, a, (int)min(checkSz, aSz));
ret = wc_AesCmacGenerate_ex(cmac,
a, &aSz,
in, inSz,
key, keySz,
heap,
devId);
if (ret == 0) {
compareRet = ConstantCompare(check, a, (int)min(checkSz, aSz));
}

if (ret == 0)
ret = compareRet ? 1 : 0;

return ret;
}


int wc_AesCmacVerify(const byte* check, word32 checkSz,
const byte* in, word32 inSz,
const byte* key, word32 keySz)
{
int ret = 0;
#ifdef WOLFSSL_SMALL_STACK
Cmac *cmac;
#else
Cmac cmac[1];
#endif

if (check == NULL || (in == NULL && inSz > 0) || key == NULL || keySz == 0) {
return BAD_FUNC_ARG;
}

#ifdef WOLFSSL_SMALL_STACK
if ((cmac = (Cmac *)XMALLOC(sizeof *cmac, NULL,
DYNAMIC_TYPE_CMAC)) == NULL) {
return MEMORY_E;
}
#endif

#ifdef WOLFSSL_CHECK_MEM_ZERO
XMEMSET(((unsigned char *)cmac) + sizeof(Aes), 0xff,
sizeof(Cmac) - sizeof(Aes));
/* Aes part is checked by wc_AesFree. */
wc_MemZero_Add("wc_AesCmacGenerate_ex cmac",
((unsigned char *)cmac) + sizeof(Aes), sizeof(Cmac) - sizeof(Aes));
#endif

ret = wc_AesCmacVerify_ex(cmac,
check, checkSz,
in, inSz,
key, keySz,
NULL,
INVALID_DEVID);

#ifdef WOLFSSL_SMALL_STACK
if (cmac) {
XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
}
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
wc_MemZero_Check(cmac, sizeof(Cmac));
#endif

return ret;
}

#endif /* WOLFSSL_CMAC && NO_AES && WOLFSSL_AES_DIRECT */
69 changes: 69 additions & 0 deletions wolfcrypt/test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -39968,16 +39968,42 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cmac_test(void)

XMEMSET(tag, 0, sizeof(tag));
tagSz = sizeof(tag);
#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)
Comment thread
bigbrett marked this conversation as resolved.
Outdated
ret = wc_AesCmacGenerate_ex(cmac, tag, &tagSz, tc->m, tc->mSz,
tc->k, tc->kSz, NULL, devId);
#else
ret = wc_AesCmacGenerate(tag, &tagSz, tc->m, tc->mSz,
tc->k, tc->kSz);
#endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
if (XMEMCMP(tag, tc->t, AES_BLOCK_SIZE) != 0)
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)
ret = wc_AesCmacVerify_ex(cmac, tc->t, tc->tSz, tc->m, tc->mSz,
tc->k, tc->kSz, HEAP_HINT, devId);
#else
ret = wc_AesCmacVerify(tc->t, tc->tSz, tc->m, tc->mSz,
tc->k, tc->kSz);
#endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);

#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)
/* Test that keyless generate with init is the same */
Comment thread
bigbrett marked this conversation as resolved.
Outdated
XMEMSET(tag, 0, sizeof(tag));
tagSz = sizeof(tag);
ret = wc_InitCmac_ex(cmac, tc->k, tc->kSz, tc->type, NULL, HEAP_HINT, devId);
if (ret != 0) {
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
}
ret = wc_AesCmacGenerate_ex(cmac, tag, &tagSz, tc->m, tc->mSz,
NULL, 0, HEAP_HINT, devId);
Comment thread
bigbrett marked this conversation as resolved.
Outdated
if (ret != 0) {
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
}
#endif

}

ret = 0;
Expand Down Expand Up @@ -49368,6 +49394,49 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
info->hmac.hmac->devId = devIdArg;
}
#endif
#if defined(WOLFSSL_CMAC) && !defined(NO_AES)
else if (info->algo_type == WC_ALGO_TYPE_CMAC) {
if (info->cmac.cmac == NULL) {
return NOT_COMPILED_IN;
Comment thread
billphipps marked this conversation as resolved.
Outdated
}

/* set devId to invalid so software is used */
info->cmac.cmac->devId = INVALID_DEVID;

/* Handle one-shot cases */
Comment thread
billphipps marked this conversation as resolved.
Outdated
if (info->cmac.key != NULL && info->cmac.in != NULL
&& info->cmac.out != NULL) {
ret = wc_AesCmacGenerate(info->cmac.out,
info->cmac.outSz,
info->cmac.in,
info->cmac.inSz,
info->cmac.key,
info->cmac.keySz);
/* Sequentially handle incremental cases */
} else {
if (info->cmac.key != NULL) {
ret = wc_InitCmac(info->cmac.cmac,
info->cmac.key,
info->cmac.keySz,
info->cmac.type,
NULL);
}
if ((ret == 0) && (info->cmac.in != NULL)) {
ret = wc_CmacUpdate(info->cmac.cmac,
info->cmac.in,
info->cmac.inSz);
}
if ((ret ==0) && (info->cmac.out != NULL)) {
ret = wc_CmacFinal(info->cmac.cmac,
info->cmac.out,
info->cmac.outSz);
}
}

/* reset devId */
info->cmac.cmac->devId = devIdArg;
}
#endif /* WOLFSSL_CMAC && !(NO_AES) && WOLFSSL_AES_DIRECT */

(void)devIdArg;
(void)myCtx;
Expand Down
14 changes: 14 additions & 0 deletions wolfssl/wolfcrypt/cmac.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,25 @@ WOLFSSL_API
int wc_AesCmacGenerate(byte* out, word32* outSz,
const byte* in, word32 inSz,
const byte* key, word32 keySz);
WOLFSSL_API
int wc_AesCmacGenerate_ex(Cmac *cmac,
byte* out, word32* outSz,
const byte* in, word32 inSz,
const byte* key, word32 keySz,
void* heap,
int devId);

WOLFSSL_API
int wc_AesCmacVerify(const byte* check, word32 checkSz,
const byte* in, word32 inSz,
const byte* key, word32 keySz);
WOLFSSL_API
int wc_AesCmacVerify_ex(Cmac* cmac,
const byte* check, word32 checkSz,
const byte* in, word32 inSz,
const byte* key, word32 keySz,
void* heap,
int devId);

WOLFSSL_LOCAL
void ShiftAndXorRb(byte* out, byte* in);
Comment thread
bigbrett marked this conversation as resolved.
Outdated
Expand Down