Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/Crypto/Cipher/AES.py: 72%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

112 statements  

1# 

2# Cipher/AES.py : AES 

3# 

4# =================================================================== 

5# The contents of this file are dedicated to the public domain. To 

6# the extent that dedication to the public domain is not available, 

7# everyone is granted a worldwide, perpetual, royalty-free, 

8# non-exclusive license to exercise all rights associated with the 

9# contents of this file for any purpose whatsoever. 

10# No rights are reserved. 

11# 

12# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 

13# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 

14# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 

15# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 

16# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 

17# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 

18# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 

19# SOFTWARE. 

20# =================================================================== 

21 

22from __future__ import annotations 

23 

24import sys 

25from typing import TYPE_CHECKING, Any, Literal, Optional, Union, overload 

26 

27from Crypto.Cipher import _create_cipher 

28from Crypto.Random import get_random_bytes 

29from Crypto.Util import _cpu_features 

30from Crypto.Util._raw_api import ( 

31 SmartPointer, 

32 VoidPointer, 

33 c_size_t, 

34 c_uint8_ptr_len, 

35 load_pycryptodome_raw_lib, 

36) 

37 

38if TYPE_CHECKING: 

39 from Crypto.Cipher._mode_cbc import CbcMode 

40 from Crypto.Cipher._mode_ccm import CcmMode 

41 from Crypto.Cipher._mode_cfb import CfbMode 

42 from Crypto.Cipher._mode_ctr import CtrMode 

43 from Crypto.Cipher._mode_eax import EaxMode 

44 from Crypto.Cipher._mode_ecb import EcbMode 

45 from Crypto.Cipher._mode_gcm import GcmMode 

46 from Crypto.Cipher._mode_kw import KWMode 

47 from Crypto.Cipher._mode_kwp import KWPMode 

48 from Crypto.Cipher._mode_ocb import OcbMode 

49 from Crypto.Cipher._mode_ofb import OfbMode 

50 from Crypto.Cipher._mode_openpgp import OpenPgpMode 

51 from Crypto.Cipher._mode_siv import SivMode 

52 from Crypto.Util.Counter import CounterParams 

53 

54Buffer = Union[bytes, bytearray, memoryview] 

55 

56MODE_ECB: Literal[1] = 1 #: Electronic Code Book (:ref:`ecb_mode`) 

57MODE_CBC: Literal[2] = 2 #: Cipher-Block Chaining (:ref:`cbc_mode`) 

58MODE_CFB: Literal[3] = 3 #: Cipher Feedback (:ref:`cfb_mode`) 

59MODE_OFB: Literal[5] = 5 #: Output Feedback (:ref:`ofb_mode`) 

60MODE_CTR: Literal[6] = 6 #: Counter mode (:ref:`ctr_mode`) 

61MODE_OPENPGP: Literal[7] = 7 #: OpenPGP mode (:ref:`openpgp_mode`) 

62MODE_CCM: Literal[8] = 8 #: Counter with CBC-MAC (:ref:`ccm_mode`) 

63MODE_EAX: Literal[9] = 9 #: :ref:`eax_mode` 

64MODE_SIV: Literal[10] = 10 #: Synthetic Initialization Vector (:ref:`siv_mode`) 

65MODE_GCM: Literal[11] = 11 #: Galois Counter Mode (:ref:`gcm_mode`) 

66MODE_OCB: Literal[12] = 12 #: Offset Code Book (:ref:`ocb_mode`) 

67MODE_KW: Literal[13] = 13 #: Key Wrap (:ref:`kw_mode`) 

68MODE_KWP: Literal[14] = 14 #: Key Wrap with Padding (:ref:`kwp_mode`) 

69 

