diff --git a/src/ssl.c b/src/ssl.c index 7a9f4bb81..4401fedee 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -42128,6 +42128,28 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) } #endif /* HAVE_PK_CALLBACKS && !NO_DH */ +#if defined(HAVE_PK_CALLBACKS) && defined(HAVE_HKDF) + +void wolfSSL_CTX_SetHKDFExtractCb(WOLFSSL_CTX* ctx, CallbackHKDFExtract cb) +{ + if (ctx) + ctx->HkdfExtractCb = cb; +} + +void wolfSSL_SetHKDFExtractCtx(WOLFSSL* ssl, void *ctx) +{ + if (ssl) + ssl->HkdfExtractCtx = ctx; +} + +void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl) +{ + if (ssl) + return ssl->HkdfExtractCtx; + + return NULL; +} +#endif /* HAVE_PK_CALLBACKS && HAVE_HKDF */ #ifdef WOLFSSL_HAVE_WOLFSCEP /* Used by autoconf to see if wolfSCEP is available */ diff --git a/src/tls13.c b/src/tls13.c index 04428314f..e43fc4585 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -850,6 +850,26 @@ static int DeriveTrafficSecret(WOLFSSL* ssl, byte* secret) ssl->specs.mac_algorithm, 0); } + +static int Tls13_HKDF_Extract(WOLFSSL *ssl, byte* prk, const byte* salt, int saltLen, + byte* ikm, int ikmLen, int digest) +{ + int ret; +#ifdef HAVE_PK_CALLBACKS + void *cb_ctx = ssl->HkdfExtractCtx; + CallbackHKDFExtract cb = ssl->ctx->HkdfExtractCb; + if (cb != NULL) { + ret = cb(prk, salt, saltLen, ikm, ikmLen, digest, cb_ctx); + } + else +#endif + { + (void)ssl; + ret = wc_Tls13_HKDF_Extract(prk, salt, saltLen, ikm, ikmLen, digest); + } + return ret; +} + /* Derive the early secret using HKDF Extract. * * ssl The SSL/TLS object. @@ -864,11 +884,11 @@ int DeriveEarlySecret(WOLFSSL* ssl) } PRIVATE_KEY_UNLOCK(); #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) - ret = wc_Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0, + ret = Tls13_HKDF_Extract(ssl, ssl->arrays->secret, NULL, 0, ssl->arrays->psk_key, ssl->arrays->psk_keySz, mac2hash(ssl->specs.mac_algorithm)); #else - ret = wc_Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0, + ret = Tls13_HKDF_Extract(ssl, ssl->arrays->secret, NULL, 0, ssl->arrays->masterSecret, 0, mac2hash(ssl->specs.mac_algorithm)); #endif PRIVATE_KEY_LOCK(); @@ -900,7 +920,7 @@ int DeriveHandshakeSecret(WOLFSSL* ssl) return ret; PRIVATE_KEY_UNLOCK(); - ret = wc_Tls13_HKDF_Extract(ssl->arrays->preMasterSecret, + ret = Tls13_HKDF_Extract(ssl, ssl->arrays->preMasterSecret, key, ssl->specs.hash_size, ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, mac2hash(ssl->specs.mac_algorithm)); @@ -928,7 +948,7 @@ int DeriveMasterSecret(WOLFSSL* ssl) return ret; PRIVATE_KEY_UNLOCK(); - ret = wc_Tls13_HKDF_Extract(ssl->arrays->masterSecret, + ret = Tls13_HKDF_Extract(ssl, ssl->arrays->masterSecret, key, ssl->specs.hash_size, ssl->arrays->masterSecret, 0, mac2hash(ssl->specs.mac_algorithm)); PRIVATE_KEY_LOCK(); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 4ba923e39..75d790865 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -119,6 +119,9 @@ #ifdef HAVE_LIBOQS #include #endif +#ifdef HAVE_HKDF + #include +#endif #ifndef WOLFSSL_NO_DEF_TICKET_ENC_CB #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \ !defined(WOLFSSL_TICKET_ENC_AES128_GCM) && \ @@ -3018,6 +3021,9 @@ struct WOLFSSL_CTX { CallbackEccVerify EccVerifyCb; /* User EccVerify Callback handler */ CallbackEccSharedSecret EccSharedSecretCb; /* User EccVerify Callback handler */ #endif /* HAVE_ECC */ + #ifdef HAVE_HKDF + CallbackHKDFExtract HkdfExtractCb; /* User hkdf Extract Callback handler */ + #endif #ifdef HAVE_ED25519 /* User Ed25519Sign Callback handler */ CallbackEd25519Sign Ed25519SignCb; @@ -4454,6 +4460,9 @@ struct WOLFSSL { void* EccVerifyCtx; /* Ecc Verify Callback Context */ void* EccSharedSecretCtx; /* Ecc Pms Callback Context */ #endif /* HAVE_ECC */ + #ifdef HAVE_HKDF + void* HkdfExtractCtx; /* Hkdf extract callback context */ + #endif #ifdef HAVE_ED25519 void* Ed25519SignCtx; /* ED25519 Sign Callback Context */ void* Ed25519VerifyCtx; /* ED25519 Verify Callback Context */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 3c5d90aa1..fb4ad0612 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3042,6 +3042,15 @@ WOLFSSL_API void wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl); #endif +#ifdef HAVE_HKDF +#include +typedef int (*CallbackHKDFExtract)(byte* prk, const byte* salt, word32 saltLen, + byte* ikm, word32 ikmLen, int digest, void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetHKDFExtractCb(WOLFSSL_CTX*, CallbackHKDFExtract); +WOLFSSL_API void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl); +WOLFSSL_API void wolfSSL_SetHKDFExtractCtx(WOLFSSL* ssl, void *ctx); +#endif + #ifndef NO_DH /* Public DH Key Callback support */ struct DhKey; diff --git a/wolfssl/test.h b/wolfssl/test.h index 51f034e58..f284d088f 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -3873,6 +3873,49 @@ static WC_INLINE int myEccSharedSecret(WOLFSSL* ssl, ecc_key* otherKey, #endif /* HAVE_ECC */ +#ifdef HAVE_HKDF +static WC_INLINE int myHkdfExtract(byte* prk, const byte* salt, word32 saltLen, + byte* ikm, word32 ikmLen, int digest, void* ctx) +{ + int ret; + int len = 0; + + switch (digest) { +#ifndef NO_SHA256 + case WC_SHA256: + len = WC_SHA256_DIGEST_SIZE; + break; +#endif + +#ifdef WOLFSSL_SHA384 + case WC_SHA384: + len = WC_SHA384_DIGEST_SIZE; + break; +#endif + +#ifdef WOLFSSL_TLS13_SHA512 + case WC_SHA512: + len = WC_SHA512_DIGEST_SIZE; + break; +#endif + default: + return BAD_FUNC_ARG; + } + + /* When length is 0 then use zeroed data of digest length. */ + if (ikmLen == 0) { + ikmLen = len; + XMEMSET(ikm, 0, len); + } + + (void)ctx; + ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk); + WOLFSSL_PKMSG("PK HKDF Extract: ret %d saltLen %d ikmLen %d\n", ret, saltLen, + ikmLen); + return ret; +} +#endif /* HAVE_HKDF */ + #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) #ifdef HAVE_ED25519_SIGN static WC_INLINE int myEd25519Sign(WOLFSSL* ssl, const byte* in, word32 inSz, @@ -4728,6 +4771,9 @@ static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx) wolfSSL_CTX_SetEccVerifyCb(ctx, myEccVerify); wolfSSL_CTX_SetEccSharedSecretCb(ctx, myEccSharedSecret); #endif /* HAVE_ECC */ + #ifdef HAVE_HKDF + wolfSSL_CTX_SetHKDFExtractCb(ctx, myHkdfExtract); + #endif /* HAVE_HKDF */ #ifndef NO_DH wolfSSL_CTX_SetDhAgreeCb(ctx, myDhCallback); #endif @@ -4790,6 +4836,9 @@ static WC_INLINE void SetupPkCallbackContexts(WOLFSSL* ssl, void* myCtx) wolfSSL_SetEccVerifyCtx(ssl, myCtx); wolfSSL_SetEccSharedSecretCtx(ssl, myCtx); #endif /* HAVE_ECC */ + #ifdef HAVE_HKDF + wolfSSL_SetHKDFExtractCtx(ssl, myCtx); + #endif /* HAVE_HKDF */ #ifndef NO_DH wolfSSL_SetDhAgreeCtx(ssl, myCtx); #endif