Skip to content

Commit 8807566

Browse files
authored
Merge pull request #9252 from bigbrett/kdf-cryptocb
HKDF cryptocb
2 parents d5750ac + 5121847 commit 8807566

File tree

6 files changed

+179
-13
lines changed

6 files changed

+179
-13
lines changed

wolfcrypt/src/cryptocb.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ static const char* GetAlgoTypeStr(int algo)
8080
case WC_ALGO_TYPE_HMAC: return "HMAC";
8181
case WC_ALGO_TYPE_CMAC: return "CMAC";
8282
case WC_ALGO_TYPE_CERT: return "Cert";
83+
case WC_ALGO_TYPE_KDF:
84+
return "KDF";
8385
}
8486
return NULL;
8587
}
@@ -172,6 +174,17 @@ static const char* GetCryptoCbCmdTypeStr(int type)
172174
}
173175
#endif
174176

177+
#if defined(HAVE_HKDF) && !defined(NO_HMAC)
178+
static const char* GetKdfTypeStr(int type)
179+
{
180+
switch (type) {
181+
case WC_KDF_TYPE_HKDF:
182+
return "HKDF";
183+
}
184+
return NULL;
185+
}
186+
#endif
187+
175188
void wc_CryptoCb_InfoString(wc_CryptoInfo* info)
176189
{
177190
if (info == NULL)
@@ -237,6 +250,12 @@ void wc_CryptoCb_InfoString(wc_CryptoInfo* info)
237250
GetAlgoTypeStr(info->algo_type),
238251
GetCryptoCbCmdTypeStr(info->cmd.type), info->cmd.type);
239252
}
253+
#endif
254+
#if defined(HAVE_HKDF) && !defined(NO_HMAC)
255+
else if (info->algo_type == WC_ALGO_TYPE_KDF) {
256+
printf("Crypto CB: %s %s (%d)\n", GetAlgoTypeStr(info->algo_type),
257+
GetKdfTypeStr(info->kdf.type), info->kdf.type);
258+
}
240259
#endif
241260
else {
242261
printf("CryptoCb: %s \n", GetAlgoTypeStr(info->algo_type));
@@ -1945,4 +1964,38 @@ int wc_CryptoCb_DefaultDevID(void)
19451964
return ret;
19461965
}
19471966

1967+
#if defined(HAVE_HKDF) && !defined(NO_HMAC)
1968+
int wc_CryptoCb_Hkdf(int hashType, const byte* inKey, word32 inKeySz,
1969+
const byte* salt, word32 saltSz, const byte* info,
1970+
word32 infoSz, byte* out, word32 outSz, int devId)
1971+
{
1972+
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
1973+
CryptoCb* dev;
1974+
1975+
/* Find registered callback device */
1976+
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_KDF);
1977+
1978+
if (dev && dev->cb) {
1979+
wc_CryptoInfo cryptoInfo;
1980+
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
1981+
1982+
cryptoInfo.algo_type = WC_ALGO_TYPE_KDF;
1983+
cryptoInfo.kdf.type = WC_KDF_TYPE_HKDF;
1984+
cryptoInfo.kdf.hkdf.hashType = hashType;
1985+
cryptoInfo.kdf.hkdf.inKey = inKey;
1986+
cryptoInfo.kdf.hkdf.inKeySz = inKeySz;
1987+
cryptoInfo.kdf.hkdf.salt = salt;
1988+
cryptoInfo.kdf.hkdf.saltSz = saltSz;
1989+
cryptoInfo.kdf.hkdf.info = info;
1990+
cryptoInfo.kdf.hkdf.infoSz = infoSz;
1991+
cryptoInfo.kdf.hkdf.out = out;
1992+
cryptoInfo.kdf.hkdf.outSz = outSz;
1993+
1994+
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
1995+
}
1996+
1997+
return wc_CryptoCb_TranslateErrorCode(ret);
1998+
}
1999+
#endif /* HAVE_HKDF && !NO_HMAC */
2000+
19482001
#endif /* WOLF_CRYPTO_CB */

