Skip to content

Commit 7a77d64

Browse files
authored
Merge pull request #7059 from bigbrett/cryptocb-oneshot-cmac
Add cryptoCb hook to one-shot CMAC functions
2 parents d4272bb + abbf9f2 commit 7a77d64

3 files changed

Lines changed: 223 additions & 21 deletions

File tree

wolfcrypt/src/cmac.c

Lines changed: 140 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ void ShiftAndXorRb(byte* out, byte* in)
9696
int wc_InitCmac_ex(Cmac* cmac, const byte* key, word32 keySz,
9797
int type, void* unused, void* heap, int devId)
9898
{
99-
int ret;
99+
int ret = 0;
100100
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
101101
byte useSW = 0;
102102
#endif
@@ -196,10 +196,12 @@ int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz)
196196
if (ret != CRYPTOCB_UNAVAILABLE)
197197
return ret;
198198
/* fall-through when unavailable */
199-
ret = 0; /* reset error code */
200199
}
201200
#endif
202201

202+
/* Clear CRYPTOCB_UNAVAILABLE return code */
203+
ret = 0;
204+
203205
while (inSz != 0) {
204206
word32 add = min(inSz, AES_BLOCK_SIZE - cmac->bufferSz);
205207
XMEMCPY(&cmac->buffer[cmac->bufferSz], in, add);
@@ -242,7 +244,7 @@ int wc_CmacFree(Cmac* cmac)
242244

243245
int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
244246
{
245-
int ret;
247+
int ret = 0;
246248
const byte* subKey;
247249
word32 remainder;
248250

@@ -296,7 +298,7 @@ int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz)
296298
}
297299