70_cproto = """ 

71 int AES_start_operation(const uint8_t key[], 

72 size_t key_len, 

73 void **pResult); 

74 int AES_encrypt(const void *state, 

75 const uint8_t *in, 

76 uint8_t *out, 

77 size_t data_len); 

78 int AES_decrypt(const void *state, 

79 const uint8_t *in, 

80 uint8_t *out, 

81 size_t data_len); 

82 int AES_stop_operation(void *state); 

83 """ 

84 

85 

86# Load portable AES 

87_raw_aes_lib = load_pycryptodome_raw_lib("Crypto.Cipher._raw_aes", _cproto) 

88 

89# Try to load AES with AES NI instructions 

90try: 

91 _raw_aesni_lib = None 

92 if _cpu_features.have_aes_ni(): 

93 _raw_aesni_lib = load_pycryptodome_raw_lib( 

94 "Crypto.Cipher._raw_aesni", _cproto.replace("AES", "AESNI") 

95 ) 

96# _raw_aesni may not have been compiled in 

97except OSError: 

98 pass 

99 

100 

101def _create_base_cipher(dict_parameters): 

102 """This method instantiates and returns a handle to a low-level 

103 base cipher. It will absorb named parameters in the process.""" 

104 

105 use_aesni = dict_parameters.pop("use_aesni", True) 

106 

107 try: 

108 key = dict_parameters.pop("key") 

109 except KeyError: 

110 raise TypeError("Missing 'key' parameter") 

111 

112 if len(key) not in key_size: 

113 raise ValueError("Incorrect AES key length (%d bytes)" % len(key)) 

114 

115 if use_aesni and _raw_aesni_lib: 

116 start_operation = _raw_aesni_lib.AESNI_start_operation 

117 stop_operation = _raw_aesni_lib.AESNI_stop_operation 

118 else: 

119 start_operation = _raw_aes_lib.AES_start_operation 

120 stop_operation = _raw_aes_lib.AES_stop_operation 

121 

122 cipher = VoidPointer() 

123 key_ptr, key_len = c_uint8_ptr_len(key) 

124 result = start_operation(key_ptr, c_size_t(key_len), cipher.address_of()) 

125 if result: 

126 raise ValueError("Error %X while instantiating the AES cipher" % result) 

127 return SmartPointer(cipher.get(), stop_operation) 

128 

129 

130def _derive_Poly1305_key_pair(key, nonce): 

131 """Derive a tuple (r, s, nonce) for a Poly1305 MAC. 

132 

133 If nonce is ``None``, a new 16-byte nonce is generated. 

134 """ 

135 

136 if len(key) != 32: 

137 raise ValueError("Poly1305 with AES requires a 32-byte key") 

138 

139 if nonce is None: 

140 nonce = get_random_bytes(16) 

141 elif len(nonce) != 16: 

142 raise ValueError("Poly1305 with AES requires a 16-byte nonce") 

143 

144 s = new(key[:16], MODE_ECB).encrypt(nonce) 

145 return key[16:], s, nonce 

146 

147 

148@overload 

149def new(key: Buffer, mode: Literal[1], use_aesni: bool = ...) -> EcbMode: ... 

150 

151 

152@overload 

153def new(key: Buffer, mode: Literal[2], iv: Optional[Buffer] = ..., use_aesni: bool = ...) -> CbcMode: ... 

154 

155 

156@overload 

157def new(key: Buffer, mode: Literal[2], IV: Optional[Buffer] = ..., use_aesni: bool = ...) -> CbcMode: ... 

158 

159 

160@overload 

161def new( 

162 key: Buffer, mode: Literal[3], iv: Optional[Buffer] = ..., segment_size: int = ..., use_aesni: bool = ... 

163) -> CfbMode: ... 

164 

165 

166@overload 

167def new( 

168 key: Buffer, mode: Literal[3], IV: Optional[Buffer] = ..., segment_size: int = ..., use_aesni: bool = ... 

169) -> CfbMode: ... 

170 

171 

172@overload 

173def new(key: Buffer, mode: Literal[5], iv: Optional[Buffer] = ..., use_aesni: bool = ...) -> OfbMode: ... 