wolfcrypt/src/hmac.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,26 +1622,48 @@ int wolfSSL_GetHmacMaxSize(void)
16221622
* out The output keying material.
16231623
* returns 0 on success, otherwise failure.
16241624
*/
1625-
int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
1626-
const byte* salt, word32 saltSz,
1627-
const byte* info, word32 infoSz,
1628-
byte* out, word32 outSz)
1625+
int wc_HKDF_ex(int type, const byte* inKey, word32 inKeySz,
1626+
const byte* salt, word32 saltSz, const byte* info,
1627+
word32 infoSz, byte* out, word32 outSz, void* heap,
1628+
int devId)
16291629
{
16301630
byte prk[WC_MAX_DIGEST_SIZE];
16311631
word32 hashSz;
16321632
int ret;
16331633

1634+
(void)devId; /* suppress unused parameter warning */
1635+
1636+
#ifdef WOLF_CRYPTO_CB
1637+
/* Try crypto callback first for complete operation */
1638+
if (devId != INVALID_DEVID) {
1639+
ret = wc_CryptoCb_Hkdf(type, inKey, inKeySz, salt, saltSz, info,
1640+
infoSz, out, outSz, devId);
1641+
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1642+
return ret;
1643+
}
1644+
#endif
1645+
16341646
ret = wc_HmacSizeByType(type);
16351647
if (ret < 0) {
16361648
return ret;
16371649
}
16381650
hashSz = (word32)ret;
16391651

1640-
ret = wc_HKDF_Extract(type, salt, saltSz, inKey, inKeySz, prk);
1652+
ret = wc_HKDF_Extract_ex(type, salt, saltSz, inKey, inKeySz, prk, heap,
1653+
devId);
16411654
if (ret != 0)
16421655
return ret;
16431656

1644-
return wc_HKDF_Expand(type, prk, hashSz, info, infoSz, out, outSz);
1657+
return wc_HKDF_Expand_ex(type, prk, hashSz, info, infoSz, out, outSz,
1658+
heap, devId);
1659+
}
1660+
1661+
int wc_HKDF(int type, const byte* inKey, word32 inKeySz, const byte* salt,
1662+
word32 saltSz, const byte* info, word32 infoSz, byte* out,
1663+
word32 outSz)
1664+
{
1665+
return wc_HKDF_ex(type, inKey, inKeySz, salt, saltSz, info, infoSz, out,
1666+
outSz, NULL, INVALID_DEVID);
16451667
}
16461668

16471669
#endif /* HAVE_HKDF */

wolfcrypt/test/test.c

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27901,8 +27901,13 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
2790127901
L = (int)sizeof(okm1);
2790227902

2790327903
#ifndef NO_SHA
27904+
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
27905+
ret = wc_HKDF_ex(WC_SHA, ikm1, (word32)sizeof(ikm1), NULL, 0, NULL, 0,
27906+
okm1, (word32)L, HEAP_HINT, devId);
27907+
#else
2790427908
ret = wc_HKDF(WC_SHA, ikm1, (word32)sizeof(ikm1), NULL, 0, NULL, 0,
27905-
okm1, (word32)L);
27909+
okm1, (word32)L);
27910+
#endif
2790627911
if (ret != 0)
2790727912
return WC_TEST_RET_ENC_EC(ret);
2790827913

@@ -27912,8 +27917,13 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
2791227917
#ifndef HAVE_FIPS
2791327918
/* fips can't have key size under 14 bytes, salt is key too */
2791427919
L = (int)sizeof(okm1);
27915-
ret = wc_HKDF(WC_SHA, ikm1, 11, salt1, (word32)sizeof(salt1),
27916-
info1, (word32)sizeof(info1), okm1, (word32)L);
27920+
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
27921+
ret = wc_HKDF_ex(WC_SHA, ikm1, 11, salt1, (word32)sizeof(salt1), info1,
27922+
(word32)sizeof(info1), okm1, (word32)L, HEAP_HINT, devId);
27923+
#else
27924+
ret = wc_HKDF(WC_SHA, ikm1, 11, salt1, (word32)sizeof(salt1), info1,
27925+
(word32)sizeof(info1), okm1, (word32)L);
27926+
#endif
2791727927
if (ret != 0)
2791827928
return WC_TEST_RET_ENC_EC(ret);
2791927929

