Merge pull request #8007 from billphipps/fix_cmac_cryptocb

Update to separate CMAC and AES conditional compiles.  Correct update.
pull/8021/head
Brett Nicholas 2024-09-25 08:43:27 -06:00 committed by GitHub
commit 7592241a46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 174 additions and 86 deletions

View File

@ -32,7 +32,7 @@
#include <wolfssl/wolfcrypt/hash.h> #include <wolfssl/wolfcrypt/hash.h>
#endif #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) #if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
@ -80,7 +80,7 @@ int wc_CMAC_Grow(Cmac* cmac, const byte* in, int inSz)
} }
#endif /* WOLFSSL_HASH_KEEP */ #endif /* WOLFSSL_HASH_KEEP */
#if !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
/* Used by AES-SIV. See aes.c. */ /* Used by AES-SIV. See aes.c. */
void ShiftAndXorRb(byte* out, byte* in) void ShiftAndXorRb(byte* out, byte* in)
{ {
@ -100,6 +100,7 @@ void ShiftAndXorRb(byte* out, byte* in)
} }
} }
} }
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */
/* returns 0 on success */ /* returns 0 on success */
int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz, int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
@ -146,6 +147,10 @@ int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
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); ret = wc_AesInit(&cmac->aes, heap, devId);
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT) #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
@ -170,6 +175,12 @@ int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
ForceZero(l, AES_BLOCK_SIZE); ForceZero(l, AES_BLOCK_SIZE);
} }
} }
break;
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */
default:
return BAD_FUNC_ARG;
}
return ret; return ret;
} }
@ -201,7 +212,7 @@ int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz)
#endif #endif
{ {
ret = wc_CryptoCb_Cmac(cmac, NULL, 0, in, inSz, 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)) if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret; return ret;
/* fall-through when unavailable */ /* fall-through when unavailable */
@ -211,6 +222,10 @@ int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz)
/* Clear CRYPTOCB_UNAVAILABLE return code */ /* Clear CRYPTOCB_UNAVAILABLE return code */
ret = 0; ret = 0;
switch (cmac->type) {
#if !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
case WC_CMAC_AES:
{
while ((ret == 0) && (inSz != 0)) { while ((ret == 0) && (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);
@ -223,14 +238,19 @@ int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz)
if (cmac->totalSz != 0) { if (cmac->totalSz != 0) {
xorbuf(cmac->buffer, cmac->digest, AES_BLOCK_SIZE); xorbuf(cmac->buffer, cmac->digest, AES_BLOCK_SIZE);
} }
ret = wc_AesEncryptDirect(&cmac->aes, cmac->digest, cmac->buffer); ret = wc_AesEncryptDirect(&cmac->aes, cmac->digest,
cmac->buffer);
if (ret == 0) { if (ret == 0) {
cmac->totalSz += AES_BLOCK_SIZE; cmac->totalSz += AES_BLOCK_SIZE;
cmac->bufferSz = 0; cmac->bufferSz = 0;
} }
} }
} }
}; break;
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */
default:
ret = BAD_FUNC_ARG;
}
return ret; return ret;
} }
@ -244,7 +264,16 @@ int wc_CmacFree(Cmac* cmac)
* wc_CmacFinal() not called. */ * wc_CmacFinal() not called. */
XFREE(cmac->msg, cmac->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(cmac->msg, cmac->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif #endif
switch (cmac->type) {
#if !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
case WC_CMAC_AES:
wc_AesFree(&cmac->aes); wc_AesFree(&cmac->aes);
break;
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */
default:
/* Nothing to do */
(void)cmac;
}
ForceZero(cmac, sizeof(Cmac)); ForceZero(cmac, sizeof(Cmac));
return 0; return 0;
} }
@ -252,8 +281,6 @@ 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 = 0; int ret = 0;
const byte* subKey;
word32 remainder;
if (cmac == NULL || out == NULL || outSz == NULL) { if (cmac == NULL || out == NULL || outSz == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
@ -267,12 +294,24 @@ int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
if (cmac->devId != INVALID_DEVID) if (cmac->devId != INVALID_DEVID)
#endif #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)) if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret; return ret;
/* Clear CRYPTOCB_UNAVAILABLE return code */
ret = 0;
/* fall-through when unavailable */ /* fall-through when unavailable */
} }
#endif #endif
if (ret == 0) {
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) { if (cmac->bufferSz == AES_BLOCK_SIZE) {
subKey = cmac->k1; subKey = cmac->k1;
@ -280,7 +319,8 @@ int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
else { else {
/* ensure we will have a valid remainder value */ /* ensure we will have a valid remainder value */
if (cmac->bufferSz > AES_BLOCK_SIZE) { if (cmac->bufferSz > AES_BLOCK_SIZE) {
return BAD_STATE_E; ret = BAD_STATE_E;
break;
} }
remainder = AES_BLOCK_SIZE - cmac->bufferSz; remainder = AES_BLOCK_SIZE - cmac->bufferSz;
@ -288,7 +328,8 @@ int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
remainder = AES_BLOCK_SIZE; remainder = AES_BLOCK_SIZE;
} }
if (remainder > 1) { if (remainder > 1) {
XMEMSET(cmac->buffer + AES_BLOCK_SIZE - remainder, 0, remainder); XMEMSET(cmac->buffer + AES_BLOCK_SIZE - remainder, 0,
remainder);
} }
cmac->buffer[AES_BLOCK_SIZE - remainder] = 0x80; cmac->buffer[AES_BLOCK_SIZE - remainder] = 0x80;
@ -300,11 +341,17 @@ int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
if (ret == 0) { if (ret == 0) {
XMEMCPY(out, cmac->digest, *outSz); XMEMCPY(out, cmac->digest, *outSz);
} }
}; break;
return 0; #endif /* !NO_AES && WOLFSSL_AES_DIRECT */
default:
ret = BAD_FUNC_ARG;
}
}
return ret;
} }
int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) { int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz)
{
int ret = 0; int ret = 0;
if (cmac == NULL) if (cmac == NULL)
@ -314,7 +361,7 @@ int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) {
return ret; return ret;
} }
#if !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT)
int wc_AesCmacGenerate_ex(Cmac* cmac, int wc_AesCmacGenerate_ex(Cmac* cmac,
byte* out, word32* outSz, byte* out, word32* outSz,
const byte* in, word32 inSz, const byte* in, word32 inSz,
@ -334,8 +381,6 @@ int wc_AesCmacGenerate_ex(Cmac* cmac,
if (devId != INVALID_DEVID) if (devId != INVALID_DEVID)
#endif #endif
{ {
cmac->devCtx = NULL;
ret = wc_CryptoCb_Cmac(cmac, key, keySz, in, inSz, out, outSz, ret = wc_CryptoCb_Cmac(cmac, key, keySz, in, inSz, out, outSz,
WC_CMAC_AES, NULL); WC_CMAC_AES, NULL);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
@ -432,7 +477,8 @@ int wc_AesCmacVerify_ex(Cmac* cmac,
word32 aSz = sizeof(a); word32 aSz = sizeof(a);
int compareRet; 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; return BAD_FUNC_ARG;
} }
@ -498,5 +544,6 @@ int wc_AesCmacVerify(const byte* check, word32 checkSz,
return ret; return ret;
} }
#endif /* !NO_AES && WOLFSSL_AES_DIRECT */
#endif /* WOLFSSL_CMAC && NO_AES && WOLFSSL_AES_DIRECT */ #endif /* WOLFSSL_CMAC */

View File

@ -84,6 +84,7 @@ static const char* GetAlgoTypeStr(int algo)
case WC_ALGO_TYPE_RNG: return "RNG"; case WC_ALGO_TYPE_RNG: return "RNG";
case WC_ALGO_TYPE_SEED: return "Seed"; case WC_ALGO_TYPE_SEED: return "Seed";
case WC_ALGO_TYPE_HMAC: return "HMAC"; case WC_ALGO_TYPE_HMAC: return "HMAC";
case WC_ALGO_TYPE_CMAC: return "CMAC";
} }
return NULL; return NULL;
} }
@ -103,6 +104,7 @@ static const char* GetPkTypeStr(int pk)
} }
return NULL; return NULL;
} }
#if !defined(NO_AES) || !defined(NO_DES3)
static const char* GetCipherTypeStr(int cipher) static const char* GetCipherTypeStr(int cipher)
{ {
switch (cipher) { switch (cipher) {
@ -118,6 +120,7 @@ static const char* GetCipherTypeStr(int cipher)
} }
return NULL; return NULL;
} }
#endif /* !NO_AES || !NO_DES3 */
static const char* GetHashTypeStr(int hash) static const char* GetHashTypeStr(int hash)
{ {
switch (hash) { switch (hash) {
@ -140,6 +143,16 @@ static const char* GetHashTypeStr(int hash)
return NULL; return NULL;
} }
#ifdef WOLFSSL_CMAC
static const char* GetCmacTypeStr(int type)
{
switch (type) {
case WC_CMAC_AES: return "AES";
}
return NULL;
}
#endif /* WOLFSSL_CMAC */
#ifndef NO_RSA #ifndef NO_RSA
static const char* GetRsaType(int type) static const char* GetRsaType(int type)
{ {
@ -185,12 +198,14 @@ WOLFSSL_API void wc_CryptoCb_InfoString(wc_CryptoInfo* info)
GetPkTypeStr(info->pk.type), info->pk.type); GetPkTypeStr(info->pk.type), info->pk.type);
} }
} }
#if !defined(NO_AES) || !defined(NO_DES3)
else if (info->algo_type == WC_ALGO_TYPE_CIPHER) { else if (info->algo_type == WC_ALGO_TYPE_CIPHER) {
printf("Crypto CB: %s %s (%d) (%p ctx)\n", printf("Crypto CB: %s %s (%d) (%p ctx)\n",
GetAlgoTypeStr(info->algo_type), GetAlgoTypeStr(info->algo_type),
GetCipherTypeStr(info->cipher.type), GetCipherTypeStr(info->cipher.type),
info->cipher.type, info->cipher.ctx); info->cipher.type, info->cipher.ctx);
} }
#endif /* !NO_AES || !NO_DES3 */
else if (info->algo_type == WC_ALGO_TYPE_HASH) { else if (info->algo_type == WC_ALGO_TYPE_HASH) {
printf("Crypto CB: %s %s (%d) (%p ctx) %s\n", printf("Crypto CB: %s %s (%d) (%p ctx) %s\n",
GetAlgoTypeStr(info->algo_type), GetAlgoTypeStr(info->algo_type),
@ -205,6 +220,17 @@ WOLFSSL_API void wc_CryptoCb_InfoString(wc_CryptoInfo* info)
info->hmac.macType, info->hmac.hmac, info->hmac.macType, info->hmac.hmac,
(info->hmac.in != NULL) ? "Update" : "Final"); (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 #ifdef WOLF_CRYPTO_CB_CMD
else if (info->algo_type == WC_ALGO_TYPE_NONE) { else if (info->algo_type == WC_ALGO_TYPE_NONE) {
printf("Crypto CB: %s %s (%d)\n", printf("Crypto CB: %s %s (%d)\n",
@ -1774,7 +1800,8 @@ int wc_CryptoCb_RandomSeed(OS_Seed* os, byte* seed, word32 sz)
return wc_CryptoCb_TranslateErrorCode(ret); return wc_CryptoCb_TranslateErrorCode(ret);
} }
#endif /* !WC_NO_RNG */ #endif /* !WC_NO_RNG */
#ifdef WOLFSSL_CMAC
#if defined(WOLFSSL_CMAC)
int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz, int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz,
const byte* in, word32 inSz, byte* out, word32* outSz, int type, const byte* in, word32 inSz, byte* out, word32* outSz, int type,
void* ctx) void* ctx)
@ -1790,7 +1817,6 @@ int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz,
/* locate first callback and try using it */ /* locate first callback and try using it */
dev = wc_CryptoCb_FindDeviceByIndex(0); dev = wc_CryptoCb_FindDeviceByIndex(0);
} }
if (dev && dev->cb) { if (dev && dev->cb) {
wc_CryptoInfo cryptoInfo; wc_CryptoInfo cryptoInfo;
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
@ -1811,7 +1837,7 @@ int wc_CryptoCb_Cmac(Cmac* cmac, const byte* key, word32 keySz,
return wc_CryptoCb_TranslateErrorCode(ret); return wc_CryptoCb_TranslateErrorCode(ret);
} }
#endif #endif /* WOLFSSL_CMAC */
/* returns the default dev id for the current build */ /* returns the default dev id for the current build */
int wc_CryptoCb_DefaultDevID(void) int wc_CryptoCb_DefaultDevID(void)

View File

@ -24,9 +24,12 @@
#define WOLF_CRYPT_CMAC_H #define WOLF_CRYPT_CMAC_H
#include <wolfssl/wolfcrypt/types.h> #include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/aes.h>
#if !defined(NO_AES) && defined(WOLFSSL_CMAC) #ifdef WOLFSSL_CMAC
#ifndef NO_AES
#include <wolfssl/wolfcrypt/aes.h>
#endif
#if defined(HAVE_FIPS) && \ #if defined(HAVE_FIPS) && \
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
@ -40,16 +43,22 @@
/* avoid redefinition of structs */ /* avoid redefinition of structs */
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(2,0,0) #if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(2,0,0)
typedef enum CmacType {
WC_CMAC_AES = 1
} CmacType;
#ifndef WC_CMAC_TYPE_DEFINED #ifndef WC_CMAC_TYPE_DEFINED
typedef struct Cmac Cmac; typedef struct Cmac Cmac;
#define WC_CMAC_TYPE_DEFINED #define WC_CMAC_TYPE_DEFINED
#endif #endif
struct Cmac { struct Cmac {
#ifndef NO_AES
Aes aes; Aes aes;
byte buffer[AES_BLOCK_SIZE]; /* partially stored block */ byte buffer[AES_BLOCK_SIZE]; /* partially stored block */
byte digest[AES_BLOCK_SIZE]; /* running digest */ byte digest[AES_BLOCK_SIZE]; /* running digest */
byte k1[AES_BLOCK_SIZE]; byte k1[AES_BLOCK_SIZE];
byte k2[AES_BLOCK_SIZE]; byte k2[AES_BLOCK_SIZE];
#endif
word32 bufferSz; word32 bufferSz;
word32 totalSz; word32 totalSz;
#ifdef WOLF_CRYPTO_CB #ifdef WOLF_CRYPTO_CB
@ -70,16 +79,20 @@ struct Cmac {
#ifdef WOLFSSL_SE050 #ifdef WOLFSSL_SE050
byte useSWCrypt; /* Use SW crypt instead of SE050, before SCP03 auth */ byte useSWCrypt; /* Use SW crypt instead of SE050, before SCP03 auth */
#endif #endif
CmacType type;
}; };
typedef enum CmacType {
WC_CMAC_AES = 1
} CmacType;
#ifndef NO_AES
#define WC_CMAC_TAG_MAX_SZ AES_BLOCK_SIZE #define WC_CMAC_TAG_MAX_SZ AES_BLOCK_SIZE
#define WC_CMAC_TAG_MIN_SZ (AES_BLOCK_SIZE/4) #define WC_CMAC_TAG_MIN_SZ (AES_BLOCK_SIZE/4)
#else
/* Reasonable defaults */
#define WC_CMAC_TAG_MAX_SZ 16
#define WC_CMAC_TAG_MIN_SZ 4
#endif
#if FIPS_VERSION3_GE(6,0,0) #if FIPS_VERSION3_GE(6,0,0)
extern const unsigned int wolfCrypt_FIPS_cmac_ro_sanity[2]; extern const unsigned int wolfCrypt_FIPS_cmac_ro_sanity[2];
@ -111,6 +124,7 @@ int wc_CmacFinal(Cmac* cmac,
WOLFSSL_API WOLFSSL_API
int wc_CmacFree(Cmac* cmac); int wc_CmacFree(Cmac* cmac);
#ifndef NO_AES
WOLFSSL_API 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,
@ -134,10 +148,11 @@ int wc_AesCmacVerify_ex(Cmac* cmac,
const byte* key, word32 keySz, const byte* key, word32 keySz,
void* heap, void* heap,
int devId); int devId);
WOLFSSL_LOCAL WOLFSSL_LOCAL
void ShiftAndXorRb(byte* out, byte* in); void ShiftAndXorRb(byte* out, byte* in);
#endif /* !NO_AES */
#ifdef WOLFSSL_HASH_KEEP #ifdef WOLFSSL_HASH_KEEP
WOLFSSL_API WOLFSSL_API
int wc_CMAC_Grow(Cmac* cmac, const byte* in, int inSz); int wc_CMAC_Grow(Cmac* cmac, const byte* in, int inSz);
@ -148,6 +163,6 @@ int wc_CMAC_Grow(Cmac* cmac, const byte* in, int inSz);
#endif #endif
#endif /* NO_AES && WOLFSSL_CMAC */ #endif /* WOLFSSL_CMAC */
#endif /* WOLF_CRYPT_CMAC_H */ #endif /* WOLF_CRYPT_CMAC_H */