aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.rst5
-rw-r--r--docs/hazmat/primitives/symmetric-encryption.rst1
-rw-r--r--src/cryptography/hazmat/backends/openssl/ciphers.py5
-rw-r--r--src/cryptography/hazmat/primitives/ciphers/modes.py1
-rw-r--r--tests/hazmat/primitives/test_aes.py16
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")