174 

175 

176@overload 

177def new(key: Buffer, mode: Literal[5], IV: Optional[Buffer] = ..., use_aesni: bool = ...) -> OfbMode: ... 

178 

179 

180@overload 

181def new( 

182 key: Buffer, 

183 mode: Literal[6], 

184 nonce: Optional[Buffer] = ..., 

185 initial_value: Union[int, Buffer] = ..., 

186 counter: CounterParams = ..., 

187 use_aesni: bool = ..., 

188 threads: int = ..., 

189) -> CtrMode: ... 

190 

191 

192@overload 

193def new(key: Buffer, mode: Literal[7], iv: Optional[Buffer] = ..., use_aesni: bool = ...) -> OpenPgpMode: ... 

194 

195 

196@overload 

197def new(key: Buffer, mode: Literal[7], IV: Optional[Buffer] = ..., use_aesni: bool = ...) -> OpenPgpMode: ... 

198 

199 

200@overload 

201def new( 

202 key: Buffer, 

203 mode: Literal[8], 

204 nonce: Optional[Buffer] = ..., 

205 mac_len: int = ..., 

206 assoc_len: int = ..., 

207 use_aesni: bool = ..., 

208) -> CcmMode: ... 

209 

210 

211@overload 

212def new( 

213 key: Buffer, mode: Literal[9], nonce: Optional[Buffer] = ..., mac_len: int = ..., use_aesni: bool = ... 

214) -> EaxMode: ... 

215 

216 

217@overload 

218def new(key: Buffer, mode: Literal[10], nonce: Optional[Buffer] = ..., use_aesni: bool = ...) -> SivMode: ... 

219 

220 

221@overload 

222def new( 

223 key: Buffer, 

224 mode: Literal[11], 

225 nonce: Optional[Buffer] = ..., 

226 mac_len: int = ..., 

227 use_aesni: bool = ..., 

228 threads: int = ..., 

229) -> GcmMode: ... 

230 

231 

232@overload 

233def new( 

234 key: Buffer, 

235 mode: Literal[12], 

236 nonce: Optional[Buffer] = ..., 

237 mac_len: int = ..., 

238 use_aesni: bool = ..., 

239 threads: int = ..., 

240) -> OcbMode: ... 

241 

242 

243@overload 

244def new(key: Buffer, mode: Literal[13], use_aesni: bool = ...) -> KWMode: ... 

245 

246 

247@overload 

248def new(key: Buffer, mode: Literal[14], use_aesni: bool = ...) -> KWPMode: ... 

249 

250 

251def new(key: Buffer, mode: int, *args: Any, **kwargs: Any) -> Any: 

