diff options
Diffstat (limited to 'src')
4 files changed, 41 insertions, 39 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/ciphers.py b/src/cryptography/hazmat/backends/openssl/ciphers.py index 739ae19a..cfd6c1b5 100644 --- a/src/cryptography/hazmat/backends/openssl/ciphers.py +++ b/src/cryptography/hazmat/backends/openssl/ciphers.py @@ -13,6 +13,7 @@ from cryptography.hazmat.primitives.ciphers import modes @utils.register_interface(ciphers.CipherContext) @utils.register_interface(ciphers.AEADCipherContext) @utils.register_interface(ciphers.AEADEncryptionContext) +@utils.register_interface(ciphers.AEADDecryptionContext) class _CipherContext(object): _ENCRYPT = 1 _DECRYPT = 0 @@ -78,21 +79,22 @@ class _CipherContext(object): len(iv_nonce), self._backend._ffi.NULL ) self._backend.openssl_assert(res != 0) - if ( - self._operation == self._DECRYPT and - self._backend._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_102 and - not self._backend._lib.CRYPTOGRAPHY_IS_LIBRESSL - ): - if mode.tag is None: - raise NotImplementedError( - "delayed passing of GCM tag requires OpenSSL >= 1.0.2." - " To use this feature please update OpenSSL" - ) + if mode.tag is not None: res = self._backend._lib.EVP_CIPHER_CTX_ctrl( ctx, self._backend._lib.EVP_CTRL_GCM_SET_TAG, len(mode.tag), mode.tag ) self._backend.openssl_assert(res != 0) + self._tag = mode.tag + elif ( + self._operation == self._DECRYPT and + self._backend._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_102 and + not self._backend._lib.CRYPTOGRAPHY_IS_LIBRESSL + ): + raise NotImplementedError( + "delayed passing of GCM tag requires OpenSSL >= 1.0.2." + " To use this feature please update OpenSSL" + ) # pass key/iv res = self._backend._lib.EVP_CipherInit_ex( @@ -146,21 +148,11 @@ class _CipherContext(object): if ( self._operation == self._DECRYPT and isinstance(self._mode, modes.ModeWithAuthenticationTag) and - ( - not self._backend._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_102 or - self._backend._lib.CRYPTOGRAPHY_IS_LIBRESSL - ) + self.tag is None ): - tag = self._mode.tag - if tag is None: - raise ValueError( - "Authentication tag must be provided when decrypting." - ) - res = self._backend._lib.EVP_CIPHER_CTX_ctrl( - self._ctx, self._backend._lib.EVP_CTRL_GCM_SET_TAG, - len(tag), tag + raise ValueError( + "Authentication tag must be provided when decrypting." ) - self._backend.openssl_assert(res != 0) buf = self._backend._ffi.new("unsigned char[]", self._block_size_bytes) outlen = self._backend._ffi.new("int *") @@ -203,6 +195,23 @@ class _CipherContext(object): self._backend.openssl_assert(res == 1) return self._backend._ffi.buffer(buf)[:outlen[0]] + def finalize_with_tag(self, tag): + if ( + self._backend._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_102 and + not self._backend._lib.CRYPTOGRAPHY_IS_LIBRESSL + ): + raise NotImplementedError( + "finalize_with_tag requires OpenSSL >= 1.0.2. To use this " + "method please update OpenSSL" + ) + res = self._backend._lib.EVP_CIPHER_CTX_ctrl( + self._ctx, self._backend._lib.EVP_CTRL_GCM_SET_TAG, + len(tag), tag + ) + self._backend.openssl_assert(res != 0) + self._tag = tag + return self.finalize() + def authenticate_additional_data(self, data): outlen = self._backend._ffi.new("int *") res = self._backend._lib.EVP_CipherUpdate( diff --git a/src/cryptography/hazmat/primitives/ciphers/__init__.py b/src/cryptography/hazmat/primitives/ciphers/__init__.py index b5dd0ed7..171b1c69 100644 --- a/src/cryptography/hazmat/primitives/ciphers/__init__.py +++ b/src/cryptography/hazmat/primitives/ciphers/__init__.py @@ -5,8 +5,8 @@ from __future__ import absolute_import, division, print_function from cryptography.hazmat.primitives.ciphers.base import ( - AEADCipherContext, AEADEncryptionContext, BlockCipherAlgorithm, Cipher, - CipherAlgorithm, CipherContext + AEADCipherContext, AEADDecryptionContext, AEADEncryptionContext, + BlockCipherAlgorithm, Cipher, CipherAlgorithm, CipherContext ) @@ -16,5 +16,6 @@ __all__ = [ "BlockCipherAlgorithm", "CipherContext", "AEADCipherContext", + "AEADDecryptionContext", "AEADEncryptionContext", ] diff --git a/src/cryptography/hazmat/primitives/ciphers/base.py b/src/cryptography/hazmat/primitives/ciphers/base.py index dd024fb9..826e23ef 100644 --- a/src/cryptography/hazmat/primitives/ciphers/base.py +++ b/src/cryptography/hazmat/primitives/ciphers/base.py @@ -221,17 +221,12 @@ class _AEADCipherContext(object): return data def finalize_with_tag(self, tag): - if ( - self._ctx._backend.name == "openssl" and - self._ctx._backend._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_102 and - not self._ctx._backend._lib.CRYPTOGRAPHY_IS_LIBRESSL - ): - raise NotImplementedError( - "finalize_with_tag requires OpenSSL >= 1.0.2. To use this " - "method please update OpenSSL" - ) - self._ctx._mode._set_tag(tag) - return self.finalize() + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + data = self._ctx.finalize_with_tag(tag) + self._tag = self._ctx.tag + self._ctx = None + return data def authenticate_additional_data(self, data): if self._ctx is None: diff --git a/src/cryptography/hazmat/primitives/ciphers/modes.py b/src/cryptography/hazmat/primitives/ciphers/modes.py index 5b28157a..54670b7f 100644 --- a/src/cryptography/hazmat/primitives/ciphers/modes.py +++ b/src/cryptography/hazmat/primitives/ciphers/modes.py @@ -164,9 +164,6 @@ class GCM(object): if not isinstance(initialization_vector, bytes): raise TypeError("initialization_vector must be bytes") self._initialization_vector = initialization_vector - self._set_tag(tag, min_tag_length) - - def _set_tag(self, tag, min_tag_length=16): if tag is not None: if not isinstance(tag, bytes): raise TypeError("tag must be bytes or None") |