From 88d3abb1e6f9935f407647f63dc04681cb554aac Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 1 Feb 2019 16:54:27 -0800 Subject: [PATCH] Added Crypto callback HMAC support. --- wolfcrypt/src/cryptocb.c | 50 ++++++++++++++++++++++++++++-------- wolfcrypt/src/hmac.c | 26 +++++++++++++++++++ wolfcrypt/test/test.c | 44 +++++++++++++++++++++++++++++++ wolfssl/wolfcrypt/cryptocb.h | 16 ++++++++++++ wolfssl/wolfcrypt/hmac.h | 5 +++- wolfssl/wolfcrypt/types.h | 3 ++- 6 files changed, 132 insertions(+), 12 deletions(-) diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index bc9ccb7e2..a27d2d232 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -491,6 +491,38 @@ int wc_CryptoCb_Sha256Hash(wc_Sha256* sha256, const byte* in, } #endif /* !NO_SHA256 */ +#ifndef NO_HMAC +int wc_CryptoCb_Hmac(Hmac* hmac, int macType, const byte* in, word32 inSz, byte* digest) +{ + int ret = NOT_COMPILED_IN; + CryptoCb* dev; + + /* locate registered callback */ + if (hmac) { + dev = wc_CryptoCb_FindDevice(hmac->devId); + } + else { + /* locate first callback and try using it */ + dev = wc_CryptoCb_FindDeviceByIndex(0); + } + + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_HMAC; + cryptoInfo.hmac.macType = macType; + cryptoInfo.hmac.in = in; + cryptoInfo.hmac.inSz = inSz; + cryptoInfo.hmac.digest = digest; + cryptoInfo.hmac.hmac = hmac; + + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); + } + + return ret; +} +#endif /* !NO_HMAC */ + #ifndef WC_NO_RNG int wc_CryptoCb_RandomBlock(WC_RNG* rng, byte* out, word32 sz) { @@ -527,17 +559,15 @@ int wc_CryptoCb_RandomSeed(OS_Seed* os, byte* seed, word32 sz) /* locate registered callback */ dev = wc_CryptoCb_FindDevice(os->devId); - if (dev) { - if (dev->cb) { - wc_CryptoInfo cryptoInfo; - XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); - cryptoInfo.algo_type = WC_ALGO_TYPE_SEED; - cryptoInfo.seed.os = os; - cryptoInfo.seed.seed = seed; - cryptoInfo.seed.sz = sz; + if (dev && dev->cb) { + wc_CryptoInfo cryptoInfo; + XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo)); + cryptoInfo.algo_type = WC_ALGO_TYPE_SEED; + cryptoInfo.seed.os = os; + cryptoInfo.seed.seed = seed; + cryptoInfo.seed.sz = sz; - ret = dev->cb(os->devId, &cryptoInfo, dev->ctx); - } + ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx); } return ret; diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 549e773de..f5a27dde3 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -43,6 +43,10 @@ #include +#ifdef WOLF_CRYPTO_CB + #include +#endif + #ifdef NO_INLINE #include #else @@ -691,6 +695,15 @@ int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length) return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + if (hmac->devId != INVALID_DEVID) { + ret = wc_CryptoCb_Hmac(hmac, hmac->macType, msg, length, NULL); + if (ret != NOT_COMPILED_IN) + return ret; + /* fall-through on not compiled in */ + ret = 0; /* reset error code */ + } +#endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { #if defined(HAVE_CAVIUM) @@ -791,6 +804,15 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) return BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + if (hmac->devId != INVALID_DEVID) { + ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, hash); + if (ret != NOT_COMPILED_IN) + return ret; + /* fall-through on not compiled in */ + ret = 0; /* reset error code */ + } +#endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { int hashLen = wc_HmacSizeByType(hmac->macType); @@ -1028,6 +1050,10 @@ int wc_HmacInit(Hmac* hmac, void* heap, int devId) XMEMSET(hmac, 0, sizeof(Hmac)); hmac->heap = heap; +#ifdef WOLF_CRYPTO_CB + hmac->devId = devId; + hmac->devCtx = NULL; +#endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) hmac->keyLen = 0; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 5ad9cb5ff..fe193629a 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -22884,6 +22884,10 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) if (info == NULL) return BAD_FUNC_ARG; +#ifdef DEBUG_WOLFSSL + printf("CryptoDevCb: Algo Type %d\n", info->algo_type); +#endif + if (info->algo_type == WC_ALGO_TYPE_RNG) { #ifndef WC_NO_RNG /* set devId to invalid, so software is used */ @@ -23087,6 +23091,9 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) else if (info->algo_type == WC_ALGO_TYPE_HASH) { #if !defined(NO_SHA) if (info->hash.type == WC_HASH_TYPE_SHA) { + if (info->hash.sha1 == NULL) + return NOT_COMPILED_IN; + /* set devId to invalid, so software is used */ info->hash.sha1->devId = INVALID_DEVID; @@ -23109,6 +23116,9 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) #endif #if !defined(NO_SHA256) if (info->hash.type == WC_HASH_TYPE_SHA256) { + if (info->hash.sha256 == NULL) + return NOT_COMPILED_IN; + /* set devId to invalid, so software is used */ info->hash.sha256->devId = INVALID_DEVID; @@ -23130,6 +23140,30 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) #endif } #endif /* !NO_SHA || !NO_SHA256 */ +#ifndef NO_HMAC + else if (info->algo_type == WC_ALGO_TYPE_HMAC) { + if (info->hmac.hmac == NULL) + return NOT_COMPILED_IN; + + /* set devId to invalid, so software is used */ + info->hmac.hmac->devId = INVALID_DEVID; + + if (info->hash.in != NULL) { + ret = wc_HmacUpdate( + info->hmac.hmac, + info->hmac.in, + info->hmac.inSz); + } + else if (info->hash.digest != NULL) { + ret = wc_HmacFinal( + info->hmac.hmac, + info->hmac.digest); + } + + /* reset devId */ + info->hmac.hmac->devId = devIdArg; + } +#endif (void)devIdArg; (void)myCtx; @@ -23181,6 +23215,16 @@ int cryptocb_test(void) ret = sha256_test(); #endif #endif +#ifndef NO_HMAC + #ifndef NO_SHA + if (ret == 0) + ret = hmac_sha_test(); + #endif + #ifndef NO_SHA256 + if (ret == 0) + ret = hmac_sha256_test(); + #endif +#endif /* reset devId */ devId = INVALID_DEVID; diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index 79cf5b35b..cbef38f6f 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -44,6 +44,9 @@ #ifndef NO_SHA256 #include #endif +#ifndef NO_HMAC + #include +#endif #ifndef WC_NO_RNG #include #endif @@ -163,6 +166,15 @@ typedef struct wc_CryptoInfo { }; } hash; #endif /* !NO_SHA || !NO_SHA256 */ +#ifndef NO_HMAC + struct { + int macType; /* enum wc_HashType */ + const byte* in; + word32 inSz; + byte* digest; + Hmac* hmac; + } hmac; +#endif #ifndef WC_NO_RNG struct { WC_RNG* rng; @@ -242,6 +254,10 @@ WOLFSSL_LOCAL int wc_CryptoCb_ShaHash(wc_Sha* sha, const byte* in, WOLFSSL_LOCAL int wc_CryptoCb_Sha256Hash(wc_Sha256* sha256, const byte* in, word32 inSz, byte* digest); #endif /* !NO_SHA256 */ +#ifndef NO_HMAC +WOLFSSL_LOCAL int wc_CryptoCb_Hmac(Hmac* hmac, int macType, const byte* in, + word32 inSz, byte* digest); +#endif /* !NO_HMAC */ #ifndef WC_NO_RNG WOLFSSL_LOCAL int wc_CryptoCb_RandomBlock(WC_RNG* rng, byte* out, word32 sz); diff --git a/wolfssl/wolfcrypt/hmac.h b/wolfssl/wolfcrypt/hmac.h index 8a725397c..2dac440c7 100644 --- a/wolfssl/wolfcrypt/hmac.h +++ b/wolfssl/wolfcrypt/hmac.h @@ -142,11 +142,14 @@ typedef struct Hmac { void* heap; /* heap hint */ byte macType; /* md5 sha or sha256 */ byte innerHashKeyed; /* keyed flag */ - #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; word16 keyLen; /* hmac key length (key in ipad) */ #endif /* WOLFSSL_ASYNC_CRYPT */ +#ifdef WOLF_CRYPTO_CB + int devId; + void* devCtx; +#endif } Hmac; #endif /* HAVE_FIPS */ diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 8fef951c7..59a4a4cf0 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -544,8 +544,9 @@ WC_ALGO_TYPE_PK = 3, WC_ALGO_TYPE_RNG = 4, WC_ALGO_TYPE_SEED = 5, + WC_ALGO_TYPE_HMAC = 6, - WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_SEED + WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_HMAC }; /* hash types */