]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OpenSSL: Extend key_block size determination to support GCM/CCM ciphers
authorJouni Malinen <j@w1.fi>
Mon, 23 Dec 2019 16:58:43 +0000 (18:58 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 23 Dec 2019 18:02:45 +0000 (20:02 +0200)
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>
src/crypto/tls_openssl.c

index 5661e42d19d1d64c10c02eec44ba6c5ac8beaa2a..29115bc60c0f2d9507bf9192a0e2c77795e92708 100644 (file)
@@ -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;
+       if (cipher == NID_undef) {
+               wpa_printf(MSG_DEBUG, "OpenSSL: no cipher in use?!");
+               return -1;
+       }
        c = EVP_get_cipherbynid(cipher);
-       h = EVP_get_digestbynid(digest);
-       if (!c || !h)
+       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 */