aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2014-04-22 11:35:12 -0500
committerPaul Kehrer <paul.l.kehrer@gmail.com>2014-04-22 11:35:12 -0500
commit14df7ca79e9c86349ca5035c0f3b3fda65b6b256 (patch)
tree80e8da7e2bd28c892745fca091a7189452f3d17f
parent8a312c2ccc99351f1a05dc607a574669944ea4cd (diff)
parent9bea9373efcddd390aa2d2f63d8690d6d3ceca14 (diff)
downloadcryptography-14df7ca79e9c86349ca5035c0f3b3fda65b6b256.tar.gz
cryptography-14df7ca79e9c86349ca5035c0f3b3fda65b6b256.tar.bz2
cryptography-14df7ca79e9c86349ca5035c0f3b3fda65b6b256.zip
Merge pull request #950 from Ayrx/cmac-multibackend
CMAC multibackend
-rw-r--r--CHANGELOG.rst2
-rw-r--r--cryptography/hazmat/backends/multibackend.py20
-rw-r--r--docs/hazmat/primitives/mac/cmac.rst4
-rw-r--r--tests/hazmat/backends/test_multibackend.py34
4 files changed, 54 insertions, 6 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 9e89e563..106e0ab2 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -11,6 +11,8 @@ Changelog
to :class:`~cryptography.hazmat.primitives.asymmetric.padding.PSS`. It will be
removed from ``MGF1`` in two releases per our :doc:`/api-stability` policy.
+* Added :class:`~cryptography.hazmat.primitives.cmac.CMAC`.
+
0.3 - 2014-03-27
~~~~~~~~~~~~~~~~
diff --git a/cryptography/hazmat/backends/multibackend.py b/cryptography/hazmat/backends/multibackend.py
index 86cded85..981a60bd 100644
--- a/cryptography/hazmat/backends/multibackend.py
+++ b/cryptography/hazmat/backends/multibackend.py
@@ -16,11 +16,12 @@ from __future__ import absolute_import, division, print_function
from cryptography import utils
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
from cryptography.hazmat.backends.interfaces import (
- CipherBackend, DSABackend, HMACBackend, HashBackend, PBKDF2HMACBackend,
- RSABackend
+ CMACBackend, CipherBackend, DSABackend, HMACBackend, HashBackend,
+ PBKDF2HMACBackend, RSABackend
)
+@utils.register_interface(CMACBackend)
@utils.register_interface(CipherBackend)
@utils.register_interface(HashBackend)
@utils.register_interface(HMACBackend)
@@ -156,3 +157,18 @@ class MultiBackend(object):
return b.generate_dsa_private_key(parameters)
raise UnsupportedAlgorithm("DSA is not supported by the backend",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+
+ def cmac_algorithm_supported(self, algorithm):
+ return any(
+ b.cmac_algorithm_supported(algorithm)
+ for b in self._filtered_backends(CMACBackend)
+ )
+
+ def create_cmac_ctx(self, algorithm):
+ for b in self._filtered_backends(CMACBackend):
+ try:
+ return b.create_cmac_ctx(algorithm)
+ except UnsupportedAlgorithm:
+ pass
+ raise UnsupportedAlgorithm("This backend does not support CMAC",
+ _Reasons.UNSUPPORTED_CIPHER)
diff --git a/docs/hazmat/primitives/mac/cmac.rst b/docs/hazmat/primitives/mac/cmac.rst
index 8b88a3ce..a6b048b5 100644
--- a/docs/hazmat/primitives/mac/cmac.rst
+++ b/docs/hazmat/primitives/mac/cmac.rst
@@ -19,10 +19,12 @@ A subset of CMAC with the AES-128 algorithm is described in :rfc:`4493`.
.. class:: CMAC(algorithm, backend)
+ .. versionadded:: 0.4
+
CMAC objects take a
:class:`~cryptography.hazmat.primitives.interfaces.BlockCipherAlgorithm` provider.
- .. code-block:: pycon
+ .. doctest::
>>> from cryptography.hazmat.backends import default_backend
>>> from cryptography.hazmat.primitives import cmac
diff --git a/tests/hazmat/backends/test_multibackend.py b/tests/hazmat/backends/test_multibackend.py
index f46009d4..d8c09bd7 100644
--- a/tests/hazmat/backends/test_multibackend.py
+++ b/tests/hazmat/backends/test_multibackend.py
@@ -18,11 +18,11 @@ from cryptography.exceptions import (
UnsupportedAlgorithm, _Reasons
)
from cryptography.hazmat.backends.interfaces import (
- CipherBackend, DSABackend, HMACBackend, HashBackend, PBKDF2HMACBackend,
- RSABackend
+ CMACBackend, CipherBackend, DSABackend, HMACBackend, HashBackend,
+ PBKDF2HMACBackend, RSABackend
)
from cryptography.hazmat.backends.multibackend import MultiBackend
-from cryptography.hazmat.primitives import hashes, hmac
+from cryptography.hazmat.primitives import cmac, hashes, hmac
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
@@ -108,6 +108,19 @@ class DummyDSABackend(object):
pass
+@utils.register_interface(CMACBackend)
+class DummyCMACBackend(object):
+ def __init__(self, supported_algorithms):
+ self._algorithms = supported_algorithms
+
+ def cmac_algorithm_supported(self, algorithm):
+ return type(algorithm) in self._algorithms
+
+ def create_cmac_ctx(self, algorithm):
+ if not self.cmac_algorithm_supported(algorithm):
+ raise UnsupportedAlgorithm("", _Reasons.UNSUPPORTED_CIPHER)
+
+
class TestMultiBackend(object):
def test_ciphers(self):
backend = MultiBackend([
@@ -224,3 +237,18 @@ class TestMultiBackend(object):
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
):
backend.generate_dsa_private_key(parameters)
+
+ def test_cmac(self):
+ backend = MultiBackend([
+ DummyCMACBackend([algorithms.AES])
+ ])
+
+ fake_key = b"\x00" * 16
+
+ assert backend.cmac_algorithm_supported(
+ algorithms.AES(fake_key)) is True
+
+ cmac.CMAC(algorithms.AES(fake_key), backend)
+
+ with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
+ cmac.CMAC(algorithms.TripleDES(fake_key), backend)