1# This file is dual licensed under the terms of the Apache License, Version 2# 2.0, and the BSD License. See the LICENSE file in the root of this repository 3# for complete details. 4 5from __future__ import absolute_import, division, print_function 6 7import binascii 8 9import pytest 10 11from cryptography.exceptions import AlreadyFinalized, _Reasons 12from cryptography.hazmat.backends.interfaces import HashBackend 13from cryptography.hazmat.primitives import hashes 14 15from .utils import generate_base_hash_test 16from ...doubles import DummyHashAlgorithm 17from ...utils import raises_unsupported_algorithm 18 19 20@pytest.mark.requires_backend_interface(interface=HashBackend) 21class TestHashContext(object): 22 def test_hash_reject_unicode(self, backend): 23 m = hashes.Hash(hashes.SHA1(), backend=backend) 24 with pytest.raises(TypeError): 25 m.update(u"\u00FC") 26 27 def test_hash_algorithm_instance(self, backend): 28 with pytest.raises(TypeError): 29 hashes.Hash(hashes.SHA1, backend=backend) 30 31 def test_raises_after_finalize(self, backend): 32 h = hashes.Hash(hashes.SHA1(), backend=backend) 33 h.finalize() 34 35 with pytest.raises(AlreadyFinalized): 36 h.update(b"foo") 37 38 with pytest.raises(AlreadyFinalized): 39 h.copy() 40 41 with pytest.raises(AlreadyFinalized): 42 h.finalize() 43 44 def test_unsupported_hash(self, backend): 45 with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH): 46 hashes.Hash(DummyHashAlgorithm(), backend) 47 48 49@pytest.mark.supported( 50 only_if=lambda backend: backend.hash_supported(hashes.SHA1()), 51 skip_message="Does not support SHA1", 52) 53@pytest.mark.requires_backend_interface(interface=HashBackend) 54class TestSHA1(object): 55 test_sha1 = generate_base_hash_test( 56 hashes.SHA1(), 57 digest_size=20, 58 ) 59 60 61@pytest.mark.supported( 62 only_if=lambda backend: backend.hash_supported(hashes.SHA224()), 63 skip_message="Does not support SHA224", 64) 65@pytest.mark.requires_backend_interface(interface=HashBackend) 66class TestSHA224(object): 67 test_sha224 = generate_base_hash_test( 68 hashes.SHA224(), 69 digest_size=28, 70 ) 71 72 73@pytest.mark.supported( 74 only_if=lambda backend: backend.hash_supported(hashes.SHA256()), 75 skip_message="Does not support SHA256", 76) 77@pytest.mark.requires_backend_interface(interface=HashBackend) 78class TestSHA256(object): 79 test_sha256 = generate_base_hash_test( 80 hashes.SHA256(), 81 digest_size=32, 82 ) 83 84 85@pytest.mark.supported( 86 only_if=lambda backend: backend.hash_supported(hashes.SHA384()), 87 skip_message="Does not support SHA384", 88) 89@pytest.mark.requires_backend_interface(interface=HashBackend) 90class TestSHA384(object): 91 test_sha384 = generate_base_hash_test( 92 hashes.SHA384(), 93 digest_size=48, 94 ) 95 96 97@pytest.mark.supported( 98 only_if=lambda backend: backend.hash_supported(hashes.SHA512()), 99 skip_message="Does not support SHA512", 100) 101@pytest.mark.requires_backend_interface(interface=HashBackend) 102class TestSHA512(object): 103 test_sha512 = generate_base_hash_test( 104 hashes.SHA512(), 105 digest_size=64, 106 ) 107 108 109@pytest.mark.supported( 110 only_if=lambda backend: backend.hash_supported(hashes.MD5()), 111 skip_message="Does not support MD5", 112) 113@pytest.mark.requires_backend_interface(interface=HashBackend) 114class TestMD5(object): 115 test_md5 = generate_base_hash_test( 116 hashes.MD5(), 117 digest_size=16, 118 ) 119 120 121@pytest.mark.supported( 122 only_if=lambda backend: backend.hash_supported( 123 hashes.BLAKE2b(digest_size=64) 124 ), 125 skip_message="Does not support BLAKE2b", 126) 127@pytest.mark.requires_backend_interface(interface=HashBackend) 128class TestBLAKE2b(object): 129 test_blake2b = generate_base_hash_test( 130 hashes.BLAKE2b(digest_size=64), 131 digest_size=64, 132 ) 133 134 def test_invalid_digest_size(self, backend): 135 with pytest.raises(ValueError): 136 hashes.BLAKE2b(digest_size=65) 137 138 with pytest.raises(ValueError): 139 hashes.BLAKE2b(digest_size=0) 140 141 with pytest.raises(ValueError): 142 hashes.BLAKE2b(digest_size=-1) 143 144 145@pytest.mark.supported( 146 only_if=lambda backend: backend.hash_supported( 147 hashes.BLAKE2s(digest_size=32) 148 ), 149 skip_message="Does not support BLAKE2s", 150) 151@pytest.mark.requires_backend_interface(interface=HashBackend) 152class TestBLAKE2s(object): 153 test_blake2s = generate_base_hash_test( 154 hashes.BLAKE2s(digest_size=32), 155 digest_size=32, 156 ) 157 158 def test_invalid_digest_size(self, backend): 159 with pytest.raises(ValueError): 160 hashes.BLAKE2s(digest_size=33) 161 162 with pytest.raises(ValueError): 163 hashes.BLAKE2s(digest_size=0) 164 165 with pytest.raises(ValueError): 166 hashes.BLAKE2s(digest_size=-1) 167 168 169def test_invalid_backend(): 170 pretend_backend = object() 171 172 with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE): 173 hashes.Hash(hashes.SHA1(), pretend_backend) 174 175 176@pytest.mark.requires_backend_interface(interface=HashBackend) 177def test_buffer_protocol_hash(backend): 178 data = binascii.unhexlify(b"b4190e") 179 h = hashes.Hash(hashes.SHA256(), backend) 180 h.update(bytearray(data)) 181 assert h.finalize() == binascii.unhexlify( 182 b"dff2e73091f6c05e528896c4c831b9448653dc2ff043528f6769437bc7b975c2" 183 ) 184 185 186class TestSHAKE(object): 187 @pytest.mark.parametrize("xof", [hashes.SHAKE128, hashes.SHAKE256]) 188 def test_invalid_digest_type(self, xof): 189 with pytest.raises(TypeError): 190 xof(digest_size=object()) 191 192 @pytest.mark.parametrize("xof", [hashes.SHAKE128, hashes.SHAKE256]) 193 def test_invalid_digest_size(self, xof): 194 with pytest.raises(ValueError): 195 xof(digest_size=-5) 196 197 with pytest.raises(ValueError): 198 xof(digest_size=0) 199