aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2015-02-12 17:31:24 -0600
committerPaul Kehrer <paul.l.kehrer@gmail.com>2015-02-13 12:27:07 -0600
commit513b7cb41671ccf7d9345075534bfa3d92c1c05e (patch)
treeb6756e82399b1253e881d58390211be6ccd9d4cc
parent0f696fab0e012bca0b69f2c933c679f5ecbe80ad (diff)
downloadcryptography-513b7cb41671ccf7d9345075534bfa3d92c1c05e.tar.gz
cryptography-513b7cb41671ccf7d9345075534bfa3d92c1c05e.tar.bz2
cryptography-513b7cb41671ccf7d9345075534bfa3d92c1c05e.zip
move cipher and mode interfaces
-rw-r--r--docs/hazmat/backends/interfaces.rst24
-rw-r--r--docs/hazmat/primitives/interfaces.rst89
-rw-r--r--docs/hazmat/primitives/mac/cmac.rst8
-rw-r--r--docs/hazmat/primitives/symmetric-encryption.rst98
-rw-r--r--src/cryptography/hazmat/backends/commoncrypto/ciphers.py15
-rw-r--r--src/cryptography/hazmat/backends/openssl/ciphers.py27
-rw-r--r--src/cryptography/hazmat/primitives/ciphers/algorithms.py32
-rw-r--r--src/cryptography/hazmat/primitives/ciphers/base.py85
-rw-r--r--src/cryptography/hazmat/primitives/ciphers/modes.py76
-rw-r--r--src/cryptography/hazmat/primitives/cmac.py5
-rw-r--r--src/cryptography/hazmat/primitives/interfaces/__init__.py144
-rw-r--r--src/cryptography/hazmat/primitives/interfaces/ciphers.py76
-rw-r--r--tests/hazmat/backends/test_commoncrypto.py5
-rw-r--r--tests/hazmat/backends/test_openssl.py10
-rw-r--r--tests/hazmat/primitives/test_block.py11
15 files changed, 394 insertions, 311 deletions
diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst
index 15d8b980..2f4cdd3b 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.base.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.base.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.base.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.base.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.base.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.base.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.base.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.base.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.base.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..14e1842f 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.base.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.base.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.base.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.base.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/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst
index b2ce376b..53023015 100644
--- a/docs/hazmat/primitives/symmetric-encryption.rst
+++ b/docs/hazmat/primitives/symmetric-encryption.rst
@@ -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.base.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.base.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.base.CipherContext`
provider.
If the backend doesn't support the requested combination of ``cipher``
@@ -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.base.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.base
.. class:: CipherContext
@@ -505,6 +506,91 @@ 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.
+
+
.. _`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..54715d85 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 constant_time
+from cryptography.hazmat.primitives.ciphers import base, modes
from cryptography.hazmat.primitives.ciphers.modes import (
CFB, CFB8, CTR, OFB
)
-@utils.register_interface(interfaces.CipherContext)
+@utils.register_interface(base.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, base.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(base.AEADCipherContext)
+@utils.register_interface(base.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..e836175d 100644
--- a/src/cryptography/hazmat/backends/openssl/ciphers.py
+++ b/src/cryptography/hazmat/backends/openssl/ciphers.py
@@ -6,13 +6,12 @@ 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.ciphers import base, modes
-@utils.register_interface(interfaces.CipherContext)
-@utils.register_interface(interfaces.AEADCipherContext)
-@utils.register_interface(interfaces.AEADEncryptionContext)
+@utils.register_interface(base.CipherContext)
+@utils.register_interface(base.AEADCipherContext)
+@utils.register_interface(base.AEADEncryptionContext)
class _CipherContext(object):
_ENCRYPT = 1
_DECRYPT = 0
@@ -24,7 +23,7 @@ class _CipherContext(object):
self._operation = operation
self._tag = None
- if isinstance(self._cipher, interfaces.BlockCipherAlgorithm):
+ if isinstance(self._cipher, base.BlockCipherAlgorithm):
self._block_size = self._cipher.block_size
else:
self._block_size = 1
@@ -54,9 +53,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 +71,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 +106,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 +123,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 +132,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 +153,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 +180,7 @@ class _CipherContext(object):
tag = utils.read_only_property("_tag")
-@utils.register_interface(interfaces.CipherContext)
+@utils.register_interface(base.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/algorithms.py b/src/cryptography/hazmat/primitives/ciphers/algorithms.py
index 677d7027..0e219bec 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.base 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..d746147a 100644
--- a/src/cryptography/hazmat/primitives/cmac.py
+++ b/src/cryptography/hazmat/primitives/cmac.py
@@ -10,6 +10,7 @@ from cryptography.exceptions import (
)
from cryptography.hazmat.backends.interfaces import CMACBackend
from cryptography.hazmat.primitives import interfaces
+from cryptography.hazmat.primitives.ciphers import base
@utils.register_interface(interfaces.MACContext)
@@ -21,9 +22,9 @@ class CMAC(object):
_Reasons.BACKEND_MISSING_INTERFACE
)
- if not isinstance(algorithm, interfaces.BlockCipherAlgorithm):
+ if not isinstance(algorithm, base.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..e9ba7808 100644
--- a/src/cryptography/hazmat/primitives/interfaces/__init__.py
+++ b/src/cryptography/hazmat/primitives/interfaces/__init__.py
@@ -11,19 +11,106 @@ import six
from cryptography import utils
from cryptography.hazmat.primitives import hashes
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 base, modes
+
+
+BlockCipherAlgorithm = utils.deprecated(
+ base.BlockCipherAlgorithm,
+ __name__,
+ (
+ "The BlockCipherAlgorithm interface has moved to the "
+ "cryptography.hazmat.primitives.ciphers.base module"
+ ),
+ utils.DeprecatedIn08
+)
+
+
+CipherAlgorithm = utils.deprecated(
+ base.CipherAlgorithm,
+ __name__,
+ (
+ "The CipherAlgorithm interface has moved to the "
+ "cryptography.hazmat.primitives.ciphers.base module"
+ ),
+ utils.DeprecatedIn08
)
-__all__ = [
- "BlockCipherAlgorithm",
- "CipherAlgorithm",
- "Mode",
- "ModeWithAuthenticationTag",
- "ModeWithInitializationVector",
- "ModeWithNonce"
-]
+
+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(
+ base.CipherContext,
+ __name__,
+ (
+ "The CipherContext interface has moved to the "
+ "cryptography.hazmat.primitives.ciphers.base module"
+ ),
+ utils.DeprecatedIn08
+)
+
+
+AEADCipherContext = utils.deprecated(
+ base.AEADCipherContext,
+ __name__,
+ (
+ "The AEADCipherContext interface has moved to the "
+ "cryptography.hazmat.primitives.ciphers.base module"
+ ),
+ utils.DeprecatedIn08
+)
+
+
+AEADEncryptionContext = utils.deprecated(
+ base.AEADEncryptionContext,
+ __name__,
+ (
+ "The AEADEncryptionContext interface has moved to the "
+ "cryptography.hazmat.primitives.ciphers.base module"
+ ),
+ utils.DeprecatedIn08
+)
EllipticCurve = utils.deprecated(
@@ -154,41 +241,6 @@ 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):
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/tests/hazmat/backends/test_commoncrypto.py b/tests/hazmat/backends/test_commoncrypto.py
index 7ccc1aff..c867804e 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.algorithms import AES
-from cryptography.hazmat.primitives.ciphers.base import Cipher
+from cryptography.hazmat.primitives.ciphers.base import Cipher, CipherAlgorithm
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..878d71bb 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -23,14 +23,16 @@ 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.algorithms import AES
-from cryptography.hazmat.primitives.ciphers.modes import CBC, CTR
-from cryptography.hazmat.primitives.interfaces import BlockCipherAlgorithm
+from cryptography.hazmat.primitives.ciphers.base import (
+ BlockCipherAlgorithm, CipherAlgorithm
+)
+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 +40,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()