@@ -27923,8 +27933,13 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
2792327933
#endif /* !NO_SHA */
2792427934

2792527935
#ifndef NO_SHA256
27936+
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
27937+
ret = wc_HKDF_ex(WC_SHA256, ikm1, (word32)sizeof(ikm1), NULL, 0, NULL, 0,
27938+
okm1, (word32)L, HEAP_HINT, devId);
27939+
#else
2792627940
ret = wc_HKDF(WC_SHA256, ikm1, (word32)sizeof(ikm1), NULL, 0, NULL, 0,
27927-
okm1, (word32)L);
27941+
okm1, (word32)L);
27942+
#endif
2792827943
if (ret != 0)
2792927944
return WC_TEST_RET_ENC_EC(ret);
2793027945

@@ -27933,8 +27948,15 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
2793327948

2793427949
#ifndef HAVE_FIPS
2793527950
/* fips can't have key size under 14 bytes, salt is key too */
27936-
ret = wc_HKDF(WC_SHA256, ikm1, (word32)sizeof(ikm1),
27937-
salt1, (word32)sizeof(salt1), info1, (word32)sizeof(info1), okm1, (word32)L);
27951+
#if !defined(HAVE_SELFTEST)
27952+
ret = wc_HKDF_ex(WC_SHA256, ikm1, (word32)sizeof(ikm1),
27953+
salt1, (word32)sizeof(salt1), info1, (word32)sizeof(info1), okm1,
27954+
(word32)L, HEAP_HINT, devId);
27955+
#else
27956+
ret = wc_HKDF(WC_SHA256, ikm1, (word32)sizeof(ikm1), salt1,
27957+
(word32)sizeof(salt1), info1, (word32)sizeof(info1), okm1,
27958+
(word32)L);
27959+
#endif
2793827960
if (ret != 0)
2793927961
return WC_TEST_RET_ENC_EC(ret);
2794027962

@@ -60809,6 +60831,28 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
6080960831
info->cmac.cmac->devId = devIdArg;
6081060832
}
6081160833
#endif /* WOLFSSL_CMAC && !(NO_AES) && WOLFSSL_AES_DIRECT */
60834+
#if defined(HAVE_HKDF) && !defined(NO_HMAC)
60835+
else if (info->algo_type == WC_ALGO_TYPE_KDF) {
60836+
if (info->kdf.type == WC_KDF_TYPE_HKDF) {
60837+
/* Redirect to software implementation for testing */
60838+
60839+
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
60840+
ret = wc_HKDF_ex(info->kdf.hkdf.hashType,
60841+
info->kdf.hkdf.inKey, info->kdf.hkdf.inKeySz,
60842+
info->kdf.hkdf.salt, info->kdf.hkdf.saltSz,
60843+
info->kdf.hkdf.info, info->kdf.hkdf.infoSz,
60844+
info->kdf.hkdf.out, info->kdf.hkdf.outSz,
60845+
NULL, INVALID_DEVID);
60846+
#else
60847+
ret = wc_HKDF(info->kdf.hkdf.hashType,
60848+
info->kdf.hkdf.inKey, info->kdf.hkdf.inKeySz,
60849+
info->kdf.hkdf.salt, info->kdf.hkdf.saltSz,
60850+
info->kdf.hkdf.info, info->kdf.hkdf.infoSz,
60851+
info->kdf.hkdf.out, info->kdf.hkdf.outSz);
60852+
#endif
60853+
}
60854+
}
60855+
#endif /* HAVE_HKDF && !NO_HMAC */
6081260856

