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

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 

5import abc 

6import typing 

7 

8from cryptography import utils 

9from cryptography.exceptions import AlreadyFinalized 

10 

11 

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 """ 

19 

20 @property 

21 @abc.abstractmethod 

22 def digest_size(self) -> int: 

23 """ 

24 The size of the resulting digest in bytes. 

25 """ 

26 

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 """ 

34 

35 

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 """ 

43 

44 @abc.abstractmethod 

45 def update(self, data: bytes) -> None: 

46 """ 

47 Processes the provided bytes through the hash. 

48 """ 

49 

50 @abc.abstractmethod 

51 def finalize(self) -> bytes: 

52 """ 

53 Finalizes the hash context and returns the hash digest as bytes. 

54 """ 

55 

56 @abc.abstractmethod 

57 def copy(self) -> "HashContext": 

58 """ 

59 Return a HashContext that is a copy of the current context. 

60 """ 

61 

62 

63class ExtendableOutputFunction(metaclass=abc.ABCMeta): 

64 """ 

65 An interface for extendable output functions. 

66 """ 

67 

68 

69class Hash(HashContext): 

70 _ctx: typing.Optional[HashContext] 

71 

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 

81 

82 if ctx is None: 

83 from cryptography.hazmat.backends.openssl.backend import ( 

84 backend as ossl, 

85 ) 

86 

87 self._ctx = ossl.create_hash_ctx(self.algorithm) 

88 else: 

89 self._ctx = ctx 

90 

91 @property 

92 def algorithm(self) -> HashAlgorithm: 

93 return self._algorithm 

94 

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) 

100 

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()) 

105 

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 

112 

113 

114class SHA1(HashAlgorithm): 

115 name = "sha1" 

116 digest_size = 20 

117 block_size = 64 

118 

119 

120class SHA512_224(HashAlgorithm): # noqa: N801 

121 name = "sha512-224" 

122 digest_size = 28 

123 block_size = 128 

124 

125 

126class SHA512_256(HashAlgorithm): # noqa: N801 

127 name = "sha512-256" 

128 digest_size = 32 

129 block_size = 128 

130 

131 

132class SHA224(HashAlgorithm): 

133 name = "sha224" 

134 digest_size = 28 

135 block_size = 64 

136 

137 

138class SHA256(HashAlgorithm): 

139 name = "sha256" 

140 digest_size = 32 

141 block_size = 64 

142 

143 

144class SHA384(HashAlgorithm): 

145 name = "sha384" 

146 digest_size = 48 

147 block_size = 128 

148 

149 

150class SHA512(HashAlgorithm): 

151 name = "sha512" 

152 digest_size = 64 

153 block_size = 128 

154 

155 

156class SHA3_224(HashAlgorithm): # noqa: N801 

157 name = "sha3-224" 

158 digest_size = 28 

159 block_size = None 

160 

161 

162class SHA3_256(HashAlgorithm): # noqa: N801 

163 name = "sha3-256" 

164 digest_size = 32 

165 block_size = None 

166 

167 

168class SHA3_384(HashAlgorithm): # noqa: N801 

169 name = "sha3-384" 

170 digest_size = 48 

171 block_size = None 

172 

173 

174class SHA3_512(HashAlgorithm): # noqa: N801 

175 name = "sha3-512" 

176 digest_size = 64 

177 block_size = None 

178 

179 

180class SHAKE128(HashAlgorithm, ExtendableOutputFunction): 

181 name = "shake128" 

182 block_size = None 

183 

184 def __init__(self, digest_size: int): 

185 if not isinstance(digest_size, int): 

186 raise TypeError("digest_size must be an integer") 

187 

188 if digest_size < 1: 

189 raise ValueError("digest_size must be a positive integer") 

190 

191 self._digest_size = digest_size 

192 

193 @property 

194 def digest_size(self) -> int: 

195 return self._digest_size 

196 

197 

198class SHAKE256(HashAlgorithm, ExtendableOutputFunction): 

199 name = "shake256" 

200 block_size = None 

201 

202 def __init__(self, digest_size: int): 

203 if not isinstance(digest_size, int): 

204 raise TypeError("digest_size must be an integer") 

205 

206 if digest_size < 1: 

207 raise ValueError("digest_size must be a positive integer") 

208 

209 self._digest_size = digest_size 

210 

211 @property 

212 def digest_size(self) -> int: 

213 return self._digest_size 

214 

215 

216class MD5(HashAlgorithm): 

217 name = "md5" 

218 digest_size = 16 

219 block_size = 64 

220 

221 

222class BLAKE2b(HashAlgorithm): 

223 name = "blake2b" 

224 _max_digest_size = 64 

225 _min_digest_size = 1 

226 block_size = 128 

227 

228 def __init__(self, digest_size: int): 

229 if digest_size != 64: 

230 raise ValueError("Digest size must be 64") 

231 

232 self._digest_size = digest_size 

233 

234 @property 

235 def digest_size(self) -> int: 

236 return self._digest_size 

237 

238 

239class BLAKE2s(HashAlgorithm): 

240 name = "blake2s" 

241 block_size = 64 

242 _max_digest_size = 32 

243 _min_digest_size = 1 

244 

245 def __init__(self, digest_size: int): 

246 if digest_size != 32: 

247 raise ValueError("Digest size must be 32") 

248 

249 self._digest_size = digest_size 

250 

251 @property 

252 def digest_size(self) -> int: 

253 return self._digest_size 

254 

255 

256class SM3(HashAlgorithm): 

257 name = "sm3" 

258 digest_size = 32 

259 block_size = 64