diff options
-rw-r--r-- | CHANGELOG.rst | 5 | ||||
-rw-r--r-- | docs/hazmat/primitives/symmetric-encryption.rst | 1 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/ciphers.py | 5 | ||||
-rw-r--r-- | src/cryptography/hazmat/primitives/ciphers/modes.py | 1 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_aes.py | 16 |
5 files changed, 28 insertions, 0 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c8db7e7d..5ac43d0d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,11 @@ Changelog .. note:: This version is not yet released and is under active development. +* **SECURITY ISSUE:** + :meth:`~cryptography.hazmat.primitives.ciphers.AEADDecryptionContext.finalize_with_tag` + allowed tag truncation by default which can allow tag forgery in some cases. + The method now enforces the ``min_tag_length`` provided to the + :class:`~cryptography.hazmat.primitives.ciphers.modes.GCM` constructor. * Added support for Python 3.7. * Added :meth:`~cryptography.fernet.Fernet.extract_timestamp` to get the authenticated timestamp of a :doc:`Fernet </fernet>` token. diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index 5ebcca75..5b600090 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -670,6 +670,7 @@ Interfaces :raises ValueError: This is raised when the data provided isn't a multiple of the algorithm's block size, if ``min_tag_length`` is less than 4, or if ``len(tag) < min_tag_length``. + ``min_tag_length`` is an argument to the ``GCM`` constructor. :raises NotImplementedError: This is raised if the version of the OpenSSL backend used is 1.0.1 or earlier. diff --git a/src/cryptography/hazmat/backends/openssl/ciphers.py b/src/cryptography/hazmat/backends/openssl/ciphers.py index 462ffea2..e0ee06ee 100644 --- a/src/cryptography/hazmat/backends/openssl/ciphers.py +++ b/src/cryptography/hazmat/backends/openssl/ciphers.py @@ -199,6 +199,11 @@ class _CipherContext(object): "finalize_with_tag requires OpenSSL >= 1.0.2. To use this " "method please update OpenSSL" ) + if len(tag) < self._mode._min_tag_length: + raise ValueError( + "Authentication tag must be {0} bytes or longer.".format( + self._mode._min_tag_length) + ) res = self._backend._lib.EVP_CIPHER_CTX_ctrl( self._ctx, self._backend._lib.EVP_CTRL_AEAD_SET_TAG, len(tag), tag diff --git a/src/cryptography/hazmat/primitives/ciphers/modes.py b/src/cryptography/hazmat/primitives/ciphers/modes.py index 598dfaa4..543015fe 100644 --- a/src/cryptography/hazmat/primitives/ciphers/modes.py +++ b/src/cryptography/hazmat/primitives/ciphers/modes.py @@ -220,6 +220,7 @@ class GCM(object): min_tag_length) ) self._tag = tag + self._min_tag_length = min_tag_length tag = utils.read_only_property("_tag") initialization_vector = utils.read_only_property("_initialization_vector") diff --git a/tests/hazmat/primitives/test_aes.py b/tests/hazmat/primitives/test_aes.py index d6f83ebc..4ceccf15 100644 --- a/tests/hazmat/primitives/test_aes.py +++ b/tests/hazmat/primitives/test_aes.py @@ -439,3 +439,19 @@ class TestAESModeGCM(object): decryptor.finalize() else: decryptor.finalize_with_tag(tag) + + @pytest.mark.supported( + only_if=lambda backend: ( + not backend._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_102 or + backend._lib.CRYPTOGRAPHY_IS_LIBRESSL + ), + skip_message="Not supported on OpenSSL 1.0.1", + ) + def test_gcm_tag_decrypt_finalize_tag_length(self, backend): + decryptor = base.Cipher( + algorithms.AES(b"0" * 16), + modes.GCM(b"0" * 12), + backend=backend + ).decryptor() + with pytest.raises(ValueError): + decryptor.finalize_with_tag(b"tagtooshort") |