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
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
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# ===================================================================
22from __future__ import annotations
24import sys
25from typing import TYPE_CHECKING, Any, Literal, Optional, Union, overload
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)
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
54Buffer = Union[bytes, bytearray, memoryview]
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`)
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 """
86# Load portable AES
87_raw_aes_lib = load_pycryptodome_raw_lib("Crypto.Cipher._raw_aes", _cproto)
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
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."""
105 use_aesni = dict_parameters.pop("use_aesni", True)
107 try:
108 key = dict_parameters.pop("key")
109 except KeyError:
110 raise TypeError("Missing 'key' parameter")
112 if len(key) not in key_size:
113 raise ValueError("Incorrect AES key length (%d bytes)" % len(key))
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
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)
130def _derive_Poly1305_key_pair(key, nonce):
131 """Derive a tuple (r, s, nonce) for a Poly1305 MAC.
133 If nonce is ``None``, a new 16-byte nonce is generated.
134 """
136 if len(key) != 32:
137 raise ValueError("Poly1305 with AES requires a 32-byte key")
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")
144 s = new(key[:16], MODE_ECB).encrypt(nonce)
145 return key[16:], s, nonce
148@overload
149def new(key: Buffer, mode: Literal[1], use_aesni: bool = ...) -> EcbMode: ...
152@overload
153def new(key: Buffer, mode: Literal[2], iv: Optional[Buffer] = ..., use_aesni: bool = ...) -> CbcMode: ...
156@overload
157def new(key: Buffer, mode: Literal[2], IV: Optional[Buffer] = ..., use_aesni: bool = ...) -> CbcMode: ...
160@overload
161def new(
162 key: Buffer, mode: Literal[3], iv: Optional[Buffer] = ..., segment_size: int = ..., use_aesni: bool = ...
163) -> CfbMode: ...
166@overload
167def new(
168 key: Buffer, mode: Literal[3], IV: Optional[Buffer] = ..., segment_size: int = ..., use_aesni: bool = ...
169) -> CfbMode: ...
172@overload
173def new(key: Buffer, mode: Literal[5], iv: Optional[Buffer] = ..., use_aesni: bool = ...) -> OfbMode: ...
176@overload
177def new(key: Buffer, mode: Literal[5], IV: Optional[Buffer] = ..., use_aesni: bool = ...) -> OfbMode: ...
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: ...
192@overload
193def new(key: Buffer, mode: Literal[7], iv: Optional[Buffer] = ..., use_aesni: bool = ...) -> OpenPgpMode: ...
196@overload
197def new(key: Buffer, mode: Literal[7], IV: Optional[Buffer] = ..., use_aesni: bool = ...) -> OpenPgpMode: ...
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: ...
211@overload
212def new(
213 key: Buffer, mode: Literal[9], nonce: Optional[Buffer] = ..., mac_len: int = ..., use_aesni: bool = ...
214) -> EaxMode: ...
217@overload
218def new(key: Buffer, mode: Literal[10], nonce: Optional[Buffer] = ..., use_aesni: bool = ...) -> SivMode: ...
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: ...
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: ...
243@overload
244def new(key: Buffer, mode: Literal[13], use_aesni: bool = ...) -> KWMode: ...
247@overload
248def new(key: Buffer, mode: Literal[14], use_aesni: bool = ...) -> KWPMode: ...
251def new(key: Buffer, mode: int, *args: Any, **kwargs: Any) -> Any:
252 """Create a new AES cipher.
254 Args:
255 key(bytes/bytearray/memoryview):
256 The secret key to use in the symmetric cipher.
258 It must be 16 (*AES-128)*, 24 (*AES-192*) or 32 (*AES-256*) bytes long.
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``.
265 Keyword Args:
266 iv (bytes/bytearray/memoryview):
267 (Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``,
268 and ``MODE_OPENPGP`` modes).
270 The initialization vector to use for encryption or decryption.
272 For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 16 bytes long.
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).
279 If not provided, a random byte string is generated (you must then
280 read its value with the :attr:`iv` attribute).
282 nonce (bytes/bytearray/memoryview):
283 (Only applicable for ``MODE_CCM``, ``MODE_EAX``, ``MODE_GCM``,
284 ``MODE_SIV``, ``MODE_OCB``, and ``MODE_CTR``).
286 A value that must never be reused for any other encryption done
287 with this key (except possibly for ``MODE_SIV``, see below).
289 For ``MODE_EAX``, ``MODE_GCM`` and ``MODE_SIV`` there are no
290 restrictions on its length (recommended: **16** bytes).
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.
296 For ``MODE_OCB``, its length must be in the range **[1..15]**
297 (recommended: **15**).
299 For ``MODE_CTR``, its length must be in the range **[0..15]**
300 (recommended: **8**).
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.
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).
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.
315 mac_len (integer):
316 (Only ``MODE_EAX``, ``MODE_GCM``, ``MODE_OCB``, ``MODE_CCM``)
317 Length of the authentication tag, in bytes.
319 It must be even and in the range **[4..16]**.
320 The recommended value (and the default, if not specified) is **16**.
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.
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.
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.
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``.
344 use_aesni: (boolean):
345 Use Intel AES-NI hardware extensions (default: use if available).
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.
359 Returns:
360 an AES object, of the applicable mode.
361 """
363 kwargs["add_aes_modes"] = True
364 return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
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)