PHP 8.2: OpenSSL: New openssl_cipher_key_length function

Version8.2
TypeNew Feature

The OpenSSL extension in PHP 8.2 adds a new function named openssl_cipher_key_length, that returns the required length of the key (in bytes) for any supported OpenSSL cipher.

The information is fetched from the underlying OpenSSL library, so they are consistent and can be trusted.

This function follows similar semantics of the existing openssl_cipher_iv_length() function, which returns the initialization vector length required for the cipher.

openssl_cipher_key_length function synopsis

openssl_cipher_key_length function returns the required length of the key for a given cipher algorithm, or returns false if the cipher name is known.

For unknown cipher names, it also emits a warning openssl_cipher_key_length(): Unknown cipher algorithm.

/**
 * Returns the key length for the given cipher algorithm.
 * 
 * @param string $cipher_algo Cipher algorithm name.
 * @return int|false Length of the key, or false if the cipher name is unknown
 */
function openssl_cipher_key_length(string $cipher_algo): int|false {
}

Usage Examples

openssl_cipher_key_length("CHACHA20-POLY1305");
// 32
openssl_cipher_key_length("AES-128-GCM");
// 16
openssl_cipher_key_length("AES-256-GCM");
// 32

openssl_cipher_key_length("Does Not Exist");
// false
// Warning: openssl_cipher_key_length(): Unknown cipher algorithm in ... on line ...

User-land polyfill

Note that the openssl_cipher_key_length function uses the OpenSSL library to retrieve the key lengths, and the OpenSSL PHP extension does not hard-code any of the key length information. However because the key lengths for each cipher are constant, a (meticulous yet static) polyfill function can be created by hard-coding the key lengths of known ciphers.

The following is an example that returns key lengths of each OpenSSL cipher, and follows a similar behavior when it encounters an unknown cipher name. However, when OpenSSL is built with different or uncommon cipher suites, the following hard-coded values must be updated to maintain the compatibility with the built-in openssl_cipher_key_length function.

function openssl_cipher_key_length(string $cipher_algo): int|false {
  $length = match(strtolower($cipher_algo)) {
    'aes-128-cbc' => 16,
    'aes-128-cbc-hmac-sha1' => 16,
    'aes-128-cbc-hmac-sha256' => 16,
    'aes-128-ccm' => 16,
    'aes-128-cfb' => 16,
    'aes-128-cfb1' => 16,
    'aes-128-cfb8' => 16,
    'aes-128-ctr' => 16,
    'aes-128-ecb' => 16,
    'aes-128-gcm' => 16,
    'aes-128-ocb' => 16,
    'aes-128-ofb' => 16,
    'aes-128-wrap' => 16,
    'aes-128-wrap-pad' => 16,
    'aes-128-xts' => 32,
    'aes-192-cbc' => 24,
    'aes-192-ccm' => 24,
    'aes-192-cfb' => 24,
    'aes-192-cfb1' => 24,
    'aes-192-cfb8' => 24,
    'aes-192-ctr' => 24,
    'aes-192-ecb' => 24,
    'aes-192-gcm' => 24,
    'aes-192-ocb' => 24,
    'aes-192-ofb' => 24,
    'aes-192-wrap' => 24,
    'aes-192-wrap-pad' => 24,
    'aes-256-cbc' => 32,
    'aes-256-cbc-hmac-sha1' => 32,
    'aes-256-cbc-hmac-sha256' => 32,
    'aes-256-ccm' => 32,
    'aes-256-cfb' => 32,
    'aes-256-cfb1' => 32,
    'aes-256-cfb8' => 32,
    'aes-256-ctr' => 32,
    'aes-256-ecb' => 32,
    'aes-256-gcm' => 32,
    'aes-256-ocb' => 32,
    'aes-256-ofb' => 32,
    'aes-256-wrap' => 32,
    'aes-256-wrap-pad' => 32,
    'aes-256-xts' => 64,
    'aria-128-cbc' => 16,
    'aria-128-ccm' => 16,
    'aria-128-cfb' => 16,
    'aria-128-cfb1' => 16,
    'aria-128-cfb8' => 16,
    'aria-128-ctr' => 16,
    'aria-128-ecb' => 16,
    'aria-128-gcm' => 16,
    'aria-128-ofb' => 16,
    'aria-192-cbc' => 24,
    'aria-192-ccm' => 24,
    'aria-192-cfb' => 24,
    'aria-192-cfb1' => 24,
    'aria-192-cfb8' => 24,
    'aria-192-ctr' => 24,
    'aria-192-ecb' => 24,
    'aria-192-gcm' => 24,
    'aria-192-ofb' => 24,
    'aria-256-cbc' => 32,
    'aria-256-ccm' => 32,
    'aria-256-cfb' => 32,
    'aria-256-cfb1' => 32,
    'aria-256-cfb8' => 32,
    'aria-256-ctr' => 32,
    'aria-256-ecb' => 32,
    'aria-256-gcm' => 32,
    'aria-256-ofb' => 32,
    'camellia-128-cbc' => 16,
    'camellia-128-cfb' => 16,
    'camellia-128-cfb1' => 16,
    'camellia-128-cfb8' => 16,
    'camellia-128-ctr' => 16,
    'camellia-128-ecb' => 16,
    'camellia-128-ofb' => 16,
    'camellia-192-cbc' => 24,
    'camellia-192-cfb' => 24,
    'camellia-192-cfb1' => 24,
    'camellia-192-cfb8' => 24,
    'camellia-192-ctr' => 24,
    'camellia-192-ecb' => 24,
    'camellia-192-ofb' => 24,
    'camellia-256-cbc' => 32,
    'camellia-256-cfb' => 32,
    'camellia-256-cfb1' => 32,
    'camellia-256-cfb8' => 32,
    'camellia-256-ctr' => 32,
    'camellia-256-ecb' => 32,
    'camellia-256-ofb' => 32,
    'chacha20' => 32,
    'chacha20-poly1305' => 32,
    'des-ede-cbc' => 16,
    'des-ede-cfb' => 16,
    'des-ede-ecb' => 16,
    'des-ede-ofb' => 16,
    'des-ede3-cbc' => 24,
    'des-ede3-cfb' => 24,
    'des-ede3-cfb1' => 24,
    'des-ede3-cfb8' => 24,
    'des-ede3-ecb' => 24,
    'des-ede3-ofb' => 24,
    'des3-wrap' => 24,
    'sm4-cbc' => 16,
    'sm4-cfb' => 16,
    'sm4-ctr' => 16,
    'sm4-ecb' => 16,
    'sm4-ofb' => 16,
    default => false,
  };

  if ($length === false) {
      trigger_error('openssl_cipher_key_length(): Unknown cipher algorithm', E_USER_WARNING);
  }

  return $length;
}

Backwards Compatibility Impact

openssl_cipher_key_length is a new function added to the OpenSSL extension in PHP 8.2. It can be polyfilled in older PHP versions, albeit imperfectly, by creating a user-land PHP function with a hard-coded list of key lengths for known ciphers.


Implementation