wpa_supplicant: Support for mbedtls tls handshake
Add support for mbedtls based tls handshake, this removes dependency from internal implementation of EAP client.
This commit is contained in:
parent
7c5a5617a8
commit
bd2815db10
21 changed files with 1410 additions and 352 deletions
|
@ -18,9 +18,9 @@ set(srcs "port/os_xtensa.c"
|
|||
"src/crypto/aes-unwrap.c"
|
||||
"src/crypto/aes-wrap.c"
|
||||
"src/crypto/aes-omac1.c"
|
||||
"src/crypto/sha256-tlsprf.c"
|
||||
"src/crypto/bignum.c"
|
||||
"src/crypto/ccmp.c"
|
||||
"src/crypto/crypto_mbedtls.c"
|
||||
"src/crypto/crypto_mbedtls-bignum.c"
|
||||
"src/crypto/crypto_mbedtls-ec.c"
|
||||
"src/crypto/crypto_ops.c"
|
||||
|
@ -42,6 +42,10 @@ set(srcs "port/os_xtensa.c"
|
|||
"src/crypto/sha1.c"
|
||||
"src/crypto/sha256-internal.c"
|
||||
"src/crypto/sha256.c"
|
||||
"src/crypto/sha1-tlsprf.c"
|
||||
"src/crypto/sha256-tlsprf.c"
|
||||
"src/crypto/sha384-tlsprf.c"
|
||||
"src/crypto/sha256-prf.c"
|
||||
"src/eap_peer/chap.c"
|
||||
"src/eap_peer/eap.c"
|
||||
"src/eap_peer/eap_common.c"
|
||||
|
@ -61,23 +65,6 @@ set(srcs "port/os_xtensa.c"
|
|||
"src/rsn_supp/pmksa_cache.c"
|
||||
"src/rsn_supp/wpa.c"
|
||||
"src/rsn_supp/wpa_ie.c"
|
||||
"src/tls/asn1.c"
|
||||
"src/tls/bignum.c"
|
||||
"src/tls/pkcs1.c"
|
||||
"src/tls/pkcs5.c"
|
||||
"src/tls/pkcs8.c"
|
||||
"src/tls/rsa.c"
|
||||
"src/tls/tls_internal.c"
|
||||
"src/tls/tlsv1_client.c"
|
||||
"src/tls/tlsv1_client_read.c"
|
||||
"src/tls/tlsv1_client_write.c"
|
||||
"src/tls/tlsv1_common.c"
|
||||
"src/tls/tlsv1_cred.c"
|
||||
"src/tls/tlsv1_record.c"
|
||||
"src/tls/tlsv1_server.c"
|
||||
"src/tls/tlsv1_server_read.c"
|
||||
"src/tls/tlsv1_server_write.c"
|
||||
"src/tls/x509v3.c"
|
||||
"src/utils/base64.c"
|
||||
"src/utils/common.c"
|
||||
"src/utils/ext_password.c"
|
||||
|
@ -95,7 +82,31 @@ set(srcs "port/os_xtensa.c"
|
|||
"src/wps/wps_registrar.c"
|
||||
"src/wps/wps_validate.c")
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
if(CONFIG_WPA_MBEDTLS_CRYPTO)
|
||||
set(tls_src "src/crypto/tls_mbedtls.c")
|
||||
else()
|
||||
set(tls_src
|
||||
"src/tls/asn1.c"
|
||||
"src/tls/bignum.c"
|
||||
"src/tls/pkcs1.c"
|
||||
"src/tls/pkcs5.c"
|
||||
"src/tls/pkcs8.c"
|
||||
"src/tls/rsa.c"
|
||||
"src/tls/tls_internal.c"
|
||||
"src/tls/tlsv1_client.c"
|
||||
"src/tls/tlsv1_client_read.c"
|
||||
"src/tls/tlsv1_client_write.c"
|
||||
"src/tls/tlsv1_common.c"
|
||||
"src/tls/tlsv1_cred.c"
|
||||
"src/tls/tlsv1_record.c"
|
||||
"src/tls/tlsv1_server.c"
|
||||
"src/tls/tlsv1_server_read.c"
|
||||
"src/tls/tlsv1_server_write.c"
|
||||
"src/tls/x509v3.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "${srcs}" "${tls_src}"
|
||||
INCLUDE_DIRS include port/include include/esp_supplicant
|
||||
PRIV_INCLUDE_DIRS src
|
||||
PRIV_REQUIRES mbedtls esp_timer)
|
||||
|
|
|
@ -23,12 +23,6 @@ menu "Supplicant"
|
|||
help
|
||||
Select this to enable unity test for DPP.
|
||||
|
||||
config WPA_TLS_V12
|
||||
bool "Enable TLS v1.2"
|
||||
default n
|
||||
help
|
||||
Select this to enable TLS v1.2 for WPA2-Enterprise Authentication.
|
||||
|
||||
config WPA_WPS_WARS
|
||||
bool "Add WPS Inter operatability Fixes"
|
||||
default n
|
||||
|
|
|
@ -1,5 +1,29 @@
|
|||
COMPONENT_ADD_INCLUDEDIRS := include port/include include/esp_supplicant
|
||||
# supplicant make file
|
||||
|
||||
COMPONENT_PRIV_INCLUDEDIRS := src
|
||||
COMPONENT_SRCDIRS := port src/ap src/common src/crypto src/eap_peer src/rsn_supp src/tls src/utils src/esp_supplicant src/wps
|
||||
COMPONENT_ADD_INCLUDEDIRS := include port/include include/esp_supplicant
|
||||
|
||||
ifeq ($(CONFIG_WPA_MBEDTLS_CRYPTO), y)
|
||||
COMPONENT_OBJEXCLUDE := src/tls/asn1.o \
|
||||
src/tls/bignum.o \
|
||||
src/tls/pkcs1.o \
|
||||
src/tls/pkcs5.o \
|
||||
src/tls/pkcs8.o \
|
||||
src/tls/rsa.o \
|
||||
src/tls/tls_internal.o \
|
||||
src/tls/tlsv1_client.o \
|
||||
src/tls/tlsv1_client_read.o \
|
||||
src/tls/tlsv1_client_write.o \
|
||||
src/tls/tlsv1_common.o \
|
||||
src/tls/tlsv1_cred.o \
|
||||
src/tls/tlsv1_record.o \
|
||||
src/tls/tlsv1_server.o \
|
||||
src/tls/tlsv1_server_read.o \
|
||||
src/tls/tlsv1_server_write.o \
|
||||
src/tls/x509v3.o
|
||||
else
|
||||
COMPONENT_OBJEXCLUDE := src/crypto/tls_mbedtls.o
|
||||
endif
|
||||
|
||||
CFLAGS += -DCONFIG_DPP -DCONFIG_WPA3_SAE -DCONFIG_IEEE80211W -DESP_SUPPLICANT -DIEEE8021X_EAPOL -DEAP_PEER_METHOD -DEAP_TLS -DEAP_TTLS -DEAP_PEAP -DEAP_MSCHAPv2 -DUSE_WPA2_TASK -DCONFIG_WPS2 -DCONFIG_WPS_PIN -DUSE_WPS_TASK -DESPRESSIF_USE -DESP32_WORKAROUND -DCONFIG_ECC -D__ets__ -Wno-strict-aliasing
|
||||
|
|
|
@ -278,6 +278,9 @@ char * ets_strdup(const char *s);
|
|||
#ifndef os_strstr
|
||||
#define os_strstr(h, n) strstr((h), (n))
|
||||
#endif
|
||||
#ifndef os_strlcpy
|
||||
#define os_strlcpy(d, s, n) strlcpy((d), (s), (n))
|
||||
#endif
|
||||
|
||||
#ifndef os_snprintf
|
||||
#ifdef _MSC_VER
|
||||
|
@ -291,16 +294,4 @@ static inline int os_snprintf_error(size_t size, int res)
|
|||
{
|
||||
return res < 0 || (unsigned int) res >= size;
|
||||
}
|
||||
|
||||
/**
|
||||
* os_strlcpy - Copy a string with size bound and NUL-termination
|
||||
* @dest: Destination
|
||||
* @src: Source
|
||||
* @siz: Size of the target buffer
|
||||
* Returns: Total length of the target string (length of src) (not including
|
||||
* NUL-termination)
|
||||
*
|
||||
* This function matches in behavior with the strlcpy(3) function in OpenBSD.
|
||||
*/
|
||||
size_t os_strlcpy(char *dest, const char *src, size_t siz);
|
||||
#endif /* OS_H */
|
||||
|
|
|
@ -19,14 +19,13 @@
|
|||
|
||||
#if CONFIG_WPA_MBEDTLS_CRYPTO
|
||||
#define USE_MBEDTLS_CRYPTO 1
|
||||
#else
|
||||
#define CONFIG_TLS_INTERNAL_CLIENT
|
||||
#define CONFIG_TLSV12
|
||||
#endif
|
||||
|
||||
#if CONFIG_WPA_DEBUG_PRINT
|
||||
#define DEBUG_PRINT
|
||||
#endif
|
||||
|
||||
#if CONFIG_WPA_TLS_V12
|
||||
#define CONFIG_TLSV12
|
||||
#endif
|
||||
|
||||
#endif /* _SUPPLICANT_OPT_H */
|
||||
|
|
72
components/wpa_supplicant/src/crypto/crypto_mbedtls.c
Normal file
72
components/wpa_supplicant/src/crypto/crypto_mbedtls.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "esp_system.h"
|
||||
#endif
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "crypto.h"
|
||||
#include "random.h"
|
||||
#include "sha256.h"
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
int mbedtls_hmac_vector(mbedtls_md_type_t md_type, const u8 *key, size_t key_len,
|
||||
size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
|
||||
{
|
||||
size_t i;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
mbedtls_md_context_t md_ctx;
|
||||
int ret;
|
||||
|
||||
mbedtls_md_init(&md_ctx);
|
||||
|
||||
if((md_info = mbedtls_md_info_from_type(md_type)) == NULL )
|
||||
return -1;
|
||||
|
||||
if ((ret = mbedtls_md_setup( &md_ctx, md_info, 1)) != 0)
|
||||
return(ret);
|
||||
|
||||
mbedtls_md_hmac_starts(&md_ctx, key, key_len);
|
||||
|
||||
for( i = 0; i < num_elem; i++)
|
||||
mbedtls_md_hmac_update(&md_ctx, addr[i], len[i]);
|
||||
|
||||
mbedtls_md_hmac_finish(&md_ctx, mac);
|
||||
|
||||
mbedtls_md_free(&md_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
|
||||
const u8 *addr[], const size_t *len, u8 *mac)
|
||||
{
|
||||
return mbedtls_hmac_vector(MBEDTLS_MD_SHA384, key, key_len, num_elem, addr,
|
||||
len, mac);
|
||||
}
|
||||
|
||||
|
||||
int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
|
||||
size_t data_len, u8 *mac)
|
||||
{
|
||||
return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
|
||||
}
|
101
components/wpa_supplicant/src/crypto/sha1-tlsprf.c
Normal file
101
components/wpa_supplicant/src/crypto/sha1-tlsprf.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* TLS PRF (SHA1 + MD5)
|
||||
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "sha1.h"
|
||||
#include "md5.h"
|
||||
|
||||
|
||||
/**
|
||||
* tls_prf_sha1_md5 - Pseudo-Random Function for TLS (TLS-PRF, RFC 2246)
|
||||
* @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 2246, Chapter 5.
|
||||
*/
|
||||
int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label,
|
||||
const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
|
||||
{
|
||||
size_t L_S1, L_S2, i;
|
||||
const u8 *S1, *S2;
|
||||
u8 A_MD5[MD5_MAC_LEN], A_SHA1[SHA1_MAC_LEN];
|
||||
u8 P_MD5[MD5_MAC_LEN], P_SHA1[SHA1_MAC_LEN];
|
||||
int MD5_pos, SHA1_pos;
|
||||
const u8 *MD5_addr[3];
|
||||
size_t MD5_len[3];
|
||||
const unsigned char *SHA1_addr[3];
|
||||
size_t SHA1_len[3];
|
||||
|
||||
MD5_addr[0] = A_MD5;
|
||||
MD5_len[0] = MD5_MAC_LEN;
|
||||
MD5_addr[1] = (unsigned char *) label;
|
||||
MD5_len[1] = os_strlen(label);
|
||||
MD5_addr[2] = seed;
|
||||
MD5_len[2] = seed_len;
|
||||
|
||||
SHA1_addr[0] = A_SHA1;
|
||||
SHA1_len[0] = SHA1_MAC_LEN;
|
||||
SHA1_addr[1] = (unsigned char *) label;
|
||||
SHA1_len[1] = os_strlen(label);
|
||||
SHA1_addr[2] = seed;
|
||||
SHA1_len[2] = seed_len;
|
||||
|
||||
/* RFC 2246, 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 = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed)
|
||||
*/
|
||||
|
||||
L_S1 = L_S2 = (secret_len + 1) / 2;
|
||||
S1 = secret;
|
||||
S2 = secret + L_S1;
|
||||
if (secret_len & 1) {
|
||||
/* The last byte of S1 will be shared with S2 */
|
||||
S2--;
|
||||
}
|
||||
|
||||
hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5);
|
||||
hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
|
||||
|
||||
MD5_pos = MD5_MAC_LEN;
|
||||
SHA1_pos = SHA1_MAC_LEN;
|
||||
for (i = 0; i < outlen; i++) {
|
||||
if (MD5_pos == MD5_MAC_LEN) {
|
||||
hmac_md5_vector(S1, L_S1, 3, MD5_addr, MD5_len, P_MD5);
|
||||
MD5_pos = 0;
|
||||
hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5);
|
||||
}
|
||||
if (SHA1_pos == SHA1_MAC_LEN) {
|
||||
hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len,
|
||||
P_SHA1);
|
||||
SHA1_pos = 0;
|
||||
hmac_sha1(S2, L_S2, A_SHA1, SHA1_MAC_LEN, A_SHA1);
|
||||
}
|
||||
|
||||
out[i] = P_MD5[MD5_pos] ^ P_SHA1[SHA1_pos];
|
||||
|
||||
MD5_pos++;
|
||||
SHA1_pos++;
|
||||
}
|
||||
|
||||
os_memset(A_MD5, 0, MD5_MAC_LEN);
|
||||
os_memset(P_MD5, 0, MD5_MAC_LEN);
|
||||
os_memset(A_SHA1, 0, SHA1_MAC_LEN);
|
||||
os_memset(P_SHA1, 0, SHA1_MAC_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
108
components/wpa_supplicant/src/crypto/sha256-prf.c
Normal file
108
components/wpa_supplicant/src/crypto/sha256-prf.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* SHA256-based PRF (IEEE 802.11r)
|
||||
* Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "sha256.h"
|
||||
#include "crypto.h"
|
||||
|
||||
|
||||
/**
|
||||
* sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2)
|
||||
* @key: Key for PRF
|
||||
* @key_len: Length of the key in bytes
|
||||
* @label: A unique label for each purpose of the PRF
|
||||
* @data: Extra data to bind into the key
|
||||
* @data_len: Length of the data
|
||||
* @buf: Buffer for the generated pseudo-random key
|
||||
* @buf_len: 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.
|
||||
*/
|
||||
int sha256_prf(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
|
||||
{
|
||||
return sha256_prf_bits(key, key_len, label, data, data_len, buf,
|
||||
buf_len * 8);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sha256_prf_bits - IEEE Std 802.11-2012, 11.6.1.7.2 Key derivation function
|
||||
* @key: Key for KDF
|
||||
* @key_len: Length of the key in bytes
|
||||
* @label: A unique label for each purpose of the PRF
|
||||
* @data: Extra data to bind into the key
|
||||
* @data_len: Length of the data
|
||||
* @buf: Buffer for the generated pseudo-random key
|
||||
* @buf_len: Number of bits 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. If the requested buf_len is not divisible by eight, the least
|
||||
* significant 1-7 bits of the last octet in the output are not part of the
|
||||
* requested output.
|
||||
*/
|
||||
int sha256_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)
|
||||
{
|
||||
u16 counter = 1;
|
||||
size_t pos, plen;
|
||||
u8 hash[SHA256_MAC_LEN];
|
||||
const u8 *addr[4];
|
||||
size_t len[4];
|
||||
u8 counter_le[2], length_le[2];
|
||||
size_t buf_len = (buf_len_bits + 7) / 8;
|
||||
|
||||
addr[0] = counter_le;
|
||||
len[0] = 2;
|
||||
addr[1] = (u8 *) label;
|
||||
len[1] = os_strlen(label);
|
||||
addr[2] = data;
|
||||
len[2] = data_len;
|
||||
addr[3] = length_le;
|
||||
len[3] = sizeof(length_le);
|
||||
|
||||
WPA_PUT_LE16(length_le, buf_len_bits);
|
||||
pos = 0;
|
||||
while (pos < buf_len) {
|
||||
plen = buf_len - pos;
|
||||
WPA_PUT_LE16(counter_le, counter);
|
||||
if (plen >= SHA256_MAC_LEN) {
|
||||
if (hmac_sha256_vector(key, key_len, 4, addr, len,
|
||||
&buf[pos]) < 0)
|
||||
return -1;
|
||||
pos += SHA256_MAC_LEN;
|
||||
} else {
|
||||
if (hmac_sha256_vector(key, key_len, 4, addr, len,
|
||||
hash) < 0)
|
||||
return -1;
|
||||
os_memcpy(&buf[pos], hash, plen);
|
||||
pos += plen;
|
||||
break;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mask out unused bits in the last octet if it does not use all the
|
||||
* bits.
|
||||
*/
|
||||
if (buf_len_bits % 8) {
|
||||
u8 mask = 0xff << (8 - buf_len_bits % 8);
|
||||
buf[pos - 1] &= mask;
|
||||
}
|
||||
|
||||
os_memset(hash, 0, sizeof(hash));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -26,8 +26,8 @@
|
|||
* This function is used to derive new, cryptographically separate keys from a
|
||||
* given key in TLS. This PRF is defined in RFC 2246, Chapter 5.
|
||||
*/
|
||||
void tls_prf_sha256(const u8 *secret, size_t secret_len, const char *label,
|
||||
const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
|
||||
int tls_prf_sha256(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[SHA256_MAC_LEN];
|
||||
|
@ -50,12 +50,15 @@ void tls_prf_sha256(const u8 *secret, size_t secret_len, const char *label,
|
|||
* PRF(secret, label, seed) = P_SHA256(secret, label + seed)
|
||||
*/
|
||||
|
||||
hmac_sha256_vector(secret, secret_len, 2, &addr[1], &len[1], A);
|
||||
if (hmac_sha256_vector(secret, secret_len, 2, &addr[1], &len[1], A) < 0)
|
||||
return -1;
|
||||
|
||||
pos = 0;
|
||||
while (pos < outlen) {
|
||||
hmac_sha256_vector(secret, secret_len, 3, addr, len, P);
|
||||
hmac_sha256(secret, secret_len, A, SHA256_MAC_LEN, A);
|
||||
if (hmac_sha256_vector(secret, secret_len, 3, addr, len, P) <
|
||||
0 ||
|
||||
hmac_sha256(secret, secret_len, A, SHA256_MAC_LEN, A) < 0)
|
||||
return -1;
|
||||
|
||||
clen = outlen - pos;
|
||||
if (clen > SHA256_MAC_LEN)
|
||||
|
@ -63,4 +66,6 @@ void tls_prf_sha256(const u8 *secret, size_t secret_len, const char *label,
|
|||
os_memcpy(out + pos, P, clen);
|
||||
pos += clen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
|
|||
{
|
||||
unsigned char k_pad[64]; /* padding - key XORd with ipad/opad */
|
||||
unsigned char tk[32];
|
||||
const u8 *_addr[6];
|
||||
size_t _len[6], i;
|
||||
const u8 *_addr[11];
|
||||
size_t _len[11], i;
|
||||
|
||||
if (num_elem > 5) {
|
||||
/*
|
||||
|
@ -114,104 +114,11 @@ int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
|
|||
* @key_len: Length of the key in bytes
|
||||
* @data: Pointers to the data area
|
||||
* @data_len: Length of the data area
|
||||
* @mac: Buffer for the hash (20 bytes)
|
||||
*/
|
||||
int
|
||||
hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
|
||||
size_t data_len, u8 *mac)
|
||||
{
|
||||
return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
|
||||
}
|
||||
|
||||
/**
|
||||
* sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2)
|
||||
* @key: Key for PRF
|
||||
* @key_len: Length of the key in bytes
|
||||
* @label: A unique label for each purpose of the PRF
|
||||
* @data: Extra data to bind into the key
|
||||
* @data_len: Length of the data
|
||||
* @buf: Buffer for the generated pseudo-random key
|
||||
* @buf_len: Number of bytes of key to generate
|
||||
* @mac: Buffer for the hash (32 bytes)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function is used to derive new, cryptographically separate keys from a
|
||||
* given key.
|
||||
*/
|
||||
int sha256_prf(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *data, size_t data_len, u8 *buf, size_t buf_len)
|
||||
int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
|
||||
size_t data_len, u8 *mac)
|
||||
{
|
||||
return sha256_prf_bits(key, key_len, label, data, data_len, buf,
|
||||
buf_len * 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* sha256_prf_bits - IEEE Std 802.11-2012, 11.6.1.7.2 Key derivation function
|
||||
* @key: Key for KDF
|
||||
* @key_len: Length of the key in bytes
|
||||
* @label: A unique label for each purpose of the PRF
|
||||
* @data: Extra data to bind into the key
|
||||
* @data_len: Length of the data
|
||||
* @buf: Buffer for the generated pseudo-random key
|
||||
* @buf_len: Number of bits 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. If the requested buf_len is not divisible by eight, the least
|
||||
* significant 1-7 bits of the last octet in the output are not part of the
|
||||
* requested output.
|
||||
*/
|
||||
int sha256_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)
|
||||
{
|
||||
u16 counter = 1;
|
||||
size_t pos, plen;
|
||||
u8 hash[SHA256_MAC_LEN];
|
||||
const u8 *addr[4];
|
||||
size_t len[4];
|
||||
u8 counter_le[2], length_le[2];
|
||||
size_t buf_len = (buf_len_bits + 7) / 8;
|
||||
|
||||
addr[0] = counter_le;
|
||||
len[0] = 2;
|
||||
addr[1] = (u8 *) label;
|
||||
len[1] = os_strlen(label);
|
||||
addr[2] = data;
|
||||
len[2] = data_len;
|
||||
addr[3] = length_le;
|
||||
len[3] = sizeof(length_le);
|
||||
|
||||
WPA_PUT_LE16(length_le, buf_len_bits);
|
||||
pos = 0;
|
||||
while (pos < buf_len) {
|
||||
plen = buf_len - pos;
|
||||
WPA_PUT_LE16(counter_le, counter);
|
||||
if (plen >= SHA256_MAC_LEN) {
|
||||
if (hmac_sha256_vector(key, key_len, 4, addr, len,
|
||||
&buf[pos]) < 0)
|
||||
return -1;
|
||||
pos += SHA256_MAC_LEN;
|
||||
} else {
|
||||
if (hmac_sha256_vector(key, key_len, 4, addr, len,
|
||||
hash) < 0)
|
||||
return -1;
|
||||
os_memcpy(&buf[pos], hash, plen);
|
||||
pos += plen;
|
||||
break;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mask out unused bits in the last octet if it does not use all the
|
||||
* bits.
|
||||
*/
|
||||
if (buf_len_bits % 8) {
|
||||
u8 mask = 0xff << (8 - buf_len_bits % 8);
|
||||
buf[pos - 1] &= mask;
|
||||
}
|
||||
|
||||
os_memset(hash, 0, sizeof(hash));
|
||||
|
||||
return 0;
|
||||
return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ int sha256_prf(const u8 *key, size_t key_len, const char *label,
|
|||
int sha256_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);
|
||||
void tls_prf_sha256(const u8 *secret, size_t secret_len,
|
||||
int tls_prf_sha256(const u8 *secret, size_t secret_len,
|
||||
const char *label, const u8 *seed, size_t seed_len,
|
||||
u8 *out, size_t outlen);
|
||||
|
||||
|
|
71
components/wpa_supplicant/src/crypto/sha384-tlsprf.c
Normal file
71
components/wpa_supplicant/src/crypto/sha384-tlsprf.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* TLS PRF P_SHA384
|
||||
* Copyright (c) 2011-2019, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
|
||||
#include "utils/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;
|
||||
}
|
30
components/wpa_supplicant/src/crypto/sha384.h
Normal file
30
components/wpa_supplicant/src/crypto/sha384.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* SHA384 hash implementation and interface functions
|
||||
* Copyright (c) 2015-2017, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef SHA384_H
|
||||
#define SHA384_H
|
||||
|
||||
#define SHA384_MAC_LEN 48
|
||||
|
||||
int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
|
||||
const u8 *addr[], const size_t *len, u8 *mac);
|
||||
int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
|
||||
size_t data_len, u8 *mac);
|
||||
int sha384_prf(const u8 *key, size_t key_len, const char *label,
|
||||
const u8 *data, size_t data_len, u8 *buf, size_t buf_len);
|
||||
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);
|
||||
|
||||
#endif /* SHA384_H */
|
879
components/wpa_supplicant/src/crypto/tls_mbedtls.c
Normal file
879
components/wpa_supplicant/src/crypto/tls_mbedtls.c
Normal file
|
@ -0,0 +1,879 @@
|
|||
/**
|
||||
* Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
|
||||
#include "tls/tls.h"
|
||||
#include "crypto/sha1.h"
|
||||
#include "crypto/md5.h"
|
||||
#include "crypto/sha256.h"
|
||||
#include "crypto/sha384.h"
|
||||
#include "mbedtls/ssl_internal.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#ifdef ESPRESSIF_USE
|
||||
#include "mbedtls/esp_debug.h"
|
||||
#include "mbedtls/esp_config.h"
|
||||
#else
|
||||
#include "mbedtls/config.h"
|
||||
#endif
|
||||
|
||||
#define TLS_RANDOM_LEN 32
|
||||
#define TLS_MASTER_SECRET_LEN 48
|
||||
#define MAX_CIPHERSUITE 32
|
||||
|
||||
/* Throw a compilation error if basic requirements in mbedtls are not enabled */
|
||||
#if !defined(MBEDTLS_SSL_TLS_C)
|
||||
#error "TLS not enabled in mbedtls config"
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_SHA256_C)
|
||||
#error "SHA256 is disabled in mbedtls config"
|
||||
#endif
|
||||
|
||||
#if !defined(MBEDTLS_AES_C)
|
||||
#error "AES support is disabled in mbedtls config"
|
||||
#endif
|
||||
|
||||
uint32_t tls_instance_count;
|
||||
struct tls_data {
|
||||
/* Data for mbedlts */
|
||||
struct wpabuf *in_data;
|
||||
/* Data from mbedtls */
|
||||
struct wpabuf *out_data;
|
||||
};
|
||||
|
||||
typedef struct tls_context {
|
||||
mbedtls_ssl_context ssl; /*!< TLS/SSL context */
|
||||
mbedtls_entropy_context entropy; /*!< mbedTLS entropy context structure */
|
||||
mbedtls_ctr_drbg_context ctr_drbg; /*!< mbedTLS ctr drbg context structure */
|
||||
mbedtls_ssl_config conf; /*!< TLS/SSL config to be shared structures */
|
||||
mbedtls_x509_crt cacert; /*!< Container for X.509 CA certificate */
|
||||
mbedtls_x509_crt *cacert_ptr; /*!< Pointer to the cacert being used. */
|
||||
mbedtls_x509_crt clientcert; /*!< Container for X.509 client certificate */
|
||||
mbedtls_pk_context clientkey; /*!< Private key of client certificate */
|
||||
int ciphersuite[MAX_CIPHERSUITE];
|
||||
} tls_context_t;
|
||||
|
||||
struct tls_connection {
|
||||
tls_context_t *tls;
|
||||
struct tls_data tls_io_data;
|
||||
unsigned char randbytes[2 * TLS_RANDOM_LEN];
|
||||
};
|
||||
|
||||
static void tls_mbedtls_cleanup(tls_context_t *tls)
|
||||
{
|
||||
if (!tls) {
|
||||
return;
|
||||
}
|
||||
tls->cacert_ptr = NULL;
|
||||
mbedtls_x509_crt_free(&tls->cacert);
|
||||
mbedtls_x509_crt_free(&tls->clientcert);
|
||||
mbedtls_pk_free(&tls->clientkey);
|
||||
mbedtls_entropy_free(&tls->entropy);
|
||||
mbedtls_ssl_config_free(&tls->conf);
|
||||
mbedtls_ctr_drbg_free(&tls->ctr_drbg);
|
||||
mbedtls_ssl_free(&tls->ssl);
|
||||
}
|
||||
|
||||
static void tls_mbedtls_conn_delete(tls_context_t *tls)
|
||||
{
|
||||
if (tls != NULL) {
|
||||
tls_mbedtls_cleanup(tls);
|
||||
}
|
||||
}
|
||||
|
||||
static int tls_mbedtls_write(void *ctx, const unsigned char *buf, size_t len)
|
||||
{
|
||||
struct tls_connection *conn = (struct tls_connection *)ctx;
|
||||
struct tls_data *data = &conn->tls_io_data;
|
||||
|
||||
if (data->out_data) {
|
||||
wpabuf_resize(&data->out_data, len);
|
||||
} else {
|
||||
data->out_data = wpabuf_alloc(len);
|
||||
}
|
||||
|
||||
wpabuf_put_data(data->out_data, buf, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int tls_mbedtls_read(void *ctx, unsigned char *buf, size_t len)
|
||||
{
|
||||
struct tls_connection *conn = (struct tls_connection *)ctx;
|
||||
struct tls_data *data = &conn->tls_io_data;
|
||||
struct wpabuf *local_buf;
|
||||
size_t data_len = len;
|
||||
|
||||
if (len > wpabuf_len(data->in_data)) {
|
||||
wpa_printf(MSG_ERROR, "don't have suffient data\n");
|
||||
data_len = wpabuf_len(data->in_data);
|
||||
}
|
||||
|
||||
os_memcpy(buf, wpabuf_head(data->in_data), data_len);
|
||||
/* adjust buffer */
|
||||
if (len < wpabuf_len(data->in_data)) {
|
||||
local_buf = wpabuf_alloc_copy(wpabuf_head(data->in_data) + len,
|
||||
wpabuf_len(data->in_data) - len);
|
||||
wpabuf_free(data->in_data);
|
||||
data->in_data = local_buf;
|
||||
} else {
|
||||
wpabuf_free(data->in_data);
|
||||
data->in_data = NULL;
|
||||
}
|
||||
|
||||
return data_len;
|
||||
}
|
||||
|
||||
static int set_pki_context(tls_context_t *tls, const struct tls_connection_params *cfg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (cfg->client_cert_blob == NULL || cfg->private_key_blob == NULL) {
|
||||
wpa_printf(MSG_ERROR, "%s: config not correct", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mbedtls_x509_crt_init(&tls->clientcert);
|
||||
mbedtls_pk_init(&tls->clientkey);
|
||||
|
||||
ret = mbedtls_x509_crt_parse(&tls->clientcert,
|
||||
cfg->client_cert_blob, cfg->client_cert_blob_len);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "mbedtls_x509_crt_parse returned -0x%x", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_pk_parse_key(&tls->clientkey, cfg->private_key_blob, cfg->private_key_blob_len,
|
||||
(const unsigned char *)cfg->private_key_passwd,
|
||||
cfg->private_key_passwd ? os_strlen(cfg->private_key_passwd) : 0);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "mbedtls_pk_parse_keyfile returned -0x%x", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->clientcert, &tls->clientkey);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "mbedtls_ssl_conf_own_cert returned -0x%x", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_ca_cert(tls_context_t *tls, const unsigned char *cacert, size_t cacert_len)
|
||||
{
|
||||
tls->cacert_ptr = &tls->cacert;
|
||||
mbedtls_x509_crt_init(tls->cacert_ptr);
|
||||
int ret = mbedtls_x509_crt_parse(tls->cacert_ptr, cacert, cacert_len);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "mbedtls_x509_crt_parse returned -0x%x", -ret);
|
||||
return ret;
|
||||
}
|
||||
mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
mbedtls_ssl_conf_ca_chain(&tls->conf, tls->cacert_ptr, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tls_sig_hashes_for_eap[] = {
|
||||
#if defined(MBEDTLS_SHA512_C)
|
||||
MBEDTLS_MD_SHA512,
|
||||
MBEDTLS_MD_SHA384,
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
MBEDTLS_MD_SHA256,
|
||||
MBEDTLS_MD_SHA224,
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA1_C)
|
||||
MBEDTLS_MD_SHA1,
|
||||
#endif
|
||||
MBEDTLS_MD_NONE
|
||||
};
|
||||
|
||||
const mbedtls_x509_crt_profile eap_mbedtls_x509_crt_profile =
|
||||
{
|
||||
#if defined(MBEDTLS_SHA1_C)
|
||||
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
|
||||
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA512_C)
|
||||
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
|
||||
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ) |
|
||||
#endif
|
||||
0,
|
||||
0xFFFFFFF, /* Any PK alg */
|
||||
0xFFFFFFF, /* Any curve */
|
||||
1024,
|
||||
};
|
||||
|
||||
static void tls_enable_sha1_config(tls_context_t *tls)
|
||||
{
|
||||
const mbedtls_x509_crt_profile *crt_profile = &eap_mbedtls_x509_crt_profile;
|
||||
mbedtls_ssl_conf_cert_profile(&tls->conf, crt_profile);
|
||||
mbedtls_ssl_conf_sig_hashes(&tls->conf, tls_sig_hashes_for_eap);
|
||||
}
|
||||
|
||||
static const int eap_ciphersuite_preference[] =
|
||||
{
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
|
||||
#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C)
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
#endif
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8,
|
||||
#endif
|
||||
#endif
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
|
||||
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384,
|
||||
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM,
|
||||
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
|
||||
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
|
||||
MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8,
|
||||
|
||||
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256,
|
||||
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM,
|
||||
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8,
|
||||
#endif
|
||||
#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C)
|
||||
MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
MBEDTLS_TLS_RSA_WITH_AES_256_CCM,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256,
|
||||
MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8,
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
MBEDTLS_TLS_RSA_WITH_AES_128_CCM,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
#endif
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
|
||||
#endif
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8,
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
|
||||
#endif
|
||||
/* The PSK suites */
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CCM,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_GCM_C)
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CCM,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA,
|
||||
#endif
|
||||
#if defined(MBEDTLS_CCM_C)
|
||||
MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_DES_C)
|
||||
/* 3DES suites */
|
||||
MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
|
||||
MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
|
||||
MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
|
||||
#endif
|
||||
#if defined(MBEDTLS_ARC4_C)
|
||||
/* RC4 suites */
|
||||
MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA,
|
||||
MBEDTLS_TLS_RSA_WITH_RC4_128_SHA,
|
||||
MBEDTLS_TLS_RSA_WITH_RC4_128_MD5,
|
||||
MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA,
|
||||
MBEDTLS_TLS_PSK_WITH_RC4_128_SHA,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void tls_set_ciphersuite(tls_context_t *tls)
|
||||
{
|
||||
/* Only set ciphersuite if cert's key length is high or ciphersuites are set by user */
|
||||
if (tls->ciphersuite[0]) {
|
||||
mbedtls_ssl_conf_ciphersuites(&tls->conf, tls->ciphersuite);
|
||||
} else if (mbedtls_pk_get_bitlen(&tls->clientkey) > 2048 ||
|
||||
mbedtls_pk_get_bitlen(&tls->cacert_ptr->pk) > 2048) {
|
||||
mbedtls_ssl_conf_ciphersuites(&tls->conf, eap_ciphersuite_preference);
|
||||
}
|
||||
}
|
||||
|
||||
static int set_client_config(const struct tls_connection_params *cfg, tls_context_t *tls)
|
||||
{
|
||||
int ret;
|
||||
assert(cfg != NULL);
|
||||
assert(tls != NULL);
|
||||
|
||||
ret = mbedtls_ssl_config_defaults(&tls->conf,
|
||||
MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
if (ret != 0) {
|
||||
wpa_printf(MSG_ERROR, "mbedtls_ssl_config_defaults returned -0x%x", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Enable SHA1 support since it's not enabled by default in mbedtls */
|
||||
tls_enable_sha1_config(tls);
|
||||
|
||||
if (cfg->ca_cert_blob != NULL) {
|
||||
ret = set_ca_cert(tls, cfg->ca_cert_blob, cfg->ca_cert_blob_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
mbedtls_ssl_conf_ca_chain(&tls->conf, tls->cacert_ptr, NULL);
|
||||
} else {
|
||||
mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
}
|
||||
|
||||
if (cfg->client_cert_blob != NULL && cfg->private_key_blob != NULL) {
|
||||
ret = set_pki_context(tls, cfg);
|
||||
if (ret != 0) {
|
||||
wpa_printf(MSG_ERROR, "Failed to set client pki context");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Usages of default ciphersuites can take a lot of time on low end device
|
||||
* and can cause watchdog. Enabling the ciphers which are secured enough
|
||||
* but doesn't take that much processing power */
|
||||
tls_set_ciphersuite(tls);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tls_create_mbedtls_handle(const struct tls_connection_params *params,
|
||||
tls_context_t *tls)
|
||||
{
|
||||
int ret;
|
||||
|
||||
assert(params != NULL);
|
||||
assert(tls != NULL);
|
||||
|
||||
mbedtls_ssl_init(&tls->ssl);
|
||||
mbedtls_ctr_drbg_init(&tls->ctr_drbg);
|
||||
mbedtls_ssl_config_init(&tls->conf);
|
||||
mbedtls_entropy_init(&tls->entropy);
|
||||
|
||||
ret = set_client_config(params, tls);
|
||||
if (ret != 0) {
|
||||
wpa_printf(MSG_ERROR, "Failed to set client configurations");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_ctr_drbg_seed(&tls->ctr_drbg, mbedtls_entropy_func,
|
||||
&tls->entropy, NULL, 0);
|
||||
if (ret != 0) {
|
||||
wpa_printf(MSG_ERROR, "mbedtls_ctr_drbg_seed returned -0x%x", -ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_rng(&tls->conf, mbedtls_ctr_drbg_random, &tls->ctr_drbg);
|
||||
|
||||
ret = mbedtls_ssl_setup(&tls->ssl, &tls->conf);
|
||||
if (ret != 0) {
|
||||
wpa_printf(MSG_ERROR, "mbedtls_ssl_setup returned -0x%x", -ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Enable debug prints in case supplicant's prints are enabled */
|
||||
#if defined(DEBUG_PRINT) && defined(CONFIG_MBEDTLS_DEBUG) && defined(ESPRESSIF_USE)
|
||||
mbedtls_esp_enable_debug_log(&tls->conf, 2);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
exit:
|
||||
tls_mbedtls_cleanup(tls);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *tls_init()
|
||||
{
|
||||
tls_instance_count++;
|
||||
return &tls_instance_count;
|
||||
}
|
||||
|
||||
void tls_deinit(void *tls_ctx)
|
||||
{
|
||||
tls_instance_count--;
|
||||
}
|
||||
|
||||
struct tls_connection * tls_connection_init(void *tls_ctx)
|
||||
{
|
||||
struct tls_connection *conn = os_zalloc(sizeof(*conn));
|
||||
if (!conn) {
|
||||
wpa_printf(MSG_ERROR, "TLS: Failed to allocate connection memory");
|
||||
return NULL;
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
|
||||
void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
/* Free ssl ctx and data */
|
||||
tls_mbedtls_conn_delete((tls_context_t *) conn->tls);
|
||||
conn->tls = NULL;
|
||||
/* Data in in ssl ctx, free connection */
|
||||
os_free(conn);
|
||||
}
|
||||
|
||||
int tls_get_errors(void *tls_ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
mbedtls_ssl_context *ssl = &conn->tls->ssl;
|
||||
|
||||
if (ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_global_set_verify(void *tls_ctx, int check_crl)
|
||||
{
|
||||
wpa_printf(MSG_INFO, "TLS: global settings are not supported");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
|
||||
int verify_peer)
|
||||
{
|
||||
wpa_printf(MSG_INFO, "TLS: tls_connection_set_verify not supported");
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct wpabuf * tls_connection_handshake(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data,
|
||||
struct wpabuf **appl_data)
|
||||
{
|
||||
tls_context_t *tls = conn->tls;
|
||||
int ret = 0;
|
||||
|
||||
/* data freed by sender */
|
||||
conn->tls_io_data.out_data = NULL;
|
||||
if (wpabuf_len(in_data)) {
|
||||
conn->tls_io_data.in_data = wpabuf_dup(in_data);
|
||||
}
|
||||
ret = mbedtls_ssl_handshake_step(&tls->ssl);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "%s:%d", __func__, __LINE__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Multiple reads */
|
||||
while (conn->tls_io_data.in_data) {
|
||||
ret = mbedtls_ssl_handshake_step(&tls->ssl);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* State machine just started, get client hello */
|
||||
if (tls->ssl.state == MBEDTLS_SSL_CLIENT_HELLO) {
|
||||
ret = mbedtls_ssl_handshake_step(&tls->ssl);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "%s:%d", __func__, __LINE__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Already read sever data till hello done */
|
||||
if (tls->ssl.state == MBEDTLS_SSL_CLIENT_CERTIFICATE) {
|
||||
/* Read random data before session completes, not present after handshake */
|
||||
if (tls->ssl.handshake) {
|
||||
os_memcpy(conn->randbytes, tls->ssl.handshake->randbytes,
|
||||
TLS_RANDOM_LEN * 2);
|
||||
}
|
||||
|
||||
/* trigger state machine multiple times to reach till finish */
|
||||
while (tls->ssl.state <= MBEDTLS_SSL_CLIENT_FINISHED) {
|
||||
ret = mbedtls_ssl_handshake_step(&tls->ssl);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Trigger state machine till handshake is complete or error occures */
|
||||
if (tls->ssl.state == MBEDTLS_SSL_FLUSH_BUFFERS) {
|
||||
while (tls->ssl.state <= MBEDTLS_SSL_HANDSHAKE_OVER) {
|
||||
ret = mbedtls_ssl_handshake_step(&tls->ssl);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!conn->tls_io_data.out_data) {
|
||||
wpa_printf(MSG_INFO, "application data is null, adding one byte for ack");
|
||||
u8 *dummy = os_zalloc(1);
|
||||
conn->tls_io_data.out_data = wpabuf_alloc_ext_data(dummy, 0);
|
||||
}
|
||||
|
||||
end:
|
||||
return conn->tls_io_data.out_data;
|
||||
}
|
||||
|
||||
struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data,
|
||||
struct wpabuf **appl_data)
|
||||
{
|
||||
wpa_printf(MSG_ERROR, "%s: not supported %d", __func__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * tls_connection_encrypt(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data)
|
||||
{
|
||||
/* Reset dangling pointer */
|
||||
conn->tls_io_data.out_data = NULL;
|
||||
|
||||
ssize_t ret = mbedtls_ssl_write(&conn->tls->ssl,
|
||||
(unsigned char*) wpabuf_head(in_data), wpabuf_len(in_data));
|
||||
|
||||
if (ret < wpabuf_len(in_data)) {
|
||||
wpa_printf(MSG_ERROR, "%s:%d, not able to write whole data",
|
||||
__func__, __LINE__);
|
||||
}
|
||||
|
||||
return conn->tls_io_data.out_data;
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * tls_connection_decrypt(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const struct wpabuf *in_data)
|
||||
{
|
||||
unsigned char buf[1200];
|
||||
int ret;
|
||||
conn->tls_io_data.in_data = wpabuf_dup(in_data);
|
||||
ret = mbedtls_ssl_read(&conn->tls->ssl, buf, 1200);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "%s:%d, not able to write whole data",
|
||||
__func__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wpabuf *out = wpabuf_alloc_copy(buf, ret);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
if (conn && conn->tls && conn->tls->ssl.handshake) {
|
||||
return conn->tls->ssl.handshake->resume;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* cipher array should contain cipher number in mbedtls num as per IANA
|
||||
* Please see cipherlist is u8, therefore only initial ones are supported */
|
||||
int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
|
||||
u8 *ciphers)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (*ciphers != 0 && i < MAX_CIPHERSUITE) {
|
||||
conn->tls->ciphersuite[i] = ciphers[i];
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_get_version(void *tls_ctx, struct tls_connection *conn,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (conn == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
name = mbedtls_ssl_get_version(&conn->tls->ssl);
|
||||
if (name == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_strlcpy(buf, name, buflen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
const char *name;
|
||||
if (conn == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
name = mbedtls_ssl_get_ciphersuite(&conn->tls->ssl);
|
||||
if (name == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_strlcpy(buf, name, buflen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_enable_workaround(void *tls_ctx,
|
||||
struct tls_connection *conn)
|
||||
{
|
||||
wpa_printf(MSG_ERROR, "%s: not supported %d", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
wpa_printf(MSG_ERROR, "%s: not supported %d", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_connection_get_write_alerts(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
wpa_printf(MSG_ERROR, "%s: not supported %d", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
|
||||
const struct tls_connection_params *params)
|
||||
{
|
||||
int ret = 0;
|
||||
tls_context_t *tls = (tls_context_t *)os_zalloc(sizeof(tls_context_t));
|
||||
|
||||
if (!tls) {
|
||||
wpa_printf(MSG_ERROR, "failed to allocate tls context");
|
||||
return -1;
|
||||
}
|
||||
if (!params) {
|
||||
wpa_printf(MSG_ERROR, "configuration is null");
|
||||
ret = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = tls_create_mbedtls_handle(params, tls);
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "failed to create ssl handle");
|
||||
goto err;
|
||||
}
|
||||
mbedtls_ssl_set_bio(&tls->ssl, conn, tls_mbedtls_write, tls_mbedtls_read, NULL);
|
||||
conn->tls = (tls_context_t *)tls;
|
||||
|
||||
return ret;
|
||||
err:
|
||||
os_free(tls);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tls_global_set_params(void *tls_ctx,
|
||||
const struct tls_connection_params *params)
|
||||
{
|
||||
wpa_printf(MSG_INFO, "TLS: Global parameters not supported");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tls_connection_set_session_ticket_cb(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
tls_session_ticket_cb cb,
|
||||
void *ctx)
|
||||
{
|
||||
wpa_printf(MSG_ERROR, "TLS: %s not supported", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
|
||||
const char *label, int server_random_first,
|
||||
u8 *out, size_t out_len)
|
||||
{
|
||||
int ret;
|
||||
u8 seed[2 * TLS_RANDOM_LEN];
|
||||
mbedtls_ssl_context *ssl = &conn->tls->ssl;
|
||||
mbedtls_ssl_transform *transform = ssl->transform;
|
||||
|
||||
if (!ssl || !transform) {
|
||||
wpa_printf(MSG_ERROR, "TLS: %s, session ingo is null", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
|
||||
wpa_printf(MSG_ERROR, "TLS: %s, incorrect tls state=%d", __func__, ssl->state);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (server_random_first) {
|
||||
os_memcpy(seed, conn->randbytes + TLS_RANDOM_LEN, TLS_RANDOM_LEN);
|
||||
os_memcpy(seed + TLS_RANDOM_LEN, conn->randbytes, TLS_RANDOM_LEN);
|
||||
} else {
|
||||
os_memcpy(seed, conn->randbytes, 2 * TLS_RANDOM_LEN);
|
||||
}
|
||||
|
||||
wpa_hexdump_key(MSG_MSGDUMP, "random", seed, 2 * TLS_RANDOM_LEN);
|
||||
wpa_hexdump_key(MSG_MSGDUMP, "master", ssl->session->master, TLS_MASTER_SECRET_LEN);
|
||||
|
||||
if (transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384) {
|
||||
ret = tls_prf_sha384(ssl->session->master, TLS_MASTER_SECRET_LEN,
|
||||
label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
|
||||
} else if (transform->ciphersuite_info->mac == MBEDTLS_MD_SHA256) {
|
||||
ret = tls_prf_sha256(ssl->session->master, TLS_MASTER_SECRET_LEN,
|
||||
label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
|
||||
} else {
|
||||
ret = tls_prf_sha1_md5(ssl->session->master, TLS_MASTER_SECRET_LEN,
|
||||
label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "prf failed, ret=%d\n", ret);
|
||||
}
|
||||
wpa_hexdump_key(MSG_MSGDUMP, "key", out, out_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
|
||||
const char *label, u8 *out, size_t out_len)
|
||||
{
|
||||
return tls_connection_prf(tls_ctx, conn, label, 0, out, out_len);
|
||||
}
|
||||
|
||||
int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
|
||||
{
|
||||
if (conn->tls_io_data.in_data) {
|
||||
wpabuf_free(conn->tls_io_data.in_data);
|
||||
}
|
||||
conn->tls_io_data.in_data = NULL;
|
||||
|
||||
/* outdata may have dangling pointer */
|
||||
conn->tls_io_data.out_data = NULL;
|
||||
|
||||
return mbedtls_ssl_session_reset(&conn->tls->ssl);
|
||||
}
|
||||
|
||||
int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn,
|
||||
struct tls_random *data)
|
||||
{
|
||||
mbedtls_ssl_context *ssl = &conn->tls->ssl;
|
||||
|
||||
os_memset(data, 0, sizeof(*data));
|
||||
if (ssl->state == MBEDTLS_SSL_CLIENT_HELLO) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->client_random = conn->randbytes;
|
||||
data->client_random_len = TLS_RANDOM_LEN;
|
||||
|
||||
if (ssl->state != MBEDTLS_SSL_SERVER_HELLO) {
|
||||
data->server_random = conn->randbytes + TLS_RANDOM_LEN;
|
||||
data->server_random_len = TLS_RANDOM_LEN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -248,53 +248,21 @@ void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
|
|||
u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
|
||||
const char *label, size_t len)
|
||||
{
|
||||
struct tls_keys keys;
|
||||
u8 *rnd = NULL, *out;
|
||||
u8 *out;
|
||||
|
||||
out = os_malloc(len);
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
|
||||
/* First, try to use TLS library function for PRF, if available. */
|
||||
if (tls_connection_prf(data->ssl_ctx, data->conn, label, 0, out, len)
|
||||
== 0)
|
||||
return out;
|
||||
|
||||
/*
|
||||
* TLS library did not support key generation, so get the needed TLS
|
||||
* session parameters and use an internal implementation of TLS PRF to
|
||||
* derive the key.
|
||||
*/
|
||||
if (tls_connection_get_keys(data->ssl_ctx, data->conn, &keys))
|
||||
goto fail;
|
||||
|
||||
if (keys.client_random == NULL || keys.server_random == NULL ||
|
||||
keys.master_key == NULL)
|
||||
goto fail;
|
||||
|
||||
rnd = os_malloc(keys.client_random_len + keys.server_random_len);
|
||||
if (rnd == NULL)
|
||||
goto fail;
|
||||
os_memcpy(rnd, keys.client_random, keys.client_random_len);
|
||||
os_memcpy(rnd + keys.client_random_len, keys.server_random,
|
||||
keys.server_random_len);
|
||||
|
||||
if (tls_prf_sha1_md5(keys.master_key, keys.master_key_len,
|
||||
label, rnd, keys.client_random_len +
|
||||
keys.server_random_len, out, len)) {
|
||||
goto fail;
|
||||
if (tls_connection_export_key(data->ssl_ctx, data->conn, label, out,
|
||||
len)) {
|
||||
os_free(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_free(rnd);
|
||||
return out;
|
||||
|
||||
fail:
|
||||
os_free(out);
|
||||
os_free(rnd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_peer_tls_derive_session_id - Derive a Session-Id based on TLS data
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
|
@ -312,18 +280,17 @@ u8 * eap_peer_tls_derive_session_id(struct eap_sm *sm,
|
|||
struct eap_ssl_data *data, u8 eap_type,
|
||||
size_t *len)
|
||||
{
|
||||
struct tls_keys keys;
|
||||
struct tls_random keys;
|
||||
u8 *out;
|
||||
|
||||
/*
|
||||
* TLS library did not support session ID generation,
|
||||
* so get the needed TLS session parameters
|
||||
*/
|
||||
if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
|
||||
if (tls_connection_get_random(sm->ssl_ctx, data->conn, &keys))
|
||||
return NULL;
|
||||
|
||||
if (keys.client_random == NULL || keys.server_random == NULL ||
|
||||
keys.master_key == NULL)
|
||||
if (keys.client_random == NULL || keys.server_random == NULL)
|
||||
return NULL;
|
||||
|
||||
*len = 1 + keys.client_random_len + keys.server_random_len;
|
||||
|
|
|
@ -11,9 +11,7 @@
|
|||
|
||||
struct tls_connection;
|
||||
|
||||
struct tls_keys {
|
||||
const u8 *master_key; /* TLS master secret */
|
||||
size_t master_key_len;
|
||||
struct tls_random {
|
||||
const u8 *client_random;
|
||||
size_t client_random_len;
|
||||
const u8 *server_random;
|
||||
|
@ -287,41 +285,31 @@ int __must_check tls_connection_set_verify(void *tls_ctx,
|
|||
int verify_peer);
|
||||
|
||||
/**
|
||||
* tls_connection_get_keys - Get master key and random data from TLS connection
|
||||
* tls_connection_get_random - Get random data from TLS connection
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @keys: Structure of key/random data (filled on success)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int __must_check tls_connection_get_keys(void *tls_ctx,
|
||||
int __must_check tls_connection_get_random(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
struct tls_keys *keys);
|
||||
struct tls_random *data);
|
||||
|
||||
/**
|
||||
* tls_connection_prf - Use TLS-PRF to derive keying material
|
||||
* tls_connection_export_key - Derive keying material from a TLS connection
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* @label: Label (e.g., description of the key) for PRF
|
||||
* @server_random_first: seed is 0 = client_random|server_random,
|
||||
* 1 = server_random|client_random
|
||||
* @out: Buffer for output data from TLS-PRF
|
||||
* @out_len: Length of the output buffer
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function is optional to implement if tls_connection_get_keys() provides
|
||||
* access to master secret and server/client random values. If these values are
|
||||
* not exported from the TLS library, tls_connection_prf() is required so that
|
||||
* further keying material can be derived from the master secret. If not
|
||||
* implemented, the function will still need to be defined, but it can just
|
||||
* return -1. Example implementation of this function is in tls_prf_sha1_md5()
|
||||
* when it is called with seed set to client_random|server_random (or
|
||||
* server_random|client_random).
|
||||
* Exports keying material using the mechanism described in RFC 5705.
|
||||
*/
|
||||
int __must_check tls_connection_prf(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const char *label,
|
||||
int server_random_first,
|
||||
u8 *out, size_t out_len);
|
||||
int __must_check tls_connection_export_key(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
const char *label,
|
||||
u8 *out, size_t out_len);
|
||||
|
||||
/**
|
||||
* tls_connection_handshake - Process TLS handshake (client side)
|
||||
|
@ -506,16 +494,6 @@ int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn);
|
|||
int tls_connection_get_write_alerts(void *tls_ctx,
|
||||
struct tls_connection *conn);
|
||||
|
||||
/**
|
||||
* tls_connection_get_keyblock_size - Get TLS key_block size
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
* @conn: Connection context data from tls_connection_init()
|
||||
* Returns: Size of the key_block for the negotiated cipher suite or -1 on
|
||||
* failure
|
||||
*/
|
||||
int tls_connection_get_keyblock_size(void *tls_ctx,
|
||||
struct tls_connection *conn);
|
||||
|
||||
/**
|
||||
* tls_capabilities - Get supported TLS capabilities
|
||||
* @tls_ctx: TLS context data from tls_init()
|
||||
|
|
|
@ -18,10 +18,6 @@
|
|||
#include "tls/tlsv1_client.h"
|
||||
#include "tls/tlsv1_server.h"
|
||||
|
||||
#ifndef CONFIG_TLS_INTERNAL_CLIENT
|
||||
#define CONFIG_TLS_INTERNAL_CLIENT
|
||||
#endif
|
||||
|
||||
static int tls_ref_count = 0;
|
||||
|
||||
struct tls_global {
|
||||
|
@ -280,43 +276,76 @@ int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn,
|
||||
struct tls_keys *keys)
|
||||
int tls_connection_get_random(void *tls_ctx, struct tls_connection *conn,
|
||||
struct tls_random *data)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client)
|
||||
return tlsv1_client_get_keys(conn->client, keys);
|
||||
return tlsv1_client_get_random(conn->client, data);
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
return tlsv1_server_get_keys(conn->server, keys);
|
||||
return tlsv1_server_get_random(conn->server, data);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
|
||||
const char *label, int server_random_first,
|
||||
u8 *out, size_t out_len)
|
||||
static int tls_get_keyblock_size(struct tls_connection *conn)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client)
|
||||
return tlsv1_client_get_keyblock_size(conn->client);
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
return tlsv1_server_get_keyblock_size(conn->server);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
|
||||
const char *label, int server_random_first,
|
||||
int skip_keyblock, u8 *out, size_t out_len)
|
||||
{
|
||||
int ret = -1, skip = 0;
|
||||
u8 *tmp_out = NULL;
|
||||
u8 *_out = out;
|
||||
|
||||
if (skip_keyblock) {
|
||||
skip = tls_get_keyblock_size(conn);
|
||||
if (skip < 0)
|
||||
return -1;
|
||||
tmp_out = os_malloc(skip + out_len);
|
||||
if (!tmp_out)
|
||||
return -1;
|
||||
_out = tmp_out;
|
||||
}
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client) {
|
||||
return tlsv1_client_prf(conn->client, label,
|
||||
ret = tlsv1_client_prf(conn->client, label,
|
||||
server_random_first,
|
||||
out, out_len);
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server) {
|
||||
return tlsv1_server_prf(conn->server, label,
|
||||
ret = tlsv1_server_prf(conn->server, label,
|
||||
server_random_first,
|
||||
out, out_len);
|
||||
}
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
if (ret == 0 && skip_keyblock)
|
||||
os_memcpy(out, _out + skip, out_len);
|
||||
wpa_bin_clear_free(tmp_out, skip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
|
||||
const char *label, u8 *out, size_t out_len)
|
||||
{
|
||||
return tls_connection_prf(tls_ctx, conn, label, 0, 0, out, out_len);
|
||||
}
|
||||
|
||||
struct wpabuf * tls_connection_handshake(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
|
@ -585,28 +614,11 @@ int tls_connection_get_write_alerts(void *tls_ctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_get_keyblock_size(void *tls_ctx,
|
||||
struct tls_connection *conn)
|
||||
{
|
||||
#ifdef CONFIG_TLS_INTERNAL_CLIENT
|
||||
if (conn->client)
|
||||
return tlsv1_client_get_keyblock_size(conn->client);
|
||||
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
|
||||
#ifdef CONFIG_TLS_INTERNAL_SERVER
|
||||
if (conn->server)
|
||||
return tlsv1_server_get_keyblock_size(conn->server);
|
||||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
unsigned int tls_capabilities(void *tls_ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int tls_connection_set_session_ticket_cb(void *tls_ctx,
|
||||
struct tls_connection *conn,
|
||||
tls_session_ticket_cb cb,
|
||||
|
@ -626,90 +638,3 @@ int tls_connection_set_session_ticket_cb(void *tls_ctx,
|
|||
#endif /* CONFIG_TLS_INTERNAL_SERVER */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* tls_prf_sha1_md5 - Pseudo-Random Function for TLS (TLS-PRF, RFC 2246)
|
||||
* @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 2246, Chapter 5.
|
||||
*/
|
||||
int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label,
|
||||
const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
|
||||
{
|
||||
size_t L_S1, L_S2, i;
|
||||
const u8 *S1, *S2;
|
||||
u8 A_MD5[MD5_MAC_LEN], A_SHA1[SHA1_MAC_LEN];
|
||||
u8 P_MD5[MD5_MAC_LEN], P_SHA1[SHA1_MAC_LEN];
|
||||
int MD5_pos, SHA1_pos;
|
||||
const u8 *MD5_addr[3];
|
||||
size_t MD5_len[3];
|
||||
const unsigned char *SHA1_addr[3];
|
||||
size_t SHA1_len[3];
|
||||
|
||||
if (secret_len & 1)
|
||||
return -1;
|
||||
|
||||
MD5_addr[0] = A_MD5;
|
||||
MD5_len[0] = MD5_MAC_LEN;
|
||||
MD5_addr[1] = (unsigned char *) label;
|
||||
MD5_len[1] = os_strlen(label);
|
||||
MD5_addr[2] = seed;
|
||||
MD5_len[2] = seed_len;
|
||||
|
||||
SHA1_addr[0] = A_SHA1;
|
||||
SHA1_len[0] = SHA1_MAC_LEN;
|
||||
SHA1_addr[1] = (unsigned char *) label;
|
||||
SHA1_len[1] = os_strlen(label);
|
||||
SHA1_addr[2] = seed;
|
||||
SHA1_len[2] = seed_len;
|
||||
|
||||
/* RFC 2246, 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 = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed)
|
||||
*/
|
||||
|
||||
L_S1 = L_S2 = (secret_len + 1) / 2;
|
||||
S1 = secret;
|
||||
S2 = secret + L_S1;
|
||||
if (secret_len & 1) {
|
||||
/* The last byte of S1 will be shared with S2 */
|
||||
S2--;
|
||||
}
|
||||
|
||||
hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5);
|
||||
hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
|
||||
|
||||
MD5_pos = MD5_MAC_LEN;
|
||||
SHA1_pos = SHA1_MAC_LEN;
|
||||
for (i = 0; i < outlen; i++) {
|
||||
if (MD5_pos == MD5_MAC_LEN) {
|
||||
hmac_md5_vector(S1, L_S1, 3, MD5_addr, MD5_len, P_MD5);
|
||||
MD5_pos = 0;
|
||||
hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5);
|
||||
}
|
||||
if (SHA1_pos == SHA1_MAC_LEN) {
|
||||
hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len,
|
||||
P_SHA1);
|
||||
SHA1_pos = 0;
|
||||
hmac_sha1(S2, L_S2, A_SHA1, SHA1_MAC_LEN, A_SHA1);
|
||||
}
|
||||
|
||||
out[i] = P_MD5[MD5_pos] ^ P_SHA1[SHA1_pos];
|
||||
|
||||
MD5_pos++;
|
||||
SHA1_pos++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -729,12 +729,12 @@ int tlsv1_client_hello_ext(struct tlsv1_client *conn, int ext_type,
|
|||
|
||||
|
||||
/**
|
||||
* tlsv1_client_get_keys - Get master key and random data from TLS connection
|
||||
* tlsv1_client_get_random - Get random data from TLS connection
|
||||
* @conn: TLSv1 client connection data from tlsv1_client_init()
|
||||
* @keys: Structure of key/random data (filled on success)
|
||||
* @keys: Structure of random data (filled on success)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int tlsv1_client_get_keys(struct tlsv1_client *conn, struct tls_keys *keys)
|
||||
int tlsv1_client_get_random(struct tlsv1_client *conn, struct tls_random *keys)
|
||||
{
|
||||
os_memset(keys, 0, sizeof(*keys));
|
||||
if (conn->state == CLIENT_HELLO)
|
||||
|
@ -746,8 +746,6 @@ int tlsv1_client_get_keys(struct tlsv1_client *conn, struct tls_keys *keys)
|
|||
if (conn->state != SERVER_HELLO) {
|
||||
keys->server_random = conn->server_random;
|
||||
keys->server_random_len = TLS_RANDOM_LEN;
|
||||
keys->master_key = conn->master_secret;
|
||||
keys->master_key_len = TLS_MASTER_SECRET_LEN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -36,7 +36,7 @@ int tlsv1_client_shutdown(struct tlsv1_client *conn);
|
|||
int tlsv1_client_resumed(struct tlsv1_client *conn);
|
||||
int tlsv1_client_hello_ext(struct tlsv1_client *conn, int ext_type,
|
||||
const u8 *data, size_t data_len);
|
||||
int tlsv1_client_get_keys(struct tlsv1_client *conn, struct tls_keys *keys);
|
||||
int tlsv1_client_get_random(struct tlsv1_client *conn, struct tls_random *data);
|
||||
int tlsv1_client_get_keyblock_size(struct tlsv1_client *conn);
|
||||
int tlsv1_client_set_cipher_list(struct tlsv1_client *conn, u8 *ciphers);
|
||||
int tlsv1_client_set_cred(struct tlsv1_client *conn,
|
||||
|
|
|
@ -570,12 +570,12 @@ int tlsv1_server_resumed(struct tlsv1_server *conn)
|
|||
|
||||
|
||||
/**
|
||||
* tlsv1_server_get_keys - Get master key and random data from TLS connection
|
||||
* tlsv1_server_get_random - Get random data from TLS connection
|
||||
* @conn: TLSv1 server connection data from tlsv1_server_init()
|
||||
* @keys: Structure of key/random data (filled on success)
|
||||
* @keys: Structure of random data (filled on success)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int tlsv1_server_get_keys(struct tlsv1_server *conn, struct tls_keys *keys)
|
||||
int tlsv1_server_get_random(struct tlsv1_server *conn, struct tls_random *keys)
|
||||
{
|
||||
os_memset(keys, 0, sizeof(*keys));
|
||||
if (conn->state == CLIENT_HELLO)
|
||||
|
@ -587,8 +587,6 @@ int tlsv1_server_get_keys(struct tlsv1_server *conn, struct tls_keys *keys)
|
|||
if (conn->state != SERVER_HELLO) {
|
||||
keys->server_random = conn->server_random;
|
||||
keys->server_random_len = TLS_RANDOM_LEN;
|
||||
keys->master_key = conn->master_secret;
|
||||
keys->master_key_len = TLS_MASTER_SECRET_LEN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -32,7 +32,7 @@ int tlsv1_server_get_cipher(struct tlsv1_server *conn, char *buf,
|
|||
size_t buflen);
|
||||
int tlsv1_server_shutdown(struct tlsv1_server *conn);
|
||||
int tlsv1_server_resumed(struct tlsv1_server *conn);
|
||||
int tlsv1_server_get_keys(struct tlsv1_server *conn, struct tls_keys *keys);
|
||||
int tlsv1_server_get_random(struct tlsv1_server *conn, struct tls_random *data);
|
||||
int tlsv1_server_get_keyblock_size(struct tlsv1_server *conn);
|
||||
int tlsv1_server_set_cipher_list(struct tlsv1_server *conn, u8 *ciphers);
|
||||
int tlsv1_server_set_verify(struct tlsv1_server *conn, int verify_peer);
|
||||
|
|
Loading…
Reference in a new issue