|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import sys |
|
|
|
from Crypto.Cipher import _create_cipher |
|
from Crypto.Util._raw_api import (load_pycryptodome_raw_lib, |
|
VoidPointer, SmartPointer, |
|
c_size_t, c_uint8_ptr) |
|
|
|
from Crypto.Util import _cpu_features |
|
from Crypto.Random import get_random_bytes |
|
|
|
MODE_ECB = 1 |
|
MODE_CBC = 2 |
|
MODE_CFB = 3 |
|
MODE_OFB = 5 |
|
MODE_CTR = 6 |
|
MODE_OPENPGP = 7 |
|
MODE_CCM = 8 |
|
MODE_EAX = 9 |
|
MODE_SIV = 10 |
|
MODE_GCM = 11 |
|
MODE_OCB = 12 |
|
|
|
|
|
_cproto = """ |
|
int AES_start_operation(const uint8_t key[], |
|
size_t key_len, |
|
void **pResult); |
|
int AES_encrypt(const void *state, |
|
const uint8_t *in, |
|
uint8_t *out, |
|
size_t data_len); |
|
int AES_decrypt(const void *state, |
|
const uint8_t *in, |
|
uint8_t *out, |
|
size_t data_len); |
|
int AES_stop_operation(void *state); |
|
""" |
|
|
|
|
|
|
|
_raw_aes_lib = load_pycryptodome_raw_lib("Crypto.Cipher._raw_aes", |
|
_cproto) |
|
|
|
|
|
try: |
|
_raw_aesni_lib = None |
|
if _cpu_features.have_aes_ni(): |
|
_raw_aesni_lib = load_pycryptodome_raw_lib("Crypto.Cipher._raw_aesni", |
|
_cproto.replace("AES", |
|
"AESNI")) |
|
|
|
except OSError: |
|
pass |
|
|
|
|
|
def _create_base_cipher(dict_parameters): |
|
"""This method instantiates and returns a handle to a low-level |
|
base cipher. It will absorb named parameters in the process.""" |
|
|
|
use_aesni = dict_parameters.pop("use_aesni", True) |
|
|
|
try: |
|
key = dict_parameters.pop("key") |
|
except KeyError: |
|
raise TypeError("Missing 'key' parameter") |
|
|
|
if len(key) not in key_size: |
|
raise ValueError("Incorrect AES key length (%d bytes)" % len(key)) |
|
|
|
if use_aesni and _raw_aesni_lib: |
|
start_operation = _raw_aesni_lib.AESNI_start_operation |
|
stop_operation = _raw_aesni_lib.AESNI_stop_operation |
|
else: |
|
start_operation = _raw_aes_lib.AES_start_operation |
|
stop_operation = _raw_aes_lib.AES_stop_operation |
|
|
|
cipher = VoidPointer() |
|
result = start_operation(c_uint8_ptr(key), |
|
c_size_t(len(key)), |
|
cipher.address_of()) |
|
if result: |
|
raise ValueError("Error %X while instantiating the AES cipher" |
|
% result) |
|
return SmartPointer(cipher.get(), stop_operation) |
|
|
|
|
|
def _derive_Poly1305_key_pair(key, nonce): |
|
"""Derive a tuple (r, s, nonce) for a Poly1305 MAC. |
|
|
|
If nonce is ``None``, a new 16-byte nonce is generated. |
|
""" |
|
|
|
if len(key) != 32: |
|
raise ValueError("Poly1305 with AES requires a 32-byte key") |
|
|
|
if nonce is None: |
|
nonce = get_random_bytes(16) |
|
elif len(nonce) != 16: |
|
raise ValueError("Poly1305 with AES requires a 16-byte nonce") |
|
|
|
s = new(key[:16], MODE_ECB).encrypt(nonce) |
|
return key[16:], s, nonce |
|
|
|
|
|
def new(key, mode, *args, **kwargs): |
|
"""Create a new AES cipher. |
|
|
|
Args: |
|
key(bytes/bytearray/memoryview): |
|
The secret key to use in the symmetric cipher. |
|
|
|
It must be 16 (*AES-128)*, 24 (*AES-192*) or 32 (*AES-256*) bytes long. |
|
|
|
For ``MODE_SIV`` only, it doubles to 32, 48, or 64 bytes. |
|
mode (a ``MODE_*`` constant): |
|
The chaining mode to use for encryption or decryption. |
|
If in doubt, use ``MODE_EAX``. |
|
|
|
Keyword Args: |
|
iv (bytes/bytearray/memoryview): |
|
(Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``, |
|
and ``MODE_OPENPGP`` modes). |
|
|
|
The initialization vector to use for encryption or decryption. |
|
|
|
For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 16 bytes long. |
|
|
|
For ``MODE_OPENPGP`` mode only, |
|
it must be 16 bytes long for encryption |
|
and 18 bytes for decryption (in the latter case, it is |
|
actually the *encrypted* IV which was prefixed to the ciphertext). |
|
|
|
If not provided, a random byte string is generated (you must then |
|
read its value with the :attr:`iv` attribute). |
|
|
|
nonce (bytes/bytearray/memoryview): |
|
(Only applicable for ``MODE_CCM``, ``MODE_EAX``, ``MODE_GCM``, |
|
``MODE_SIV``, ``MODE_OCB``, and ``MODE_CTR``). |
|
|
|
A value that must never be reused for any other encryption done |
|
with this key (except possibly for ``MODE_SIV``, see below). |
|
|
|
For ``MODE_EAX``, ``MODE_GCM`` and ``MODE_SIV`` there are no |
|
restrictions on its length (recommended: **16** bytes). |
|
|
|
For ``MODE_CCM``, its length must be in the range **[7..13]**. |
|
Bear in mind that with CCM there is a trade-off between nonce |
|
length and maximum message size. Recommendation: **11** bytes. |
|
|
|
For ``MODE_OCB``, its length must be in the range **[1..15]** |
|
(recommended: **15**). |
|
|
|
For ``MODE_CTR``, its length must be in the range **[0..15]** |
|
(recommended: **8**). |
|
|
|
For ``MODE_SIV``, the nonce is optional, if it is not specified, |
|
then no nonce is being used, which renders the encryption |
|
deterministic. |
|
|
|
If not provided, for modes other than ``MODE_SIV``, a random |
|
byte string of the recommended length is used (you must then |
|
read its value with the :attr:`nonce` attribute). |
|
|
|
segment_size (integer): |
|
(Only ``MODE_CFB``).The number of **bits** the plaintext and ciphertext |
|
are segmented in. It must be a multiple of 8. |
|
If not specified, it will be assumed to be 8. |
|
|
|
mac_len (integer): |
|
(Only ``MODE_EAX``, ``MODE_GCM``, ``MODE_OCB``, ``MODE_CCM``) |
|
Length of the authentication tag, in bytes. |
|
|
|
It must be even and in the range **[4..16]**. |
|
The recommended value (and the default, if not specified) is **16**. |
|
|
|
msg_len (integer): |
|
(Only ``MODE_CCM``). Length of the message to (de)cipher. |
|
If not specified, ``encrypt`` must be called with the entire message. |
|
Similarly, ``decrypt`` can only be called once. |
|
|
|
assoc_len (integer): |
|
(Only ``MODE_CCM``). Length of the associated data. |
|
If not specified, all associated data is buffered internally, |
|
which may represent a problem for very large messages. |
|
|
|
initial_value (integer or bytes/bytearray/memoryview): |
|
(Only ``MODE_CTR``). |
|
The initial value for the counter. If not present, the cipher will |
|
start counting from 0. The value is incremented by one for each block. |
|
The counter number is encoded in big endian mode. |
|
|
|
counter (object): |
|
(Only ``MODE_CTR``). |
|
Instance of ``Crypto.Util.Counter``, which allows full customization |
|
of the counter block. This parameter is incompatible to both ``nonce`` |
|
and ``initial_value``. |
|
|
|
use_aesni: (boolean): |
|
Use Intel AES-NI hardware extensions (default: use if available). |
|
|
|
Returns: |
|
an AES object, of the applicable mode. |
|
""" |
|
|
|
kwargs["add_aes_modes"] = True |
|
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs) |
|
|
|
|
|
|
|
block_size = 16 |
|
|
|
key_size = (16, 24, 32) |
|
|