mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #7059 from bigbrett/cryptocb-oneshot-cmac
Add cryptoCb hook to one-shot CMAC functionspull/7132/head
commit
7a77d64d56
|
@ -96,7 +96,7 @@ void ShiftAndXorRb(byte* out, byte* in)
|
||||||
int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
|
int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
|
||||||
int type, void* unused, void* heap, int devId)
|
int type, void* unused, void* heap, int devId)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
|
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
|
||||||
byte useSW = 0;
|
byte useSW = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -196,10 +196,12 @@ int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz)
|
||||||
if (ret != CRYPTOCB_UNAVAILABLE)
|
if (ret != CRYPTOCB_UNAVAILABLE)
|
||||||
return ret;
|
return ret;
|
||||||
/* fall-through when unavailable */
|
/* fall-through when unavailable */
|
||||||
ret = 0; /* reset error code */
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Clear CRYPTOCB_UNAVAILABLE return code */
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
while (inSz != 0) {
|
while (inSz != 0) {
|
||||||
word32 add = min(inSz, AES_BLOCK_SIZE - cmac->bufferSz);
|
word32 add = min(inSz, AES_BLOCK_SIZE - cmac->bufferSz);
|
||||||
XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);
|
XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);
|
||||||
|
@ -242,7 +244,7 @@ int wc_CmacFree(Cmac* cmac)
|
||||||
|
|
||||||
int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
|
int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
const byte* subKey;
|
const byte* subKey;
|
||||||
word32 remainder;
|
word32 remainder;
|
||||||
|
|
||||||
|
@ -296,7 +298,7 @@ int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
|
||||||
}
|
}
|
||||||
|
|
||||||
int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) {
|
int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) {
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
if (cmac == NULL)
|
if (cmac == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
@ -305,11 +307,70 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) {
|
||||||
return ret;
|
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) {
|
||||||
|
(void)wc_CmacFree(cmac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_CmacFinal(cmac, out, outSz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int wc_AesCmacGenerate(byte* out, word32* outSz,
|
int wc_AesCmacGenerate(byte* out, word32* outSz,
|
||||||
const byte* in, word32 inSz,
|
const byte* in, word32 inSz,
|
||||||
const byte* key, word32 keySz)
|
const byte* key, word32 keySz)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
Cmac *cmac;
|
Cmac *cmac;
|
||||||
#else
|
#else
|
||||||
|
@ -326,21 +387,22 @@ int wc_AesCmacGenerate(byte* out, word32* outSz,
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
#ifdef WOLFSSL_CHECK_MEM_ZERO
|
||||||
XMEMSET(((unsigned char *)cmac) + sizeof(Aes), 0xff,
|
XMEMSET(((unsigned char *)cmac) + sizeof(Aes), 0xff,
|
||||||
sizeof(Cmac) - sizeof(Aes));
|
sizeof(Cmac) - sizeof(Aes));
|
||||||
/* Aes part is checked by wc_AesFree. */
|
/* 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));
|
((unsigned char *)cmac) + sizeof(Aes), sizeof(Cmac) - sizeof(Aes));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
|
ret = wc_AesCmacGenerate_ex(cmac,
|
||||||
if (ret == 0) {
|
out, outSz,
|
||||||
ret = wc_CmacUpdate(cmac, in, inSz);
|
in, inSz,
|
||||||
}
|
key, keySz,
|
||||||
if (ret == 0) {
|
NULL,
|
||||||
ret = wc_CmacFinal(cmac, out, outSz);
|
INVALID_DEVID);
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
if (cmac) {
|
if (cmac) {
|
||||||
|
@ -354,23 +416,31 @@ int wc_AesCmacGenerate(byte* out, word32* outSz,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int wc_AesCmacVerify(const byte* check, word32 checkSz,
|
int wc_AesCmacVerify_ex(Cmac* cmac,
|
||||||
const byte* in, word32 inSz,
|
const byte* check, word32 checkSz,
|
||||||
const byte* key, word32 keySz)
|
const byte* in, word32 inSz,
|
||||||
|
const byte* key, word32 keySz,
|
||||||
|
void* heap, int devId)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
byte a[AES_BLOCK_SIZE];
|
byte a[AES_BLOCK_SIZE];
|
||||||
word32 aSz = sizeof(a);
|
word32 aSz = sizeof(a);
|
||||||
int compareRet;
|
int compareRet;
|
||||||
|
|
||||||
if (check == NULL || checkSz == 0 || (in == NULL && inSz != 0) ||
|
if (cmac == NULL || check == NULL || checkSz == 0 || (in == NULL && inSz != 0)) {
|
||||||
key == NULL || keySz == 0) {
|
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMEMSET(a, 0, aSz);
|
XMEMSET(a, 0, aSz);
|
||||||
ret = wc_AesCmacGenerate(a, &aSz, in, inSz, key, keySz);
|
ret = wc_AesCmacGenerate_ex(cmac,
|
||||||
compareRet = ConstantCompare(check, a, (int)min(checkSz, aSz));
|
a, &aSz,
|
||||||
|
in, inSz,
|
||||||
|
key, keySz,
|
||||||
|
heap,
|
||||||
|
devId);
|
||||||
|
if (ret == 0) {
|
||||||
|
compareRet = ConstantCompare(check, a, (int)min(checkSz, aSz));
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = compareRet ? 1 : 0;
|
ret = compareRet ? 1 : 0;
|
||||||
|
@ -378,4 +448,53 @@ int wc_AesCmacVerify(const byte* check, word32 checkSz,
|
||||||
return ret;
|
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 */
|
#endif /* WOLFSSL_CMAC && NO_AES && WOLFSSL_AES_DIRECT */
|
||||||
|
|
|
@ -39967,16 +39967,42 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cmac_test(void)
|
||||||
|
|
||||||
XMEMSET(tag, 0, sizeof(tag));
|
XMEMSET(tag, 0, sizeof(tag));
|
||||||
tagSz = sizeof(tag);
|
tagSz = sizeof(tag);
|
||||||
|
#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)
|
||||||
|
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,
|
ret = wc_AesCmacGenerate(tag, &tagSz, tc->m, tc->mSz,
|
||||||
tc->k, tc->kSz);
|
tc->k, tc->kSz);
|
||||||
|
#endif
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||||
if (XMEMCMP(tag, tc->t, AES_BLOCK_SIZE) != 0)
|
if (XMEMCMP(tag, tc->t, AES_BLOCK_SIZE) != 0)
|
||||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
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,
|
ret = wc_AesCmacVerify(tc->t, tc->tSz, tc->m, tc->mSz,
|
||||||
tc->k, tc->kSz);
|
tc->k, tc->kSz);
|
||||||
|
#endif
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
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 */
|
||||||
|
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);
|
||||||
|
if (ret != 0) {
|
||||||
|
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -49428,6 +49454,49 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
||||||
info->hmac.hmac->devId = devIdArg;
|
info->hmac.hmac->devId = devIdArg;
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set devId to invalid so software is used */
|
||||||
|
info->cmac.cmac->devId = INVALID_DEVID;
|
||||||
|
|
||||||
|
/* Handle one-shot cases */
|
||||||
|
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)devIdArg;
|
||||||
(void)myCtx;
|
(void)myCtx;
|
||||||
|
|
|
@ -111,11 +111,25 @@ WOLFSSL_API
|
||||||
int wc_AesCmacGenerate(byte* out, word32* outSz,
|
int wc_AesCmacGenerate(byte* out, word32* outSz,
|
||||||
const byte* in, word32 inSz,
|
const byte* in, word32 inSz,
|
||||||
const byte* key, word32 keySz);
|
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
|
WOLFSSL_API
|
||||||
int wc_AesCmacVerify(const byte* check, word32 checkSz,
|
int wc_AesCmacVerify(const byte* check, word32 checkSz,
|
||||||
const byte* in, word32 inSz,
|
const byte* in, word32 inSz,
|
||||||
const byte* key, word32 keySz);
|
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
|
WOLFSSL_LOCAL
|
||||||
void ShiftAndXorRb(byte* out, byte* in);
|
void ShiftAndXorRb(byte* out, byte* in);
|
||||||
|
|
Loading…
Reference in New Issue