Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/hashes.py: 74%
153 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:36 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:36 +0000
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.
5import abc
6import typing
8from cryptography import utils
9from cryptography.exceptions import AlreadyFinalized
12class HashAlgorithm(metaclass=abc.ABCMeta):
13 @property
14 @abc.abstractmethod
15 def name(self) -> str:
16 """
17 A string naming this algorithm (e.g. "sha256", "md5").
18 """
20 @property
21 @abc.abstractmethod
22 def digest_size(self) -> int:
23 """
24 The size of the resulting digest in bytes.
25 """
27 @property
28 @abc.abstractmethod
29 def block_size(self) -> typing.Optional[int]:
30 """
31 The internal block size of the hash function, or None if the hash
32 function does not use blocks internally (e.g. SHA3).
33 """
36class HashContext(metaclass=abc.ABCMeta):
37 @property
38 @abc.abstractmethod
39 def algorithm(self) -> HashAlgorithm:
40 """
41 A HashAlgorithm that will be used by this context.
42 """
44 @abc.abstractmethod
45 def update(self, data: bytes) -> None:
46 """
47 Processes the provided bytes through the hash.
48 """
50 @abc.abstractmethod
51 def finalize(self) -> bytes:
52 """
53 Finalizes the hash context and returns the hash digest as bytes.
54 """
56 @abc.abstractmethod
57 def copy(self) -> "HashContext":
58 """
59 Return a HashContext that is a copy of the current context.
60 """
63class ExtendableOutputFunction(metaclass=abc.ABCMeta):
64 """
65 An interface for extendable output functions.
66 """
69class Hash(HashContext):
70 _ctx: typing.Optional[HashContext]
72 def __init__(
73 self,
74 algorithm: HashAlgorithm,
75 backend: typing.Any = None,
76 ctx: typing.Optional["HashContext"] = None,
77 ) -> None:
78 if not isinstance(algorithm, HashAlgorithm):
79 raise TypeError("Expected instance of hashes.HashAlgorithm.")
80 self._algorithm = algorithm
82 if ctx is None:
83 from cryptography.hazmat.backends.openssl.backend import (
84 backend as ossl,
85 )
87 self._ctx = ossl.create_hash_ctx(self.algorithm)
88 else:
89 self._ctx = ctx
91 @property
92 def algorithm(self) -> HashAlgorithm:
93 return self._algorithm
95 def update(self, data: bytes) -> None:
96 if self._ctx is None:
97 raise AlreadyFinalized("Context was already finalized.")
98 utils._check_byteslike("data", data)
99 self._ctx.update(data)
101 def copy(self) -> "Hash":
102 if self._ctx is None:
103 raise AlreadyFinalized("Context was already finalized.")
104 return Hash(self.algorithm, ctx=self._ctx.copy())
106 def finalize(self) -> bytes:
107 if self._ctx is None:
108 raise AlreadyFinalized("Context was already finalized.")
109 digest = self._ctx.finalize()
110 self._ctx = None
111 return digest
114class SHA1(HashAlgorithm):
115 name = "sha1"
116 digest_size = 20
117 block_size = 64
120class SHA512_224(HashAlgorithm): # noqa: N801
121 name = "sha512-224"
122 digest_size = 28
123 block_size = 128
126class SHA512_256(HashAlgorithm): # noqa: N801
127 name = "sha512-256"
128 digest_size = 32
129 block_size = 128
132class SHA224(HashAlgorithm):
133 name = "sha224"
134 digest_size = 28
135 block_size = 64
138class SHA256(HashAlgorithm):
139 name = "sha256"
140 digest_size = 32
141 block_size = 64
144class SHA384(HashAlgorithm):
145 name = "sha384"
146 digest_size = 48
147 block_size = 128
150class SHA512(HashAlgorithm):
151 name = "sha512"
152 digest_size = 64
153 block_size = 128
156class SHA3_224(HashAlgorithm): # noqa: N801
157 name = "sha3-224"
158 digest_size = 28
159 block_size = None
162class SHA3_256(HashAlgorithm): # noqa: N801
163 name = "sha3-256"
164 digest_size = 32
165 block_size = None
168class SHA3_384(HashAlgorithm): # noqa: N801
169 name = "sha3-384"
170 digest_size = 48
171 block_size = None
174class SHA3_512(HashAlgorithm): # noqa: N801
175 name = "sha3-512"
176 digest_size = 64
177 block_size = None
180class SHAKE128(HashAlgorithm, ExtendableOutputFunction):
181 name = "shake128"
182 block_size = None
184 def __init__(self, digest_size: int):
185 if not isinstance(digest_size, int):
186 raise TypeError("digest_size must be an integer")
188 if digest_size < 1:
189 raise ValueError("digest_size must be a positive integer")
191 self._digest_size = digest_size
193 @property
194 def digest_size(self) -> int:
195 return self._digest_size
198class SHAKE256(HashAlgorithm, ExtendableOutputFunction):
199 name = "shake256"
200 block_size = None
202 def __init__(self, digest_size: int):
203 if not isinstance(digest_size, int):
204 raise TypeError("digest_size must be an integer")
206 if digest_size < 1:
207 raise ValueError("digest_size must be a positive integer")
209 self._digest_size = digest_size
211 @property
212 def digest_size(self) -> int:
213 return self._digest_size
216class MD5(HashAlgorithm):
217 name = "md5"
218 digest_size = 16
219 block_size = 64
222class BLAKE2b(HashAlgorithm):
223 name = "blake2b"
224 _max_digest_size = 64
225 _min_digest_size = 1
226 block_size = 128
228 def __init__(self, digest_size: int):
229 if digest_size != 64:
230 raise ValueError("Digest size must be 64")
232 self._digest_size = digest_size
234 @property
235 def digest_size(self) -> int:
236 return self._digest_size
239class BLAKE2s(HashAlgorithm):
240 name = "blake2s"
241 block_size = 64
242 _max_digest_size = 32
243 _min_digest_size = 1
245 def __init__(self, digest_size: int):
246 if digest_size != 32:
247 raise ValueError("Digest size must be 32")
249 self._digest_size = digest_size
251 @property
252 def digest_size(self) -> int:
253 return self._digest_size
256class SM3(HashAlgorithm):
257 name = "sm3"
258 digest_size = 32
259 block_size = 64