Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/hashes.py: 73%
149 statements
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +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 (
10 AlreadyFinalized,
11)
14class HashAlgorithm(metaclass=abc.ABCMeta):
15 @abc.abstractproperty
16 def name(self) -> str:
17 """
18 A string naming this algorithm (e.g. "sha256", "md5").
19 """
21 @abc.abstractproperty
22 def digest_size(self) -> int:
23 """
24 The size of the resulting digest in bytes.
25 """
27 @abc.abstractproperty
28 def block_size(self) -> typing.Optional[int]:
29 """
30 The internal block size of the hash function, or None if the hash
31 function does not use blocks internally (e.g. SHA3).
32 """
35class HashContext(metaclass=abc.ABCMeta):
36 @abc.abstractproperty
37 def algorithm(self) -> HashAlgorithm:
38 """
39 A HashAlgorithm that will be used by this context.
40 """
42 @abc.abstractmethod
43 def update(self, data: bytes) -> None:
44 """
45 Processes the provided bytes through the hash.
46 """
48 @abc.abstractmethod
49 def finalize(self) -> bytes:
50 """
51 Finalizes the hash context and returns the hash digest as bytes.
52 """
54 @abc.abstractmethod
55 def copy(self) -> "HashContext":
56 """
57 Return a HashContext that is a copy of the current context.
58 """
61class ExtendableOutputFunction(metaclass=abc.ABCMeta):
62 """
63 An interface for extendable output functions.
64 """
67class Hash(HashContext):
68 _ctx: typing.Optional[HashContext]
70 def __init__(
71 self,
72 algorithm: HashAlgorithm,
73 backend: typing.Any = None,
74 ctx: typing.Optional["HashContext"] = None,
75 ):
76 if not isinstance(algorithm, HashAlgorithm):
77 raise TypeError("Expected instance of hashes.HashAlgorithm.")
78 self._algorithm = algorithm
80 if ctx is None:
81 from cryptography.hazmat.backends.openssl.backend import (
82 backend as ossl,
83 )
85 self._ctx = ossl.create_hash_ctx(self.algorithm)
86 else:
87 self._ctx = ctx
89 @property
90 def algorithm(self) -> HashAlgorithm:
91 return self._algorithm
93 def update(self, data: bytes) -> None:
94 if self._ctx is None:
95 raise AlreadyFinalized("Context was already finalized.")
96 utils._check_byteslike("data", data)
97 self._ctx.update(data)
99 def copy(self) -> "Hash":
100 if self._ctx is None:
101 raise AlreadyFinalized("Context was already finalized.")
102 return Hash(self.algorithm, ctx=self._ctx.copy())
104 def finalize(self) -> bytes:
105 if self._ctx is None:
106 raise AlreadyFinalized("Context was already finalized.")
107 digest = self._ctx.finalize()
108 self._ctx = None
109 return digest
112class SHA1(HashAlgorithm):
113 name = "sha1"
114 digest_size = 20
115 block_size = 64
118class SHA512_224(HashAlgorithm): # noqa: N801
119 name = "sha512-224"
120 digest_size = 28
121 block_size = 128
124class SHA512_256(HashAlgorithm): # noqa: N801
125 name = "sha512-256"
126 digest_size = 32
127 block_size = 128
130class SHA224(HashAlgorithm):
131 name = "sha224"
132 digest_size = 28
133 block_size = 64
136class SHA256(HashAlgorithm):
137 name = "sha256"
138 digest_size = 32
139 block_size = 64
142class SHA384(HashAlgorithm):
143 name = "sha384"
144 digest_size = 48
145 block_size = 128
148class SHA512(HashAlgorithm):
149 name = "sha512"
150 digest_size = 64
151 block_size = 128
154class SHA3_224(HashAlgorithm): # noqa: N801
155 name = "sha3-224"
156 digest_size = 28
157 block_size = None
160class SHA3_256(HashAlgorithm): # noqa: N801
161 name = "sha3-256"
162 digest_size = 32
163 block_size = None
166class SHA3_384(HashAlgorithm): # noqa: N801
167 name = "sha3-384"
168 digest_size = 48
169 block_size = None
172class SHA3_512(HashAlgorithm): # noqa: N801
173 name = "sha3-512"
174 digest_size = 64
175 block_size = None
178class SHAKE128(HashAlgorithm, ExtendableOutputFunction):
179 name = "shake128"
180 block_size = None
182 def __init__(self, digest_size: int):
183 if not isinstance(digest_size, int):
184 raise TypeError("digest_size must be an integer")
186 if digest_size < 1:
187 raise ValueError("digest_size must be a positive integer")
189 self._digest_size = digest_size
191 @property
192 def digest_size(self) -> int:
193 return self._digest_size
196class SHAKE256(HashAlgorithm, ExtendableOutputFunction):
197 name = "shake256"
198 block_size = None
200 def __init__(self, digest_size: int):
201 if not isinstance(digest_size, int):
202 raise TypeError("digest_size must be an integer")
204 if digest_size < 1:
205 raise ValueError("digest_size must be a positive integer")
207 self._digest_size = digest_size
209 @property
210 def digest_size(self) -> int:
211 return self._digest_size
214class MD5(HashAlgorithm):
215 name = "md5"
216 digest_size = 16
217 block_size = 64
220class BLAKE2b(HashAlgorithm):
221 name = "blake2b"
222 _max_digest_size = 64
223 _min_digest_size = 1
224 block_size = 128
226 def __init__(self, digest_size: int):
228 if digest_size != 64:
229 raise ValueError("Digest size must be 64")
231 self._digest_size = digest_size
233 @property
234 def digest_size(self) -> int:
235 return self._digest_size
238class BLAKE2s(HashAlgorithm):
239 name = "blake2s"
240 block_size = 64
241 _max_digest_size = 32
242 _min_digest_size = 1
244 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