From 17c8f126c7c7d5ce886112a6e924277a7b203f25 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 15 Mar 2018 13:35:10 -0400 Subject: Brainpool curves (#4129) * added brainpool ec-curves key_length >= 256bit * limit brainpool curves to the set that appear required + docs * oops * typos all around me * add brainpool ECDH kex tests * switch to using rfc 7027 vectors * review feedback * empty commits are the best --- CHANGELOG.rst | 4 +++ docs/hazmat/primitives/asymmetric/ec.rst | 22 ++++++++++++++++ .../hazmat/primitives/asymmetric/ec.py | 22 ++++++++++++++++ tests/hazmat/primitives/test_ec.py | 29 +++++++++++++++++++++- 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 79ce603b..2f8924fd 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,10 @@ Changelog * **BACKWARDS INCOMPATIBLE:** Support for Python 2.6 has been dropped. * Resolved a bug in ``HKDF`` that incorrectly constrained output size. +* Added :class:`~cryptography.hazmat.primitives.asymmetric.ec.BrainpoolP256R1`, + :class:`~cryptography.hazmat.primitives.asymmetric.ec.BrainpoolP384R1`, and + :class:`~cryptography.hazmat.primitives.asymmetric.ec.BrainpoolP512R1` to + support inter-operating with systems like German smart meters. * Added token rotation support to :doc:`Fernet ` with :meth:`~cryptography.fernet.MultiFernet.rotate`. * Fixed a memory leak in diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst index 5d6251f1..edcfdfcb 100644 --- a/docs/hazmat/primitives/asymmetric/ec.rst +++ b/docs/hazmat/primitives/asymmetric/ec.rst @@ -414,6 +414,28 @@ All named curves are instances of :class:`EllipticCurve`. SECG curve ``secp256k1``. +.. class:: BrainpoolP256R1 + + .. versionadded:: 2.2 + + Brainpool curve specified in :rfc:`5639`. These curves are discouraged + for new systems. + +.. class:: BrainpoolP384R1 + + .. versionadded:: 2.2 + + Brainpool curve specified in :rfc:`5639`. These curves are discouraged + for new systems. + +.. class:: BrainpoolP512R1 + + .. versionadded:: 2.2 + + Brainpool curve specified in :rfc:`5639`. These curves are discouraged + for new systems. + + Key Interfaces ~~~~~~~~~~~~~~ diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py index 7931b086..83266bb4 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -228,6 +228,24 @@ class SECP192R1(object): key_size = 192 +@utils.register_interface(EllipticCurve) +class BrainpoolP256R1(object): + name = "brainpoolP256r1" + key_size = 256 + + +@utils.register_interface(EllipticCurve) +class BrainpoolP384R1(object): + name = "brainpoolP384r1" + key_size = 384 + + +@utils.register_interface(EllipticCurve) +class BrainpoolP512R1(object): + name = "brainpoolP512r1" + key_size = 512 + + _CURVE_TYPES = { "prime192v1": SECP192R1, "prime256v1": SECP256R1, @@ -250,6 +268,10 @@ _CURVE_TYPES = { "sect283r1": SECT283R1, "sect409r1": SECT409R1, "sect571r1": SECT571R1, + + "brainpoolP256r1": BrainpoolP256R1, + "brainpoolP384r1": BrainpoolP384R1, + "brainpoolP512r1": BrainpoolP512R1, } diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index 02b1cdc6..1b491a10 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -26,7 +26,7 @@ from .fixtures_ec import EC_KEY_SECP384R1 from ...doubles import DummyKeySerializationEncryption from ...utils import ( load_fips_ecdsa_key_pair_vectors, load_fips_ecdsa_signing_vectors, - load_kasvs_ecdh_vectors, load_vectors_from_file, + load_kasvs_ecdh_vectors, load_nist_vectors, load_vectors_from_file, raises_unsupported_algorithm ) @@ -1101,6 +1101,33 @@ class TestECDH(object): else: assert z == vector['Z'] + @pytest.mark.parametrize( + "vector", + load_vectors_from_file( + os.path.join("asymmetric", "ECDH", "brainpool.txt"), + load_nist_vectors + ) + ) + def test_brainpool_kex(self, backend, vector): + curve = ec._CURVE_TYPES[vector['curve'].decode('ascii')] + _skip_exchange_algorithm_unsupported(backend, ec.ECDH(), curve) + key = ec.EllipticCurvePrivateNumbers( + int(vector['da'], 16), + ec.EllipticCurvePublicNumbers( + int(vector['x_qa'], 16), int(vector['y_qa'], 16), curve() + ) + ).private_key(backend) + peer = ec.EllipticCurvePrivateNumbers( + int(vector['db'], 16), + ec.EllipticCurvePublicNumbers( + int(vector['x_qb'], 16), int(vector['y_qb'], 16), curve() + ) + ).private_key(backend) + shared_secret = key.exchange(ec.ECDH(), peer.public_key()) + assert shared_secret == binascii.unhexlify(vector["x_z"]) + shared_secret_2 = peer.exchange(ec.ECDH(), key.public_key()) + assert shared_secret_2 == binascii.unhexlify(vector["x_z"]) + def test_exchange_unsupported_algorithm(self, backend): _skip_curve_unsupported(backend, ec.SECP256R1()) -- cgit v1.2.3