aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cryptography/hazmat/primitives/ciphers/algorithms.py8
-rw-r--r--cryptography/hazmat/primitives/ciphers/base.py3
-rw-r--r--cryptography/hazmat/primitives/interfaces.py14
-rw-r--r--docs/hazmat/primitives/interfaces.rst26
-rw-r--r--tests/hazmat/bindings/test_openssl.py12
-rw-r--r--tests/hazmat/primitives/test_block.py12
6 files changed, 67 insertions, 8 deletions
diff --git a/cryptography/hazmat/primitives/ciphers/algorithms.py b/cryptography/hazmat/primitives/ciphers/algorithms.py
index c135f563..1ed487b6 100644
--- a/cryptography/hazmat/primitives/ciphers/algorithms.py
+++ b/cryptography/hazmat/primitives/ciphers/algorithms.py
@@ -13,7 +13,10 @@
from __future__ import absolute_import, division, print_function
+from cryptography.hazmat.primitives import interfaces
+
+@interfaces.register(interfaces.CipherAlgorithm)
class AES(object):
name = "AES"
block_size = 128
@@ -33,6 +36,7 @@ class AES(object):
return len(self.key) * 8
+@interfaces.register(interfaces.CipherAlgorithm)
class Camellia(object):
name = "camellia"
block_size = 128
@@ -52,6 +56,7 @@ class Camellia(object):
return len(self.key) * 8
+@interfaces.register(interfaces.CipherAlgorithm)
class TripleDES(object):
name = "3DES"
block_size = 64
@@ -75,6 +80,7 @@ class TripleDES(object):
return len(self.key) * 8
+@interfaces.register(interfaces.CipherAlgorithm)
class Blowfish(object):
name = "Blowfish"
block_size = 64
@@ -94,6 +100,7 @@ class Blowfish(object):
return len(self.key) * 8
+@interfaces.register(interfaces.CipherAlgorithm)
class CAST5(object):
name = "CAST5"
block_size = 64
@@ -113,6 +120,7 @@ class CAST5(object):
return len(self.key) * 8
+@interfaces.register(interfaces.CipherAlgorithm)
class ARC4(object):
name = "RC4"
block_size = 1
diff --git a/cryptography/hazmat/primitives/ciphers/base.py b/cryptography/hazmat/primitives/ciphers/base.py
index 0fe11996..78bf7e0c 100644
--- a/cryptography/hazmat/primitives/ciphers/base.py
+++ b/cryptography/hazmat/primitives/ciphers/base.py
@@ -24,6 +24,9 @@ class Cipher(object):
_default_backend as backend,
)
+ if not isinstance(algorithm, interfaces.CipherAlgorithm):
+ raise TypeError("Expected interface of interfaces.CipherAlgorithm")
+
self.algorithm = algorithm
self.mode = mode
self._backend = backend
diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py
index 67dbe6fa..bbbb266c 100644
--- a/cryptography/hazmat/primitives/interfaces.py
+++ b/cryptography/hazmat/primitives/interfaces.py
@@ -25,6 +25,20 @@ def register(iface):
return register_decorator
+class CipherAlgorithm(six.with_metaclass(abc.ABCMeta)):
+ @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)
+ """
+
+
class Mode(six.with_metaclass(abc.ABCMeta)):
@abc.abstractproperty
def name(self):
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
index 7068316e..11cff51a 100644
--- a/docs/hazmat/primitives/interfaces.rst
+++ b/docs/hazmat/primitives/interfaces.rst
@@ -12,11 +12,33 @@ to document argument and return types.
.. _`Abstract Base Classes`: http://docs.python.org/3.2/library/abc.html
-Cipher Modes
-~~~~~~~~~~~~
+Symmetric Ciphers
+~~~~~~~~~~~~~~~~~
.. currentmodule:: cryptography.hazmat.primitives.interfaces
+
+.. 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.
+
+
+Cipher Modes
+------------
+
Interfaces used by the symmetric cipher modes described in
:ref:`Symmetric Encryption Modes <symmetric-encryption-modes>`.
diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/bindings/test_openssl.py
index 241c6411..e4f8dd8b 100644
--- a/tests/hazmat/bindings/test_openssl.py
+++ b/tests/hazmat/bindings/test_openssl.py
@@ -15,16 +15,18 @@ import pytest
from cryptography.exceptions import UnsupportedAlgorithm
from cryptography.hazmat.bindings.openssl.backend import backend, Backend
+from cryptography.hazmat.primitives import interfaces
from cryptography.hazmat.primitives.ciphers import Cipher
from cryptography.hazmat.primitives.ciphers.algorithms import AES
from cryptography.hazmat.primitives.ciphers.modes import CBC
-class FakeMode(object):
+class DummyMode(object):
pass
-class FakeCipher(object):
+@interfaces.register(interfaces.CipherAlgorithm)
+class DummyCipher(object):
pass
@@ -58,12 +60,12 @@ class TestOpenSSL(object):
def test_nonexistent_cipher(self):
b = Backend()
b.register_cipher_adapter(
- FakeCipher,
- FakeMode,
+ DummyCipher,
+ DummyMode,
lambda backend, cipher, mode: backend.ffi.NULL
)
cipher = Cipher(
- FakeCipher(), FakeMode(), backend=b,
+ DummyCipher(), DummyMode(), backend=b,
)
with pytest.raises(UnsupportedAlgorithm):
cipher.encryptor()
diff --git a/tests/hazmat/primitives/test_block.py b/tests/hazmat/primitives/test_block.py
index 938cff36..963136b9 100644
--- a/tests/hazmat/primitives/test_block.py
+++ b/tests/hazmat/primitives/test_block.py
@@ -24,6 +24,11 @@ from cryptography.hazmat.primitives.ciphers import (
)
+@interfaces.register(interfaces.CipherAlgorithm)
+class DummyCipher(object):
+ pass
+
+
class TestCipher(object):
def test_instantiate_without_backend(self):
Cipher(
@@ -45,6 +50,11 @@ class TestCipher(object):
)
assert isinstance(cipher.decryptor(), interfaces.CipherContext)
+ def test_instantiate_with_non_algorithm(self):
+ algorithm = object()
+ with pytest.raises(TypeError):
+ Cipher(algorithm, mode=None)
+
class TestCipherContext(object):
def test_use_after_finalize(self, backend):
@@ -90,7 +100,7 @@ class TestCipherContext(object):
def test_nonexistent_cipher(self, backend):
cipher = Cipher(
- object(), object(), backend
+ DummyCipher(), object(), backend
)
with pytest.raises(UnsupportedAlgorithm):
cipher.encryptor()