6081360857
(void)devIdArg;
6081460858
(void)myCtx;
@@ -60960,6 +61004,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void)
6096061004
ret = hmac_sha3_test();
6096161005
#endif
6096261006
#endif
61007+
#if defined(HAVE_HKDF) && !defined(NO_HMAC)
61008+
if (ret == 0)
61009+
ret = hkdf_test();
61010+
#endif
6096361011
#ifndef NO_PWDBASED
6096461012
#if defined(HAVE_PBKDF2) && !defined(NO_SHA256) && !defined(NO_HMAC)
6096561013
PRIVATE_KEY_UNLOCK();

wolfssl/wolfcrypt/cryptocb.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,29 @@ typedef struct wc_CryptoInfo {
468468
void *ctx;
469469
} cmd;
470470
#endif
471+
#ifdef HAVE_HKDF
472+
struct {
473+
int type; /* enum wc_KdfType */
474+
#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES
475+
union {
476+
#endif
477+
struct { /* HKDF one-shot */
478+
int hashType; /* WC_SHA256, etc. */
479+
const byte* inKey; /* Input keying material */
480+
word32 inKeySz;
481+
const byte* salt; /* Optional salt */
482+
word32 saltSz;
483+
const byte* info; /* Optional info */
484+
word32 infoSz;
485+
byte* out; /* Output key material */
486+
word32 outSz;
487+
} hkdf;
488+
/* Future KDF type structures here */
489+
#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES
490+
};
491+
#endif
492+
} kdf;
493+
#endif
471494
#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES
472495
};
473496
#endif
@@ -666,6 +689,14 @@ WOLFSSL_LOCAL int wc_CryptoCb_Hmac(Hmac* hmac, int macType, const byte* in,
666689
word32 inSz, byte* digest);
667690
#endif /* !NO_HMAC */
668691

692+
#ifdef HAVE_HKDF
693+
WOLFSSL_LOCAL int wc_CryptoCb_Hkdf(int hashType, const byte* inKey,
694+
word32 inKeySz, const byte* salt,
695+
word32 saltSz, const byte* info,
696+
word32 infoSz, byte* out, word32 outSz,
697+
int devId);
698+
#endif
699+
669700
#ifndef WC_NO_RNG
670701
WOLFSSL_LOCAL int wc_CryptoCb_RandomBlock(WC_RNG* rng, byte* out, word32 sz);
671702
WOLFSSL_LOCAL int wc_CryptoCb_RandomSeed(OS_Seed* os, byte* seed, word32 sz);

wolfssl/wolfcrypt/hmac.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ WOLFSSL_API int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
216216
const byte* salt, word32 saltSz,
217217
const byte* info, word32 infoSz,
218218
byte* out, word32 outSz);
219+
WOLFSSL_API int wc_HKDF_ex(int type, const byte* inKey, word32 inKeySz,
220+
const byte* salt, word32 saltSz,
221+
const byte* info, word32 infoSz,
222+
byte* out, word32 outSz, void* heap, int devId);
219223

220224
#endif /* HAVE_HKDF */
221225

wolfssl/wolfcrypt/types.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1220,8 +1220,16 @@ enum wc_AlgoType {
12201220
WC_ALGO_TYPE_HMAC = 6,
12211221
WC_ALGO_TYPE_CMAC = 7,
12221222
WC_ALGO_TYPE_CERT = 8,
1223+
WC_ALGO_TYPE_KDF = 9,
12231224

1224-
WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_CERT
1225+
WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_KDF
1226+
};
1227+
1228+
/* KDF types */
1229+
enum wc_KdfType {
1230+
WC_KDF_TYPE_NONE = 0,
1231+
WC_KDF_TYPE_HKDF = 1
1232+
/* Future: WC_KDF_TYPE_PBKDF2 = 2, WC_KDF_TYPE_SCRYPT = 3, etc. */
12251233
};
12261234

12271235
/* hash types */

0 commit comments

Comments
 (0)