• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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