Use tls_connection_prf() for all EAP TLS-based key derivation

tls_openssl.c is the only remaining TLS/crypto wrapper that needs the
internal PRF implementation for EAP-FAST (since
SSL_export_keying_material() is not available in older versions and does
not support server-random-before-client case). As such, it is cleaner to
assume that TLS libraries support tls_connection_prf() and move the
additional support code for the otherwise unsupported cases into
tls_openssl.c.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2015-03-31 15:47:32 +03:00 committed by Jouni Malinen
parent df8191d0b8
commit fa0e715100
4 changed files with 75 additions and 101 deletions

View file

@ -96,8 +96,7 @@ void eap_fast_derive_master_secret(const u8 *pac_key, const u8 *server_random,
u8 * eap_fast_derive_key(void *ssl_ctx, struct tls_connection *conn,
const char *label, size_t len)
{
struct tls_keys keys;
u8 *rnd = NULL, *out;
u8 *out;
int block_size;
block_size = tls_connection_get_keyblock_size(ssl_ctx, conn);
@ -108,37 +107,15 @@ u8 * eap_fast_derive_key(void *ssl_ctx, struct tls_connection *conn,
if (out == NULL)
return NULL;
if (tls_connection_prf(ssl_ctx, conn, label, 1, out, block_size + len)
== 0) {
os_memmove(out, out + block_size, len);
return out;
if (tls_connection_prf(ssl_ctx, conn, label, 1, out, block_size + len))
{
os_free(out);
return NULL;
}
if (tls_connection_get_keys(ssl_ctx, conn, &keys))
goto fail;
rnd = os_malloc(keys.client_random_len + keys.server_random_len);
if (rnd == NULL)
goto fail;
os_memcpy(rnd, keys.server_random, keys.server_random_len);
os_memcpy(rnd + keys.server_random_len, keys.client_random,
keys.client_random_len);
wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: master_secret for key "
"expansion", keys.master_key, keys.master_key_len);
if (tls_prf_sha1_md5(keys.master_key, keys.master_key_len,
label, rnd, keys.client_random_len +
keys.server_random_len, out, block_size + len))
goto fail;
os_free(rnd);
os_memmove(out, out + block_size, len);
os_memset(out + len, 0, block_size);
return out;
fail:
os_free(rnd);
os_free(out);
return NULL;
}