Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

disallow implicit tag truncation with finalize_with_tag #4342

Merged
merged 1 commit into from Jul 17, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.
+28 −0
Diff settings

Always

Just for now

disallow implicit tag truncation with finalize_with_tag

  • Loading branch information...
reaperhulk committed Jul 17, 2018
commit 688e0f673bfbf43fa898994326c6877f00ab19ef
Copy path View file
@@ -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.
@@ -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.

@@ -199,6 +199,11 @@ def finalize_with_tag(self, tag):
"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
@@ -220,6 +220,7 @@ def __init__(self, initialization_vector, tag=None, min_tag_length=16):
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")
@@ -439,3 +439,19 @@ def test_gcm_tag_decrypt_finalize(self, backend):
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")
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.