298300
int wc_CmacFinal(Cmac* cmac, byte* out, word32* outSz) {
299-
int ret;
301+
int ret = 0;
300302

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

310+
311+
int wc_AesCmacGenerate_ex(Cmac* cmac,
312+
byte* out, word32* outSz,
313+
const byte* in, word32 inSz,
314+
const byte* key, word32 keySz,
315+
void* heap, int devId)
316+
{
317+
int ret = 0;
318+
319+
if (cmac == NULL) {
320+
return BAD_FUNC_ARG;
321+
}
322+
323+
#ifdef WOLF_CRYPTO_CB
324+
/* Set devId regardless of value (invalid or not) */
325+
cmac->devId = devId;
326+
#ifndef WOLF_CRYPTO_CB_FIND
327+
if (devId != INVALID_DEVID)
328+
#endif
329+
{
330+
cmac->devCtx = NULL;
331+
332+
ret = wc_CryptoCb_Cmac(cmac, key, keySz, in, inSz, out, outSz,
333+
WC_CMAC_AES, NULL);
334+
if (ret != CRYPTOCB_UNAVAILABLE)
335+
return ret;
336+
337+
/* Clear CRYPTOCB_UNAVAILABLE return code */
338+
ret = 0;
339+
340+
/* fall-through when unavailable */
341+
}
342+
#endif
343+
344+
if ( ((out == NULL) && (outSz != NULL) && (*outSz > 0))
345+
|| (in == NULL && inSz > 0)
346+
|| (key == NULL && keySz > 0)) {
347+
return BAD_FUNC_ARG;
348+
}
349+
350+
/* Init step is optional */
351+
if (key != NULL) {
352+
ret = wc_InitCmac_ex(cmac, key, keySz, WC_CMAC_AES, NULL, heap, devId);
353+
}
354+
if (ret == 0) {
355+
ret = wc_CmacUpdate(cmac, in, inSz);
356+
/* Ensure we are freed and zeroed if not calling wc_CmacFinal */
357+
if (ret != 0) {
358+
(void)wc_CmacFree(cmac);
359+
}
360+
}
361+
if (ret == 0) {
362+
ret = wc_CmacFinal(cmac, out, outSz);
363+
}
364+
365+
return ret;
366+
}
367+
368+
308369
int wc_AesCmacGenerate(byte* out, word32* outSz,
309370
const byte* in, word32 inSz,
310371
const byte* key, word32 keySz)
311372
{
312-
int ret;
373+
int ret = 0;
313374
#ifdef WOLFSSL_SMALL_STACK
314375
Cmac *cmac;
315376
#else
@@ -326,21 +387,22 @@ int wc_AesCmacGenerate(byte* out, word32* outSz,
326387
return MEMORY_E;
327388
}
328389
#endif
390+
329391
#ifdef WOLFSSL_CHECK_MEM_ZERO
330392
XMEMSET(((unsigned char *)cmac) + sizeof(Aes), 0xff,
331393
sizeof(Cmac) - sizeof(Aes));
332394
/* Aes part is checked by wc_AesFree. */
333-
wc_MemZero_Add("wc_AesCmacGenerate cmac",
395+
wc_MemZero_Add("wc_AesCmacGenerate_ex cmac",
334396
((unsigned char *)cmac) + sizeof(Aes), sizeof(Cmac) - sizeof(Aes));
335397
#endif
336398

337-
ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
338-
if (ret == 0) {
339-
ret = wc_CmacUpdate(cmac, in, inSz);
340-
}
341-
if (ret == 0) {
342-
ret = wc_CmacFinal(cmac, out, outSz);
343-
}
399+
ret = wc_AesCmacGenerate_ex(cmac,
400+
out, outSz,
401+
in, inSz,
402+
key, keySz,
403+
NULL,
404+
INVALID_DEVID);
405+
344406

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

356418

357-
int wc_AesCmacVerify(const byte* check, word32 checkSz,
358-
const byte* in, word32 inSz,
359-
const byte* key, word32 keySz)
419+
int wc_AesCmacVerify_ex(Cmac* cmac,
420+
const byte* check, word32 checkSz,
421+
const byte* in, word32 inSz,
422+
const byte* key, word32 keySz,
423+
void* heap, int devId)
360424
{
361-
int ret;
425+
int ret = 0;
362426
byte a[AES_BLOCK_SIZE];
363427
word32 aSz = sizeof(a);
364428
int compareRet;
365429

366-
if (check == NULL || checkSz == 0 || (in == NULL && inSz != 0) ||
367-
key == NULL || keySz == 0) {
430+
if (cmac == NULL || check == NULL || checkSz == 0 || (in == NULL && inSz != 0)) {
368431
return BAD_FUNC_ARG;
369432
}
370433

371434
XMEMSET(a, 0, aSz);
372-
ret = wc_AesCmacGenerate(a, &aSz, in, inSz, key, keySz);
373-
compareRet = ConstantCompare(check, a, (int)min(checkSz, aSz));
435+
ret = wc_AesCmacGenerate_ex(cmac,
436+
a, &aSz,
437+
in, inSz,
438+
key, keySz,
439+
heap,
440+
devId);
441+
if (ret == 0) {
442+
compareRet = ConstantCompare(check, a, (int)min(checkSz, aSz));
443+
}
374444

375445
if (ret == 0)
376446
ret = compareRet ? 1 : 0;
377447

378448
return ret;
379449
}
380450

451+
452+
int wc_AesCmacVerify(const byte* check, word32 checkSz,
453+
const byte* in, word32 inSz,
454+
const byte* key, word32 keySz)
455+
{
456+
int ret = 0;
457+
#ifdef WOLFSSL_SMALL_STACK
458+
Cmac *cmac;
459+
#else
460+
Cmac cmac[1];
461+
#endif
462+
463+
if (check == NULL || (in == NULL && inSz > 0) || key == NULL || keySz == 0) {
464+
return BAD_FUNC_ARG;
465+
}
466+
467+
#ifdef WOLFSSL_SMALL_STACK
468+
if ((cmac = (Cmac *)XMALLOC(sizeof *cmac, NULL,
469+
DYNAMIC_TYPE_CMAC)) == NULL) {
470+
return MEMORY_E;
471+
}
472+
#endif
473+
474+
#ifdef WOLFSSL_CHECK_MEM_ZERO
475+
XMEMSET(((unsigned char *)cmac) + sizeof(Aes), 0xff,
476+
sizeof(Cmac) - sizeof(Aes));
477+
/* Aes part is checked by wc_AesFree. */
478+
wc_MemZero_Add("wc_AesCmacGenerate_ex cmac",
479+
((unsigned char *)cmac) + sizeof(Aes), sizeof(Cmac) - sizeof(Aes));
480+
#endif
481+
482+
ret = wc_AesCmacVerify_ex(cmac,
483+
check, checkSz,
484+
in, inSz,
485+
key, keySz,
486+
NULL,
487+
INVALID_DEVID);
488+
489+
#ifdef WOLFSSL_SMALL_STACK
490+
if (cmac) {
491+
XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
492+
}
493+
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
494+
wc_MemZero_Check(cmac, sizeof(Cmac));
495+
#endif
496+
497+
return ret;
498+
}
499+
381500
#endif /* WOLFSSL_CMAC && NO_AES && WOLFSSL_AES_DIRECT */

wolfcrypt/test/test.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39967,16 +39967,42 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cmac_test(void)
3996739967

3996839968
XMEMSET(tag, 0, sizeof(tag));
3996939969
tagSz = sizeof(tag);
39970+
#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)
39971+
ret = wc_AesCmacGenerate_ex(cmac, tag, &tagSz, tc->m, tc->mSz,
39972+
tc->k, tc->kSz, NULL, devId);
39973+
#else
3997039974
ret = wc_AesCmacGenerate(tag, &tagSz, tc->m, tc->mSz,
3997139975
tc->k, tc->kSz);
39976+
#endif
3997239977
if (ret != 0)
3997339978
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
3997439979
if (XMEMCMP(tag, tc->t, AES_BLOCK_SIZE) != 0)
3997539980
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
39981+
#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)
39982+
ret = wc_AesCmacVerify_ex(cmac, tc->t, tc->tSz, tc->m, tc->mSz,
39983+
tc->k, tc->kSz, HEAP_HINT, devId);
39984+
#else
3997639985
ret = wc_AesCmacVerify(tc->t, tc->tSz, tc->m, tc->mSz,
3997739986
tc->k, tc->kSz);
39987+
#endif
3997839988
if (ret != 0)
3997939989
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
39990+
39991+
#if !defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)
39992+
/* Test that keyless generate with init is the same */
39993+
XMEMSET(tag, 0, sizeof(tag));
39994+
tagSz = sizeof(tag);
39995+
ret = wc_InitCmac_ex(cmac, tc->k, tc->kSz, tc->type, NULL, HEAP_HINT, devId);
39996+
if (ret != 0) {
39997+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
39998+
}
39999+
ret = wc_AesCmacGenerate_ex(cmac, tag, &tagSz, tc->m, tc->mSz,
40000+
NULL, 0, HEAP_HINT, devId);
40001+
if (ret != 0) {
40002+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
40003+
}
40004+
#endif
40005+
3998040006
}
3998140007

3998240008
ret = 0;
@@ -49428,6 +49454,49 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
4942849454
info->hmac.hmac->devId = devIdArg;
4942949455
}
4943049456
#endif
49457+
#if defined(WOLFSSL_CMAC) && !defined(NO_AES)
49458+
else if (info->algo_type == WC_ALGO_TYPE_CMAC) {
49459+
if (info->cmac.cmac == NULL) {
49460+
return NOT_COMPILED_IN;
49461+
}
49462+
49463+
/* set devId to invalid so software is used */
49464+
info->cmac.cmac->devId = INVALID_DEVID;
49465+
49466+
/* Handle one-shot cases */
49467+
if (info->cmac.key != NULL && info->cmac.in != NULL
49468+
&& info->cmac.out != NULL) {
49469+
ret = wc_AesCmacGenerate(info->cmac.out,
49470+
info->cmac.outSz,
49471+
info->cmac.in,
49472+
info->cmac.inSz,
49473+
info->cmac.key,
49474+
info->cmac.keySz);
49475+
/* Sequentially handle incremental cases */
49476+
} else {
49477+
if (info->cmac.key != NULL) {
49478+
ret = wc_InitCmac(info->cmac.cmac,
49479+
info->cmac.key,
49480+
info->cmac.keySz,
49481+
info->cmac.type,
49482+
NULL);
49483+
}
49484+
if ((ret == 0) && (info->cmac.in != NULL)) {
49485+
ret = wc_CmacUpdate(info->cmac.cmac,
49486+
info->cmac.in,
49487+
info->cmac.inSz);
49488+
}
49489+
if ((ret ==0) && (info->cmac.out != NULL)) {
49490+
ret = wc_CmacFinal(info->cmac.cmac,
49491+
info->cmac.out,
49492+
info->cmac.outSz);
49493+
}
49494+
}
49495+
49496+
/* reset devId */
49497+
info->cmac.cmac->devId = devIdArg;
49498+
}
49499+
#endif /* WOLFSSL_CMAC && !(NO_AES) && WOLFSSL_AES_DIRECT */
4943149500

4943249501
(void)devIdArg;
4943349502
(void)myCtx;

wolfssl/wolfcrypt/cmac.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,25 @@ WOLFSSL_API
111111
int wc_AesCmacGenerate(byte* out, word32* outSz,
112112
const byte* in, word32 inSz,
113113
const byte* key, word32 keySz);
114+
WOLFSSL_API
115+
int wc_AesCmacGenerate_ex(Cmac *cmac,
116+
byte* out, word32* outSz,
117+
const byte* in, word32 inSz,
118+
const byte* key, word32 keySz,
119+
void* heap,
120+
int devId);
114121

115122
WOLFSSL_API
116123
int wc_AesCmacVerify(const byte* check, word32 checkSz,
117124
const byte* in, word32 inSz,
118125
const byte* key, word32 keySz);
126+
WOLFSSL_API
127+
int wc_AesCmacVerify_ex(Cmac* cmac,
128+
const byte* check, word32 checkSz,
129+
const byte* in, word32 inSz,
130+
const byte* key, word32 keySz,
131+
void* heap,
132+
int devId);
119133

120134
WOLFSSL_LOCAL
121135
void ShiftAndXorRb(byte* out, byte* in);

0 commit comments

Comments
 (0)