OpenSSL: Implement openssl_tls_prf() for OpenSSL 1.1.0
This needs to use the new accessor functions since the SSL session details are not directly accessible anymore and there is now sufficient helper functions to get to the needed information. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
4d2a1b4f8f
commit
3de28506d2
1 changed files with 102 additions and 0 deletions
|
@ -2680,6 +2680,7 @@ int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
|
|||
|
||||
static int openssl_get_keyblock_size(SSL *ssl)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
const EVP_CIPHER *c;
|
||||
const EVP_MD *h;
|
||||
int md_size;
|
||||
|
@ -2709,6 +2710,33 @@ static int openssl_get_keyblock_size(SSL *ssl)
|
|||
return 2 * (EVP_CIPHER_key_length(c) +
|
||||
md_size +
|
||||
EVP_CIPHER_iv_length(c));
|
||||
#else
|
||||
const SSL_CIPHER *ssl_cipher;
|
||||
int cipher, digest;
|
||||
const EVP_CIPHER *c;
|
||||
const EVP_MD *h;
|
||||
|
||||
ssl_cipher = SSL_get_current_cipher(ssl);
|
||||
if (!ssl_cipher)
|
||||
return -1;
|
||||
cipher = SSL_CIPHER_get_cipher_nid(ssl_cipher);
|
||||
digest = SSL_CIPHER_get_digest_nid(ssl_cipher);
|
||||
wpa_printf(MSG_DEBUG, "OpenSSL: cipher nid %d digest nid %d",
|
||||
cipher, digest);
|
||||
if (cipher < 0 || digest < 0)
|
||||
return -1;
|
||||
c = EVP_get_cipherbynid(cipher);
|
||||
h = EVP_get_digestbynid(digest);
|
||||
if (!c || !h)
|
||||
return -1;
|
||||
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"OpenSSL: keyblock size: key_len=%d MD_size=%d IV_len=%d",
|
||||
EVP_CIPHER_key_length(c), EVP_MD_size(h),
|
||||
EVP_CIPHER_iv_length(c));
|
||||
return 2 * (EVP_CIPHER_key_length(c) + EVP_MD_size(h) +
|
||||
EVP_CIPHER_iv_length(c));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -2721,6 +2749,7 @@ static int openssl_tls_prf(void *tls_ctx, struct tls_connection *conn,
|
|||
"mode");
|
||||
return -1;
|
||||
#else /* CONFIG_FIPS */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
SSL *ssl;
|
||||
u8 *rnd;
|
||||
int ret = -1;
|
||||
|
@ -2780,6 +2809,79 @@ static int openssl_tls_prf(void *tls_ctx, struct tls_connection *conn,
|
|||
bin_clear_free(tmp_out, skip);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
SSL *ssl;
|
||||
SSL_SESSION *sess;
|
||||
u8 *rnd;
|
||||
int ret = -1;
|
||||
int skip = 0;
|
||||
u8 *tmp_out = NULL;
|
||||
u8 *_out = out;
|
||||
unsigned char client_random[SSL3_RANDOM_SIZE];
|
||||
unsigned char server_random[SSL3_RANDOM_SIZE];
|
||||
unsigned char master_key[64];
|
||||
size_t master_key_len;
|
||||
|
||||
/*
|
||||
* 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 (conn == NULL)
|
||||
return -1;
|
||||
ssl = conn->ssl;
|
||||
if (ssl == NULL)
|
||||
return -1;
|
||||
sess = SSL_get_session(ssl);
|
||||
if (!sess)
|
||||
return -1;
|
||||
|
||||
if (skip_keyblock) {
|
||||
skip = openssl_get_keyblock_size(ssl);
|
||||
if (skip < 0)
|
||||
return -1;
|
||||
tmp_out = os_malloc(skip + out_len);
|
||||
if (!tmp_out)
|
||||
return -1;
|
||||
_out = tmp_out;
|
||||
}
|
||||
|
||||
rnd = os_malloc(2 * SSL3_RANDOM_SIZE);
|
||||
if (!rnd) {
|
||||
os_free(tmp_out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSL_get_client_random(ssl, client_random, sizeof(client_random));
|
||||
SSL_get_server_random(ssl, server_random, sizeof(server_random));
|
||||
master_key_len = SSL_SESSION_get_master_key(sess, master_key,
|
||||
sizeof(master_key));
|
||||
|
||||
if (server_random_first) {
|
||||
os_memcpy(rnd, server_random, SSL3_RANDOM_SIZE);
|
||||
os_memcpy(rnd + SSL3_RANDOM_SIZE, client_random,
|
||||
SSL3_RANDOM_SIZE);
|
||||
} else {
|
||||
os_memcpy(rnd, client_random, SSL3_RANDOM_SIZE);
|
||||
os_memcpy(rnd + SSL3_RANDOM_SIZE, server_random,
|
||||
SSL3_RANDOM_SIZE);
|
||||
}
|
||||
|
||||
/* TODO: TLSv1.2 may need another PRF. This could use something closer
|
||||
* to SSL_export_keying_material() design. */
|
||||
if (tls_prf_sha1_md5(master_key, master_key_len,
|
||||
label, rnd, 2 * SSL3_RANDOM_SIZE,
|
||||
_out, skip + out_len) == 0)
|
||||
ret = 0;
|
||||
os_memset(master_key, 0, sizeof(master_key));
|
||||
os_free(rnd);
|
||||
if (ret == 0 && skip_keyblock)
|
||||
os_memcpy(out, _out + skip, out_len);
|
||||
bin_clear_free(tmp_out, skip);
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
#endif /* CONFIG_FIPS */
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue