diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index 5661e42d1..29115bc60 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -4047,6 +4047,7 @@ static int openssl_get_keyblock_size(SSL *ssl) int cipher, digest; const EVP_CIPHER *c; const EVP_MD *h; + int mac_key_len, enc_key_len, fixed_iv_len; ssl_cipher = SSL_get_current_cipher(ssl); if (!ssl_cipher) @@ -4057,17 +4058,33 @@ static int openssl_get_keyblock_size(SSL *ssl) cipher, digest); if (cipher < 0 || digest < 0) return -1; - c = EVP_get_cipherbynid(cipher); - h = EVP_get_digestbynid(digest); - if (!c || !h) + if (cipher == NID_undef) { + wpa_printf(MSG_DEBUG, "OpenSSL: no cipher in use?!"); 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, - "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)); + "OpenSSL: keyblock size: mac_key_len=%d enc_key_len=%d fixed_iv_len=%d", + mac_key_len, enc_key_len, fixed_iv_len); + return 2 * (mac_key_len + enc_key_len + fixed_iv_len); #endif } #endif /* OPENSSL_NEED_EAP_FAST_PRF */