From 1050ddf44f0713a587cd0ba239e23c95064a39bc Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 27 Jan 2014 21:04:03 -0600 Subject: PBKDF2 support for OpenSSL backend --- tests/conftest.py | 3 ++- tests/hazmat/primitives/test_pbkdf2_vectors.py | 37 ++++++++++++++++++++++++++ tests/hazmat/primitives/utils.py | 25 +++++++++++++++++ tests/utils.py | 4 +++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 tests/hazmat/primitives/test_pbkdf2_vectors.py (limited to 'tests') diff --git a/tests/conftest.py b/tests/conftest.py index a9acb54a..7370294f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,7 +2,7 @@ import pytest from cryptography.hazmat.backends import _ALL_BACKENDS from cryptography.hazmat.backends.interfaces import ( - HMACBackend, CipherBackend, HashBackend + HMACBackend, CipherBackend, HashBackend, PBKDF2Backend ) from .utils import check_for_iface, check_backend_support, select_backends @@ -21,6 +21,7 @@ def pytest_runtest_setup(item): check_for_iface("hmac", HMACBackend, item) check_for_iface("cipher", CipherBackend, item) check_for_iface("hash", HashBackend, item) + check_for_iface("pbkdf2", PBKDF2Backend, item) check_backend_support(item) diff --git a/tests/hazmat/primitives/test_pbkdf2_vectors.py b/tests/hazmat/primitives/test_pbkdf2_vectors.py new file mode 100644 index 00000000..e6e3935f --- /dev/null +++ b/tests/hazmat/primitives/test_pbkdf2_vectors.py @@ -0,0 +1,37 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +import pytest + +from cryptography.hazmat.primitives import hashes + +from .utils import generate_pbkdf2_test +from ...utils import load_nist_vectors + + +@pytest.mark.supported( + only_if=lambda backend: backend.pbkdf2_hash_supported(hashes.SHA1()), + skip_message="Does not support SHA1 for PBKDF2", +) +@pytest.mark.pbkdf2 +class TestPBKDF2_SHA1(object): + test_pbkdf2_sha1 = generate_pbkdf2_test( + load_nist_vectors, + "KDF", + [ + "rfc-6070-PBKDF2-SHA1.txt", + ], + hashes.SHA1(), + ) diff --git a/tests/hazmat/primitives/utils.py b/tests/hazmat/primitives/utils.py index f27afe41..3a1d6d88 100644 --- a/tests/hazmat/primitives/utils.py +++ b/tests/hazmat/primitives/utils.py @@ -4,6 +4,7 @@ import os import pytest from cryptography.hazmat.primitives import hashes, hmac +from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2 from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.exceptions import ( AlreadyFinalized, NotYetFinalized, AlreadyUpdated, InvalidTag, @@ -211,6 +212,30 @@ def hmac_test(backend, algorithm, params): assert h.finalize() == binascii.unhexlify(md.encode("ascii")) +def generate_pbkdf2_test(param_loader, path, file_names, algorithm): + all_params = _load_all_params(path, file_names, param_loader) + + @pytest.mark.parametrize("params", all_params) + def test_pbkdf2(self, backend, params): + pbkdf2_test(backend, algorithm, params) + return test_pbkdf2 + + +def pbkdf2_test(backend, algorithm, params): + # Password and salt can contain \0, which should be loaded as a null char. + # The NIST loader loads them as literal strings so we replace with the + # proper value. + kdf = PBKDF2( + algorithm, + int(params["length"]), + params["salt"], + int(params["iterations"]), + backend + ) + derived_key = kdf.derive(params["password"]) + assert binascii.hexlify(derived_key) == params["derived_key"] + + def generate_aead_exception_test(cipher_factory, mode_factory): def test_aead_exception(self, backend): aead_exception_test(backend, cipher_factory, mode_factory) diff --git a/tests/utils.py b/tests/utils.py index 507bc421..5c0e524f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -89,6 +89,10 @@ def load_nist_vectors(vector_data): # Build our data using a simple Key = Value format name, value = [c.strip() for c in line.split("=")] + # Some tests (PBKDF2) contain \0, which should be interpreted as a + # null character rather than literal. + value = value.replace("\\0", "\0") + # COUNT is a special token that indicates a new block of data if name.upper() == "COUNT": test_data = {} -- cgit v1.2.3