Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions wolfcrypt/src/cryptocb.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ static const char* GetKdfTypeStr(int type)
switch (type) {
case WC_KDF_TYPE_HKDF:
return "HKDF";
case WC_KDF_TYPE_HKDF_EXTRACT:
return "HKDF Extract";
case WC_KDF_TYPE_HKDF_EXPAND:
return "HKDF Expand";
case WC_KDF_TYPE_TWOSTEP_CMAC:
return "TWOSTEP_CMAC";
}
Expand Down Expand Up @@ -2527,6 +2531,64 @@ int wc_CryptoCb_Hkdf(int hashType, const byte* inKey, word32 inKeySz,

return wc_CryptoCb_TranslateErrorCode(ret);
}

int wc_CryptoCb_Hkdf_Extract(int hashType, const byte* salt, word32 saltSz,
const byte* inKey, word32 inKeySz, byte* out, int devId)
Comment thread
twcook86 marked this conversation as resolved.
{
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
CryptoCb* dev;

/* Find registered callback device */
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_KDF);

if (dev && dev->cb) {
wc_CryptoInfo cryptoInfo;
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));

cryptoInfo.algo_type = WC_ALGO_TYPE_KDF;
cryptoInfo.kdf.type = WC_KDF_TYPE_HKDF_EXTRACT;
cryptoInfo.kdf.hkdf_extract.hashType = hashType;
cryptoInfo.kdf.hkdf_extract.salt = salt;
cryptoInfo.kdf.hkdf_extract.saltSz = saltSz;
cryptoInfo.kdf.hkdf_extract.inKey = inKey;
cryptoInfo.kdf.hkdf_extract.inKeySz = inKeySz;
cryptoInfo.kdf.hkdf_extract.out = out;

ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
}

return wc_CryptoCb_TranslateErrorCode(ret);
}

int wc_CryptoCb_Hkdf_Expand(int hashType, const byte* inKey, word32 inKeySz,
const byte* info, word32 infoSz, byte* out, word32 outSz,
int devId)
Comment thread
twcook86 marked this conversation as resolved.
{
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
CryptoCb* dev;

/* Find registered callback device */
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_KDF);

if (dev && dev->cb) {
wc_CryptoInfo cryptoInfo;
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));

cryptoInfo.algo_type = WC_ALGO_TYPE_KDF;
cryptoInfo.kdf.type = WC_KDF_TYPE_HKDF_EXPAND;
cryptoInfo.kdf.hkdf_expand.hashType = hashType;
cryptoInfo.kdf.hkdf_expand.inKey = inKey;
cryptoInfo.kdf.hkdf_expand.inKeySz = inKeySz;
cryptoInfo.kdf.hkdf_expand.info = info;
cryptoInfo.kdf.hkdf_expand.infoSz = infoSz;
cryptoInfo.kdf.hkdf_expand.out = out;
cryptoInfo.kdf.hkdf_expand.outSz = outSz;

ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
}

return wc_CryptoCb_TranslateErrorCode(ret);
}
#endif /* HAVE_HKDF && !NO_HMAC */

#ifdef WOLF_CRYPTO_CB_COPY
Expand Down
39 changes: 28 additions & 11 deletions wolfcrypt/src/hmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1754,19 +1754,27 @@ int wolfSSL_GetHmacMaxSize(void)
const byte* localSalt; /* either points to user input or tmp */
word32 hashSz;

