Skip to content

Commit d4378e4

Browse files
reaperhulkalex
authored andcommitted
disallow implicit tag truncation with finalize_with_tag (#4342)
1 parent c574e75 commit d4378e4

File tree

5 files changed

+28
-0
lines changed

5 files changed

+28
-0
lines changed

CHANGELOG.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ Changelog
88

99
.. note:: This version is not yet released and is under active development.
1010

11+
* **SECURITY ISSUE:**
12+
:meth:`~cryptography.hazmat.primitives.ciphers.AEADDecryptionContext.finalize_with_tag`
13+
allowed tag truncation by default which can allow tag forgery in some cases.
14+
The method now enforces the ``min_tag_length`` provided to the
15+
:class:`~cryptography.hazmat.primitives.ciphers.modes.GCM` constructor.
1116
* Added support for Python 3.7.
1217
* Added :meth:`~cryptography.fernet.Fernet.extract_timestamp` to get the
1318
authenticated timestamp of a :doc:`Fernet </fernet>` token.

docs/hazmat/primitives/symmetric-encryption.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ Interfaces
670670
:raises ValueError: This is raised when the data provided isn't
671671
a multiple of the algorithm's block size, if ``min_tag_length`` is
672672
less than 4, or if ``len(tag) < min_tag_length``.
673+
``min_tag_length`` is an argument to the ``GCM`` constructor.
673674
:raises NotImplementedError: This is raised if the version of the
674675
OpenSSL backend used is 1.0.1 or earlier.
675676

src/cryptography/hazmat/backends/openssl/ciphers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ def finalize_with_tag(self, tag):
199199
"finalize_with_tag requires OpenSSL >= 1.0.2. To use this "
200200
"method please update OpenSSL"
201201
)
202+
if len(tag) < self._mode._min_tag_length:
203+
raise ValueError(
204+
"Authentication tag must be {0} bytes or longer.".format(
205+
self._mode._min_tag_length)
206+
)
202207
res = self._backend._lib.EVP_CIPHER_CTX_ctrl(
203208
self._ctx, self._backend._lib.EVP_CTRL_AEAD_SET_TAG,
204209
len(tag), tag

src/cryptography/hazmat/primitives/ciphers/modes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ def __init__(self, initialization_vector, tag=None, min_tag_length=16):
220220
min_tag_length)
221221
)
222222
self._tag = tag
223+
self._min_tag_length = min_tag_length
223224

224225
tag = utils.read_only_property("_tag")
225226
initialization_vector = utils.read_only_property("_initialization_vector")

tests/hazmat/primitives/test_aes.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,3 +439,19 @@ def test_gcm_tag_decrypt_finalize(self, backend):
439439
decryptor.finalize()
440440
else:
441441
decryptor.finalize_with_tag(tag)
442+
443+
@pytest.mark.supported(
444+
only_if=lambda backend: (
445+
not backend._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_102 or
446+
backend._lib.CRYPTOGRAPHY_IS_LIBRESSL
447+
),
448+
skip_message="Not supported on OpenSSL 1.0.1",
449+
)
450+
def test_gcm_tag_decrypt_finalize_tag_length(self, backend):
451+
decryptor = base.Cipher(
452+
algorithms.AES(b"0" * 16),
453+
modes.GCM(b"0" * 12),
454+
backend=backend
455+
).decryptor()
456+
with pytest.raises(ValueError):
457+
decryptor.finalize_with_tag(b"tagtooshort")

0 commit comments

Comments
 (0)