|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +# |
| 3 | +# Cipher/AES.py : AES |
| 4 | +# |
| 5 | +# =================================================================== |
| 6 | +# The contents of this file are dedicated to the public domain. To |
| 7 | +# the extent that dedication to the public domain is not available, |
| 8 | +# everyone is granted a worldwide, perpetual, royalty-free, |
| 9 | +# non-exclusive license to exercise all rights associated with the |
| 10 | +# contents of this file for any purpose whatsoever. |
| 11 | +# No rights are reserved. |
| 12 | +# |
| 13 | +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 14 | +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 15 | +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 16 | +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
| 17 | +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
| 18 | +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 19 | +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 20 | +# SOFTWARE. |
| 21 | +# =================================================================== |
| 22 | +""" |
| 23 | +Module's constants for the modes of operation supported with AES: |
| 24 | +
|
| 25 | +:var MODE_ECB: :ref:`Electronic Code Book (ECB) <ecb_mode>` |
| 26 | +:var MODE_CBC: :ref:`Cipher-Block Chaining (CBC) <cbc_mode>` |
| 27 | +:var MODE_CFB: :ref:`Cipher FeedBack (CFB) <cfb_mode>` |
| 28 | +:var MODE_OFB: :ref:`Output FeedBack (OFB) <ofb_mode>` |
| 29 | +:var MODE_CTR: :ref:`CounTer Mode (CTR) <ctr_mode>` |
| 30 | +:var MODE_OPENPGP: :ref:`OpenPGP Mode <openpgp_mode>` |
| 31 | +:var MODE_CCM: :ref:`Counter with CBC-MAC (CCM) Mode <ccm_mode>` |
| 32 | +:var MODE_EAX: :ref:`EAX Mode <eax_mode>` |
| 33 | +:var MODE_GCM: :ref:`Galois Counter Mode (GCM) <gcm_mode>` |
| 34 | +:var MODE_SIV: :ref:`Syntethic Initialization Vector (SIV) <siv_mode>` |
| 35 | +:var MODE_OCB: :ref:`Offset Code Book (OCB) <ocb_mode>` |
| 36 | +""" |
| 37 | + |
| 38 | +import sys |
| 39 | + |
| 40 | +from Cryptodome.Cipher import _create_cipher |
| 41 | +from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, |
| 42 | + VoidPointer, SmartPointer, |
| 43 | + c_size_t, c_uint8_ptr) |
| 44 | + |
| 45 | +from Cryptodome.Util import _cpu_features |
| 46 | +from Cryptodome.Random import get_random_bytes |
| 47 | + |
| 48 | + |
| 49 | +_cproto = """ |
| 50 | + int AES_start_operation(const uint8_t key[], |
| 51 | + size_t key_len, |
| 52 | + void **pResult); |
| 53 | + int AES_encrypt(const void *state, |
| 54 | + const uint8_t *in, |
| 55 | + uint8_t *out, |
| 56 | + size_t data_len); |
| 57 | + int AES_decrypt(const void *state, |
| 58 | + const uint8_t *in, |
| 59 | + uint8_t *out, |
| 60 | + size_t data_len); |
| 61 | + int AES_stop_operation(void *state); |
| 62 | + """ |
| 63 | + |
| 64 | + |
| 65 | +# Load portable AES |
| 66 | +_raw_aes_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_aes", |
| 67 | + _cproto) |
| 68 | + |
| 69 | +# Try to load AES with AES NI instructions |
| 70 | +try: |
| 71 | + _raw_aesni_lib = None |
| 72 | + if _cpu_features.have_aes_ni(): |
| 73 | + _raw_aesni_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_aesni", |
| 74 | + _cproto.replace("AES", |
| 75 | + "AESNI")) |
| 76 | +# _raw_aesni may not have been compiled in |
| 77 | +except OSError: |
| 78 | + pass |
| 79 | + |
| 80 | + |
| 81 | +def _create_base_cipher(dict_parameters): |
| 82 | + """This method instantiates and returns a handle to a low-level |
| 83 | + base cipher. It will absorb named parameters in the process.""" |
| 84 | + |
| 85 | + use_aesni = dict_parameters.pop("use_aesni", True) |
| 86 | + |
| 87 | + try: |
| 88 | + key = dict_parameters.pop("key") |
| 89 | + except KeyError: |
| 90 | + raise TypeError("Missing 'key' parameter") |
| 91 | + |
| 92 | + if len(key) not in key_size: |
| 93 | + raise ValueError("Incorrect AES key length (%d bytes)" % len(key)) |
| 94 | + |
| 95 | + if use_aesni and _raw_aesni_lib: |
| 96 | + start_operation = _raw_aesni_lib.AESNI_start_operation |
| 97 | + stop_operation = _raw_aesni_lib.AESNI_stop_operation |
| 98 | + else: |
| 99 | + start_operation = _raw_aes_lib.AES_start_operation |
| 100 | + stop_operation = _raw_aes_lib.AES_stop_operation |
| 101 | + |
| 102 | + cipher = VoidPointer() |
| 103 | + result = start_operation(c_uint8_ptr(key), |
| 104 | + c_size_t(len(key)), |
| 105 | + cipher.address_of()) |
| 106 | + if result: |
| 107 | + raise ValueError("Error %X while instantiating the AES cipher" |
| 108 | + % result) |
| 109 | + return SmartPointer(cipher.get(), stop_operation) |
| 110 | + |
| 111 | + |
| 112 | +def _derive_Poly1305_key_pair(key, nonce): |
| 113 | + """Derive a tuple (r, s, nonce) for a Poly1305 MAC. |
| 114 | + |
| 115 | + If nonce is ``None``, a new 16-byte nonce is generated. |
| 116 | + """ |
| 117 | + |
| 118 | + if len(key) != 32: |
| 119 | + raise ValueError("Poly1305 with AES requires a 32-byte key") |
| 120 | + |
| 121 | + if nonce is None: |
| 122 | + nonce = get_random_bytes(16) |
| 123 | + elif len(nonce) != 16: |
| 124 | + raise ValueError("Poly1305 with AES requires a 16-byte nonce") |
| 125 | + |
| 126 | + s = new(key[:16], MODE_ECB).encrypt(nonce) |
| 127 | + return key[16:], s, nonce |
| 128 | + |
| 129 | + |
| 130 | +def new(key, mode, *args, **kwargs): |
| 131 | + """Create a new AES cipher. |
| 132 | +
|
| 133 | + :param key: |
| 134 | + The secret key to use in the symmetric cipher. |
| 135 | +
|
| 136 | + It must be 16, 24 or 32 bytes long (respectively for *AES-128*, |
| 137 | + *AES-192* or *AES-256*). |
| 138 | +
|
| 139 | + For ``MODE_SIV`` only, it doubles to 32, 48, or 64 bytes. |
| 140 | + :type key: bytes/bytearray/memoryview |
| 141 | +
|
| 142 | + :param mode: |
| 143 | + The chaining mode to use for encryption or decryption. |
| 144 | + If in doubt, use ``MODE_EAX``. |
| 145 | + :type mode: One of the supported ``MODE_*`` constants |
| 146 | +
|
| 147 | + :Keyword Arguments: |
| 148 | + * **iv** (*bytes*, *bytearray*, *memoryview*) -- |
| 149 | + (Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``, |
| 150 | + and ``MODE_OPENPGP`` modes). |
| 151 | +
|
| 152 | + The initialization vector to use for encryption or decryption. |
| 153 | +
|
| 154 | + For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 16 bytes long. |
| 155 | +
|
| 156 | + For ``MODE_OPENPGP`` mode only, |
| 157 | + it must be 16 bytes long for encryption |
| 158 | + and 18 bytes for decryption (in the latter case, it is |
| 159 | + actually the *encrypted* IV which was prefixed to the ciphertext). |
| 160 | +
|
| 161 | + If not provided, a random byte string is generated (you must then |
| 162 | + read its value with the :attr:`iv` attribute). |
| 163 | +
|
| 164 | + * **nonce** (*bytes*, *bytearray*, *memoryview*) -- |
| 165 | + (Only applicable for ``MODE_CCM``, ``MODE_EAX``, ``MODE_GCM``, |
| 166 | + ``MODE_SIV``, ``MODE_OCB``, and ``MODE_CTR``). |
| 167 | +
|
| 168 | + A value that must never be reused for any other encryption done |
| 169 | + with this key (except possibly for ``MODE_SIV``, see below). |
| 170 | +
|
| 171 | + For ``MODE_EAX``, ``MODE_GCM`` and ``MODE_SIV`` there are no |
| 172 | + restrictions on its length (recommended: **16** bytes). |
| 173 | +
|
| 174 | + For ``MODE_CCM``, its length must be in the range **[7..13]**. |
| 175 | + Bear in mind that with CCM there is a trade-off between nonce |
| 176 | + length and maximum message size. Recommendation: **11** bytes. |
| 177 | +
|
| 178 | + For ``MODE_OCB``, its length must be in the range **[1..15]** |
| 179 | + (recommended: **15**). |
| 180 | +
|
| 181 | + For ``MODE_CTR``, its length must be in the range **[0..15]** |
| 182 | + (recommended: **8**). |
| 183 | + |
| 184 | + For ``MODE_SIV``, the nonce is optional, if it is not specified, |
| 185 | + then no nonce is being used, which renders the encryption |
| 186 | + deterministic. |
| 187 | +
|
| 188 | + If not provided, for modes other than ``MODE_SIV```, a random |
| 189 | + byte string of the recommended length is used (you must then |
| 190 | + read its value with the :attr:`nonce` attribute). |
| 191 | +
|
| 192 | + * **segment_size** (*integer*) -- |
| 193 | + (Only ``MODE_CFB``).The number of **bits** the plaintext and ciphertext |
| 194 | + are segmented in. It must be a multiple of 8. |
| 195 | + If not specified, it will be assumed to be 8. |
| 196 | +
|
| 197 | + * **mac_len** : (*integer*) -- |
| 198 | + (Only ``MODE_EAX``, ``MODE_GCM``, ``MODE_OCB``, ``MODE_CCM``) |
| 199 | + Length of the authentication tag, in bytes. |
| 200 | +
|
| 201 | + It must be even and in the range **[4..16]**. |
| 202 | + The recommended value (and the default, if not specified) is **16**. |
| 203 | +
|
| 204 | + * **msg_len** : (*integer*) -- |
| 205 | + (Only ``MODE_CCM``). Length of the message to (de)cipher. |
| 206 | + If not specified, ``encrypt`` must be called with the entire message. |
| 207 | + Similarly, ``decrypt`` can only be called once. |
| 208 | +
|
| 209 | + * **assoc_len** : (*integer*) -- |
| 210 | + (Only ``MODE_CCM``). Length of the associated data. |
| 211 | + If not specified, all associated data is buffered internally, |
| 212 | + which may represent a problem for very large messages. |
| 213 | +
|
| 214 | + * **initial_value** : (*integer* or *bytes/bytearray/memoryview*) -- |
| 215 | + (Only ``MODE_CTR``). |
| 216 | + The initial value for the counter. If not present, the cipher will |
| 217 | + start counting from 0. The value is incremented by one for each block. |
| 218 | + The counter number is encoded in big endian mode. |
| 219 | +
|
| 220 | + * **counter** : (*object*) -- |
| 221 | + Instance of ``Cryptodome.Util.Counter``, which allows full customization |
| 222 | + of the counter block. This parameter is incompatible to both ``nonce`` |
| 223 | + and ``initial_value``. |
| 224 | +
|
| 225 | + * **use_aesni** : (*boolean*) -- |
| 226 | + Use Intel AES-NI hardware extensions (default: use if available). |
| 227 | +
|
| 228 | + :Return: an AES object, of the applicable mode. |
| 229 | + """ |
| 230 | + |
| 231 | + kwargs["add_aes_modes"] = True |
| 232 | + return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs) |
| 233 | + |
| 234 | + |
| 235 | +MODE_ECB = 1 |
| 236 | +MODE_CBC = 2 |
| 237 | +MODE_CFB = 3 |
| 238 | +MODE_OFB = 5 |
| 239 | +MODE_CTR = 6 |
| 240 | +MODE_OPENPGP = 7 |
| 241 | +MODE_CCM = 8 |
| 242 | +MODE_EAX = 9 |
| 243 | +MODE_SIV = 10 |
| 244 | +MODE_GCM = 11 |
| 245 | +MODE_OCB = 12 |
| 246 | + |
| 247 | +# Size of a data block (in bytes) |
| 248 | +block_size = 16 |
| 249 | +# Size of a key (in bytes) |
| 250 | +key_size = (16, 24, 32) |
0 commit comments