mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
Move the TLSv1.3 KDF into wolfCrypt with the other KDFs.
This commit is contained in:
93
src/tls13.c
93
src/tls13.c
@ -134,6 +134,18 @@
|
||||
*/
|
||||
#define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; }
|
||||
|
||||
#if (defined(HAVE_FIPS) && \
|
||||
(!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 4))) || \
|
||||
defined(HAVE_SELFTEST)
|
||||
|
||||
enum {
|
||||
/*
|
||||
MAX_HKDF_LABEL_SZ = OPAQUE16_LEN +
|
||||
OPAQUE8_LEN + PROTOCOL_LABEL_SZ + MAX_LABEL_SZ +
|
||||
OPAQUE8_LEN + WC_MAX_DIGEST_SIZE
|
||||
*/
|
||||
MAX_TLS13_HKDF_LABEL_SZ = 47 + WC_MAX_DIGEST_SIZE
|
||||
};
|
||||
|
||||
/* Extract data using HMAC, salt and input.
|
||||
* RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
|
||||
@ -143,37 +155,35 @@
|
||||
* saltLen The length of the salt.
|
||||
* ikm The input keying material.
|
||||
* ikmLen The length of the input keying material.
|
||||
* mac The type of digest to use.
|
||||
* digest The type of digest to use.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
|
||||
byte* ikm, int ikmLen, int mac)
|
||||
static int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
|
||||
byte* ikm, int ikmLen, int digest)
|
||||
{
|
||||
int ret;
|
||||
int hash = 0;
|
||||
int len = 0;
|
||||
|
||||
switch (mac) {
|
||||
switch (digest) {
|
||||
#ifndef NO_SHA256
|
||||
case sha256_mac:
|
||||
hash = WC_SHA256;
|
||||
case WC_SHA256:
|
||||
len = WC_SHA256_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case sha384_mac:
|
||||
hash = WC_SHA384;
|
||||
case WC_SHA384:
|
||||
len = WC_SHA384_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13_SHA512
|
||||
case sha512_mac:
|
||||
hash = WC_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. */
|
||||
@ -189,7 +199,7 @@ static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
|
||||
WOLFSSL_BUFFER(ikm, ikmLen);
|
||||
#endif
|
||||
|
||||
ret = wc_HKDF_Extract(hash, salt, saltLen, ikm, ikmLen, prk);
|
||||
ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk);
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG(" PRK");
|
||||
@ -199,6 +209,7 @@ static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Expand data using HMAC, salt and label and info.
|
||||
* TLS v1.3 defines this function.
|
||||
*
|
||||
@ -213,7 +224,7 @@ static int Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
|
||||
* digest The type of digest to use.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int HKDF_Expand_Label(byte* okm, word32 okmLen,
|
||||
static int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
|
||||
const byte* prk, word32 prkLen,
|
||||
const byte* protocol, word32 protocolLen,
|
||||
const byte* label, word32 labelLen,
|
||||
@ -222,7 +233,7 @@ static int HKDF_Expand_Label(byte* okm, word32 okmLen,
|
||||
{
|
||||
int ret = 0;
|
||||
int idx = 0;
|
||||
byte data[MAX_HKDF_LABEL_SZ];
|
||||
byte data[MAX_TLS13_HKDF_LABEL_SZ];
|
||||
|
||||
/* Output length. */
|
||||
data[idx++] = (byte)(okmLen >> 8);
|
||||
@ -262,6 +273,8 @@ static int HKDF_Expand_Label(byte* okm, word32 okmLen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HAVE_FIPS */
|
||||
|
||||
/* Size of the TLS v1.3 label use when deriving keys. */
|
||||
#define TLS13_PROTOCOL_LABEL_SZ 6
|
||||
/* The protocol label for TLS v1.3. */
|
||||
@ -355,7 +368,7 @@ static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen,
|
||||
if (outputLen == -1)
|
||||
outputLen = hashSz;
|
||||
|
||||
return HKDF_Expand_Label(output, outputLen, secret, hashSz,
|
||||
return wc_Tls13_HKDF_Expand_Label(output, outputLen, secret, hashSz,
|
||||
protocol, protocolLen, label, labelLen,
|
||||
hash, hashSz, digestAlg);
|
||||
}
|
||||
@ -424,11 +437,41 @@ static int DeriveKey(WOLFSSL* ssl, byte* output, int outputLen,
|
||||
if (includeMsgs)
|
||||
hashOutSz = hashSz;
|
||||
|
||||
return HKDF_Expand_Label(output, outputLen, secret, hashSz,
|
||||
return wc_Tls13_HKDF_Expand_Label(output, outputLen, secret, hashSz,
|
||||
protocol, protocolLen, label, labelLen,
|
||||
hash, hashOutSz, digestAlg);
|
||||
}
|
||||
|
||||
/* Convert TLS mac ID to a hash algorithm ID
|
||||
*
|
||||
* mac Mac ID to convert
|
||||
* returns hash ID on success, or the NONE type.
|
||||
*/
|
||||
static WC_INLINE int mac2hash(int mac)
|
||||
{
|
||||
int hash = WC_HASH_TYPE_NONE;
|
||||
switch (mac) {
|
||||
#ifndef NO_SHA256
|
||||
case sha256_mac:
|
||||
hash = WC_SHA256;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case sha384_mac:
|
||||
hash = WC_SHA384;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_TLS13_SHA512
|
||||
case sha512_mac:
|
||||
hash = WC_SHA512;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
#ifndef NO_PSK
|
||||
/* The length of the binder key label. */
|
||||
#define BINDER_KEY_LABEL_SZ 10
|
||||
@ -904,12 +947,12 @@ int DeriveEarlySecret(WOLFSSL* ssl)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
|
||||
return Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
|
||||
return wc_Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
|
||||
ssl->arrays->psk_key, ssl->arrays->psk_keySz,
|
||||
ssl->specs.mac_algorithm);
|
||||
mac2hash(ssl->specs.mac_algorithm));
|
||||
#else
|
||||
return Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
|
||||
ssl->arrays->masterSecret, 0, ssl->specs.mac_algorithm);
|
||||
return wc_Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
|
||||
ssl->arrays->masterSecret, 0, mac2hash(ssl->specs.mac_algorithm));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -937,10 +980,10 @@ int DeriveHandshakeSecret(WOLFSSL* ssl)
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return Tls13_HKDF_Extract(ssl->arrays->preMasterSecret,
|
||||
return wc_Tls13_HKDF_Extract(ssl->arrays->preMasterSecret,
|
||||
key, ssl->specs.hash_size,
|
||||
ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz,
|
||||
ssl->specs.mac_algorithm);
|
||||
mac2hash(ssl->specs.mac_algorithm));
|
||||
}
|
||||
|
||||
/* Derive the master secret using HKDF Extract.
|
||||
@ -961,9 +1004,9 @@ int DeriveMasterSecret(WOLFSSL* ssl)
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
ret = Tls13_HKDF_Extract(ssl->arrays->masterSecret,
|
||||
ret = wc_Tls13_HKDF_Extract(ssl->arrays->masterSecret,
|
||||
key, ssl->specs.hash_size,
|
||||
ssl->arrays->masterSecret, 0, ssl->specs.mac_algorithm);
|
||||
ssl->arrays->masterSecret, 0, mac2hash(ssl->specs.mac_algorithm));
|
||||
|
||||
#ifdef HAVE_KEYING_MATERIAL
|
||||
if (ret != 0)
|
||||
@ -1021,7 +1064,7 @@ int DeriveResumptionPSK(WOLFSSL* ssl, byte* nonce, byte nonceLen, byte* secret)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
return HKDF_Expand_Label(secret, ssl->specs.hash_size,
|
||||
return wc_Tls13_HKDF_Expand_Label(secret, ssl->specs.hash_size,
|
||||
ssl->session.masterSecret, ssl->specs.hash_size,
|
||||
protocol, protocolLen, resumptionLabel,
|
||||
RESUMPTION_LABEL_SZ, nonce, nonceLen, digestAlg);
|
||||
|
@ -1597,6 +1597,133 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen,
|
||||
return wc_HKDF_Expand(type, prk, hashSz, info, infoSz, out, outSz);
|
||||
}
|
||||
|
||||
#if !defined(HAVE_FIPS) || \
|
||||
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 4)
|
||||
/* Extract data using HMAC, salt and input.
|
||||
* RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
|
||||
*
|
||||
* prk The generated pseudorandom key.
|
||||
* salt The salt.
|
||||
* saltLen The length of the salt.
|
||||
* ikm The input keying material.
|
||||
* ikmLen The length of the input keying material.
|
||||
* digest The type of digest to use.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
|
||||
byte* ikm, int ikmLen, int digest)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG(" Salt");
|
||||
WOLFSSL_BUFFER(salt, saltLen);
|
||||
WOLFSSL_MSG(" IKM");
|
||||
WOLFSSL_BUFFER(ikm, ikmLen);
|
||||
#endif
|
||||
|
||||
ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk);
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG(" PRK");
|
||||
WOLFSSL_BUFFER(prk, len);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Expand data using HMAC, salt and label and info.
|
||||
* TLS v1.3 defines this function.
|
||||
*
|
||||
* okm The generated pseudorandom key - output key material.
|
||||
* okmLen The length of generated pseudorandom key -
|
||||
* output key material.
|
||||
* prk The salt - pseudo-random key.
|
||||
* prkLen The length of the salt - pseudo-random key.
|
||||
* protocol The TLS protocol label.
|
||||
* protocolLen The length of the TLS protocol label.
|
||||
* info The information to expand.
|
||||
* infoLen The length of the information.
|
||||
* digest The type of digest to use.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
|
||||
const byte* prk, word32 prkLen,
|
||||
const byte* protocol, word32 protocolLen,
|
||||
const byte* label, word32 labelLen,
|
||||
const byte* info, word32 infoLen,
|
||||
int digest)
|
||||
{
|
||||
int ret = 0;
|
||||
int idx = 0;
|
||||
byte data[MAX_TLS13_HKDF_LABEL_SZ];
|
||||
|
||||
/* Output length. */
|
||||
data[idx++] = (byte)(okmLen >> 8);
|
||||
data[idx++] = (byte)okmLen;
|
||||
/* Length of protocol | label. */
|
||||
data[idx++] = (byte)(protocolLen + labelLen);
|
||||
/* Protocol */
|
||||
XMEMCPY(&data[idx], protocol, protocolLen);
|
||||
idx += protocolLen;
|
||||
/* Label */
|
||||
XMEMCPY(&data[idx], label, labelLen);
|
||||
idx += labelLen;
|
||||
/* Length of hash of messages */
|
||||
data[idx++] = (byte)infoLen;
|
||||
/* Hash of messages */
|
||||
XMEMCPY(&data[idx], info, infoLen);
|
||||
idx += infoLen;
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG(" PRK");
|
||||
WOLFSSL_BUFFER(prk, prkLen);
|
||||
WOLFSSL_MSG(" Info");
|
||||
WOLFSSL_BUFFER(data, idx);
|
||||
#endif
|
||||
|
||||
ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
|
||||
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG(" OKM");
|
||||
WOLFSSL_BUFFER(okm, okmLen);
|
||||
#endif
|
||||
|
||||
ForceZero(data, idx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* newer HAVE_FIPS */
|
||||
|
||||
#endif /* HAVE_HKDF */
|
||||
|
||||
|
||||
|
@ -1362,9 +1362,6 @@ enum Misc {
|
||||
KEY_LABEL_SZ = 13, /* TLS key block expansion sz */
|
||||
PROTOCOL_LABEL_SZ = 9, /* Length of the protocol label */
|
||||
MAX_LABEL_SZ = 34, /* Maximum length of a label */
|
||||
MAX_HKDF_LABEL_SZ = OPAQUE16_LEN +
|
||||
OPAQUE8_LEN + PROTOCOL_LABEL_SZ + MAX_LABEL_SZ +
|
||||
OPAQUE8_LEN + WC_MAX_DIGEST_SIZE,
|
||||
MAX_REQUEST_SZ = 256, /* Maximum cert req len (no auth yet */
|
||||
SESSION_FLUSH_COUNT = 256, /* Flush session cache unless user turns off */
|
||||
TLS_MAX_PAD_SZ = 255, /* Max padding in TLS */
|
||||
|
@ -234,6 +234,30 @@ WOLFSSL_API int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
|
||||
const byte* info, word32 infoSz,
|
||||
byte* out, word32 outSz);
|
||||
|
||||
#if (!defined(HAVE_FIPS) || \
|
||||
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 4))) && \
|
||||
!defined(HAVE_SELFTEST)
|
||||
|
||||
enum {
|
||||
/*
|
||||
MAX_HKDF_LABEL_SZ = OPAQUE16_LEN +
|
||||
OPAQUE8_LEN + PROTOCOL_LABEL_SZ + MAX_LABEL_SZ +
|
||||
OPAQUE8_LEN + WC_MAX_DIGEST_SIZE
|
||||
*/
|
||||
MAX_TLS13_HKDF_LABEL_SZ = 47 + WC_MAX_DIGEST_SIZE
|
||||
};
|
||||
|
||||
WOLFSSL_API int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, int saltLen,
|
||||
byte* ikm, int ikmLen, int digest);
|
||||
|
||||
WOLFSSL_API int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
|
||||
const byte* prk, word32 prkLen,
|
||||
const byte* protocol, word32 protocolLen,
|
||||
const byte* label, word32 labelLen,
|
||||
const byte* info, word32 infoLen,
|
||||
int digest);
|
||||
|
||||
#endif /* HAVE_FIPS */
|
||||
#endif /* HAVE_HKDF */
|
||||
|
||||
#ifdef WOLFSSL_WOLFSSH
|
||||
|
Reference in New Issue
Block a user