if (out == NULL || (inKey == NULL && inKeySz > 0)) {
if (out == NULL || (inKey == NULL && inKeySz > 0))
return BAD_FUNC_ARG;

#ifdef WOLF_CRYPTO_CB
/* Try crypto callback first */
if (devId != INVALID_DEVID) {
ret = wc_CryptoCb_Hkdf_Extract(type, salt, saltSz, inKey, inKeySz,
out, devId);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
}
#endif

Comment thread
twcook86 marked this conversation as resolved.
ret = wc_HmacSizeByType(type);
if (ret < 0) {
if (ret < 0)
return ret;
}
hashSz = (word32)ret;

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

hashSz = (word32)ret;
localSalt = salt;
if (localSalt == NULL) {
XMEMSET(tmp, 0, hashSz);
Expand Down Expand Up @@ -1822,25 +1830,35 @@ int wolfSSL_GetHmacMaxSize(void)
word32 hashSz;
byte n = 0x1;

if (out == NULL || (inKey == NULL && inKeySz > 0))
return BAD_FUNC_ARG;

ret = wc_HmacSizeByType(type);
if (ret < 0) {
if (ret < 0)
return ret;
}
hashSz = (word32)ret;

/* RFC 5869 states that the length of output keying material in
* octets must be L <= 255*HashLen or N = ceil(L/HashLen) */

if (out == NULL || ((outSz/hashSz) + ((outSz % hashSz) != 0)) > 255) {
if (outSz/hashSz + ((outSz % hashSz) != 0) > 255)
return BAD_FUNC_ARG;

#ifdef WOLF_CRYPTO_CB
/* Try crypto callback first for complete operation */
if (devId != INVALID_DEVID) {
ret = wc_CryptoCb_Hkdf_Expand(type, inKey, inKeySz, info, infoSz,
out, outSz, devId);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
}
#endif

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

ret = wc_HmacInit(myHmac, heap, devId);
if (ret != 0) {
WC_FREE_VAR_EX(myHmac, NULL, DYNAMIC_TYPE_HMAC);
WC_FREE_VAR_EX(myHmac, NULL, DYNAMIC_TYPE_HMAC);
return ret;
}

Expand Down Expand Up @@ -1927,9 +1945,8 @@ int wolfSSL_GetHmacMaxSize(void)
#endif

ret = wc_HmacSizeByType(type);
if (ret < 0) {
if (ret < 0)
return ret;
}
hashSz = (word32)ret;

ret = wc_HKDF_Extract_ex(type, salt, saltSz, inKey, inKeySz, prk, heap,
Expand Down
146 changes: 143 additions & 3 deletions wolfcrypt/test/test.c
Comment thread
twcook86 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -34735,6 +34735,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)

#if !defined(NO_SHA) || !defined(NO_SHA256)
int L;
byte prk[WC_MAX_DIGEST_SIZE];
byte okm1[42];
byte ikm1[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
Expand Down Expand Up @@ -34799,7 +34800,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
#ifndef HAVE_FIPS
/* fips can't have key size under 14 bytes, salt is key too */
L = (int)sizeof(okm1);
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
#if !defined(HAVE_SELFTEST)
ret = wc_HKDF_ex(WC_SHA, ikm1, 11, salt1, (word32)sizeof(salt1), info1,
(word32)sizeof(info1), okm1, (word32)L, HEAP_HINT, devId);
#else
Expand All @@ -34811,7 +34812,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)

if (XMEMCMP(okm1, res2, (unsigned long)L) != 0)
return WC_TEST_RET_ENC_NC;
#endif /* HAVE_FIPS */
#endif /* !HAVE_FIPS */
#endif /* !NO_SHA */

#ifndef NO_SHA256
Expand Down Expand Up @@ -34844,7 +34845,106 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)

if (XMEMCMP(okm1, res4, (unsigned long)L) != 0)
return WC_TEST_RET_ENC_NC;
#endif /* HAVE_FIPS */
#endif /* !HAVE_FIPS */
#endif /* !NO_SHA256 */

#ifndef NO_SHA
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
ret = wc_HKDF_Extract_ex(WC_SHA, NULL, 0, ikm1, (word32)sizeof(ikm1),
prk, HEAP_HINT, devId);
#else
ret = wc_HKDF_Extract(WC_SHA, NULL, 0, ikm1, (word32)sizeof(ikm1), prk);
#endif
if (ret != 0)
return WC_TEST_RET_ENC_EC(ret);

#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
ret = wc_HKDF_Expand_ex(WC_SHA, prk, WC_SHA_DIGEST_SIZE, NULL, 0,
okm1, (word32)L, HEAP_HINT, devId);
#else
ret = wc_HKDF_Expand(WC_SHA, prk, WC_SHA_DIGEST_SIZE, NULL, 0,
okm1, (word32)L);
#endif
if (ret != 0)
return WC_TEST_RET_ENC_EC(ret);

if (XMEMCMP(okm1, res1, (unsigned long)L) != 0)
return WC_TEST_RET_ENC_NC;

#ifndef HAVE_FIPS
/* fips can't have key size under 14 bytes, salt is key too */
#if !defined(HAVE_SELFTEST)
ret = wc_HKDF_Extract_ex(WC_SHA, salt1, (word32)sizeof(salt1), ikm1, 11,
prk, HEAP_HINT, devId);
#else
ret = wc_HKDF_Extract(WC_SHA, salt1, (word32)sizeof(salt1), ikm1, 11, prk);
#endif
if (ret != 0)
return WC_TEST_RET_ENC_EC(ret);

#if !defined(HAVE_SELFTEST)
ret = wc_HKDF_Expand_ex(WC_SHA, prk, WC_SHA_DIGEST_SIZE, info1,
(word32)sizeof(info1), okm1, (word32)L, HEAP_HINT, devId);
#else
ret = wc_HKDF_Expand(WC_SHA, prk, WC_SHA_DIGEST_SIZE, info1,
(word32)sizeof(info1), okm1, (word32)L);
#endif
if (ret != 0)
return WC_TEST_RET_ENC_EC(ret);

if (XMEMCMP(okm1, res2, (unsigned long)L) != 0)
return WC_TEST_RET_ENC_NC;
#endif /* !HAVE_FIPS */
#endif /* !NO_SHA */

#ifndef NO_SHA256
#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
ret = wc_HKDF_Extract_ex(WC_SHA256, NULL, 0, ikm1, (word32)sizeof(ikm1),
prk, HEAP_HINT, devId);
#else
ret = wc_HKDF_Extract(WC_SHA256, NULL, 0, ikm1, (word32)sizeof(ikm1), prk);
#endif
if (ret != 0)
return WC_TEST_RET_ENC_EC(ret);

#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
ret = wc_HKDF_Expand_ex(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, NULL, 0,
okm1, (word32)L, HEAP_HINT, devId);
#else
ret = wc_HKDF_Expand(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, NULL, 0,
okm1, (word32)L);
#endif
if (ret != 0)
return WC_TEST_RET_ENC_EC(ret);

if (XMEMCMP(okm1, res3, (unsigned long)L) != 0)
return WC_TEST_RET_ENC_NC;

#ifndef HAVE_FIPS
/* fips can't have key size under 14 bytes, salt is key too */
#if !defined(HAVE_SELFTEST)
ret = wc_HKDF_Extract_ex(WC_SHA256, salt1, (word32)sizeof(salt1), ikm1,
(word32)sizeof(ikm1), prk, HEAP_HINT, devId);
#else
ret = wc_HKDF_Extract(WC_SHA256, salt1, (word32)sizeof(salt1), ikm1,
(word32)sizeof(ikm1), prk);
#endif
if (ret != 0)
return WC_TEST_RET_ENC_EC(ret);

#if !defined(HAVE_SELFTEST)
ret = wc_HKDF_Expand_ex(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, info1,
(word32)sizeof(info1), okm1, (word32)L, HEAP_HINT, devId);
#else
ret = wc_HKDF_Expand(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, info1,
(word32)sizeof(info1), okm1, (word32)L);
#endif
if (ret != 0)
return WC_TEST_RET_ENC_EC(ret);

if (XMEMCMP(okm1, res4, (unsigned long)L) != 0)
return WC_TEST_RET_ENC_NC;
#endif /* !HAVE_FIPS */
#endif /* !NO_SHA256 */
#endif /* !NO_SHA || !NO_SHA256 */

Expand All @@ -34858,6 +34958,16 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void)
ret = wc_HKDF_Extract(WC_SHA256, NULL, 0, NULL, 5, okm1);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
return WC_TEST_RET_ENC_EC(ret);
/* wc_HKDF_Expand bad arg: NULL out */
ret = wc_HKDF_Expand(WC_SHA256, prk, WC_SHA256_DIGEST_SIZE, info1,
(word32)sizeof(info1), NULL, (word32)L);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
return WC_TEST_RET_ENC_EC(ret);
/* wc_HKDF_Expand bad arg: NULL inKey with non-zero inKeySz */
ret = wc_HKDF_Expand(WC_SHA256, NULL, WC_SHA256_DIGEST_SIZE, info1,
(word32)sizeof(info1), okm1, (word32)L);
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
return WC_TEST_RET_ENC_EC(ret);
#endif /* !NO_SHA256 && !HAVE_SELFTEST && */
/* (!HAVE_FIPS || FIPS_VERSION3_GE(7,0,0)) */

Expand Down Expand Up @@ -74152,6 +74262,36 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
info->kdf.hkdf.out, info->kdf.hkdf.outSz);
#endif
}
if (info->kdf.type == WC_KDF_TYPE_HKDF_EXTRACT) {
#if !defined(HAVE_SELFTEST) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
ret = wc_HKDF_Extract_ex(info->kdf.hkdf_extract.hashType,
info->kdf.hkdf_extract.salt, info->kdf.hkdf_extract.saltSz,
info->kdf.hkdf_extract.inKey, info->kdf.hkdf_extract.inKeySz,
info->kdf.hkdf_extract.out,
NULL, INVALID_DEVID);
#else
ret = wc_HKDF_Extract(info->kdf.hkdf_extract.hashType,
info->kdf.hkdf_extract.salt, info->kdf.hkdf_extract.saltSz,
info->kdf.hkdf_extract.inKey, info->kdf.hkdf_extract.inKeySz,
info->kdf.hkdf_extract.out);
#endif
}
if (info->kdf.type == WC_KDF_TYPE_HKDF_EXPAND) {
#if !defined(HAVE_SELFTEST) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(7,0))
ret = wc_HKDF_Expand_ex(info->kdf.hkdf_expand.hashType,
info->kdf.hkdf_expand.inKey, info->kdf.hkdf_expand.inKeySz,
info->kdf.hkdf_expand.info, info->kdf.hkdf_expand.infoSz,
info->kdf.hkdf_expand.out, info->kdf.hkdf_expand.outSz,
NULL, INVALID_DEVID);
#else
ret = wc_HKDF_Expand(info->kdf.hkdf_expand.hashType,
info->kdf.hkdf_expand.inKey, info->kdf.hkdf_expand.inKeySz,
info->kdf.hkdf_expand.info, info->kdf.hkdf_expand.infoSz,
info->kdf.hkdf_expand.out, info->kdf.hkdf_expand.outSz);
#endif
}
#endif /* HAVE_HKDF && !NO_HMAC */
#if defined(HAVE_CMAC_KDF)
if (info->kdf.type == WC_KDF_TYPE_TWOSTEP_CMAC) {
Expand Down
22 changes: 22 additions & 0 deletions wolfssl/wolfcrypt/cryptocb.h
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,23 @@ typedef struct wc_CryptoInfo {
byte* out; /* Output key material */
word32 outSz;
} hkdf;
struct { /* HKDF extract */
int hashType; /* WC_SHA256, etc. */
const byte* salt; /* Optional salt */
word32 saltSz;
const byte* inKey; /* Input keying material */
word32 inKeySz;
byte* out; /* Output key material */
} hkdf_extract;
struct { /* HKDF expand */
int hashType; /* WC_SHA256, etc. */
const byte* inKey; /* Input keying material */
word32 inKeySz;
const byte* info; /* Optional info */
word32 infoSz;
byte* out; /* Output key material */
word32 outSz;
} hkdf_expand;
#endif
#if defined(HAVE_CMAC_KDF)
struct { /* NIST.SP.800-56Cr2 two-step cmac KDF */
Expand Down Expand Up @@ -894,6 +911,11 @@ WOLFSSL_LOCAL int wc_CryptoCb_Hkdf(int hashType, const byte* inKey,
word32 saltSz, const byte* info,
word32 infoSz, byte* out, word32 outSz,
int devId);
WOLFSSL_LOCAL int wc_CryptoCb_Hkdf_Extract(int hashType, const byte* salt,
word32 saltSz, const byte* inKey, word32 inKeySz, byte* out, int devId);
WOLFSSL_LOCAL int wc_CryptoCb_Hkdf_Expand(int hashType, const byte* inKey,
word32 inKeySz, const byte* info, word32 infoSz,
byte* out, word32 outSz, int devId);
#endif

#if defined(HAVE_CMAC_KDF)
Expand Down
6 changes: 4 additions & 2 deletions wolfssl/wolfcrypt/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1440,8 +1440,10 @@ enum wc_AlgoType {
enum wc_KdfType {
WC_KDF_TYPE_NONE = 0,
WC_KDF_TYPE_HKDF = 1,
WC_KDF_TYPE_TWOSTEP_CMAC = 2 /* NIST SP 800-56C two-step cmac kdf. */
/* Future: WC_KDF_TYPE_PBKDF2 = 3, WC_KDF_TYPE_SCRYPT = 4, etc. */
WC_KDF_TYPE_TWOSTEP_CMAC = 2, /* NIST SP 800-56C two-step cmac kdf. */
WC_KDF_TYPE_HKDF_EXTRACT = 3,
WC_KDF_TYPE_HKDF_EXPAND = 4
/* Future: WC_KDF_TYPE_PBKDF2 = 5, WC_KDF_TYPE_SCRYPT = 6, etc. */
Comment thread
twcook86 marked this conversation as resolved.
};

/* hash types */
Expand Down
Loading