OpenSSL: Extend key_block size determination to support GCM/CCM ciphers

These ciphers do not use a separate MAC algorithm, so digest nid will be
NID_undef. In addition, the fixed_iv_length needs to be set to 4 which
is the implicit part of the IV from PRF. This is needed to fix EAP-FAST
key derivation for cases where GCM/CCM ciphers are used for TLS.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2019-12-23 18:58:43 +02:00
parent f94e677d33
commit b2e2a8588d

View file

@ -4047,6 +4047,7 @@ static int openssl_get_keyblock_size(SSL *ssl)
int cipher, digest; int cipher, digest;
const EVP_CIPHER *c; const EVP_CIPHER *c;
const EVP_MD *h; const EVP_MD *h;
int mac_key_len, enc_key_len, fixed_iv_len;
ssl_cipher = SSL_get_current_cipher(ssl); ssl_cipher = SSL_get_current_cipher(ssl);
if (!ssl_cipher) if (!ssl_cipher)
@ -4057,17 +4058,33 @@ static int openssl_get_keyblock_size(SSL *ssl)
cipher, digest); cipher, digest);
if (cipher < 0 || digest < 0) if (cipher < 0 || digest < 0)
return -1; return -1;
c = EVP_get_cipherbynid(cipher); if (cipher == NID_undef) {
h = EVP_get_digestbynid(digest); wpa_printf(MSG_DEBUG, "OpenSSL: no cipher in use?!");
if (!c || !h)
return -1; return -1;
}
c = EVP_get_cipherbynid(cipher);
if (!c)
return -1;
enc_key_len = EVP_CIPHER_key_length(c);
if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE ||
EVP_CIPHER_mode(c) == EVP_CIPH_CCM_MODE)
fixed_iv_len = 4; /* only part of IV from PRF */
else
fixed_iv_len = EVP_CIPHER_iv_length(c);
if (digest == NID_undef) {
wpa_printf(MSG_DEBUG, "OpenSSL: no digest in use (e.g., AEAD)");
mac_key_len = 0;
} else {
h = EVP_get_digestbynid(digest);
if (!h)
return -1;
mac_key_len = EVP_MD_size(h);
}
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"OpenSSL: keyblock size: key_len=%d MD_size=%d IV_len=%d", "OpenSSL: keyblock size: mac_key_len=%d enc_key_len=%d fixed_iv_len=%d",
EVP_CIPHER_key_length(c), EVP_MD_size(h), mac_key_len, enc_key_len, fixed_iv_len);
EVP_CIPHER_iv_length(c)); return 2 * (mac_key_len + enc_key_len + fixed_iv_len);
return 2 * (EVP_CIPHER_key_length(c) + EVP_MD_size(h) +
EVP_CIPHER_iv_length(c));
#endif #endif
} }
#endif /* OPENSSL_NEED_EAP_FAST_PRF */ #endif /* OPENSSL_NEED_EAP_FAST_PRF */