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

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 ( 

10 AlreadyFinalized, 

11) 

12 

13 

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

20 

21 @abc.abstractproperty 

22 def digest_size(self) -> int: 

23 """ 

24 The size of the resulting digest in bytes. 

25 """ 

26 

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

33 

34 

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

41 

42 @abc.abstractmethod 

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

44 """ 

45 Processes the provided bytes through the hash. 

46 """ 

47 

48 @abc.abstractmethod 

49 def finalize(self) -> bytes: 

50 """ 

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

52 """ 

53 

54 @abc.abstractmethod 

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

56 """ 

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

58 """ 

59 

60 

61class ExtendableOutputFunction(metaclass=abc.ABCMeta): 

62 """ 

63 An interface for extendable output functions. 

64 """ 

65 

66 

67class Hash(HashContext): 

68 _ctx: typing.Optional[HashContext] 

69 

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 

79 

80 if ctx is None: 

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

82 backend as ossl, 

83 ) 

84 

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

86 else: 

87 self._ctx = ctx 

88 

89 @property 

90 def algorithm(self) -> HashAlgorithm: 

91 return self._algorithm 

92 

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) 

98 

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

103 

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 

110 

111 

112class SHA1(HashAlgorithm): 

113 name = "sha1" 

114 digest_size = 20 

115 block_size = 64 

116 

117 

118class SHA512_224(HashAlgorithm): # noqa: N801 

119 name = "sha512-224" 

120 digest_size = 28 

121 block_size = 128 

122 

123 

124class SHA512_256(HashAlgorithm): # noqa: N801 

125 name = "sha512-256" 

126 digest_size = 32 

127 block_size = 128 

128 

129 

130class SHA224(HashAlgorithm): 

131 name = "sha224" 

132 digest_size = 28 

133 block_size = 64 

134 

135 

136class SHA256(HashAlgorithm): 

137 name = "sha256" 

138 digest_size = 32 

139 block_size = 64 

140 

141 

142class SHA384(HashAlgorithm): 

143 name = "sha384" 

144 digest_size = 48 

145 block_size = 128 

146 

147 

148class SHA512(HashAlgorithm): 

149 name = "sha512" 

150 digest_size = 64 

151 block_size = 128 

152 

153 

154class SHA3_224(HashAlgorithm): # noqa: N801 

155 name = "sha3-224" 

156 digest_size = 28 

157 block_size = None 

158 

159 

160class SHA3_256(HashAlgorithm): # noqa: N801 

161 name = "sha3-256" 

162 digest_size = 32 

163 block_size = None 

164 

165 

166class SHA3_384(HashAlgorithm): # noqa: N801 

167 name = "sha3-384" 

168 digest_size = 48 

169 block_size = None 

170 

171 

172class SHA3_512(HashAlgorithm): # noqa: N801 

173 name = "sha3-512" 

174 digest_size = 64 

175 block_size = None 

176 

177 

178class SHAKE128(HashAlgorithm, ExtendableOutputFunction): 

179 name = "shake128" 

180 block_size = None 

181 

182 def __init__(self, digest_size: int): 

183 if not isinstance(digest_size, int): 

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

185 

186 if digest_size < 1: 

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

188 

189 self._digest_size = digest_size 

190 

191 @property 

192 def digest_size(self) -> int: 

193 return self._digest_size 

194 

195 

196class SHAKE256(HashAlgorithm, ExtendableOutputFunction): 

197 name = "shake256" 

198 block_size = None 

199 

200 def __init__(self, digest_size: int): 

201 if not isinstance(digest_size, int): 

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

203 

204 if digest_size < 1: 

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

206 

207 self._digest_size = digest_size 

208 

209 @property 

210 def digest_size(self) -> int: 

211 return self._digest_size 

212 

213 

214class MD5(HashAlgorithm): 

215 name = "md5" 

216 digest_size = 16 

217 block_size = 64 

218 

219 

220class BLAKE2b(HashAlgorithm): 

221 name = "blake2b" 

222 _max_digest_size = 64 

223 _min_digest_size = 1 

224 block_size = 128 

225 

226 def __init__(self, digest_size: int): 

227 

228 if digest_size != 64: 

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

230 

231 self._digest_size = digest_size 

232 

233 @property 

234 def digest_size(self) -> int: 

235 return self._digest_size 

236 

237 

238class BLAKE2s(HashAlgorithm): 

239 name = "blake2s" 

240 block_size = 64 

241 _max_digest_size = 32 

242 _min_digest_size = 1 

243 

244 def __init__(self, digest_size: int): 

245 

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