diff options
author | Alex Stapleton <alexs@prol.etari.at> | 2015-02-16 15:59:50 +0000 |
---|---|---|
committer | Alex Stapleton <alexs@prol.etari.at> | 2015-02-16 15:59:50 +0000 |
commit | 99c1b803aeb2260d8dbc131aca608276a714285c (patch) | |
tree | 979666c5fb3b4aca15549bb0bff09487956cacc7 | |
parent | ebc1717d73eaccffeddc32cee9eb0ad5936f7a4b (diff) | |
parent | 7c5c9fedd513f4ef66b62fcf5fdcde8dc30fe532 (diff) | |
download | cryptography-99c1b803aeb2260d8dbc131aca608276a714285c.tar.gz cryptography-99c1b803aeb2260d8dbc131aca608276a714285c.tar.bz2 cryptography-99c1b803aeb2260d8dbc131aca608276a714285c.zip |
Merge pull request #1659 from reaperhulk/move-cipher-interfaces
Move cipher and mode interfaces
19 files changed, 466 insertions, 338 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a25ec6db..0f03d0ad 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,22 @@ Changelog :class:`~cryptography.hazmat.primitives.hashes.HashContext` were moved from :mod:`~cryptography.hazmat.primitives.interfaces` to :mod:`~cryptography.hazmat.primitives.hashes`. +* :class:`~cryptography.hazmat.primitives.ciphers.CipherContext`, + :class:`~cryptography.hazmat.primitives.ciphers.AEADCipherContext`, + :class:`~cryptography.hazmat.primitives.ciphers.AEADEncryptionContext`, + :class:`~cryptography.hazmat.primitives.ciphers.CipherAlgorithm`, and + :class:`~cryptography.hazmat.primitives.ciphers.BlockCipherAlgorithm` + were moved from :mod:`~cryptography.hazmat.primitives.interfaces` to + :mod:`~cryptography.hazmat.primitives.ciphers`. +* :class:`~cryptography.hazmat.primitives.ciphers.modes.Mode`, + :class:`~cryptography.hazmat.primitives.ciphers.modes.ModeWithInitializationVector`, + :class:`~cryptography.hazmat.primitives.ciphers.modes.ModeWithNonce`, and + :class:`~cryptography.hazmat.primitives.ciphers.modes.ModeWithAuthenticationTag` + were moved from :mod:`~cryptography.hazmat.primitives.interfaces` to + :mod:`~cryptography.hazmat.primitives.ciphers.modes`. +* :class:`~cryptography.hazmat.primitives.padding.PaddingContext` was moved + from :mod:`~cryptography.hazmat.primitives.interfaces` to + :mod:`~cryptography.hazmat.primitives.padding`. * :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAParameters`, :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAParametersWithNumbers`, :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey`, diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst index 15d8b980..407140bd 100644 --- a/docs/hazmat/backends/interfaces.rst +++ b/docs/hazmat/backends/interfaces.rst @@ -30,10 +30,10 @@ A specific ``backend`` may provide one or more of these interfaces. this backend. :param cipher: An instance of a - :class:`~cryptography.hazmat.primitives.interfaces.CipherAlgorithm` + :class:`~cryptography.hazmat.primitives.ciphers.CipherAlgorithm` provider. :param mode: An instance of a - :class:`~cryptography.hazmat.primitives.interfaces.Mode` provider. + :class:`~cryptography.hazmat.primitives.ciphers.modes.Mode` provider. :returns: ``True`` if the specified ``cipher`` and ``mode`` combination is supported by this backend, otherwise ``False`` @@ -42,18 +42,18 @@ A specific ``backend`` may provide one or more of these interfaces. .. method:: create_symmetric_encryption_ctx(cipher, mode) Create a - :class:`~cryptography.hazmat.primitives.interfaces.CipherContext` that + :class:`~cryptography.hazmat.primitives.ciphers.CipherContext` that can be used for encrypting data with the symmetric ``cipher`` using the given ``mode``. :param cipher: An instance of a - :class:`~cryptography.hazmat.primitives.interfaces.CipherAlgorithm` + :class:`~cryptography.hazmat.primitives.ciphers.CipherAlgorithm` provider. :param mode: An instance of a - :class:`~cryptography.hazmat.primitives.interfaces.Mode` provider. + :class:`~cryptography.hazmat.primitives.ciphers.modes.Mode` provider. :returns: - :class:`~cryptography.hazmat.primitives.interfaces.CipherContext` + :class:`~cryptography.hazmat.primitives.ciphers.CipherContext` :raises ValueError: When tag is not None in an AEAD mode @@ -61,18 +61,18 @@ A specific ``backend`` may provide one or more of these interfaces. .. method:: create_symmetric_decryption_ctx(cipher, mode) Create a - :class:`~cryptography.hazmat.primitives.interfaces.CipherContext` that + :class:`~cryptography.hazmat.primitives.ciphers.CipherContext` that can be used for decrypting data with the symmetric ``cipher`` using the given ``mode``. :param cipher: An instance of a - :class:`~cryptography.hazmat.primitives.interfaces.CipherAlgorithm` + :class:`~cryptography.hazmat.primitives.ciphers.CipherAlgorithm` provider. :param mode: An instance of a - :class:`~cryptography.hazmat.primitives.interfaces.Mode` provider. + :class:`~cryptography.hazmat.primitives.ciphers.modes.Mode` provider. :returns: - :class:`~cryptography.hazmat.primitives.interfaces.CipherContext` + :class:`~cryptography.hazmat.primitives.ciphers.CipherContext` :raises ValueError: When tag is None in an AEAD mode @@ -157,7 +157,7 @@ A specific ``backend`` may provide one or more of these interfaces. .. method:: cmac_algorithm_supported(algorithm) :param algorithm: An instance of a - :class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm` + :class:`~cryptography.hazmat.primitives.ciphers.BlockCipherAlgorithm` provider. :return: Returns True if the block cipher is supported for CMAC by this backend @@ -168,7 +168,7 @@ A specific ``backend`` may provide one or more of these interfaces. uses the specified ``algorithm`` to calculate a message authentication code. :param algorithm: An instance of a - :class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm` + :class:`~cryptography.hazmat.primitives.ciphers.BlockCipherAlgorithm` provider. :returns: diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst index 86a3a7e4..67c6b3d5 100644 --- a/docs/hazmat/primitives/interfaces.rst +++ b/docs/hazmat/primitives/interfaces.rst @@ -14,95 +14,6 @@ to document argument and return types. .. _`Abstract Base Classes`: https://docs.python.org/3/library/abc.html -Symmetric ciphers ------------------ - -.. class:: CipherAlgorithm - - A named symmetric encryption algorithm. - - .. attribute:: name - - :type: str - - The standard name for the mode, for example, "AES", "Camellia", or - "Blowfish". - - .. attribute:: key_size - - :type: int - - The number of bits in the key being used. - - -.. class:: BlockCipherAlgorithm - - A block cipher algorithm. - - .. attribute:: block_size - - :type: int - - The number of bits in a block. - - -Cipher modes -~~~~~~~~~~~~ - -Interfaces used by the symmetric cipher modes described in -:ref:`Symmetric Encryption Modes <symmetric-encryption-modes>`. - -.. class:: Mode - - A named cipher mode. - - .. attribute:: name - - :type: str - - This should be the standard shorthand name for the mode, for example - Cipher-Block Chaining mode is "CBC". - - The name may be used by a backend to influence the operation of a - cipher in conjunction with the algorithm's name. - - .. method:: validate_for_algorithm(algorithm) - - :param CipherAlgorithm algorithm: - - Checks that the combination of this mode with the provided algorithm - meets any necessary invariants. This should raise an exception if they - are not met. - - For example, the - :class:`~cryptography.hazmat.primitives.ciphers.modes.CBC` mode uses - this method to check that the provided initialization vector's length - matches the block size of the algorithm. - - -.. class:: ModeWithInitializationVector - - A cipher mode with an initialization vector. - - .. attribute:: initialization_vector - - :type: bytes - - Exact requirements of the initialization are described by the - documentation of individual modes. - - -.. class:: ModeWithNonce - - A cipher mode with a nonce. - - .. attribute:: nonce - - :type: bytes - - Exact requirements of the nonce are described by the documentation of - individual modes. - Asymmetric interfaces --------------------- diff --git a/docs/hazmat/primitives/mac/cmac.rst b/docs/hazmat/primitives/mac/cmac.rst index 1ba1b3fa..e04a849f 100644 --- a/docs/hazmat/primitives/mac/cmac.rst +++ b/docs/hazmat/primitives/mac/cmac.rst @@ -22,7 +22,7 @@ A subset of CMAC with the AES-128 algorithm is described in :rfc:`4493`. .. versionadded:: 0.4 CMAC objects take a - :class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm` provider. + :class:`~cryptography.hazmat.primitives.ciphers.BlockCipherAlgorithm` provider. .. doctest:: @@ -39,7 +39,7 @@ A subset of CMAC with the AES-128 algorithm is described in :rfc:`4493`. raised. If ``algorithm`` isn't a - :class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm` + :class:`~cryptography.hazmat.primitives.ciphers.BlockCipherAlgorithm` provider then ``TypeError`` will be raised. To check that a given signature is correct use the :meth:`verify` method. @@ -55,13 +55,13 @@ A subset of CMAC with the AES-128 algorithm is described in :rfc:`4493`. cryptography.exceptions.InvalidSignature: Signature did not match digest. :param algorithm: An - :class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm` + :class:`~cryptography.hazmat.primitives.ciphers.BlockCipherAlgorithm` provider. :param backend: An :class:`~cryptography.hazmat.backends.interfaces.CMACBackend` provider. :raises TypeError: This is raised if the provided ``algorithm`` is not an instance of - :class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm` + :class:`~cryptography.hazmat.primitives.ciphers.BlockCipherAlgorithm` :raises cryptography.exceptions.UnsupportedAlgorithm: This is raised if the provided ``backend`` does not implement :class:`~cryptography.hazmat.backends.interfaces.CMACBackend` diff --git a/docs/hazmat/primitives/padding.rst b/docs/hazmat/primitives/padding.rst index 0322f9d2..a60f5ac8 100644 --- a/docs/hazmat/primitives/padding.rst +++ b/docs/hazmat/primitives/padding.rst @@ -3,7 +3,7 @@ Padding ======= -.. currentmodule:: cryptography.hazmat.primitives.padding +.. module:: cryptography.hazmat.primitives.padding Padding is a way to take data that may or may not be a multiple of the block size for a cipher and extend it out so that it is. This is required for many @@ -44,18 +44,16 @@ multiple of the block size. .. method:: padder() :returns: A padding - :class:`~cryptography.hazmat.primitives.interfaces.PaddingContext` + :class:`~cryptography.hazmat.primitives.padding.PaddingContext` provider. .. method:: unpadder() :returns: An unpadding - :class:`~cryptography.hazmat.primitives.interfaces.PaddingContext` + :class:`~cryptography.hazmat.primitives.padding.PaddingContext` provider. -.. currentmodule:: cryptography.hazmat.primitives.interfaces - .. class:: PaddingContext When calling ``padder()`` or ``unpadder()`` the result will conform to the diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index b2ce376b..1cbf60ee 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -4,7 +4,7 @@ Symmetric encryption ==================== -.. currentmodule:: cryptography.hazmat.primitives.ciphers +.. module:: cryptography.hazmat.primitives.ciphers Symmetric encryption is a way to `encrypt`_ or hide the contents of material @@ -43,10 +43,10 @@ in an "encrypt-then-MAC" formulation as `described by Colin Percival`_. 'a secret message' :param algorithms: A - :class:`~cryptography.hazmat.primitives.interfaces.CipherAlgorithm` + :class:`~cryptography.hazmat.primitives.ciphers.CipherAlgorithm` provider such as those described :ref:`below <symmetric-encryption-algorithms>`. - :param mode: A :class:`~cryptography.hazmat.primitives.interfaces.Mode` + :param mode: A :class:`~cryptography.hazmat.primitives.ciphers.modes.Mode` provider such as those described :ref:`below <symmetric-encryption-modes>`. :param backend: A @@ -60,7 +60,7 @@ in an "encrypt-then-MAC" formulation as `described by Colin Percival`_. .. method:: encryptor() :return: An encrypting - :class:`~cryptography.hazmat.primitives.interfaces.CipherContext` + :class:`~cryptography.hazmat.primitives.ciphers.CipherContext` provider. If the backend doesn't support the requested combination of ``cipher`` @@ -70,7 +70,7 @@ in an "encrypt-then-MAC" formulation as `described by Colin Percival`_. .. method:: decryptor() :return: A decrypting - :class:`~cryptography.hazmat.primitives.interfaces.CipherContext` + :class:`~cryptography.hazmat.primitives.ciphers.CipherContext` provider. If the backend doesn't support the requested combination of ``cipher`` @@ -193,7 +193,7 @@ Weak ciphers Modes ~~~~~ -.. currentmodule:: cryptography.hazmat.primitives.ciphers.modes +.. module:: cryptography.hazmat.primitives.ciphers.modes .. class:: CBC(initialization_vector) @@ -293,7 +293,7 @@ Modes .. danger:: When using this mode you **must** not use the decrypted data until - :meth:`~cryptography.hazmat.primitives.interfaces.CipherContext.finalize` + :meth:`~cryptography.hazmat.primitives.ciphers.CipherContext.finalize` has been called. GCM provides **no** guarantees of ciphertext integrity until decryption is complete. @@ -422,7 +422,8 @@ Insecure modes Interfaces ---------- -.. currentmodule:: cryptography.hazmat.primitives.interfaces + +.. currentmodule:: cryptography.hazmat.primitives.ciphers .. class:: CipherContext @@ -505,6 +506,103 @@ Interfaces :raises: :class:`~cryptography.exceptions.NotYetFinalized` if called before the context is finalized. +.. class:: CipherAlgorithm + + A named symmetric encryption algorithm. + + .. attribute:: name + + :type: str + + The standard name for the mode, for example, "AES", "Camellia", or + "Blowfish". + + .. attribute:: key_size + + :type: int + + The number of bits in the key being used. + + +.. class:: BlockCipherAlgorithm + + A block cipher algorithm. + + .. attribute:: block_size + + :type: int + + The number of bits in a block. + +Interfaces used by the symmetric cipher modes described in +:ref:`Symmetric Encryption Modes <symmetric-encryption-modes>`. + +.. currentmodule:: cryptography.hazmat.primitives.ciphers.modes + +.. class:: Mode + + A named cipher mode. + + .. attribute:: name + + :type: str + + This should be the standard shorthand name for the mode, for example + Cipher-Block Chaining mode is "CBC". + + The name may be used by a backend to influence the operation of a + cipher in conjunction with the algorithm's name. + + .. method:: validate_for_algorithm(algorithm) + + :param CipherAlgorithm algorithm: + + Checks that the combination of this mode with the provided algorithm + meets any necessary invariants. This should raise an exception if they + are not met. + + For example, the + :class:`~cryptography.hazmat.primitives.ciphers.modes.CBC` mode uses + this method to check that the provided initialization vector's length + matches the block size of the algorithm. + + +.. class:: ModeWithInitializationVector + + A cipher mode with an initialization vector. + + .. attribute:: initialization_vector + + :type: bytes + + Exact requirements of the initialization are described by the + documentation of individual modes. + + +.. class:: ModeWithNonce + + A cipher mode with a nonce. + + .. attribute:: nonce + + :type: bytes + + Exact requirements of the nonce are described by the documentation of + individual modes. + + +.. class:: ModeWithAuthenticationTag + + A cipher mode with an authentication tag. + + .. attribute:: tag + + :type: bytes + + Exact requirements of the tag are described by the documentation of + individual modes. + + .. _`described by Colin Percival`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html .. _`recommends a 96-bit IV length`: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf diff --git a/src/cryptography/hazmat/backends/commoncrypto/ciphers.py b/src/cryptography/hazmat/backends/commoncrypto/ciphers.py index 7e537db9..1ce8aec5 100644 --- a/src/cryptography/hazmat/backends/commoncrypto/ciphers.py +++ b/src/cryptography/hazmat/backends/commoncrypto/ciphers.py @@ -8,13 +8,14 @@ from cryptography import utils from cryptography.exceptions import ( InvalidTag, UnsupportedAlgorithm, _Reasons ) -from cryptography.hazmat.primitives import constant_time, interfaces +from cryptography.hazmat.primitives import ciphers, constant_time +from cryptography.hazmat.primitives.ciphers import modes from cryptography.hazmat.primitives.ciphers.modes import ( CFB, CFB8, CTR, OFB ) -@utils.register_interface(interfaces.CipherContext) +@utils.register_interface(ciphers.CipherContext) class _CipherContext(object): def __init__(self, backend, cipher, mode, operation): self._backend = backend @@ -31,7 +32,7 @@ class _CipherContext(object): # treat RC4 and other stream cipher block sizes). # This bug has been filed as rdar://15589470 self._bytes_processed = 0 - if (isinstance(cipher, interfaces.BlockCipherAlgorithm) and not + if (isinstance(cipher, ciphers.BlockCipherAlgorithm) and not isinstance(mode, (OFB, CFB, CFB8, CTR))): self._byte_block_size = cipher.block_size // 8 else: @@ -51,9 +52,9 @@ class _CipherContext(object): ctx = self._backend._ffi.new("CCCryptorRef *") ctx = self._backend._ffi.gc(ctx, self._backend._release_cipher_ctx) - if isinstance(mode, interfaces.ModeWithInitializationVector): + if isinstance(mode, modes.ModeWithInitializationVector): iv_nonce = mode.initialization_vector - elif isinstance(mode, interfaces.ModeWithNonce): + elif isinstance(mode, modes.ModeWithNonce): iv_nonce = mode.nonce else: iv_nonce = self._backend._ffi.NULL @@ -101,8 +102,8 @@ class _CipherContext(object): return self._backend._ffi.buffer(buf)[:outlen[0]] -@utils.register_interface(interfaces.AEADCipherContext) -@utils.register_interface(interfaces.AEADEncryptionContext) +@utils.register_interface(ciphers.AEADCipherContext) +@utils.register_interface(ciphers.AEADEncryptionContext) class _GCMCipherContext(object): def __init__(self, backend, cipher, mode, operation): self._backend = backend diff --git a/src/cryptography/hazmat/backends/openssl/ciphers.py b/src/cryptography/hazmat/backends/openssl/ciphers.py index d665f36d..64097c7b 100644 --- a/src/cryptography/hazmat/backends/openssl/ciphers.py +++ b/src/cryptography/hazmat/backends/openssl/ciphers.py @@ -6,13 +6,13 @@ from __future__ import absolute_import, division, print_function from cryptography import utils from cryptography.exceptions import InvalidTag, UnsupportedAlgorithm, _Reasons -from cryptography.hazmat.primitives import interfaces -from cryptography.hazmat.primitives.ciphers.modes import GCM +from cryptography.hazmat.primitives import ciphers +from cryptography.hazmat.primitives.ciphers import modes -@utils.register_interface(interfaces.CipherContext) -@utils.register_interface(interfaces.AEADCipherContext) -@utils.register_interface(interfaces.AEADEncryptionContext) +@utils.register_interface(ciphers.CipherContext) +@utils.register_interface(ciphers.AEADCipherContext) +@utils.register_interface(ciphers.AEADEncryptionContext) class _CipherContext(object): _ENCRYPT = 1 _DECRYPT = 0 @@ -24,7 +24,7 @@ class _CipherContext(object): self._operation = operation self._tag = None - if isinstance(self._cipher, interfaces.BlockCipherAlgorithm): + if isinstance(self._cipher, ciphers.BlockCipherAlgorithm): self._block_size = self._cipher.block_size else: self._block_size = 1 @@ -54,9 +54,9 @@ class _CipherContext(object): _Reasons.UNSUPPORTED_CIPHER ) - if isinstance(mode, interfaces.ModeWithInitializationVector): + if isinstance(mode, modes.ModeWithInitializationVector): iv_nonce = mode.initialization_vector - elif isinstance(mode, interfaces.ModeWithNonce): + elif isinstance(mode, modes.ModeWithNonce): iv_nonce = mode.nonce else: iv_nonce = self._backend._ffi.NULL @@ -72,7 +72,7 @@ class _CipherContext(object): ctx, len(cipher.key) ) assert res != 0 - if isinstance(mode, GCM): + if isinstance(mode, modes.GCM): res = self._backend._lib.EVP_CIPHER_CTX_ctrl( ctx, self._backend._lib.EVP_CTRL_GCM_SET_IVLEN, len(iv_nonce), self._backend._ffi.NULL @@ -107,7 +107,7 @@ class _CipherContext(object): # should be taken only when length is zero and mode is not GCM because # AES GCM can return improper tag values if you don't call update # with empty plaintext when authenticating AAD for ...reasons. - if len(data) == 0 and not isinstance(self._mode, GCM): + if len(data) == 0 and not isinstance(self._mode, modes.GCM): return b"" buf = self._backend._ffi.new("unsigned char[]", @@ -124,7 +124,7 @@ class _CipherContext(object): # even if you are only using authenticate_additional_data or the # GCM tag will be wrong. An (empty) call to update resolves this # and is harmless for all other versions of OpenSSL. - if isinstance(self._mode, GCM): + if isinstance(self._mode, modes.GCM): self.update(b"") buf = self._backend._ffi.new("unsigned char[]", self._block_size) @@ -133,7 +133,7 @@ class _CipherContext(object): if res == 0: errors = self._backend._consume_errors() - if not errors and isinstance(self._mode, GCM): + if not errors and isinstance(self._mode, modes.GCM): raise InvalidTag assert errors @@ -154,7 +154,7 @@ class _CipherContext(object): else: raise self._backend._unknown_error(errors[0]) - if (isinstance(self._mode, GCM) and + if (isinstance(self._mode, modes.GCM) and self._operation == self._ENCRYPT): block_byte_size = self._block_size // 8 tag_buf = self._backend._ffi.new( @@ -181,7 +181,7 @@ class _CipherContext(object): tag = utils.read_only_property("_tag") -@utils.register_interface(interfaces.CipherContext) +@utils.register_interface(ciphers.CipherContext) class _AESCTRCipherContext(object): """ This is needed to provide support for AES CTR mode in OpenSSL 0.9.8. It can diff --git a/src/cryptography/hazmat/primitives/ciphers/__init__.py b/src/cryptography/hazmat/primitives/ciphers/__init__.py index d779531d..b5dd0ed7 100644 --- a/src/cryptography/hazmat/primitives/ciphers/__init__.py +++ b/src/cryptography/hazmat/primitives/ciphers/__init__.py @@ -4,9 +4,17 @@ from __future__ import absolute_import, division, print_function -from cryptography.hazmat.primitives.ciphers.base import Cipher +from cryptography.hazmat.primitives.ciphers.base import ( + AEADCipherContext, AEADEncryptionContext, BlockCipherAlgorithm, Cipher, + CipherAlgorithm, CipherContext +) __all__ = [ "Cipher", + "CipherAlgorithm", + "BlockCipherAlgorithm", + "CipherContext", + "AEADCipherContext", + "AEADEncryptionContext", ] diff --git a/src/cryptography/hazmat/primitives/ciphers/algorithms.py b/src/cryptography/hazmat/primitives/ciphers/algorithms.py index 677d7027..b71dddbb 100644 --- a/src/cryptography/hazmat/primitives/ciphers/algorithms.py +++ b/src/cryptography/hazmat/primitives/ciphers/algorithms.py @@ -5,7 +5,9 @@ from __future__ import absolute_import, division, print_function from cryptography import utils -from cryptography.hazmat.primitives import interfaces +from cryptography.hazmat.primitives.ciphers import ( + BlockCipherAlgorithm, CipherAlgorithm +) def _verify_key_size(algorithm, key): @@ -17,8 +19,8 @@ def _verify_key_size(algorithm, key): return key -@utils.register_interface(interfaces.BlockCipherAlgorithm) -@utils.register_interface(interfaces.CipherAlgorithm) +@utils.register_interface(BlockCipherAlgorithm) +@utils.register_interface(CipherAlgorithm) class AES(object): name = "AES" block_size = 128 @@ -32,8 +34,8 @@ class AES(object): return len(self.key) * 8 -@utils.register_interface(interfaces.BlockCipherAlgorithm) -@utils.register_interface(interfaces.CipherAlgorithm) +@utils.register_interface(BlockCipherAlgorithm) +@utils.register_interface(CipherAlgorithm) class Camellia(object): name = "camellia" block_size = 128 @@ -47,8 +49,8 @@ class Camellia(object): return len(self.key) * 8 -@utils.register_interface(interfaces.BlockCipherAlgorithm) -@utils.register_interface(interfaces.CipherAlgorithm) +@utils.register_interface(BlockCipherAlgorithm) +@utils.register_interface(CipherAlgorithm) class TripleDES(object): name = "3DES" block_size = 64 @@ -66,8 +68,8 @@ class TripleDES(object): return len(self.key) * 8 -@utils.register_interface(interfaces.BlockCipherAlgorithm) -@utils.register_interface(interfaces.CipherAlgorithm) +@utils.register_interface(BlockCipherAlgorithm) +@utils.register_interface(CipherAlgorithm) class Blowfish(object): name = "Blowfish" block_size = 64 @@ -81,8 +83,8 @@ class Blowfish(object): return len(self.key) * 8 -@utils.register_interface(interfaces.BlockCipherAlgorithm) -@utils.register_interface(interfaces.CipherAlgorithm) +@utils.register_interface(BlockCipherAlgorithm) +@utils.register_interface(CipherAlgorithm) class CAST5(object): name = "CAST5" block_size = 64 @@ -96,7 +98,7 @@ class CAST5(object): return len(self.key) * 8 -@utils.register_interface(interfaces.CipherAlgorithm) +@utils.register_interface(CipherAlgorithm) class ARC4(object): name = "RC4" key_sizes = frozenset([40, 56, 64, 80, 128, 192, 256]) @@ -109,7 +111,7 @@ class ARC4(object): return len(self.key) * 8 -@utils.register_interface(interfaces.CipherAlgorithm) +@utils.register_interface(CipherAlgorithm) class IDEA(object): name = "IDEA" block_size = 64 @@ -123,8 +125,8 @@ class IDEA(object): return len(self.key) * 8 -@utils.register_interface(interfaces.BlockCipherAlgorithm) -@utils.register_interface(interfaces.CipherAlgorithm) +@utils.register_interface(BlockCipherAlgorithm) +@utils.register_interface(CipherAlgorithm) class SEED(object): name = "SEED" block_size = 128 diff --git a/src/cryptography/hazmat/primitives/ciphers/base.py b/src/cryptography/hazmat/primitives/ciphers/base.py index 81b8d778..8f3028fc 100644 --- a/src/cryptography/hazmat/primitives/ciphers/base.py +++ b/src/cryptography/hazmat/primitives/ciphers/base.py @@ -4,13 +4,76 @@ from __future__ import absolute_import, division, print_function +import abc + +import six + from cryptography import utils from cryptography.exceptions import ( AlreadyFinalized, AlreadyUpdated, NotYetFinalized, UnsupportedAlgorithm, _Reasons ) from cryptography.hazmat.backends.interfaces import CipherBackend -from cryptography.hazmat.primitives import interfaces +from cryptography.hazmat.primitives.ciphers import modes + + +@six.add_metaclass(abc.ABCMeta) +class CipherAlgorithm(object): + @abc.abstractproperty + def name(self): + """ + A string naming this mode (e.g. "AES", "Camellia"). + """ + + @abc.abstractproperty + def key_size(self): + """ + The size of the key being used as an integer in bits (e.g. 128, 256). + """ + + +@six.add_metaclass(abc.ABCMeta) +class BlockCipherAlgorithm(object): + @abc.abstractproperty + def block_size(self): + """ + The size of a block as an integer in bits (e.g. 64, 128). + """ + + +@six.add_metaclass(abc.ABCMeta) +class CipherContext(object): + @abc.abstractmethod + def update(self, data): + """ + Processes the provided bytes through the cipher and returns the results + as bytes. + """ + + @abc.abstractmethod + def finalize(self): + """ + Returns the results of processing the final block as bytes. + """ + + +@six.add_metaclass(abc.ABCMeta) +class AEADCipherContext(object): + @abc.abstractmethod + def authenticate_additional_data(self, data): + """ + Authenticates the provided bytes. + """ + + +@six.add_metaclass(abc.ABCMeta) +class AEADEncryptionContext(object): + @abc.abstractproperty + def tag(self): + """ + Returns tag bytes. This is only available after encryption is + finalized. + """ class Cipher(object): @@ -21,10 +84,8 @@ class Cipher(object): _Reasons.BACKEND_MISSING_INTERFACE ) - if not isinstance(algorithm, interfaces.CipherAlgorithm): - raise TypeError( - "Expected interface of interfaces.CipherAlgorithm." - ) + if not isinstance(algorithm, CipherAlgorithm): + raise TypeError("Expected interface of CipherAlgorithm.") if mode is not None: mode.validate_for_algorithm(algorithm) @@ -34,7 +95,7 @@ class Cipher(object): self._backend = backend def encryptor(self): - if isinstance(self.mode, interfaces.ModeWithAuthenticationTag): + if isinstance(self.mode, modes.ModeWithAuthenticationTag): if self.mode.tag is not None: raise ValueError( "Authentication tag must be None when encrypting." @@ -45,7 +106,7 @@ class Cipher(object): return self._wrap_ctx(ctx, encrypt=True) def decryptor(self): - if isinstance(self.mode, interfaces.ModeWithAuthenticationTag): + if isinstance(self.mode, modes.ModeWithAuthenticationTag): if self.mode.tag is None: raise ValueError( "Authentication tag must be provided when decrypting." @@ -56,7 +117,7 @@ class Cipher(object): return self._wrap_ctx(ctx, encrypt=False) def _wrap_ctx(self, ctx, encrypt): - if isinstance(self.mode, interfaces.ModeWithAuthenticationTag): + if isinstance(self.mode, modes.ModeWithAuthenticationTag): if encrypt: return _AEADEncryptionContext(ctx) else: @@ -65,7 +126,7 @@ class Cipher(object): return _CipherContext(ctx) -@utils.register_interface(interfaces.CipherContext) +@utils.register_interface(CipherContext) class _CipherContext(object): def __init__(self, ctx): self._ctx = ctx @@ -83,8 +144,8 @@ class _CipherContext(object): return data -@utils.register_interface(interfaces.AEADCipherContext) -@utils.register_interface(interfaces.CipherContext) +@utils.register_interface(AEADCipherContext) +@utils.register_interface(CipherContext) class _AEADCipherContext(object): def __init__(self, ctx): self._ctx = ctx @@ -113,7 +174,7 @@ class _AEADCipherContext(object): self._ctx.authenticate_additional_data(data) -@utils.register_interface(interfaces.AEADEncryptionContext) +@utils.register_interface(AEADEncryptionContext) class _AEADEncryptionContext(_AEADCipherContext): @property def tag(self): diff --git a/src/cryptography/hazmat/primitives/ciphers/modes.py b/src/cryptography/hazmat/primitives/ciphers/modes.py index fc269de9..e31c9060 100644 --- a/src/cryptography/hazmat/primitives/ciphers/modes.py +++ b/src/cryptography/hazmat/primitives/ciphers/modes.py @@ -4,8 +4,54 @@ from __future__ import absolute_import, division, print_function +import abc + +import six + from cryptography import utils -from cryptography.hazmat.primitives import interfaces + + +@six.add_metaclass(abc.ABCMeta) +class Mode(object): + @abc.abstractproperty + def name(self): + """ + A string naming this mode (e.g. "ECB", "CBC"). + """ + + @abc.abstractmethod + def validate_for_algorithm(self, algorithm): + """ + Checks that all the necessary invariants of this (mode, algorithm) + combination are met. + """ + + +@six.add_metaclass(abc.ABCMeta) +class ModeWithInitializationVector(object): + @abc.abstractproperty + def initialization_vector(self): + """ + The value of the initialization vector for this mode as bytes. + """ + + +@six.add_metaclass(abc.ABCMeta) +class ModeWithNonce(object): + @abc.abstractproperty + def nonce(self): + """ + The value of the nonce for this mode as bytes. + """ + + +@six.add_metaclass(abc.ABCMeta) +class ModeWithAuthenticationTag(object): + @abc.abstractproperty + def tag(self): + """ + The value of the tag supplied to the constructor of this mode. + """ def _check_iv_length(self, algorithm): @@ -15,8 +61,8 @@ def _check_iv_length(self, algorithm): )) -@utils.register_interface(interfaces.Mode) -@utils.register_interface(interfaces.ModeWithInitializationVector) +@utils.register_interface(Mode) +@utils.register_interface(ModeWithInitializationVector) class CBC(object): name = "CBC" @@ -27,7 +73,7 @@ class CBC(object): validate_for_algorithm = _check_iv_length -@utils.register_interface(interfaces.Mode) +@utils.register_interface(Mode) class ECB(object): name = "ECB" @@ -35,8 +81,8 @@ class ECB(object): pass -@utils.register_interface(interfaces.Mode) -@utils.register_interface(interfaces.ModeWithInitializationVector) +@utils.register_interface(Mode) +@utils.register_interface(ModeWithInitializationVector) class OFB(object): name = "OFB" @@ -47,8 +93,8 @@ class OFB(object): validate_for_algorithm = _check_iv_length -@utils.register_interface(interfaces.Mode) -@utils.register_interface(interfaces.ModeWithInitializationVector) +@utils.register_interface(Mode) +@utils.register_interface(ModeWithInitializationVector) class CFB(object): name = "CFB" @@ -59,8 +105,8 @@ class CFB(object): validate_for_algorithm = _check_iv_length -@utils.register_interface(interfaces.Mode) -@utils.register_interface(interfaces.ModeWithInitializationVector) +@utils.register_interface(Mode) +@utils.register_interface(ModeWithInitializationVector) class CFB8(object): name = "CFB8" @@ -71,8 +117,8 @@ class CFB8(object): validate_for_algorithm = _check_iv_length -@utils.register_interface(interfaces.Mode) -@utils.register_interface(interfaces.ModeWithNonce) +@utils.register_interface(Mode) +@utils.register_interface(ModeWithNonce) class CTR(object): name = "CTR" @@ -88,9 +134,9 @@ class CTR(object): )) -@utils.register_interface(interfaces.Mode) -@utils.register_interface(interfaces.ModeWithInitializationVector) -@utils.register_interface(interfaces.ModeWithAuthenticationTag) +@utils.register_interface(Mode) +@utils.register_interface(ModeWithInitializationVector) +@utils.register_interface(ModeWithAuthenticationTag) class GCM(object): name = "GCM" diff --git a/src/cryptography/hazmat/primitives/cmac.py b/src/cryptography/hazmat/primitives/cmac.py index ccbe07ee..c2038a30 100644 --- a/src/cryptography/hazmat/primitives/cmac.py +++ b/src/cryptography/hazmat/primitives/cmac.py @@ -9,7 +9,7 @@ from cryptography.exceptions import ( AlreadyFinalized, UnsupportedAlgorithm, _Reasons ) from cryptography.hazmat.backends.interfaces import CMACBackend -from cryptography.hazmat.primitives import interfaces +from cryptography.hazmat.primitives import ciphers, interfaces @utils.register_interface(interfaces.MACContext) @@ -21,9 +21,9 @@ class CMAC(object): _Reasons.BACKEND_MISSING_INTERFACE ) - if not isinstance(algorithm, interfaces.BlockCipherAlgorithm): + if not isinstance(algorithm, ciphers.BlockCipherAlgorithm): raise TypeError( - "Expected instance of interfaces.BlockCipherAlgorithm." + "Expected instance of BlockCipherAlgorithm." ) self._algorithm = algorithm diff --git a/src/cryptography/hazmat/primitives/interfaces/__init__.py b/src/cryptography/hazmat/primitives/interfaces/__init__.py index 17bac1e6..5de7fb8c 100644 --- a/src/cryptography/hazmat/primitives/interfaces/__init__.py +++ b/src/cryptography/hazmat/primitives/interfaces/__init__.py @@ -9,21 +9,108 @@ import abc import six from cryptography import utils -from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives import ciphers, hashes, padding from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa -from cryptography.hazmat.primitives.interfaces.ciphers import ( - BlockCipherAlgorithm, CipherAlgorithm, Mode, - ModeWithAuthenticationTag, ModeWithInitializationVector, ModeWithNonce +from cryptography.hazmat.primitives.ciphers import modes + + +BlockCipherAlgorithm = utils.deprecated( + ciphers.BlockCipherAlgorithm, + __name__, + ( + "The BlockCipherAlgorithm interface has moved to the " + "cryptography.hazmat.primitives.ciphers module" + ), + utils.DeprecatedIn08 +) + + +CipherAlgorithm = utils.deprecated( + ciphers.CipherAlgorithm, + __name__, + ( + "The CipherAlgorithm interface has moved to the " + "cryptography.hazmat.primitives.ciphers module" + ), + utils.DeprecatedIn08 +) + + +Mode = utils.deprecated( + modes.Mode, + __name__, + ( + "The Mode interface has moved to the " + "cryptography.hazmat.primitives.ciphers.modes module" + ), + utils.DeprecatedIn08 +) + + +ModeWithAuthenticationTag = utils.deprecated( + modes.ModeWithAuthenticationTag, + __name__, + ( + "The ModeWithAuthenticationTag interface has moved to the " + "cryptography.hazmat.primitives.ciphers.modes module" + ), + utils.DeprecatedIn08 +) + + +ModeWithInitializationVector = utils.deprecated( + modes.ModeWithInitializationVector, + __name__, + ( + "The ModeWithInitializationVector interface has moved to the " + "cryptography.hazmat.primitives.ciphers.modes module" + ), + utils.DeprecatedIn08 +) + + +ModeWithNonce = utils.deprecated( + modes.ModeWithNonce, + __name__, + ( + "The ModeWithNonce interface has moved to the " + "cryptography.hazmat.primitives.ciphers.modes module" + ), + utils.DeprecatedIn08 +) + + +CipherContext = utils.deprecated( + ciphers.CipherContext, + __name__, + ( + "The CipherContext interface has moved to the " + "cryptography.hazmat.primitives.ciphers module" + ), + utils.DeprecatedIn08 +) + + +AEADCipherContext = utils.deprecated( + ciphers.AEADCipherContext, + __name__, + ( + "The AEADCipherContext interface has moved to the " + "cryptography.hazmat.primitives.ciphers module" + ), + utils.DeprecatedIn08 ) -__all__ = [ - "BlockCipherAlgorithm", - "CipherAlgorithm", - "Mode", - "ModeWithAuthenticationTag", - "ModeWithInitializationVector", - "ModeWithNonce" -] + +AEADEncryptionContext = utils.deprecated( + ciphers.AEADEncryptionContext, + __name__, + ( + "The AEADEncryptionContext interface has moved to the " + "cryptography.hazmat.primitives.ciphers module" + ), + utils.DeprecatedIn08 +) EllipticCurve = utils.deprecated( @@ -153,54 +240,15 @@ DSAPublicKeyWithNumbers = utils.deprecated( ) -@six.add_metaclass(abc.ABCMeta) -class CipherContext(object): - @abc.abstractmethod - def update(self, data): - """ - Processes the provided bytes through the cipher and returns the results - as bytes. - """ - - @abc.abstractmethod - def finalize(self): - """ - Returns the results of processing the final block as bytes. - """ - - -@six.add_metaclass(abc.ABCMeta) -class AEADCipherContext(object): - @abc.abstractmethod - def authenticate_additional_data(self, data): - """ - Authenticates the provided bytes. - """ - - -@six.add_metaclass(abc.ABCMeta) -class AEADEncryptionContext(object): - @abc.abstractproperty - def tag(self): - """ - Returns tag bytes. This is only available after encryption is - finalized. - """ - - -@six.add_metaclass(abc.ABCMeta) -class PaddingContext(object): - @abc.abstractmethod - def update(self, data): - """ - Pads the provided bytes and returns any available data as bytes. - """ - - @abc.abstractmethod - def finalize(self): - """ - Finalize the padding, returns bytes. - """ +PaddingContext = utils.deprecated( + padding.PaddingContext, + __name__, + ( + "The PaddingContext interface has moved to the " + "cryptography.hazmat.primitives.padding module" + ), + utils.DeprecatedIn08 +) HashContext = utils.deprecated( diff --git a/src/cryptography/hazmat/primitives/interfaces/ciphers.py b/src/cryptography/hazmat/primitives/interfaces/ciphers.py deleted file mode 100644 index 075a9c25..00000000 --- a/src/cryptography/hazmat/primitives/interfaces/ciphers.py +++ /dev/null @@ -1,76 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import absolute_import, division, print_function - -import abc - -import six - - -@six.add_metaclass(abc.ABCMeta) -class CipherAlgorithm(object): - @abc.abstractproperty - def name(self): - """ - A string naming this mode (e.g. "AES", "Camellia"). - """ - - @abc.abstractproperty - def key_size(self): - """ - The size of the key being used as an integer in bits (e.g. 128, 256). - """ - - -@six.add_metaclass(abc.ABCMeta) -class BlockCipherAlgorithm(object): - @abc.abstractproperty - def block_size(self): - """ - The size of a block as an integer in bits (e.g. 64, 128). - """ - - -@six.add_metaclass(abc.ABCMeta) -class Mode(object): - @abc.abstractproperty - def name(self): - """ - A string naming this mode (e.g. "ECB", "CBC"). - """ - - @abc.abstractmethod - def validate_for_algorithm(self, algorithm): - """ - Checks that all the necessary invariants of this (mode, algorithm) - combination are met. - """ - - -@six.add_metaclass(abc.ABCMeta) -class ModeWithInitializationVector(object): - @abc.abstractproperty - def initialization_vector(self): - """ - The value of the initialization vector for this mode as bytes. - """ - - -@six.add_metaclass(abc.ABCMeta) -class ModeWithNonce(object): - @abc.abstractproperty - def nonce(self): - """ - The value of the nonce for this mode as bytes. - """ - - -@six.add_metaclass(abc.ABCMeta) -class ModeWithAuthenticationTag(object): - @abc.abstractproperty - def tag(self): - """ - The value of the tag supplied to the constructor of this mode. - """ diff --git a/src/cryptography/hazmat/primitives/padding.py b/src/cryptography/hazmat/primitives/padding.py index 49cae9d6..8ad64dec 100644 --- a/src/cryptography/hazmat/primitives/padding.py +++ b/src/cryptography/hazmat/primitives/padding.py @@ -4,12 +4,13 @@ from __future__ import absolute_import, division, print_function +import abc + import six from cryptography import utils from cryptography.exceptions import AlreadyFinalized from cryptography.hazmat.bindings.utils import LazyLibrary, build_ffi -from cryptography.hazmat.primitives import interfaces TYPES = """ @@ -59,6 +60,21 @@ _ffi = build_ffi(cdef_source=TYPES, verify_source=FUNCTIONS) _lib = LazyLibrary(_ffi) +@six.add_metaclass(abc.ABCMeta) +class PaddingContext(object): + @abc.abstractmethod + def update(self, data): + """ + Pads the provided bytes and returns any available data as bytes. + """ + + @abc.abstractmethod + def finalize(self): + """ + Finalize the padding, returns bytes. + """ + + class PKCS7(object): def __init__(self, block_size): if not (0 <= block_size < 256): @@ -76,7 +92,7 @@ class PKCS7(object): return _PKCS7UnpaddingContext(self.block_size) -@utils.register_interface(interfaces.PaddingContext) +@utils.register_interface(PaddingContext) class _PKCS7PaddingContext(object): def __init__(self, block_size): self.block_size = block_size @@ -109,7 +125,7 @@ class _PKCS7PaddingContext(object): return result -@utils.register_interface(interfaces.PaddingContext) +@utils.register_interface(PaddingContext) class _PKCS7UnpaddingContext(object): def __init__(self, block_size): self.block_size = block_size diff --git a/tests/hazmat/backends/test_commoncrypto.py b/tests/hazmat/backends/test_commoncrypto.py index 7ccc1aff..f7200016 100644 --- a/tests/hazmat/backends/test_commoncrypto.py +++ b/tests/hazmat/backends/test_commoncrypto.py @@ -9,15 +9,14 @@ import pytest from cryptography import utils from cryptography.exceptions import InternalError, _Reasons from cryptography.hazmat.backends import _available_backends -from cryptography.hazmat.primitives import interfaces +from cryptography.hazmat.primitives.ciphers import Cipher, CipherAlgorithm from cryptography.hazmat.primitives.ciphers.algorithms import AES -from cryptography.hazmat.primitives.ciphers.base import Cipher from cryptography.hazmat.primitives.ciphers.modes import CBC, GCM from ...utils import raises_unsupported_algorithm -@utils.register_interface(interfaces.CipherAlgorithm) +@utils.register_interface(CipherAlgorithm) class DummyCipher(object): name = "dummy-cipher" block_size = None diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 97d58085..6e3d80e9 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -21,16 +21,17 @@ from cryptography.hazmat.backends.openssl.backend import ( from cryptography.hazmat.backends.openssl.ec import _sn_to_elliptic_curve from cryptography.hazmat.primitives import hashes, interfaces from cryptography.hazmat.primitives.asymmetric import dsa, padding -from cryptography.hazmat.primitives.ciphers import Cipher +from cryptography.hazmat.primitives.ciphers import ( + BlockCipherAlgorithm, Cipher, CipherAlgorithm +) from cryptography.hazmat.primitives.ciphers.algorithms import AES -from cryptography.hazmat.primitives.ciphers.modes import CBC, CTR -from cryptography.hazmat.primitives.interfaces import BlockCipherAlgorithm +from cryptography.hazmat.primitives.ciphers.modes import CBC, CTR, Mode from ..primitives.fixtures_rsa import RSA_KEY_512 from ...utils import load_vectors_from_file, raises_unsupported_algorithm -@utils.register_interface(interfaces.Mode) +@utils.register_interface(Mode) class DummyMode(object): name = "dummy-mode" @@ -38,7 +39,7 @@ class DummyMode(object): pass -@utils.register_interface(interfaces.CipherAlgorithm) +@utils.register_interface(CipherAlgorithm) class DummyCipher(object): name = "dummy-cipher" key_size = None diff --git a/tests/hazmat/primitives/test_block.py b/tests/hazmat/primitives/test_block.py index 22e6d0e9..1b3fc1cb 100644 --- a/tests/hazmat/primitives/test_block.py +++ b/tests/hazmat/primitives/test_block.py @@ -13,9 +13,8 @@ from cryptography.exceptions import ( AlreadyFinalized, _Reasons ) from cryptography.hazmat.backends.interfaces import CipherBackend -from cryptography.hazmat.primitives import interfaces from cryptography.hazmat.primitives.ciphers import ( - Cipher, algorithms, modes + Cipher, algorithms, base, modes ) from .utils import ( @@ -24,7 +23,7 @@ from .utils import ( from ...utils import raises_unsupported_algorithm -@utils.register_interface(interfaces.Mode) +@utils.register_interface(modes.Mode) class DummyMode(object): name = "dummy-mode" @@ -32,7 +31,7 @@ class DummyMode(object): pass -@utils.register_interface(interfaces.CipherAlgorithm) +@utils.register_interface(base.CipherAlgorithm) class DummyCipher(object): name = "dummy-cipher" key_size = None @@ -46,7 +45,7 @@ class TestCipher(object): modes.CBC(binascii.unhexlify(b"0" * 32)), backend ) - assert isinstance(cipher.encryptor(), interfaces.CipherContext) + assert isinstance(cipher.encryptor(), base.CipherContext) def test_creates_decryptor(self, backend): cipher = Cipher( @@ -54,7 +53,7 @@ class TestCipher(object): modes.CBC(binascii.unhexlify(b"0" * 32)), backend ) - assert isinstance(cipher.decryptor(), interfaces.CipherContext) + assert isinstance(cipher.decryptor(), base.CipherContext) def test_instantiate_with_non_algorithm(self, backend): algorithm = object() |