252 """Create a new AES cipher. 

253 

254 Args: 

255 key(bytes/bytearray/memoryview): 

256 The secret key to use in the symmetric cipher. 

257 

258 It must be 16 (*AES-128)*, 24 (*AES-192*) or 32 (*AES-256*) bytes long. 

259 

260 For ``MODE_SIV`` only, it doubles to 32, 48, or 64 bytes. 

261 mode (a ``MODE_*`` constant): 

262 The chaining mode to use for encryption or decryption. 

263 If in doubt, use ``MODE_EAX``. 

264 

265 Keyword Args: 

266 iv (bytes/bytearray/memoryview): 

267 (Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``, 

268 and ``MODE_OPENPGP`` modes). 

269 

270 The initialization vector to use for encryption or decryption. 

271 

272 For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 16 bytes long. 

273 

274 For ``MODE_OPENPGP`` mode only, 

275 it must be 16 bytes long for encryption 

276 and 18 bytes for decryption (in the latter case, it is 

277 actually the *encrypted* IV which was prefixed to the ciphertext). 

278 

279 If not provided, a random byte string is generated (you must then 

280 read its value with the :attr:`iv` attribute). 

281 

282 nonce (bytes/bytearray/memoryview): 

283 (Only applicable for ``MODE_CCM``, ``MODE_EAX``, ``MODE_GCM``, 

284 ``MODE_SIV``, ``MODE_OCB``, and ``MODE_CTR``). 

285 

286 A value that must never be reused for any other encryption done 

287 with this key (except possibly for ``MODE_SIV``, see below). 

288 

289 For ``MODE_EAX``, ``MODE_GCM`` and ``MODE_SIV`` there are no 

290 restrictions on its length (recommended: **16** bytes). 

291 

292 For ``MODE_CCM``, its length must be in the range **[7..13]**. 

293 Bear in mind that with CCM there is a trade-off between nonce 

294 length and maximum message size. Recommendation: **11** bytes. 

295 

296 For ``MODE_OCB``, its length must be in the range **[1..15]** 

297 (recommended: **15**). 

298 

299 For ``MODE_CTR``, its length must be in the range **[0..15]** 

300 (recommended: **8**). 

301 

302 For ``MODE_SIV``, the nonce is optional, if it is not specified, 

303 then no nonce is being used, which renders the encryption 

304 deterministic. 

305 

306 If not provided, for modes other than ``MODE_SIV``, a random 

307 byte string of the recommended length is used (you must then 

308 read its value with the :attr:`nonce` attribute). 

309 

310 segment_size (integer): 

311 (Only ``MODE_CFB``).The number of **bits** the plaintext and ciphertext 

312 are segmented in. It must be a multiple of 8. 

313 If not specified, it will be assumed to be 8. 

314 

315 mac_len (integer): 

316 (Only ``MODE_EAX``, ``MODE_GCM``, ``MODE_OCB``, ``MODE_CCM``) 

317 Length of the authentication tag, in bytes. 

318 

319 It must be even and in the range **[4..16]**. 

320 The recommended value (and the default, if not specified) is **16**. 

321 

322 msg_len (integer): 

323 (Only ``MODE_CCM``). Length of the message to (de)cipher. 

324 If not specified, ``encrypt`` must be called with the entire message. 

325 Similarly, ``decrypt`` can only be called once. 

326 

327 assoc_len (integer): 

328 (Only ``MODE_CCM``). Length of the associated data. 

329 If not specified, all associated data is buffered internally, 

330 which may represent a problem for very large messages. 

331 

332 initial_value (integer or bytes/bytearray/memoryview): 

333 (Only ``MODE_CTR``). 

334 The initial value for the counter. If not present, the cipher will 

335 start counting from 0. The value is incremented by one for each block. 

336 The counter number is encoded in big endian mode. 

337 

338 counter (object): 

339 (Only ``MODE_CTR``). 

340 Instance of ``Crypto.Util.Counter``, which allows full customization 

341 of the counter block. This parameter is incompatible to both ``nonce`` 

342 and ``initial_value``. 

343 

344 use_aesni: (boolean): 

345 Use Intel AES-NI hardware extensions (default: use if available). 

346 

347 threads (integer): 

348 (Only ``MODE_CTR``, ``MODE_GCM`` and ``MODE_OCB``). 

349 The maximum number of threads used to encrypt or decrypt long data 

350 (default: 1, no extra threads). 

351 Use 0 for as many threads as the CPU cores available 

352 to this process. 

353 Each thread processes at least 1 MiB of a single call to 

354 ``encrypt()`` or ``decrypt()``: with shorter inputs, 

355 fewer threads are used, or none at all. 

356 For best results, do not exceed the number of physical cores. 

357 The output does not depend on the number of threads. 

358 

359 Returns: 

360 an AES object, of the applicable mode. 

361 """ 

362 

363 kwargs["add_aes_modes"] = True 

364 return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs) 

365 

366 

367# Size of a data block (in bytes) 

368block_size: int = 16 

369# Size of a key (in bytes) 

370key_size: tuple[int, int, int] = (16, 24, 32)