Skip to content

Commit 6ef3df2

Browse files
authored
Merge pull request #10598 from twcook86/hkdf_cryptocb_split
Create individual crypto callbacks for hkdf extract and hkdf expand
2 parents cee4b2b + 2ba2e38 commit 6ef3df2

6 files changed

Lines changed: 268 additions & 18 deletions

File tree

doc/dox_comments/header_files/hmac.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ int wc_HKDF_Extract(
254254
\param saltSz length of the salt. Use 0 if not using a salt
255255
\param inKey pointer to the buffer containing the key to use for KDF
256256
\param inKeySz length of the input key
257-
\param out pointer to the buffer in which to store the derived key
257+
\param out pointer to the buffer in which to store the derived key. Must be
258+
digest length per hash 'type'. See wc_HmacSizeByType()
258259
\param heap heap hint to use for memory. Can be NULL
259260
\param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used
260261
@@ -275,6 +276,7 @@ int wc_HKDF_Extract(
275276
\sa wc_HKDF_Extract
276277
\sa wc_HKDF_Expand
277278
\sa wc_HKDF_Expand_ex
279+
\sa wc_HmacSizeByType
278280
*/
279281
int wc_HKDF_Extract_ex(
280282
int type,

wolfcrypt/src/cryptocb.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@ static const char* GetKdfTypeStr(int type)
240240
switch (type) {
241241
case WC_KDF_TYPE_HKDF:
242242
return "HKDF";
243+
case WC_KDF_TYPE_HKDF_EXTRACT:
244+
return "HKDF Extract";
245+
case WC_KDF_TYPE_HKDF_EXPAND:
246+
return "HKDF Expand";
243247
case WC_KDF_TYPE_TWOSTEP_CMAC:
244248
return "TWOSTEP_CMAC";
245249
}
@@ -2610,6 +2614,65 @@ int wc_CryptoCb_Hkdf(int hashType, const byte* inKey, word32 inKeySz,
26102614

26112615
return wc_CryptoCb_TranslateErrorCode(ret);
26122616
}
2617+
2618+
/* NOTE: size of 'out' must be the digest size per hashType */
2619+
int wc_CryptoCb_Hkdf_Extract(int hashType, const byte* salt, word32 saltSz,
2620+
const byte* inKey, word32 inKeySz, byte* out, int devId)
2621+
{
2622+
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
2623+
CryptoCb* dev;
2624+
2625+
/* Find registered callback device */
2626+
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_KDF);
2627+
2628+
if (dev && dev->cb) {
2629+
wc_CryptoInfo cryptoInfo;
2630+
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
2631+
2632+
cryptoInfo.algo_type = WC_ALGO_TYPE_KDF;
2633+
cryptoInfo.kdf.type = WC_KDF_TYPE_HKDF_EXTRACT;
2634+
cryptoInfo.kdf.hkdf_extract.hashType = hashType;
2635+
cryptoInfo.kdf.hkdf_extract.salt = salt;
2636+
cryptoInfo.kdf.hkdf_extract.saltSz = saltSz;
2637+
cryptoInfo.kdf.hkdf_extract.inKey = inKey;
2638+
cryptoInfo.kdf.hkdf_extract.inKeySz = inKeySz;
2639+
cryptoInfo.kdf.hkdf_extract.out = out;
2640+
2641+
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
2642+
}
2643+
2644+
return wc_CryptoCb_TranslateErrorCode(ret);
2645+
}
2646+
2647+
int wc_CryptoCb_Hkdf_Expand(int hashType, const byte* inKey, word32 inKeySz,
2648+
const byte* info, word32 infoSz, byte* out, word32 outSz,
2649+
int devId)
2650+
{
2651+
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
2652+
CryptoCb* dev;
2653+
2654+
/* Find registered callback device */
2655+
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_KDF);
2656+
2657+
if (dev && dev->cb) {
2658+
wc_CryptoInfo cryptoInfo;
2659+
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
2660+
2661+
cryptoInfo.algo_type = WC_ALGO_TYPE_KDF;
2662+
cryptoInfo.kdf.type = WC_KDF_TYPE_HKDF_EXPAND;
2663+
cryptoInfo.kdf.hkdf_expand.hashType = hashType;
2664+
cryptoInfo.kdf.hkdf_expand.inKey = inKey;
2665+
cryptoInfo.kdf.hkdf_expand.inKeySz = inKeySz;
2666+
cryptoInfo.kdf.hkdf_expand.info = info;
2667+
cryptoInfo.kdf.hkdf_expand.infoSz = infoSz;
2668+
cryptoInfo.kdf.hkdf_expand.out = out;
2669+
cryptoInfo.kdf.hkdf_expand.outSz = outSz;
2670+
2671+
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
2672+
}
2673+
2674+
return wc_CryptoCb_TranslateErrorCode(ret);
2675+
}
26132676
#endif /* HAVE_HKDF && !NO_HMAC */
26142677

26152678
#ifdef WOLF_CRYPTO_CB_COPY

wolfcrypt/src/hmac.c

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,15 +1760,25 @@ int wolfSSL_GetHmacMaxSize(void)
17601760
return BAD_FUNC_ARG;
17611761
}
17621762

