From f7b4ede584f5612546a07eb085eb5672629dcb96 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Dec 2013 17:25:19 -0600 Subject: restrict gcm tags to a minimum of 4 bytes in length --- cryptography/hazmat/backends/openssl/backend.py | 6 +++--- tests/hazmat/primitives/utils.py | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 5b7cb3de..559ace7e 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -319,9 +319,9 @@ class _CipherContext(object): ) assert res != 0 if operation == self._DECRYPT: - if not mode.tag: - raise ValueError("Authentication tag must be supplied " - "when decrypting") + if not mode.tag or len(mode.tag) < 4: + raise ValueError("Authentication tag must be provided " + "and >= 4 bytes when decrypting") res = self._backend.lib.EVP_CIPHER_CTX_ctrl( ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_TAG, len(mode.tag), mode.tag diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index 227a4055..b00d3184 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -359,6 +359,13 @@ def aead_tag_exception_test(backend, cipher_factory, mode_factory, mode_factory(binascii.unhexlify(b"0" * 24)), backend ) + with pytest.raises(ValueError): + cipher.decryptor() + cipher = Cipher( + cipher_factory(binascii.unhexlify(b"0" * 32)), + mode_factory(binascii.unhexlify(b"0" * 24), b"000"), + backend + ) with pytest.raises(ValueError): cipher.decryptor() cipher = Cipher( -- cgit v1.2.3 From ca73504e62e2c55a7235f94c78cb8ee4d3718590 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Dec 2013 17:31:48 -0600 Subject: add note regarding not truncating tags --- docs/hazmat/primitives/symmetric-encryption.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index f4d0457a..8ed64c7c 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -352,6 +352,11 @@ Modes Do not reuse an ``initialization_vector`` with a given ``key``. + .. note:: + + Do not truncate the GCM authentication tag unless absolutely necessary. + If you must truncate the minimum allowable length is 4 bytes. + :param bytes tag: The tag bytes to verify during decryption. When encrypting this must be None. -- cgit v1.2.3 From a7fbf07a3e96133b40df05ac5be159bbf6f1fc91 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Dec 2013 18:12:25 -0600 Subject: doc updates --- cryptography/hazmat/backends/openssl/backend.py | 2 +- docs/hazmat/primitives/symmetric-encryption.rst | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 559ace7e..9697a4a6 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -321,7 +321,7 @@ class _CipherContext(object): if operation == self._DECRYPT: if not mode.tag or len(mode.tag) < 4: raise ValueError("Authentication tag must be provided " - "and >= 4 bytes when decrypting") + "and 4 bytes or longer when decrypting") res = self._backend.lib.EVP_CIPHER_CTX_ctrl( ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_TAG, len(mode.tag), mode.tag diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index 8ed64c7c..85d7d5b1 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -354,8 +354,10 @@ Modes .. note:: - Do not truncate the GCM authentication tag unless absolutely necessary. - If you must truncate the minimum allowable length is 4 bytes. + `NIST SP-800-38D`_ recommends that GCM tags be 128, 120, 122, 104, or + 96-bits in length. Tags are shortened by truncating bytes. Longer tags + provide better security margins. If you must shorten the tag the minimum + allowed length is 4 bytes (32 bits). :param bytes tag: The tag bytes to verify during decryption. When encrypting this must be None. @@ -395,3 +397,4 @@ Insecure Modes .. _`described by Colin Percival`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html .. _`recommends 96-bit IV length`: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf +.. _`NIST SP-800-38D`: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf -- cgit v1.2.3 From fc73e2d04315e21011869fbd925df9e7a99d21ae Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Dec 2013 18:41:38 -0600 Subject: prose updates for GCM tag --- cryptography/hazmat/backends/openssl/backend.py | 4 ++-- docs/hazmat/primitives/symmetric-encryption.rst | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index 9697a4a6..b0ea96ea 100644 --- a/cryptography/hazmat/backends/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -320,8 +320,8 @@ class _CipherContext(object): assert res != 0 if operation == self._DECRYPT: if not mode.tag or len(mode.tag) < 4: - raise ValueError("Authentication tag must be provided " - "and 4 bytes or longer when decrypting") + raise ValueError("Authentication tag must be provided and " + "be 4 bytes or longer when decrypting") res = self._backend.lib.EVP_CIPHER_CTX_ctrl( ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_TAG, len(mode.tag), mode.tag diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index 85d7d5b1..f009bb78 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -354,10 +354,12 @@ Modes .. note:: - `NIST SP-800-38D`_ recommends that GCM tags be 128, 120, 122, 104, or - 96-bits in length. Tags are shortened by truncating bytes. Longer tags - provide better security margins. If you must shorten the tag the minimum - allowed length is 4 bytes (32 bits). + Cryptography will emit a 128-bit tag when finalizing encryption. + You can shorten a tag by truncating it to the desired length, but this + is **not recommended** as it lowers the security margins of the + authentication (`NIST SP-800-38D`_ recommends 96-bit or greater). + If you must shorten the tag the minimum allowed length is 4 bytes + (32 bit). :param bytes tag: The tag bytes to verify during decryption. When encrypting this must be None. -- cgit v1.2.3 From 048d6cb43a0757f3b4cca385e788d30173ebcb17 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Dec 2013 18:53:19 -0600 Subject: a few more doc changes to gcm tag info --- docs/hazmat/primitives/symmetric-encryption.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index f009bb78..6e3c1024 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -357,9 +357,10 @@ Modes Cryptography will emit a 128-bit tag when finalizing encryption. You can shorten a tag by truncating it to the desired length, but this is **not recommended** as it lowers the security margins of the - authentication (`NIST SP-800-38D`_ recommends 96-bit or greater). + authentication (`NIST SP-800-38D`_ recommends 96-bits or greater). If you must shorten the tag the minimum allowed length is 4 bytes - (32 bit). + (32-bits). Applications **must** verify the tag is the expected length + to guarantee the expected security margin. :param bytes tag: The tag bytes to verify during decryption. When encrypting this must be None. -- cgit v1.2.3