diff --git a/components/wpa_supplicant/CMakeLists.txt b/components/wpa_supplicant/CMakeLists.txt index 330b94d6c..f3cfecc3f 100644 --- a/components/wpa_supplicant/CMakeLists.txt +++ b/components/wpa_supplicant/CMakeLists.txt @@ -10,6 +10,7 @@ set(srcs "port/os_xtensa.c" "src/crypto/aes-internal.c" "src/crypto/aes-unwrap.c" "src/crypto/aes-wrap.c" + "src/crypto/sha256-tlsprf.c" "src/crypto/bignum.c" "src/crypto/crypto_mbedtls.c" "src/crypto/crypto_ops.c" @@ -102,4 +103,6 @@ target_compile_definitions(${COMPONENT_LIB} PRIVATE ESPRESSIF_USE ESP32_WORKAROUND CONFIG_ECC + CONFIG_TLSV12 + CONFIG_SHA256 ) diff --git a/components/wpa_supplicant/src/crypto/crypto_internal.c b/components/wpa_supplicant/src/crypto/crypto_internal.c index ca82d0d52..32edaa217 100644 --- a/components/wpa_supplicant/src/crypto/crypto_internal.c +++ b/components/wpa_supplicant/src/crypto/crypto_internal.c @@ -73,7 +73,7 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, case CRYPTO_HASH_ALG_SHA256: #ifdef USE_MBEDTLS_CRYPTO mbedtls_sha256_init(&ctx->u.sha256); - mbedtls_sha256_starts(&ctx->u.sha256, 0); + mbedtls_sha256_starts_ret(&ctx->u.sha256, 0); #else /* USE_MBEDTLS_CRYPTO */ sha256_init(&ctx->u.sha256); #endif /* USE_MBEDTLS_CRYPTO */ @@ -122,9 +122,9 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, if (key_len > sizeof(k_pad)) { #ifdef USE_MBEDTLS_CRYPTO mbedtls_sha256_init(&ctx->u.sha256); - mbedtls_sha256_starts(&ctx->u.sha256, 0); - mbedtls_sha256_update(&ctx->u.sha256, key, key_len); - mbedtls_sha256_finish(&ctx->u.sha256, tk); + mbedtls_sha256_starts_ret(&ctx->u.sha256, 0); + mbedtls_sha256_update_ret(&ctx->u.sha256, key, key_len); + mbedtls_sha256_finish_ret(&ctx->u.sha256, tk); mbedtls_sha256_free(&ctx->u.sha256); #else /* USE_MBEDTLS_CRYPTO */ sha256_init(&ctx->u.sha256); @@ -144,8 +144,8 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, k_pad[i] ^= 0x36; #ifdef USE_MBEDTLS_CRYPTO mbedtls_sha256_init(&ctx->u.sha256); - mbedtls_sha256_starts(&ctx->u.sha256, 0); - mbedtls_sha256_update(&ctx->u.sha256, k_pad, sizeof(k_pad)); + mbedtls_sha256_starts_ret(&ctx->u.sha256, 0); + mbedtls_sha256_update_ret(&ctx->u.sha256, k_pad, sizeof(k_pad)); #else /* USE_MBEDTLS_CRYPTO */ sha256_init(&ctx->u.sha256); sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad)); @@ -179,7 +179,7 @@ void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) case CRYPTO_HASH_ALG_SHA256: case CRYPTO_HASH_ALG_HMAC_SHA256: #ifdef USE_MBEDTLS_CRYPTO - mbedtls_sha256_update(&ctx->u.sha256, data, len); + mbedtls_sha256_update_ret(&ctx->u.sha256, data, len); #else /* USE_MBEDTLS_CRYPTO */ sha256_process(&ctx->u.sha256, data, len); #endif /* USE_MBEDTLS_CRYPTO */ @@ -232,7 +232,7 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) } *len = 32; #ifdef USE_MBEDTLS_CRYPTO - mbedtls_sha256_finish(&ctx->u.sha256, mac); + mbedtls_sha256_finish_ret(&ctx->u.sha256, mac); mbedtls_sha256_free(&ctx->u.sha256); #else /* USE_MBEDTLS_CRYPTO */ sha256_done(&ctx->u.sha256, mac); @@ -289,7 +289,7 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) *len = 32; #ifdef USE_MBEDTLS_CRYPTO - mbedtls_sha256_finish(&ctx->u.sha256, mac); + mbedtls_sha256_finish_ret(&ctx->u.sha256, mac); mbedtls_sha256_free(&ctx->u.sha256); #else /* USE_MBEDTLS_CRYPTO */ sha256_done(&ctx->u.sha256, mac); @@ -302,10 +302,10 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) k_pad[i] ^= 0x5c; #ifdef USE_MBEDTLS_CRYPTO mbedtls_sha256_init(&ctx->u.sha256); - mbedtls_sha256_starts(&ctx->u.sha256, 0); - mbedtls_sha256_update(&ctx->u.sha256, k_pad, sizeof(k_pad)); - mbedtls_sha256_update(&ctx->u.sha256, mac, 32); - mbedtls_sha256_finish(&ctx->u.sha256, mac); + mbedtls_sha256_starts_ret(&ctx->u.sha256, 0); + mbedtls_sha256_update_ret(&ctx->u.sha256, k_pad, sizeof(k_pad)); + mbedtls_sha256_update_ret(&ctx->u.sha256, mac, 32); + mbedtls_sha256_finish_ret(&ctx->u.sha256, mac); mbedtls_sha256_free(&ctx->u.sha256); #else /* USE_MBEDTLS_CRYPTO */ sha256_init(&ctx->u.sha256); diff --git a/components/wpa_supplicant/src/crypto/sha256-tlsprf.c b/components/wpa_supplicant/src/crypto/sha256-tlsprf.c new file mode 100644 index 000000000..8483867ff --- /dev/null +++ b/components/wpa_supplicant/src/crypto/sha256-tlsprf.c @@ -0,0 +1,66 @@ +/* + * TLS PRF P_SHA256 + * Copyright (c) 2011, Jouni Malinen + * + * 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" + + +/** + * tls_prf_sha256 - Pseudo-Random Function for TLS v1.2 (P_SHA256, 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 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) +{ + size_t clen; + u8 A[SHA256_MAC_LEN]; + u8 P[SHA256_MAC_LEN]; + size_t pos; + const unsigned char *addr[3]; + size_t len[3]; + + addr[0] = A; + len[0] = SHA256_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_SHA256(secret, label + seed) + */ + + hmac_sha256_vector(secret, secret_len, 2, &addr[1], &len[1], A); + + 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); + + clen = outlen - pos; + if (clen > SHA256_MAC_LEN) + clen = SHA256_MAC_LEN; + os_memcpy(out + pos, P, clen); + pos += clen; + } +} diff --git a/components/wpa_supplicant/src/crypto/sha256.h b/components/wpa_supplicant/src/crypto/sha256.h index dc597f09b..0515e2409 100644 --- a/components/wpa_supplicant/src/crypto/sha256.h +++ b/components/wpa_supplicant/src/crypto/sha256.h @@ -24,4 +24,8 @@ void hmac_sha256(const u8 *key, size_t key_len, const u8 *data, void 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); +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); + #endif /* SHA256_H */