1763+
#ifdef WOLF_CRYPTO_CB
1764+
/* Try crypto callback first */
1765+
if (devId != INVALID_DEVID) {
1766+
ret = wc_CryptoCb_Hkdf_Extract(type, salt, saltSz, inKey, inKeySz,
1767+
out, devId);
1768+
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1769+
return ret;
1770+
}
1771+
#endif
1772+
17631773
ret = wc_HmacSizeByType(type);
17641774
if (ret < 0) {
17651775
return ret;
17661776
}
1777+
hashSz = (word32)ret;
17671778

17681779
WC_ALLOC_VAR_EX(myHmac, Hmac, 1, NULL, DYNAMIC_TYPE_HMAC,
17691780
return MEMORY_E);
17701781

1771-
hashSz = (word32)ret;
17721782
localSalt = salt;
17731783
if (localSalt == NULL) {
17741784
XMEMSET(tmp, 0, hashSz);
@@ -1824,6 +1834,10 @@ int wolfSSL_GetHmacMaxSize(void)
18241834
word32 hashSz;
18251835
byte n = 0x1;
18261836

1837+
if (out == NULL || (inKey == NULL && inKeySz > 0)) {
1838+
return BAD_FUNC_ARG;
1839+
}
1840+
18271841
ret = wc_HmacSizeByType(type);
18281842
if (ret < 0) {
18291843
return ret;
@@ -1832,17 +1846,25 @@ int wolfSSL_GetHmacMaxSize(void)
18321846

18331847
/* RFC 5869 states that the length of output keying material in
18341848
* octets must be L <= 255*HashLen or N = ceil(L/HashLen) */
1835-
1836-
if (out == NULL || ((outSz/hashSz) + ((outSz % hashSz) != 0)) > 255) {
1849+
if (outSz/hashSz + ((outSz % hashSz) != 0) > 255)
18371850
return BAD_FUNC_ARG;
1851+
1852+
#ifdef WOLF_CRYPTO_CB
1853+
/* Try crypto callback first for complete operation */
1854+
if (devId != INVALID_DEVID) {
1855+
ret = wc_CryptoCb_Hkdf_Expand(type, inKey, inKeySz, info, infoSz,
1856+
out, outSz, devId);
1857+
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1858+
return ret;
18381859
}
1860+
#endif
18391861

18401862
WC_ALLOC_VAR_EX(myHmac, Hmac, 1, NULL, DYNAMIC_TYPE_HMAC,
18411863
return MEMORY_E);
18421864

18431865
ret = wc_HmacInit(myHmac, heap, devId);
18441866
if (ret != 0) {
1845-
WC_FREE_VAR_EX(myHmac, NULL, DYNAMIC_TYPE_HMAC);
1867+
WC_FREE_VAR_EX(myHmac, NULL, DYNAMIC_TYPE_HMAC);
18461868
return ret;
18471869
}
18481870

@@ -1929,9 +1951,8 @@ int wolfSSL_GetHmacMaxSize(void)
19291951
#endif
19301952

19311953
ret = wc_HmacSizeByType(type);
1932-
if (ret < 0) {
1954+
if (ret < 0)
19331955
return ret;
1934-
}
19351956
hashSz = (word32)ret;
19361957

19371958
ret = wc_HKDF_Extract_ex(type, salt, saltSz, inKey, inKeySz, prk, heap,

wolfcrypt/test/test.c

Lines changed: 145 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34880,6 +34880,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
3488034880

3488134881
#if !defined(NO_SHA) || !defined(NO_SHA256)
3488234882
int L;
34883+
byte prk[WC_MAX_DIGEST_SIZE];
3488334884
byte okm1[42];
3488434885
byte ikm1[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
3488534886
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
@@ -34944,7 +34945,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
3494434945
#ifndef HAVE_FIPS
3494534946
/* fips can't have key size under 14 bytes, salt is key too */
3494634947
L = (int)sizeof(okm1);
34947-
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
34948+
#if !defined(HAVE_SELFTEST)
3494834949
ret = wc_HKDF_ex(WC_SHA, ikm1, 11, salt1, (word32)sizeof(salt1), info1,
3494934950
(word32)sizeof(info1), okm1, (word32)L, HEAP_HINT, devId);
3495034951
#else
@@ -34956,7 +34957,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
3495634957

3495734958
if (XMEMCMP(okm1, res2, (unsigned long)L) != 0)
3495834959
return WC_TEST_RET_ENC_NC;
34959-
#endif /* HAVE_FIPS */
34960+
#endif /* !HAVE_FIPS */
3496034961
#endif /* !NO_SHA */
3496134962

3496234963
#ifndef NO_SHA256
@@ -34989,7 +34990,106 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
3498934990

3499034991
if (XMEMCMP(okm1, res4, (unsigned long)L) != 0)
3499134992
return WC_TEST_RET_ENC_NC;
34992-
#endif /* HAVE_FIPS */
34993+
#endif /* !HAVE_FIPS */
34994+
#endif /* !NO_SHA256 */
34995+
34996+
#ifndef NO_SHA
34997+
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
34998+
ret = wc_HKDF_Extract_ex(WC_SHA, NULL, 0, ikm1, (word32)sizeof(ikm1),
34999+
prk, HEAP_HINT, devId);
35000+
#else
35001+
ret = wc_HKDF_Extract(WC_SHA, NULL, 0, ikm1, (word32)sizeof(ikm1), prk);
35002+
#endif
35003+
if (ret != 0)
35004+
return WC_TEST_RET_ENC_EC(ret);
35005+
35006+
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
35007+
ret = wc_HKDF_Expand_ex(WC_SHA, prk, WC_SHA_DIGEST_SIZE, NULL, 0,
35008+
okm1, (word32)L, HEAP_HINT, devId);
35009+
#else
35010+
ret = wc_HKDF_Expand(WC_SHA, prk, WC_SHA_DIGEST_SIZE, NULL, 0,
35011+
okm1, (word32)L);
35012+
#endif
35013+
if (ret != 0)
35014+
return WC_TEST_RET_ENC_EC(ret);
35015+
35016+
if (XMEMCMP(okm1, res1, (unsigned long)L) != 0)
35017+
return WC_TEST_RET_ENC_NC;
35018+
35019+
#ifndef HAVE_FIPS
35020+
/* fips can't have key size under 14 bytes, salt is key too */
35021+
#if !defined(HAVE_SELFTEST)
35022+
ret = wc_HKDF_Extract_ex(WC_SHA, salt1, (word32)sizeof(salt1), ikm1, 11,
35023+
prk, HEAP_HINT, devId);
35024+
#else
35025+
ret = wc_HKDF_Extract(WC_SHA, salt1, (word32)sizeof(salt1), ikm1, 11, prk);
35026+
#endif
35027+
if (ret != 0)
35028+
return WC_TEST_RET_ENC_EC(ret);
35029+
35030+
#if !defined(HAVE_SELFTEST)
35031+
ret = wc_HKDF_Expand_ex(WC_SHA, prk, WC_SHA_DIGEST_SIZE, info1,
35032+
(word32)sizeof(info1), okm1, (word32)L, HEAP_HINT, devId);
35033+
#else
35034+
ret = wc_HKDF_Expand(WC_SHA, prk, WC_SHA_DIGEST_SIZE, info1,
35035+
(word32)sizeof(info1), okm1, (word32)L);
35036+
#endif
35037+
if (ret != 0)
35038+
return WC_TEST_RET_ENC_EC(ret);
35039+
35040+
if (XMEMCMP(okm1, res2, (unsigned long)L) != 0)
35041+
return WC_TEST_RET_ENC_NC;
35042+
#endif /* !HAVE_FIPS */
35043+
#endif /* !NO_SHA */
35044+
35045+
#ifndef NO_SHA256
35046+
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
35047+
ret = wc_HKDF_Extract_ex(WC_SHA256, NULL, 0, ikm1, (word32)sizeof(ikm1),
35048+
prk, HEAP_HINT, devId);
35049+
#else
35050+
ret = wc_HKDF_Extract(WC_SHA256, NULL, 0, ikm1, (word32)sizeof(ikm1), prk);
35051+
#endif
35052+
if (ret != 0)
35053+
return WC_TEST_RET_ENC_EC(ret);
35054+
35055+
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
35056+
ret = wc_HKDF_Expand_ex(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, NULL, 0,
35057+
okm1, (word32)L, HEAP_HINT, devId);
35058+
#else
35059+
ret = wc_HKDF_Expand(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, NULL, 0,
35060+
okm1, (word32)L);
35061+
#endif
35062+
if (ret != 0)
35063+
return WC_TEST_RET_ENC_EC(ret);
35064+
35065+
if (XMEMCMP(okm1, res3, (unsigned long)L) != 0)
35066+
return WC_TEST_RET_ENC_NC;
35067+
35068+
#ifndef HAVE_FIPS
35069+
/* fips can't have key size under 14 bytes, salt is key too */
35070+
#if !defined(HAVE_SELFTEST)
35071+
ret = wc_HKDF_Extract_ex(WC_SHA256, salt1, (word32)sizeof(salt1), ikm1,
35072+
(word32)sizeof(ikm1), prk, HEAP_HINT, devId);
35073+
#else
35074+
ret = wc_HKDF_Extract(WC_SHA256, salt1, (word32)sizeof(salt1), ikm1,
35075+
(word32)sizeof(ikm1), prk);
35076+
#endif
35077+
if (ret != 0)
35078+
return WC_TEST_RET_ENC_EC(ret);
35079+
35080+
#if !defined(HAVE_SELFTEST)
35081+
ret = wc_HKDF_Expand_ex(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, info1,
35082+
(word32)sizeof(info1), okm1, (word32)L, HEAP_HINT, devId);
35083+
#else
35084+
ret = wc_HKDF_Expand(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, info1,
35085+
(word32)sizeof(info1), okm1, (word32)L);
35086+
#endif
35087+
if (ret != 0)
35088+
return WC_TEST_RET_ENC_EC(ret);
35089+
35090+
if (XMEMCMP(okm1, res4, (unsigned long)L) != 0)
35091+
return WC_TEST_RET_ENC_NC;
35092+
#endif /* !HAVE_FIPS */
3499335093
#endif /* !NO_SHA256 */
3499435094
#endif /* !NO_SHA || !NO_SHA256 */
3499535095

@@ -35003,8 +35103,18 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
3500335103
ret = wc_HKDF_Extract(WC_SHA256, NULL, 0, NULL, 5, okm1);
3500435104
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
3500535105
return WC_TEST_RET_ENC_EC(ret);
35006-
#endif /* !NO_SHA256 && !HAVE_SELFTEST && */
35007-
/* (!HAVE_FIPS || FIPS_VERSION3_GE(7,0,0)) */
35106+
/* wc_HKDF_Expand bad arg: NULL out */
35107+
ret = wc_HKDF_Expand(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, NULL, 0,
35108+
NULL, (word32)L);
35109+
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
35110+
return WC_TEST_RET_ENC_EC(ret);
35111+
/* wc_HKDF_Expand bad arg: NULL inKey with non-zero inKeySz */
35112+
ret = wc_HKDF_Expand(WC_SHA256, NULL, WC_SHA256_DIGEST_SIZE, NULL, 0,
35113+
okm1, (word32)L);
35114+
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
35115+
return WC_TEST_RET_ENC_EC(ret);
35116+
#endif /* !NO_SHA256 && !HAVE_SELFTEST */
35117+
/* && (!HAVE_FIPS || FIPS_VERSION3_GE(7,0,0)) */
3500835118

3500935119
return 0;
3501035120
}
@@ -74538,6 +74648,36 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
7453874648
info->kdf.hkdf.out, info->kdf.hkdf.outSz);
7453974649
#endif
7454074650
}
74651+
if (info->kdf.type == WC_KDF_TYPE_HKDF_EXTRACT) {
74652+
#if !defined(HAVE_SELFTEST) && \
74653+
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
74654+
ret = wc_HKDF_Extract_ex(info->kdf.hkdf_extract.hashType,
74655+
info->kdf.hkdf_extract.salt, info->kdf.hkdf_extract.saltSz,
74656+
info->kdf.hkdf_extract.inKey, info->kdf.hkdf_extract.inKeySz,
74657+
info->kdf.hkdf_extract.out,
74658+
NULL, INVALID_DEVID);
74659+
#else
74660+
ret = wc_HKDF_Extract(info->kdf.hkdf_extract.hashType,
74661+
info->kdf.hkdf_extract.salt, info->kdf.hkdf_extract.saltSz,
74662+
info->kdf.hkdf_extract.inKey, info->kdf.hkdf_extract.inKeySz,
74663+
info->kdf.hkdf_extract.out);
74664+
#endif
74665+
}
74666+
if (info->kdf.type == WC_KDF_TYPE_HKDF_EXPAND) {
74667+
#if !defined(HAVE_SELFTEST) && \
74668+
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
74669+
ret = wc_HKDF_Expand_ex(info->kdf.hkdf_expand.hashType,
74670+
info->kdf.hkdf_expand.inKey, info->kdf.hkdf_expand.inKeySz,
74671+
info->kdf.hkdf_expand.info, info->kdf.hkdf_expand.infoSz,
74672+
info->kdf.hkdf_expand.out, info->kdf.hkdf_expand.outSz,
74673+
NULL, INVALID_DEVID);
74674+
#else
74675+
ret = wc_HKDF_Expand(info->kdf.hkdf_expand.hashType,
74676+
info->kdf.hkdf_expand.inKey, info->kdf.hkdf_expand.inKeySz,
74677+
info->kdf.hkdf_expand.info, info->kdf.hkdf_expand.infoSz,
74678+
info->kdf.hkdf_expand.out, info->kdf.hkdf_expand.outSz);
74679+
#endif
74680+
}
7454174681
#endif /* HAVE_HKDF && !NO_HMAC */
7454274682
#if defined(HAVE_CMAC_KDF)
7454374683
if (info->kdf.type == WC_KDF_TYPE_TWOSTEP_CMAC) {

0 commit comments

Comments
 (0)