From 52069c7eff4822650ed98358719ccebd85d53163 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 16 Aug 2019 21:15:32 +0300 Subject: [PATCH] Add TLS-PRF using HMAC with P_SHA384 for TEAP This version of TLS PRF is needed when using TEAP with TLS ciphersuites that are defined to use SHA384 instead of SHA256. Signed-off-by: Jouni Malinen --- hostapd/Android.mk | 5 +++ hostapd/Makefile | 5 +++ src/crypto/sha384-tlsprf.c | 71 ++++++++++++++++++++++++++++++++++++++ src/crypto/sha384.h | 3 ++ wpa_supplicant/Android.mk | 5 +++ wpa_supplicant/Makefile | 5 +++ 6 files changed, 94 insertions(+) create mode 100644 src/crypto/sha384-tlsprf.c diff --git a/hostapd/Android.mk b/hostapd/Android.mk index 79b8a4840..9824a529d 100644 --- a/hostapd/Android.mk +++ b/hostapd/Android.mk @@ -494,6 +494,8 @@ OBJS += src/eap_common/eap_teap_common.c TLS_FUNCS=y NEED_T_PRF=y NEED_SHA384=y +NEED_TLS_PRF_SHA256=y +NEED_TLS_PRF_SHA384=y NEED_AES_UNWRAP=y endif @@ -923,6 +925,9 @@ endif ifdef NEED_TLS_PRF_SHA256 OBJS += src/crypto/sha256-tlsprf.c endif +ifdef NEED_TLS_PRF_SHA384 +OBJS += src/crypto/sha384-tlsprf.c +endif ifdef NEED_HMAC_SHA256_KDF OBJS += src/crypto/sha256-kdf.c endif diff --git a/hostapd/Makefile b/hostapd/Makefile index 2a6bd7ac8..2cbd6d9e6 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -533,6 +533,8 @@ OBJS += ../src/eap_common/eap_teap_common.o TLS_FUNCS=y NEED_T_PRF=y NEED_SHA384=y +NEED_TLS_PRF_SHA256=y +NEED_TLS_PRF_SHA384=y NEED_AES_UNWRAP=y endif @@ -1068,6 +1070,9 @@ endif ifdef NEED_TLS_PRF_SHA256 OBJS += ../src/crypto/sha256-tlsprf.o endif +ifdef NEED_TLS_PRF_SHA384 +OBJS += ../src/crypto/sha384-tlsprf.o +endif ifdef NEED_HMAC_SHA256_KDF OBJS += ../src/crypto/sha256-kdf.o endif diff --git a/src/crypto/sha384-tlsprf.c b/src/crypto/sha384-tlsprf.c new file mode 100644 index 000000000..9ff96ac2c --- /dev/null +++ b/src/crypto/sha384-tlsprf.c @@ -0,0 +1,71 @@ +/* + * TLS PRF P_SHA384 + * Copyright (c) 2011-2019, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "includes.h" + +#include "common.h" +#include "sha384.h" + + +/** + * tls_prf_sha384 - Pseudo-Random Function for TLS v1.2 (P_SHA384, RFC 5246) + * @secret: Key for PRF + * @secret_len: Length of the key in bytes + * @label: A unique label for each purpose of the PRF + * @seed: Seed value to bind into the key + * @seed_len: Length of the seed + * @out: Buffer for the generated pseudo-random key + * @outlen: Number of bytes of key to generate + * Returns: 0 on success, -1 on failure. + * + * This function is used to derive new, cryptographically separate keys from a + * given key in TLS. This PRF is defined in RFC 5246, Chapter 5. + */ +int tls_prf_sha384(const u8 *secret, size_t secret_len, const char *label, + const u8 *seed, size_t seed_len, u8 *out, size_t outlen) +{ + size_t clen; + u8 A[SHA384_MAC_LEN]; + u8 P[SHA384_MAC_LEN]; + size_t pos; + const unsigned char *addr[3]; + size_t len[3]; + + addr[0] = A; + len[0] = SHA384_MAC_LEN; + addr[1] = (unsigned char *) label; + len[1] = os_strlen(label); + addr[2] = seed; + len[2] = seed_len; + + /* + * RFC 5246, Chapter 5 + * A(0) = seed, A(i) = HMAC(secret, A(i-1)) + * P_hash = HMAC(secret, A(1) + seed) + HMAC(secret, A(2) + seed) + .. + * PRF(secret, label, seed) = P_SHA384(secret, label + seed) + */ + + if (hmac_sha384_vector(secret, secret_len, 2, &addr[1], &len[1], A) < 0) + return -1; + + pos = 0; + while (pos < outlen) { + if (hmac_sha384_vector(secret, secret_len, 3, addr, len, P) < + 0 || + hmac_sha384(secret, secret_len, A, SHA384_MAC_LEN, A) < 0) + return -1; + + clen = outlen - pos; + if (clen > SHA384_MAC_LEN) + clen = SHA384_MAC_LEN; + os_memcpy(out + pos, P, clen); + pos += clen; + } + + return 0; +} diff --git a/src/crypto/sha384.h b/src/crypto/sha384.h index 224142538..d946907c6 100644 --- a/src/crypto/sha384.h +++ b/src/crypto/sha384.h @@ -20,6 +20,9 @@ int sha384_prf(const u8 *key, size_t key_len, const char *label, int sha384_prf_bits(const u8 *key, size_t key_len, const char *label, const u8 *data, size_t data_len, u8 *buf, size_t buf_len_bits); +int tls_prf_sha384(const u8 *secret, size_t secret_len, + const char *label, const u8 *seed, size_t seed_len, + u8 *out, size_t outlen); int hmac_sha384_kdf(const u8 *secret, size_t secret_len, const char *label, const u8 *seed, size_t seed_len, u8 *out, size_t outlen); diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index b5d982de3..093dcea86 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -659,6 +659,8 @@ TLS_FUNCS=y CONFIG_IEEE8021X_EAPOL=y NEED_T_PRF=y NEED_SHA384=y +NEED_TLS_PRF_SHA256=y +NEED_TLS_PRF_SHA384=y endif ifdef CONFIG_EAP_PAX @@ -1366,6 +1368,9 @@ endif ifdef NEED_TLS_PRF_SHA256 SHA256OBJS += src/crypto/sha256-tlsprf.c endif +ifdef NEED_TLS_PRF_SHA384 +SHA256OBJS += src/crypto/sha384-tlsprf.c +endif ifdef NEED_HMAC_SHA256_KDF L_CFLAGS += -DCONFIG_HMAC_SHA256_KDF SHA256OBJS += src/crypto/sha256-kdf.c diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index f1384d5fa..a0106abed 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -686,6 +686,8 @@ TLS_FUNCS=y CONFIG_IEEE8021X_EAPOL=y NEED_T_PRF=y NEED_SHA384=y +NEED_TLS_PRF_SHA256=y +NEED_TLS_PRF_SHA384=y endif ifdef CONFIG_EAP_PAX @@ -1501,6 +1503,9 @@ endif ifdef NEED_TLS_PRF_SHA256 SHA256OBJS += ../src/crypto/sha256-tlsprf.o endif +ifdef NEED_TLS_PRF_SHA384 +SHA256OBJS += ../src/crypto/sha384-tlsprf.o +endif ifdef NEED_HMAC_SHA256_KDF CFLAGS += -DCONFIG_HMAC_SHA256_KDF OBJS += ../src/crypto/sha256-kdf.o