123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- # -*- coding: utf-8 -*-
- #
- # Cipher/AES.py : AES
- #
- # ===================================================================
- # The contents of this file are dedicated to the public domain. To
- # the extent that dedication to the public domain is not available,
- # everyone is granted a worldwide, perpetual, royalty-free,
- # non-exclusive license to exercise all rights associated with the
- # contents of this file for any purpose whatsoever.
- # No rights are reserved.
- #
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- # SOFTWARE.
- # ===================================================================
- """
- Module's constants for the modes of operation supported with AES:
- :var MODE_ECB: :ref:`Electronic Code Book (ECB) <ecb_mode>`
- :var MODE_CBC: :ref:`Cipher-Block Chaining (CBC) <cbc_mode>`
- :var MODE_CFB: :ref:`Cipher FeedBack (CFB) <cfb_mode>`
- :var MODE_OFB: :ref:`Output FeedBack (OFB) <ofb_mode>`
- :var MODE_CTR: :ref:`CounTer Mode (CTR) <ctr_mode>`
- :var MODE_OPENPGP: :ref:`OpenPGP Mode <openpgp_mode>`
- :var MODE_CCM: :ref:`Counter with CBC-MAC (CCM) Mode <ccm_mode>`
- :var MODE_EAX: :ref:`EAX Mode <eax_mode>`
- :var MODE_GCM: :ref:`Galois Counter Mode (GCM) <gcm_mode>`
- :var MODE_SIV: :ref:`Syntethic Initialization Vector (SIV) <siv_mode>`
- :var MODE_OCB: :ref:`Offset Code Book (OCB) <ocb_mode>`
- """
- import sys
- from Cryptodome.Cipher import _create_cipher
- from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib,
- VoidPointer, SmartPointer,
- c_size_t, c_uint8_ptr)
- from Cryptodome.Util import _cpu_features
- from Cryptodome.Random import get_random_bytes
- _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);
- """
- # Load portable AES
- _raw_aes_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_aes",
- _cproto)
- # Try to load AES with AES NI instructions
- try:
- _raw_aesni_lib = None
- if _cpu_features.have_aes_ni():
- _raw_aesni_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_aesni",
- _cproto.replace("AES",
- "AESNI"))
- # _raw_aesni may not have been compiled in
- 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.
- :param key:
- The secret key to use in the symmetric cipher.
- It must be 16, 24 or 32 bytes long (respectively for *AES-128*,
- *AES-192* or *AES-256*).
- For ``MODE_SIV`` only, it doubles to 32, 48, or 64 bytes.
- :type key: bytes/bytearray/memoryview
- :param mode:
- The chaining mode to use for encryption or decryption.
- If in doubt, use ``MODE_EAX``.
- :type mode: One of the supported ``MODE_*`` constants
- :Keyword Arguments:
- * **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*) --
- Instance of ``Cryptodome.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).
- :Return: an AES object, of the applicable mode.
- """
- kwargs["add_aes_modes"] = True
- return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
- 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
- # Size of a data block (in bytes)
- block_size = 16
- # Size of a key (in bytes)
- key_size = (16, 24, 32)
|