aboutsummaryrefslogtreecommitdiff
path: root/frozen_deps/Cryptodome/Cipher
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2020-11-17 20:04:09 -0500
committerDeterminant <[email protected]>2020-11-17 20:04:09 -0500
commitc4d90bf4ea0c5b7a016028ed994de19638d3113b (patch)
tree693279a91311155f565e90ecd2d93bf701d6d4e9 /frozen_deps/Cryptodome/Cipher
parent3bef51eec2299403467e621ae660cef3f9256ac8 (diff)
support saving as a keystore file
Diffstat (limited to 'frozen_deps/Cryptodome/Cipher')
-rw-r--r--frozen_deps/Cryptodome/Cipher/AES.py250
-rw-r--r--frozen_deps/Cryptodome/Cipher/AES.pyi47
-rw-r--r--frozen_deps/Cryptodome/Cipher/ARC2.py175
-rw-r--r--frozen_deps/Cryptodome/Cipher/ARC2.pyi35
-rw-r--r--frozen_deps/Cryptodome/Cipher/ARC4.py137
-rw-r--r--frozen_deps/Cryptodome/Cipher/ARC4.pyi16
-rw-r--r--frozen_deps/Cryptodome/Cipher/Blowfish.py159
-rw-r--r--frozen_deps/Cryptodome/Cipher/Blowfish.pyi35
-rw-r--r--frozen_deps/Cryptodome/Cipher/CAST.py159
-rw-r--r--frozen_deps/Cryptodome/Cipher/CAST.pyi35
-rw-r--r--frozen_deps/Cryptodome/Cipher/ChaCha20.py286
-rw-r--r--frozen_deps/Cryptodome/Cipher/ChaCha20.pyi25
-rw-r--r--frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.py336
-rw-r--r--frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.pyi28
-rw-r--r--frozen_deps/Cryptodome/Cipher/DES.py158
-rw-r--r--frozen_deps/Cryptodome/Cipher/DES.pyi35
-rw-r--r--frozen_deps/Cryptodome/Cipher/DES3.py187
-rw-r--r--frozen_deps/Cryptodome/Cipher/DES3.pyi37
-rw-r--r--frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.py239
-rw-r--r--frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.pyi35
-rw-r--r--frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.py199
-rw-r--r--frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.pyi17
-rw-r--r--frozen_deps/Cryptodome/Cipher/Salsa20.py167
-rw-r--r--frozen_deps/Cryptodome/Cipher/Salsa20.pyi27
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.sobin0 -> 14354 bytes
-rw-r--r--frozen_deps/Cryptodome/Cipher/_EKSBlowfish.py131
-rw-r--r--frozen_deps/Cryptodome/Cipher/_EKSBlowfish.pyi15
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_Salsa20.cpython-38-x86_64-linux-gnu.sobin0 -> 21734 bytes
-rw-r--r--frozen_deps/Cryptodome/Cipher/__init__.py79
-rw-r--r--frozen_deps/Cryptodome/Cipher/__init__.pyi0
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_chacha20.cpython-38-x86_64-linux-gnu.sobin0 -> 25741 bytes
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_cbc.py293
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_cbc.pyi25
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_ccm.py650
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_ccm.pyi47
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_cfb.py293
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_cfb.pyi26
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_ctr.py393
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_ctr.pyi27
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_eax.py408
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_eax.pyi45
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_ecb.py218
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_ecb.pyi19
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_gcm.py620
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_gcm.pyi45
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_ocb.py525
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_ocb.pyi36
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_ofb.py282
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_ofb.pyi25
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_openpgp.py206
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_openpgp.pyi20
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_siv.py392
-rw-r--r--frozen_deps/Cryptodome/Cipher/_mode_siv.pyi38
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_aes.cpython-38-x86_64-linux-gnu.sobin0 -> 54112 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_aesni.cpython-38-x86_64-linux-gnu.sobin0 -> 52331 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_arc2.cpython-38-x86_64-linux-gnu.sobin0 -> 18917 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_blowfish.cpython-38-x86_64-linux-gnu.sobin0 -> 26938 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_cast.cpython-38-x86_64-linux-gnu.sobin0 -> 44422 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_cbc.cpython-38-x86_64-linux-gnu.sobin0 -> 17215 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_cfb.cpython-38-x86_64-linux-gnu.sobin0 -> 22696 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_ctr.cpython-38-x86_64-linux-gnu.sobin0 -> 23249 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_des.cpython-38-x86_64-linux-gnu.sobin0 -> 62525 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_des3.cpython-38-x86_64-linux-gnu.sobin0 -> 63370 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_ecb.cpython-38-x86_64-linux-gnu.sobin0 -> 10893 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_eksblowfish.cpython-38-x86_64-linux-gnu.sobin0 -> 58926 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_ocb.cpython-38-x86_64-linux-gnu.sobin0 -> 30281 bytes
-rwxr-xr-xfrozen_deps/Cryptodome/Cipher/_raw_ofb.cpython-38-x86_64-linux-gnu.sobin0 -> 14743 bytes
67 files changed, 7682 insertions, 0 deletions
diff --git a/frozen_deps/Cryptodome/Cipher/AES.py b/frozen_deps/Cryptodome/Cipher/AES.py
new file mode 100644
index 0000000..dd2671a
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/AES.py
@@ -0,0 +1,250 @@
+# -*- 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)
diff --git a/frozen_deps/Cryptodome/Cipher/AES.pyi b/frozen_deps/Cryptodome/Cipher/AES.pyi
new file mode 100644
index 0000000..c150efb
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/AES.pyi
@@ -0,0 +1,47 @@
+from typing import Union, Tuple, Optional, Dict
+
+from Cryptodome.Cipher._mode_ecb import EcbMode
+from Cryptodome.Cipher._mode_cbc import CbcMode
+from Cryptodome.Cipher._mode_cfb import CfbMode
+from Cryptodome.Cipher._mode_ofb import OfbMode
+from Cryptodome.Cipher._mode_ctr import CtrMode
+from Cryptodome.Cipher._mode_openpgp import OpenPgpMode
+from Cryptodome.Cipher._mode_ccm import CcmMode
+from Cryptodome.Cipher._mode_eax import EaxMode
+from Cryptodome.Cipher._mode_gcm import GcmMode
+from Cryptodome.Cipher._mode_siv import SivMode
+from Cryptodome.Cipher._mode_ocb import OcbMode
+
+AESMode = int
+
+MODE_ECB: AESMode
+MODE_CBC: AESMode
+MODE_CFB: AESMode
+MODE_OFB: AESMode
+MODE_CTR: AESMode
+MODE_OPENPGP: AESMode
+MODE_CCM: AESMode
+MODE_EAX: AESMode
+MODE_GCM: AESMode
+MODE_SIV: AESMode
+MODE_OCB: AESMode
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+def new(key: Buffer,
+ mode: AESMode,
+ iv : Buffer = ...,
+ IV : Buffer = ...,
+ nonce : Buffer = ...,
+ segment_size : int = ...,
+ mac_len : int = ...,
+ assoc_len : int = ...,
+ initial_value : Union[int, Buffer] = ...,
+ counter : Dict = ...,
+ use_aesni : bool = ...) -> \
+ Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode,
+ OpenPgpMode, CcmMode, EaxMode, GcmMode,
+ SivMode, OcbMode]: ...
+
+block_size: int
+key_size: Tuple[int, int, int]
diff --git a/frozen_deps/Cryptodome/Cipher/ARC2.py b/frozen_deps/Cryptodome/Cipher/ARC2.py
new file mode 100644
index 0000000..4dc1bb8
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/ARC2.py
@@ -0,0 +1,175 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/ARC2.py : ARC2.py
+#
+# ===================================================================
+# 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 ARC2:
+
+: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_EAX: :ref:`EAX Mode <eax_mode>`
+"""
+
+import sys
+
+from Cryptodome.Cipher import _create_cipher
+from Cryptodome.Util.py3compat import byte_string
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib,
+ VoidPointer, SmartPointer,
+ c_size_t, c_uint8_ptr)
+
+_raw_arc2_lib = load_pycryptodome_raw_lib(
+ "Cryptodome.Cipher._raw_arc2",
+ """
+ int ARC2_start_operation(const uint8_t key[],
+ size_t key_len,
+ size_t effective_key_len,
+ void **pResult);
+ int ARC2_encrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int ARC2_decrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int ARC2_stop_operation(void *state);
+ """
+ )
+
+
+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."""
+
+ try:
+ key = dict_parameters.pop("key")
+ except KeyError:
+ raise TypeError("Missing 'key' parameter")
+
+ effective_keylen = dict_parameters.pop("effective_keylen", 1024)
+
+ if len(key) not in key_size:
+ raise ValueError("Incorrect ARC2 key length (%d bytes)" % len(key))
+
+ if not (40 <= effective_keylen <= 1024):
+ raise ValueError("'effective_key_len' must be at least 40 and no larger than 1024 "
+ "(not %d)" % effective_keylen)
+
+ start_operation = _raw_arc2_lib.ARC2_start_operation
+ stop_operation = _raw_arc2_lib.ARC2_stop_operation
+
+ cipher = VoidPointer()
+ result = start_operation(c_uint8_ptr(key),
+ c_size_t(len(key)),
+ c_size_t(effective_keylen),
+ cipher.address_of())
+ if result:
+ raise ValueError("Error %X while instantiating the ARC2 cipher"
+ % result)
+
+ return SmartPointer(cipher.get(), stop_operation)
+
+
+def new(key, mode, *args, **kwargs):
+ """Create a new RC2 cipher.
+
+ :param key:
+ The secret key to use in the symmetric cipher.
+ Its length can vary from 5 to 128 bytes; the actual search space
+ (and the cipher strength) can be reduced with the ``effective_keylen`` parameter.
+ :type key: bytes, bytearray, memoryview
+
+ :param mode:
+ The chaining mode to use for encryption or decryption.
+ :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 8 bytes long.
+
+ For ``MODE_OPENPGP`` mode only,
+ it must be 8 bytes long for encryption
+ and 10 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_EAX`` and ``MODE_CTR``).
+
+ A value that must never be reused for any other encryption done
+ with this key.
+
+ For ``MODE_EAX`` there are no
+ restrictions on its length (recommended: **16** bytes).
+
+ For ``MODE_CTR``, its length must be in the range **[0..7]**.
+
+ If not provided for ``MODE_EAX``, a random byte string is generated (you
+ can read it back via the ``nonce`` attribute).
+
+ * **effective_keylen** (*integer*) --
+ Optional. Maximum strength in bits of the actual key used by the ARC2 algorithm.
+ If the supplied ``key`` parameter is longer (in bits) of the value specified
+ here, it will be weakened to match it.
+ If not specified, no limitation is applied.
+
+ * **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``)
+ Length of the authentication tag, in bytes.
+ It must be no longer than 8 (default).
+
+ * **initial_value** : (*integer*) --
+ (Only ``MODE_CTR``). The initial value for the counter within
+ the counter block. By default it is **0**.
+
+ :Return: an ARC2 object, of the applicable mode.
+ """
+
+ 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_EAX = 9
+
+# Size of a data block (in bytes)
+block_size = 8
+# Size of a key (in bytes)
+key_size = range(5, 128 + 1)
diff --git a/frozen_deps/Cryptodome/Cipher/ARC2.pyi b/frozen_deps/Cryptodome/Cipher/ARC2.pyi
new file mode 100644
index 0000000..9659c68
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/ARC2.pyi
@@ -0,0 +1,35 @@
+from typing import Union, Dict, Iterable
+
+from Cryptodome.Cipher._mode_ecb import EcbMode
+from Cryptodome.Cipher._mode_cbc import CbcMode
+from Cryptodome.Cipher._mode_cfb import CfbMode
+from Cryptodome.Cipher._mode_ofb import OfbMode
+from Cryptodome.Cipher._mode_ctr import CtrMode
+from Cryptodome.Cipher._mode_openpgp import OpenPgpMode
+from Cryptodome.Cipher._mode_eax import EaxMode
+
+ARC2Mode = int
+
+MODE_ECB: ARC2Mode
+MODE_CBC: ARC2Mode
+MODE_CFB: ARC2Mode
+MODE_OFB: ARC2Mode
+MODE_CTR: ARC2Mode
+MODE_OPENPGP: ARC2Mode
+MODE_EAX: ARC2Mode
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+def new(key: Buffer,
+ mode: ARC2Mode,
+ iv : Buffer = ...,
+ IV : Buffer = ...,
+ nonce : Buffer = ...,
+ segment_size : int = ...,
+ mac_len : int = ...,
+ initial_value : Union[int, Buffer] = ...,
+ counter : Dict = ...) -> \
+ Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode, OpenPgpMode]: ...
+
+block_size: int
+key_size: Iterable[int]
diff --git a/frozen_deps/Cryptodome/Cipher/ARC4.py b/frozen_deps/Cryptodome/Cipher/ARC4.py
new file mode 100644
index 0000000..e640e77
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/ARC4.py
@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/ARC4.py : ARC4
+#
+# ===================================================================
+# 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.
+# ===================================================================
+
+from Cryptodome.Util.py3compat import b
+
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer,
+ create_string_buffer, get_raw_buffer,
+ SmartPointer, c_size_t, c_uint8_ptr)
+
+
+_raw_arc4_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._ARC4", """
+ int ARC4_stream_encrypt(void *rc4State, const uint8_t in[],
+ uint8_t out[], size_t len);
+ int ARC4_stream_init(uint8_t *key, size_t keylen,
+ void **pRc4State);
+ int ARC4_stream_destroy(void *rc4State);
+ """)
+
+
+class ARC4Cipher:
+ """ARC4 cipher object. Do not create it directly. Use
+ :func:`Cryptodome.Cipher.ARC4.new` instead.
+ """
+
+ def __init__(self, key, *args, **kwargs):
+ """Initialize an ARC4 cipher object
+
+ See also `new()` at the module level."""
+
+ if len(args) > 0:
+ ndrop = args[0]
+ args = args[1:]
+ else:
+ ndrop = kwargs.pop('drop', 0)
+
+ if len(key) not in key_size:
+ raise ValueError("Incorrect ARC4 key length (%d bytes)" %
+ len(key))
+
+ self._state = VoidPointer()
+ result = _raw_arc4_lib.ARC4_stream_init(c_uint8_ptr(key),
+ c_size_t(len(key)),
+ self._state.address_of())
+ if result != 0:
+ raise ValueError("Error %d while creating the ARC4 cipher"
+ % result)
+ self._state = SmartPointer(self._state.get(),
+ _raw_arc4_lib.ARC4_stream_destroy)
+
+ if ndrop > 0:
+ # This is OK even if the cipher is used for decryption,
+ # since encrypt and decrypt are actually the same thing
+ # with ARC4.
+ self.encrypt(b'\x00' * ndrop)
+
+ self.block_size = 1
+ self.key_size = len(key)
+
+ def encrypt(self, plaintext):
+ """Encrypt a piece of data.
+
+ :param plaintext: The data to encrypt, of any size.
+ :type plaintext: bytes, bytearray, memoryview
+ :returns: the encrypted byte string, of equal length as the
+ plaintext.
+ """
+
+ ciphertext = create_string_buffer(len(plaintext))
+ result = _raw_arc4_lib.ARC4_stream_encrypt(self._state.get(),
+ c_uint8_ptr(plaintext),
+ ciphertext,
+ c_size_t(len(plaintext)))
+ if result:
+ raise ValueError("Error %d while encrypting with RC4" % result)
+ return get_raw_buffer(ciphertext)
+
+ def decrypt(self, ciphertext):
+ """Decrypt a piece of data.
+
+ :param ciphertext: The data to decrypt, of any size.
+ :type ciphertext: bytes, bytearray, memoryview
+ :returns: the decrypted byte string, of equal length as the
+ ciphertext.
+ """
+
+ try:
+ return self.encrypt(ciphertext)
+ except ValueError as e:
+ raise ValueError(str(e).replace("enc", "dec"))
+
+
+def new(key, *args, **kwargs):
+ """Create a new ARC4 cipher.
+
+ :param key:
+ The secret key to use in the symmetric cipher.
+ Its length must be in the range ``[5..256]``.
+ The recommended length is 16 bytes.
+ :type key: bytes, bytearray, memoryview
+
+ :Keyword Arguments:
+ * *drop* (``integer``) --
+ The amount of bytes to discard from the initial part of the keystream.
+ In fact, such part has been found to be distinguishable from random
+ data (while it shouldn't) and also correlated to key.
+
+ The recommended value is 3072_ bytes. The default value is 0.
+
+ :Return: an `ARC4Cipher` object
+
+ .. _3072: http://eprint.iacr.org/2002/067.pdf
+ """
+ return ARC4Cipher(key, *args, **kwargs)
+
+# Size of a data block (in bytes)
+block_size = 1
+# Size of a key (in bytes)
+key_size = range(5, 256+1)
diff --git a/frozen_deps/Cryptodome/Cipher/ARC4.pyi b/frozen_deps/Cryptodome/Cipher/ARC4.pyi
new file mode 100644
index 0000000..2e75d6f
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/ARC4.pyi
@@ -0,0 +1,16 @@
+from typing import Any, Union, Iterable
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+class ARC4Cipher:
+ block_size: int
+ key_size: int
+
+ def __init__(self, key: Buffer, *args: Any, **kwargs: Any) -> None: ...
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ def decrypt(self, ciphertext: Buffer) -> bytes: ...
+
+def new(key: Buffer, drop : int = ...) -> ARC4Cipher: ...
+
+block_size: int
+key_size: Iterable[int]
diff --git a/frozen_deps/Cryptodome/Cipher/Blowfish.py b/frozen_deps/Cryptodome/Cipher/Blowfish.py
new file mode 100644
index 0000000..536cbc8
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/Blowfish.py
@@ -0,0 +1,159 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/Blowfish.py : Blowfish
+#
+# ===================================================================
+# 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 Blowfish:
+
+: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_EAX: :ref:`EAX Mode <eax_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)
+
+_raw_blowfish_lib = load_pycryptodome_raw_lib(
+ "Cryptodome.Cipher._raw_blowfish",
+ """
+ int Blowfish_start_operation(const uint8_t key[],
+ size_t key_len,
+ void **pResult);
+ int Blowfish_encrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int Blowfish_decrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int Blowfish_stop_operation(void *state);
+ """
+ )
+
+
+def _create_base_cipher(dict_parameters):
+ """This method instantiates and returns a smart pointer to
+ a low-level base cipher. It will absorb named parameters in
+ the process."""
+
+ try:
+ key = dict_parameters.pop("key")
+ except KeyError:
+ raise TypeError("Missing 'key' parameter")
+
+ if len(key) not in key_size:
+ raise ValueError("Incorrect Blowfish key length (%d bytes)" % len(key))
+
+ start_operation = _raw_blowfish_lib.Blowfish_start_operation
+ stop_operation = _raw_blowfish_lib.Blowfish_stop_operation
+
+ void_p = VoidPointer()
+ result = start_operation(c_uint8_ptr(key),
+ c_size_t(len(key)),
+ void_p.address_of())
+ if result:
+ raise ValueError("Error %X while instantiating the Blowfish cipher"
+ % result)
+ return SmartPointer(void_p.get(), stop_operation)
+
+
+def new(key, mode, *args, **kwargs):
+ """Create a new Blowfish cipher
+
+ :param key:
+ The secret key to use in the symmetric cipher.
+ Its length can vary from 5 to 56 bytes.
+ :type key: bytes, bytearray, memoryview
+
+ :param mode:
+ The chaining mode to use for encryption or decryption.
+ :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 8 bytes long.
+
+ For ``MODE_OPENPGP`` mode only,
+ it must be 8 bytes long for encryption
+ and 10 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_EAX`` and ``MODE_CTR``).
+
+ A value that must never be reused for any other encryption done
+ with this key.
+
+ For ``MODE_EAX`` there are no
+ restrictions on its length (recommended: **16** bytes).
+
+ For ``MODE_CTR``, its length must be in the range **[0..7]**.
+
+ If not provided for ``MODE_EAX``, a random byte string is generated (you
+ can read it back via the ``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``)
+ Length of the authentication tag, in bytes.
+ It must be no longer than 8 (default).
+
+ * **initial_value** : (*integer*) --
+ (Only ``MODE_CTR``). The initial value for the counter within
+ the counter block. By default it is **0**.
+
+ :Return: a Blowfish object, of the applicable mode.
+ """
+
+ 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_EAX = 9
+
+# Size of a data block (in bytes)
+block_size = 8
+# Size of a key (in bytes)
+key_size = range(4, 56 + 1)
diff --git a/frozen_deps/Cryptodome/Cipher/Blowfish.pyi b/frozen_deps/Cryptodome/Cipher/Blowfish.pyi
new file mode 100644
index 0000000..a669240
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/Blowfish.pyi
@@ -0,0 +1,35 @@
+from typing import Union, Dict, Iterable
+
+from Cryptodome.Cipher._mode_ecb import EcbMode
+from Cryptodome.Cipher._mode_cbc import CbcMode
+from Cryptodome.Cipher._mode_cfb import CfbMode
+from Cryptodome.Cipher._mode_ofb import OfbMode
+from Cryptodome.Cipher._mode_ctr import CtrMode
+from Cryptodome.Cipher._mode_openpgp import OpenPgpMode
+from Cryptodome.Cipher._mode_eax import EaxMode
+
+BlowfishMode = int
+
+MODE_ECB: BlowfishMode
+MODE_CBC: BlowfishMode
+MODE_CFB: BlowfishMode
+MODE_OFB: BlowfishMode
+MODE_CTR: BlowfishMode
+MODE_OPENPGP: BlowfishMode
+MODE_EAX: BlowfishMode
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+def new(key: Buffer,
+ mode: BlowfishMode,
+ iv : Buffer = ...,
+ IV : Buffer = ...,
+ nonce : Buffer = ...,
+ segment_size : int = ...,
+ mac_len : int = ...,
+ initial_value : Union[int, Buffer] = ...,
+ counter : Dict = ...) -> \
+ Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode, OpenPgpMode]: ...
+
+block_size: int
+key_size: Iterable[int]
diff --git a/frozen_deps/Cryptodome/Cipher/CAST.py b/frozen_deps/Cryptodome/Cipher/CAST.py
new file mode 100644
index 0000000..84eb88e
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/CAST.py
@@ -0,0 +1,159 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/CAST.py : CAST
+#
+# ===================================================================
+# 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 CAST:
+
+: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_EAX: :ref:`EAX Mode <eax_mode>`
+"""
+
+import sys
+
+from Cryptodome.Cipher import _create_cipher
+from Cryptodome.Util.py3compat import byte_string
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib,
+ VoidPointer, SmartPointer,
+ c_size_t, c_uint8_ptr)
+
+_raw_cast_lib = load_pycryptodome_raw_lib(
+ "Cryptodome.Cipher._raw_cast",
+ """
+ int CAST_start_operation(const uint8_t key[],
+ size_t key_len,
+ void **pResult);
+ int CAST_encrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int CAST_decrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int CAST_stop_operation(void *state);
+ """)
+
+
+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."""
+
+ try:
+ key = dict_parameters.pop("key")
+ except KeyError:
+ raise TypeError("Missing 'key' parameter")
+
+ if len(key) not in key_size:
+ raise ValueError("Incorrect CAST key length (%d bytes)" % len(key))
+
+ start_operation = _raw_cast_lib.CAST_start_operation
+ stop_operation = _raw_cast_lib.CAST_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 CAST cipher"
+ % result)
+
+ return SmartPointer(cipher.get(), stop_operation)
+
+
+def new(key, mode, *args, **kwargs):
+ """Create a new CAST cipher
+
+ :param key:
+ The secret key to use in the symmetric cipher.
+ Its length can vary from 5 to 16 bytes.
+ :type key: bytes, bytearray, memoryview
+
+ :param mode:
+ The chaining mode to use for encryption or decryption.
+ :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 8 bytes long.
+
+ For ``MODE_OPENPGP`` mode only,
+ it must be 8 bytes long for encryption
+ and 10 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_EAX`` and ``MODE_CTR``).
+
+ A value that must never be reused for any other encryption done
+ with this key.
+
+ For ``MODE_EAX`` there are no
+ restrictions on its length (recommended: **16** bytes).
+
+ For ``MODE_CTR``, its length must be in the range **[0..7]**.
+
+ If not provided for ``MODE_EAX``, a random byte string is generated (you
+ can read it back via the ``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``)
+ Length of the authentication tag, in bytes.
+ It must be no longer than 8 (default).
+
+ * **initial_value** : (*integer*) --
+ (Only ``MODE_CTR``). The initial value for the counter within
+ the counter block. By default it is **0**.
+
+ :Return: a CAST object, of the applicable mode.
+ """
+
+ 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_EAX = 9
+
+# Size of a data block (in bytes)
+block_size = 8
+# Size of a key (in bytes)
+key_size = range(5, 16 + 1)
diff --git a/frozen_deps/Cryptodome/Cipher/CAST.pyi b/frozen_deps/Cryptodome/Cipher/CAST.pyi
new file mode 100644
index 0000000..6b411cf
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/CAST.pyi
@@ -0,0 +1,35 @@
+from typing import Union, Dict, Iterable
+
+from Cryptodome.Cipher._mode_ecb import EcbMode
+from Cryptodome.Cipher._mode_cbc import CbcMode
+from Cryptodome.Cipher._mode_cfb import CfbMode
+from Cryptodome.Cipher._mode_ofb import OfbMode
+from Cryptodome.Cipher._mode_ctr import CtrMode
+from Cryptodome.Cipher._mode_openpgp import OpenPgpMode
+from Cryptodome.Cipher._mode_eax import EaxMode
+
+CASTMode = int
+
+MODE_ECB: CASTMode
+MODE_CBC: CASTMode
+MODE_CFB: CASTMode
+MODE_OFB: CASTMode
+MODE_CTR: CASTMode
+MODE_OPENPGP: CASTMode
+MODE_EAX: CASTMode
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+def new(key: Buffer,
+ mode: CASTMode,
+ iv : Buffer = ...,
+ IV : Buffer = ...,
+ nonce : Buffer = ...,
+ segment_size : int = ...,
+ mac_len : int = ...,
+ initial_value : Union[int, Buffer] = ...,
+ counter : Dict = ...) -> \
+ Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode, OpenPgpMode]: ...
+
+block_size: int
+key_size : Iterable[int]
diff --git a/frozen_deps/Cryptodome/Cipher/ChaCha20.py b/frozen_deps/Cryptodome/Cipher/ChaCha20.py
new file mode 100644
index 0000000..0cd9102
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/ChaCha20.py
@@ -0,0 +1,286 @@
+# ===================================================================
+#
+# Copyright (c) 2014, Legrandin <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+from Cryptodome.Random import get_random_bytes
+
+from Cryptodome.Util.py3compat import _copy_bytes
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib,
+ create_string_buffer,
+ get_raw_buffer, VoidPointer,
+ SmartPointer, c_size_t,
+ c_uint8_ptr, c_ulong,
+ is_writeable_buffer)
+
+_raw_chacha20_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._chacha20",
+ """
+ int chacha20_init(void **pState,
+ const uint8_t *key,
+ size_t keySize,
+ const uint8_t *nonce,
+ size_t nonceSize);
+
+ int chacha20_destroy(void *state);
+
+ int chacha20_encrypt(void *state,
+ const uint8_t in[],
+ uint8_t out[],
+ size_t len);
+
+ int chacha20_seek(void *state,
+ unsigned long block_high,
+ unsigned long block_low,
+ unsigned offset);
+ int hchacha20( const uint8_t key[32],
+ const uint8_t nonce16[16],
+ uint8_t subkey[32]);
+ """)
+
+
+def _HChaCha20(key, nonce):
+
+ assert(len(key) == 32)
+ assert(len(nonce) == 16)
+
+ subkey = bytearray(32)
+ result = _raw_chacha20_lib.hchacha20(
+ c_uint8_ptr(key),
+ c_uint8_ptr(nonce),
+ c_uint8_ptr(subkey))
+ if result:
+ raise ValueError("Error %d when deriving subkey with HChaCha20" % result)
+
+ return subkey
+
+
+class ChaCha20Cipher(object):
+ """ChaCha20 (or XChaCha20) cipher object.
+ Do not create it directly. Use :py:func:`new` instead.
+
+ :var nonce: The nonce with length 8, 12 or 24 bytes
+ :vartype nonce: bytes
+ """
+
+ block_size = 1
+
+ def __init__(self, key, nonce):
+ """Initialize a ChaCha20/XChaCha20 cipher object
+
+ See also `new()` at the module level."""
+
+ # XChaCha20 requires a key derivation with HChaCha20
+ # See 2.3 in https://tools.ietf.org/html/draft-arciszewski-xchacha-03
+ if len(nonce) == 24:
+ key = _HChaCha20(key, nonce[:16])
+ nonce = b'\x00' * 4 + nonce[16:]
+ self._name = "XChaCha20"
+ else:
+ self._name = "ChaCha20"
+
+ self.nonce = _copy_bytes(None, None, nonce)
+
+ self._next = ( self.encrypt, self.decrypt )
+
+ self._state = VoidPointer()
+ result = _raw_chacha20_lib.chacha20_init(
+ self._state.address_of(),
+ c_uint8_ptr(key),
+ c_size_t(len(key)),
+ self.nonce,
+ c_size_t(len(nonce)))
+ if result:
+ raise ValueError("Error %d instantiating a %s cipher" % (result,
+ self._name))
+ self._state = SmartPointer(self._state.get(),
+ _raw_chacha20_lib.chacha20_destroy)
+
+ def encrypt(self, plaintext, output=None):
+ """Encrypt a piece of data.
+
+ Args:
+ plaintext(bytes/bytearray/memoryview): The data to encrypt, of any size.
+ Keyword Args:
+ output(bytes/bytearray/memoryview): The location where the ciphertext
+ is written to. If ``None``, the ciphertext is returned.
+ Returns:
+ If ``output`` is ``None``, the ciphertext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.encrypt not in self._next:
+ raise TypeError("Cipher object can only be used for decryption")
+ self._next = ( self.encrypt, )
+ return self._encrypt(plaintext, output)
+
+ def _encrypt(self, plaintext, output):
+ """Encrypt without FSM checks"""
+
+ if output is None:
+ ciphertext = create_string_buffer(len(plaintext))
+ else:
+ ciphertext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(plaintext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+ result = _raw_chacha20_lib.chacha20_encrypt(
+ self._state.get(),
+ c_uint8_ptr(plaintext),
+ c_uint8_ptr(ciphertext),
+ c_size_t(len(plaintext)))
+ if result:
+ raise ValueError("Error %d while encrypting with %s" % (result, self._name))
+
+ if output is None:
+ return get_raw_buffer(ciphertext)
+ else:
+ return None
+
+ def decrypt(self, ciphertext, output=None):
+ """Decrypt a piece of data.
+
+ Args:
+ ciphertext(bytes/bytearray/memoryview): The data to decrypt, of any size.
+ Keyword Args:
+ output(bytes/bytearray/memoryview): The location where the plaintext
+ is written to. If ``None``, the plaintext is returned.
+ Returns:
+ If ``output`` is ``None``, the plaintext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.decrypt not in self._next:
+ raise TypeError("Cipher object can only be used for encryption")
+ self._next = ( self.decrypt, )
+
+ try:
+ return self._encrypt(ciphertext, output)
+ except ValueError as e:
+ raise ValueError(str(e).replace("enc", "dec"))
+
+ def seek(self, position):
+ """Seek to a certain position in the key stream.
+
+ Args:
+ position (integer):
+ The absolute position within the key stream, in bytes.
+ """
+
+ position, offset = divmod(position, 64)
+ block_low = position & 0xFFFFFFFF
+ block_high = position >> 32
+
+ result = _raw_chacha20_lib.chacha20_seek(
+ self._state.get(),
+ c_ulong(block_high),
+ c_ulong(block_low),
+ offset
+ )
+ if result:
+ raise ValueError("Error %d while seeking with %s" % (result, self._name))
+
+
+def _derive_Poly1305_key_pair(key, nonce):
+ """Derive a tuple (r, s, nonce) for a Poly1305 MAC.
+
+ If nonce is ``None``, a new 12-byte nonce is generated.
+ """
+
+ if len(key) != 32:
+ raise ValueError("Poly1305 with ChaCha20 requires a 32-byte key")
+
+ if nonce is None:
+ padded_nonce = nonce = get_random_bytes(12)
+ elif len(nonce) == 8:
+ # See RFC7538, 2.6: [...] ChaCha20 as specified here requires a 96-bit
+ # nonce. So if the provided nonce is only 64-bit, then the first 32
+ # bits of the nonce will be set to a constant number.
+ # This will usually be zero, but for protocols with multiple senders it may be
+ # different for each sender, but should be the same for all
+ # invocations of the function with the same key by a particular
+ # sender.
+ padded_nonce = b'\x00\x00\x00\x00' + nonce
+ elif len(nonce) == 12:
+ padded_nonce = nonce
+ else:
+ raise ValueError("Poly1305 with ChaCha20 requires an 8- or 12-byte nonce")
+
+ rs = new(key=key, nonce=padded_nonce).encrypt(b'\x00' * 32)
+ return rs[:16], rs[16:], nonce
+
+
+def new(**kwargs):
+ """Create a new ChaCha20 or XChaCha20 cipher
+
+ Keyword Args:
+ key (bytes/bytearray/memoryview): The secret key to use.
+ It must be 32 bytes long.
+ nonce (bytes/bytearray/memoryview): A mandatory value that
+ must never be reused for any other encryption
+ done with this key.
+
+ For ChaCha20, it must be 8 or 12 bytes long.
+
+ For XChaCha20, it must be 24 bytes long.
+
+ If not provided, 8 bytes will be randomly generated
+ (you can find them back in the ``nonce`` attribute).
+
+ :Return: a :class:`Cryptodome.Cipher.ChaCha20.ChaCha20Cipher` object
+ """
+
+ try:
+ key = kwargs.pop("key")
+ except KeyError as e:
+ raise TypeError("Missing parameter %s" % e)
+
+ nonce = kwargs.pop("nonce", None)
+ if nonce is None:
+ nonce = get_random_bytes(8)
+
+ if len(key) != 32:
+ raise ValueError("ChaCha20/XChaCha20 key must be 32 bytes long")
+
+ if len(nonce) not in (8, 12, 24):
+ raise ValueError("Nonce must be 8/12 bytes(ChaCha20) or 24 bytes (XChaCha20)")
+
+ if kwargs:
+ raise TypeError("Unknown parameters: " + str(kwargs))
+
+ return ChaCha20Cipher(key, nonce)
+
+# Size of a data block (in bytes)
+block_size = 1
+
+# Size of a key (in bytes)
+key_size = 32
diff --git a/frozen_deps/Cryptodome/Cipher/ChaCha20.pyi b/frozen_deps/Cryptodome/Cipher/ChaCha20.pyi
new file mode 100644
index 0000000..3d00a1d
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/ChaCha20.pyi
@@ -0,0 +1,25 @@
+from typing import Union, overload
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+def _HChaCha20(key: Buffer, nonce: Buffer) -> bytearray: ...
+
+class ChaCha20Cipher:
+ block_size: int
+ nonce: bytes
+
+ def __init__(self, key: Buffer, nonce: Buffer) -> None: ...
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ def seek(self, position: int) -> None: ...
+
+def new(key: Buffer, nonce: Buffer = ...) -> ChaCha20Cipher: ...
+
+block_size: int
+key_size: int
diff --git a/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.py b/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.py
new file mode 100644
index 0000000..b6bc7a6
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.py
@@ -0,0 +1,336 @@
+# ===================================================================
+#
+# Copyright (c) 2018, Helder Eijs <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+from binascii import unhexlify
+
+from Cryptodome.Cipher import ChaCha20
+from Cryptodome.Cipher.ChaCha20 import _HChaCha20
+from Cryptodome.Hash import Poly1305, BLAKE2s
+
+from Cryptodome.Random import get_random_bytes
+
+from Cryptodome.Util.number import long_to_bytes
+from Cryptodome.Util.py3compat import _copy_bytes, bord
+from Cryptodome.Util._raw_api import is_buffer
+
+
+def _enum(**enums):
+ return type('Enum', (), enums)
+
+
+_CipherStatus = _enum(PROCESSING_AUTH_DATA=1,
+ PROCESSING_CIPHERTEXT=2,
+ PROCESSING_DONE=3)
+
+
+class ChaCha20Poly1305Cipher(object):
+ """ChaCha20-Poly1305 and XChaCha20-Poly1305 cipher object.
+ Do not create it directly. Use :py:func:`new` instead.
+
+ :var nonce: The nonce with length 8, 12 or 24 bytes
+ :vartype nonce: byte string
+ """
+
+ def __init__(self, key, nonce):
+ """Initialize a ChaCha20-Poly1305 AEAD cipher object
+
+ See also `new()` at the module level."""
+
+ self.nonce = _copy_bytes(None, None, nonce)
+
+ self._next = (self.update, self.encrypt, self.decrypt, self.digest,
+ self.verify)
+
+ self._authenticator = Poly1305.new(key=key, nonce=nonce, cipher=ChaCha20)
+
+ self._cipher = ChaCha20.new(key=key, nonce=nonce)
+ self._cipher.seek(64) # Block counter starts at 1
+
+ self._len_aad = 0
+ self._len_ct = 0
+ self._mac_tag = None
+ self._status = _CipherStatus.PROCESSING_AUTH_DATA
+
+ def update(self, data):
+ """Protect the associated data.
+
+ Associated data (also known as *additional authenticated data* - AAD)
+ is the piece of the message that must stay in the clear, while
+ still allowing the receiver to verify its integrity.
+ An example is packet headers.
+
+ The associated data (possibly split into multiple segments) is
+ fed into :meth:`update` before any call to :meth:`decrypt` or :meth:`encrypt`.
+ If there is no associated data, :meth:`update` is not called.
+
+ :param bytes/bytearray/memoryview assoc_data:
+ A piece of associated data. There are no restrictions on its size.
+ """
+
+ if self.update not in self._next:
+ raise TypeError("update() method cannot be called")
+
+ self._len_aad += len(data)
+ self._authenticator.update(data)
+
+ def _pad_aad(self):
+
+ assert(self._status == _CipherStatus.PROCESSING_AUTH_DATA)
+ if self._len_aad & 0x0F:
+ self._authenticator.update(b'\x00' * (16 - (self._len_aad & 0x0F)))
+ self._status = _CipherStatus.PROCESSING_CIPHERTEXT
+
+ def encrypt(self, plaintext, output=None):
+ """Encrypt a piece of data.
+
+ Args:
+ plaintext(bytes/bytearray/memoryview): The data to encrypt, of any size.
+ Keyword Args:
+ output(bytes/bytearray/memoryview): The location where the ciphertext
+ is written to. If ``None``, the ciphertext is returned.
+ Returns:
+ If ``output`` is ``None``, the ciphertext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.encrypt not in self._next:
+ raise TypeError("encrypt() method cannot be called")
+
+ if self._status == _CipherStatus.PROCESSING_AUTH_DATA:
+ self._pad_aad()
+
+ self._next = (self.encrypt, self.digest)
+
+ result = self._cipher.encrypt(plaintext, output=output)
+ self._len_ct += len(plaintext)
+ if output is None:
+ self._authenticator.update(result)
+ else:
+ self._authenticator.update(output)
+ return result
+
+ def decrypt(self, ciphertext, output=None):
+ """Decrypt a piece of data.
+
+ Args:
+ ciphertext(bytes/bytearray/memoryview): The data to decrypt, of any size.
+ Keyword Args:
+ output(bytes/bytearray/memoryview): The location where the plaintext
+ is written to. If ``None``, the plaintext is returned.
+ Returns:
+ If ``output`` is ``None``, the plaintext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.decrypt not in self._next:
+ raise TypeError("decrypt() method cannot be called")
+
+ if self._status == _CipherStatus.PROCESSING_AUTH_DATA:
+ self._pad_aad()
+
+ self._next = (self.decrypt, self.verify)
+
+ self._len_ct += len(ciphertext)
+ self._authenticator.update(ciphertext)
+ return self._cipher.decrypt(ciphertext, output=output)
+
+ def _compute_mac(self):
+ """Finalize the cipher (if not done already) and return the MAC."""
+
+ if self._mac_tag:
+ assert(self._status == _CipherStatus.PROCESSING_DONE)
+ return self._mac_tag
+
+ assert(self._status != _CipherStatus.PROCESSING_DONE)
+
+ if self._status == _CipherStatus.PROCESSING_AUTH_DATA:
+ self._pad_aad()
+
+ if self._len_ct & 0x0F:
+ self._authenticator.update(b'\x00' * (16 - (self._len_ct & 0x0F)))
+
+ self._status = _CipherStatus.PROCESSING_DONE
+
+ self._authenticator.update(long_to_bytes(self._len_aad, 8)[::-1])
+ self._authenticator.update(long_to_bytes(self._len_ct, 8)[::-1])
+ self._mac_tag = self._authenticator.digest()
+ return self._mac_tag
+
+ def digest(self):
+ """Compute the *binary* authentication tag (MAC).
+
+ :Return: the MAC tag, as 16 ``bytes``.
+ """
+
+ if self.digest not in self._next:
+ raise TypeError("digest() method cannot be called")
+ self._next = (self.digest,)
+
+ return self._compute_mac()
+
+ def hexdigest(self):
+ """Compute the *printable* authentication tag (MAC).
+
+ This method is like :meth:`digest`.
+
+ :Return: the MAC tag, as a hexadecimal string.
+ """
+ return "".join(["%02x" % bord(x) for x in self.digest()])
+
+ def verify(self, received_mac_tag):
+ """Validate the *binary* authentication tag (MAC).
+
+ The receiver invokes this method at the very end, to
+ check if the associated data (if any) and the decrypted
+ messages are valid.
+
+ :param bytes/bytearray/memoryview received_mac_tag:
+ This is the 16-byte *binary* MAC, as received from the sender.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ if self.verify not in self._next:
+ raise TypeError("verify() cannot be called"
+ " when encrypting a message")
+ self._next = (self.verify,)
+
+ secret = get_random_bytes(16)
+
+ self._compute_mac()
+
+ mac1 = BLAKE2s.new(digest_bits=160, key=secret,
+ data=self._mac_tag)
+ mac2 = BLAKE2s.new(digest_bits=160, key=secret,
+ data=received_mac_tag)
+
+ if mac1.digest() != mac2.digest():
+ raise ValueError("MAC check failed")
+
+ def hexverify(self, hex_mac_tag):
+ """Validate the *printable* authentication tag (MAC).
+
+ This method is like :meth:`verify`.
+
+ :param string hex_mac_tag:
+ This is the *printable* MAC.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ self.verify(unhexlify(hex_mac_tag))
+
+ def encrypt_and_digest(self, plaintext):
+ """Perform :meth:`encrypt` and :meth:`digest` in one step.
+
+ :param plaintext: The data to encrypt, of any size.
+ :type plaintext: bytes/bytearray/memoryview
+ :return: a tuple with two ``bytes`` objects:
+
+ - the ciphertext, of equal length as the plaintext
+ - the 16-byte MAC tag
+ """
+
+ return self.encrypt(plaintext), self.digest()
+
+ def decrypt_and_verify(self, ciphertext, received_mac_tag):
+ """Perform :meth:`decrypt` and :meth:`verify` in one step.
+
+ :param ciphertext: The piece of data to decrypt.
+ :type ciphertext: bytes/bytearray/memoryview
+ :param bytes received_mac_tag:
+ This is the 16-byte *binary* MAC, as received from the sender.
+ :return: the decrypted data (as ``bytes``)
+ :raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ plaintext = self.decrypt(ciphertext)
+ self.verify(received_mac_tag)
+ return plaintext
+
+
+def new(**kwargs):
+ """Create a new ChaCha20-Poly1305 or XChaCha20-Poly1305 AEAD cipher.
+
+ :keyword key: The secret key to use. It must be 32 bytes long.
+ :type key: byte string
+
+ :keyword nonce:
+ A value that must never be reused for any other encryption
+ done with this key.
+
+ For ChaCha20-Poly1305, it must be 8 or 12 bytes long.
+
+ For XChaCha20-Poly1305, it must be 24 bytes long.
+
+ If not provided, 12 ``bytes`` will be generated randomly
+ (you can find them back in the ``nonce`` attribute).
+ :type nonce: bytes, bytearray, memoryview
+
+ :Return: a :class:`Cryptodome.Cipher.ChaCha20.ChaCha20Poly1305Cipher` object
+ """
+
+ try:
+ key = kwargs.pop("key")
+ except KeyError as e:
+ raise TypeError("Missing parameter %s" % e)
+
+ self._len_ct += len(plaintext)
+
+ if len(key) != 32:
+ raise ValueError("Key must be 32 bytes long")
+
+ nonce = kwargs.pop("nonce", None)
+ if nonce is None:
+ nonce = get_random_bytes(12)
+
+ if len(nonce) in (8, 12):
+ pass
+ elif len(nonce) == 24:
+ key = _HChaCha20(key, nonce[:16])
+ nonce = b'\x00\x00\x00\x00' + nonce[16:]
+ else:
+ raise ValueError("Nonce must be 8, 12 or 24 bytes long")
+
+ if not is_buffer(nonce):
+ raise TypeError("nonce must be bytes, bytearray or memoryview")
+
+ if kwargs:
+ raise TypeError("Unknown parameters: " + str(kwargs))
+
+ return ChaCha20Poly1305Cipher(key, nonce)
+
+
+# Size of a key (in bytes)
+key_size = 32
diff --git a/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.pyi b/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.pyi
new file mode 100644
index 0000000..ef0450f
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/ChaCha20_Poly1305.pyi
@@ -0,0 +1,28 @@
+from typing import Union, Tuple, overload
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+class ChaCha20Poly1305Cipher:
+ nonce: bytes
+
+ def __init__(self, key: Buffer, nonce: Buffer) -> None: ...
+ def update(self, data: Buffer) -> None: ...
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ def digest(self) -> bytes: ...
+ def hexdigest(self) -> str: ...
+ def verify(self, received_mac_tag: Buffer) -> None: ...
+ def hexverify(self, received_mac_tag: str) -> None: ...
+ def encrypt_and_digest(self, plaintext: Buffer) -> Tuple[bytes, bytes]: ...
+ def decrypt_and_verify(self, ciphertext: Buffer, received_mac_tag: Buffer) -> bytes: ...
+
+def new(key: Buffer, nonce: Buffer = ...) -> ChaCha20Poly1305Cipher: ...
+
+block_size: int
+key_size: int
diff --git a/frozen_deps/Cryptodome/Cipher/DES.py b/frozen_deps/Cryptodome/Cipher/DES.py
new file mode 100644
index 0000000..026b491
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/DES.py
@@ -0,0 +1,158 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/DES.py : DES
+#
+# ===================================================================
+# 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 Single DES:
+
+: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_EAX: :ref:`EAX Mode <eax_mode>`
+"""
+
+import sys
+
+from Cryptodome.Cipher import _create_cipher
+from Cryptodome.Util.py3compat import byte_string
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib,
+ VoidPointer, SmartPointer,
+ c_size_t, c_uint8_ptr)
+
+_raw_des_lib = load_pycryptodome_raw_lib(
+ "Cryptodome.Cipher._raw_des",
+ """
+ int DES_start_operation(const uint8_t key[],
+ size_t key_len,
+ void **pResult);
+ int DES_encrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int DES_decrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int DES_stop_operation(void *state);
+ """)
+
+
+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."""
+
+ try:
+ key = dict_parameters.pop("key")
+ except KeyError:
+ raise TypeError("Missing 'key' parameter")
+
+ if len(key) != key_size:
+ raise ValueError("Incorrect DES key length (%d bytes)" % len(key))
+
+ start_operation = _raw_des_lib.DES_start_operation
+ stop_operation = _raw_des_lib.DES_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 DES cipher"
+ % result)
+ return SmartPointer(cipher.get(), stop_operation)
+
+
+def new(key, mode, *args, **kwargs):
+ """Create a new DES cipher.
+
+ :param key:
+ The secret key to use in the symmetric cipher.
+ It must be 8 byte long. The parity bits will be ignored.
+ :type key: bytes/bytearray/memoryview
+
+ :param mode:
+ The chaining mode to use for encryption or decryption.
+ :type mode: One of the supported ``MODE_*`` constants
+
+ :Keyword Arguments:
+ * **iv** (*byte string*) --
+ (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 8 bytes long.
+
+ For ``MODE_OPENPGP`` mode only,
+ it must be 8 bytes long for encryption
+ and 10 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** (*byte string*) --
+ (Only applicable for ``MODE_EAX`` and ``MODE_CTR``).
+
+ A value that must never be reused for any other encryption done
+ with this key.
+
+ For ``MODE_EAX`` there are no
+ restrictions on its length (recommended: **16** bytes).
+
+ For ``MODE_CTR``, its length must be in the range **[0..7]**.
+
+ If not provided for ``MODE_EAX``, a random byte string is generated (you
+ can read it back via the ``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``)
+ Length of the authentication tag, in bytes.
+ It must be no longer than 8 (default).
+
+ * **initial_value** : (*integer*) --
+ (Only ``MODE_CTR``). The initial value for the counter within
+ the counter block. By default it is **0**.
+
+ :Return: a DES object, of the applicable mode.
+ """
+
+ 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_EAX = 9
+
+# Size of a data block (in bytes)
+block_size = 8
+# Size of a key (in bytes)
+key_size = 8
diff --git a/frozen_deps/Cryptodome/Cipher/DES.pyi b/frozen_deps/Cryptodome/Cipher/DES.pyi
new file mode 100644
index 0000000..1ba2752
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/DES.pyi
@@ -0,0 +1,35 @@
+from typing import Union, Dict, Iterable
+
+from Cryptodome.Cipher._mode_ecb import EcbMode
+from Cryptodome.Cipher._mode_cbc import CbcMode
+from Cryptodome.Cipher._mode_cfb import CfbMode
+from Cryptodome.Cipher._mode_ofb import OfbMode
+from Cryptodome.Cipher._mode_ctr import CtrMode
+from Cryptodome.Cipher._mode_openpgp import OpenPgpMode
+from Cryptodome.Cipher._mode_eax import EaxMode
+
+DESMode = int
+
+MODE_ECB: DESMode
+MODE_CBC: DESMode
+MODE_CFB: DESMode
+MODE_OFB: DESMode
+MODE_CTR: DESMode
+MODE_OPENPGP: DESMode
+MODE_EAX: DESMode
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+def new(key: Buffer,
+ mode: DESMode,
+ iv : Buffer = ...,
+ IV : Buffer = ...,
+ nonce : Buffer = ...,
+ segment_size : int = ...,
+ mac_len : int = ...,
+ initial_value : Union[int, Buffer] = ...,
+ counter : Dict = ...) -> \
+ Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode, OpenPgpMode]: ...
+
+block_size: int
+key_size: int
diff --git a/frozen_deps/Cryptodome/Cipher/DES3.py b/frozen_deps/Cryptodome/Cipher/DES3.py
new file mode 100644
index 0000000..3b2828e
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/DES3.py
@@ -0,0 +1,187 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/DES3.py : DES3
+#
+# ===================================================================
+# 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 Triple DES:
+
+: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_EAX: :ref:`EAX Mode <eax_mode>`
+"""
+
+import sys
+
+from Cryptodome.Cipher import _create_cipher
+from Cryptodome.Util.py3compat import byte_string, bchr, bord, bstr
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib,
+ VoidPointer, SmartPointer,
+ c_size_t)
+
+_raw_des3_lib = load_pycryptodome_raw_lib(
+ "Cryptodome.Cipher._raw_des3",
+ """
+ int DES3_start_operation(const uint8_t key[],
+ size_t key_len,
+ void **pResult);
+ int DES3_encrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int DES3_decrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int DES3_stop_operation(void *state);
+ """)
+
+
+def adjust_key_parity(key_in):
+ """Set the parity bits in a TDES key.
+
+ :param key_in: the TDES key whose bits need to be adjusted
+ :type key_in: byte string
+
+ :returns: a copy of ``key_in``, with the parity bits correctly set
+ :rtype: byte string
+
+ :raises ValueError: if the TDES key is not 16 or 24 bytes long
+ :raises ValueError: if the TDES key degenerates into Single DES
+ """
+
+ def parity_byte(key_byte):
+ parity = 1
+ for i in range(1, 8):
+ parity ^= (key_byte >> i) & 1
+ return (key_byte & 0xFE) | parity
+
+ if len(key_in) not in key_size:
+ raise ValueError("Not a valid TDES key")
+
+ key_out = b"".join([ bchr(parity_byte(bord(x))) for x in key_in ])
+
+ if key_out[:8] == key_out[8:16] or key_out[-16:-8] == key_out[-8:]:
+ raise ValueError("Triple DES key degenerates to single DES")
+
+ return key_out
+
+
+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."""
+
+ try:
+ key_in = dict_parameters.pop("key")
+ except KeyError:
+ raise TypeError("Missing 'key' parameter")
+
+ key = adjust_key_parity(bstr(key_in))
+
+ start_operation = _raw_des3_lib.DES3_start_operation
+ stop_operation = _raw_des3_lib.DES3_stop_operation
+
+ cipher = VoidPointer()
+ result = start_operation(key,
+ c_size_t(len(key)),
+ cipher.address_of())
+ if result:
+ raise ValueError("Error %X while instantiating the TDES cipher"
+ % result)
+ return SmartPointer(cipher.get(), stop_operation)
+
+
+def new(key, mode, *args, **kwargs):
+ """Create a new Triple DES cipher.
+
+ :param key:
+ The secret key to use in the symmetric cipher.
+ It must be 16 or 24 byte long. The parity bits will be ignored.
+ :type key: bytes/bytearray/memoryview
+
+ :param mode:
+ The chaining mode to use for encryption or decryption.
+ :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 8 bytes long.
+
+ For ``MODE_OPENPGP`` mode only,
+ it must be 8 bytes long for encryption
+ and 10 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_EAX`` and ``MODE_CTR``).
+
+ A value that must never be reused for any other encryption done
+ with this key.
+
+ For ``MODE_EAX`` there are no
+ restrictions on its length (recommended: **16** bytes).
+
+ For ``MODE_CTR``, its length must be in the range **[0..7]**.
+
+ If not provided for ``MODE_EAX``, a random byte string is generated (you
+ can read it back via the ``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``)
+ Length of the authentication tag, in bytes.
+ It must be no longer than 8 (default).
+
+ * **initial_value** : (*integer*) --
+ (Only ``MODE_CTR``). The initial value for the counter within
+ the counter block. By default it is **0**.
+
+ :Return: a Triple DES object, of the applicable mode.
+ """
+
+ 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_EAX = 9
+
+# Size of a data block (in bytes)
+block_size = 8
+# Size of a key (in bytes)
+key_size = (16, 24)
diff --git a/frozen_deps/Cryptodome/Cipher/DES3.pyi b/frozen_deps/Cryptodome/Cipher/DES3.pyi
new file mode 100644
index 0000000..c1a524f
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/DES3.pyi
@@ -0,0 +1,37 @@
+from typing import Union, Dict, Tuple
+
+from Cryptodome.Cipher._mode_ecb import EcbMode
+from Cryptodome.Cipher._mode_cbc import CbcMode
+from Cryptodome.Cipher._mode_cfb import CfbMode
+from Cryptodome.Cipher._mode_ofb import OfbMode
+from Cryptodome.Cipher._mode_ctr import CtrMode
+from Cryptodome.Cipher._mode_openpgp import OpenPgpMode
+from Cryptodome.Cipher._mode_eax import EaxMode
+
+def adjust_key_parity(key_in: bytes) -> bytes: ...
+
+DES3Mode = int
+
+MODE_ECB: DES3Mode
+MODE_CBC: DES3Mode
+MODE_CFB: DES3Mode
+MODE_OFB: DES3Mode
+MODE_CTR: DES3Mode
+MODE_OPENPGP: DES3Mode
+MODE_EAX: DES3Mode
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+def new(key: Buffer,
+ mode: DES3Mode,
+ iv : Buffer = ...,
+ IV : Buffer = ...,
+ nonce : Buffer = ...,
+ segment_size : int = ...,
+ mac_len : int = ...,
+ initial_value : Union[int, Buffer] = ...,
+ counter : Dict = ...) -> \
+ Union[EcbMode, CbcMode, CfbMode, OfbMode, CtrMode, OpenPgpMode]: ...
+
+block_size: int
+key_size: Tuple[int, int]
diff --git a/frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.py b/frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.py
new file mode 100644
index 0000000..3207bbe
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.py
@@ -0,0 +1,239 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/PKCS1_OAEP.py : PKCS#1 OAEP
+#
+# ===================================================================
+# 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.
+# ===================================================================
+
+from Cryptodome.Signature.pss import MGF1
+import Cryptodome.Hash.SHA1
+
+from Cryptodome.Util.py3compat import bord, _copy_bytes
+import Cryptodome.Util.number
+from Cryptodome.Util.number import ceil_div, bytes_to_long, long_to_bytes
+from Cryptodome.Util.strxor import strxor
+from Cryptodome import Random
+
+class PKCS1OAEP_Cipher:
+ """Cipher object for PKCS#1 v1.5 OAEP.
+ Do not create directly: use :func:`new` instead."""
+
+ def __init__(self, key, hashAlgo, mgfunc, label, randfunc):
+ """Initialize this PKCS#1 OAEP cipher object.
+
+ :Parameters:
+ key : an RSA key object
+ If a private half is given, both encryption and decryption are possible.
+ If a public half is given, only encryption is possible.
+ hashAlgo : hash object
+ The hash function to use. This can be a module under `Cryptodome.Hash`
+ or an existing hash object created from any of such modules. If not specified,
+ `Cryptodome.Hash.SHA1` is used.
+ mgfunc : callable
+ A mask generation function that accepts two parameters: a string to
+ use as seed, and the lenth of the mask to generate, in bytes.
+ If not specified, the standard MGF1 consistent with ``hashAlgo`` is used (a safe choice).
+ label : bytes/bytearray/memoryview
+ A label to apply to this particular encryption. If not specified,
+ an empty string is used. Specifying a label does not improve
+ security.
+ randfunc : callable
+ A function that returns random bytes.
+
+ :attention: Modify the mask generation function only if you know what you are doing.
+ Sender and receiver must use the same one.
+ """
+ self._key = key
+
+ if hashAlgo:
+ self._hashObj = hashAlgo
+ else:
+ self._hashObj = Cryptodome.Hash.SHA1
+
+ if mgfunc:
+ self._mgf = mgfunc
+ else:
+ self._mgf = lambda x,y: MGF1(x,y,self._hashObj)
+
+ self._label = _copy_bytes(None, None, label)
+ self._randfunc = randfunc
+
+ def can_encrypt(self):
+ """Legacy function to check if you can call :meth:`encrypt`.
+
+ .. deprecated:: 3.0"""
+ return self._key.can_encrypt()
+
+ def can_decrypt(self):
+ """Legacy function to check if you can call :meth:`decrypt`.
+
+ .. deprecated:: 3.0"""
+ return self._key.can_decrypt()
+
+ def encrypt(self, message):
+ """Encrypt a message with PKCS#1 OAEP.
+
+ :param message:
+ The message to encrypt, also known as plaintext. It can be of
+ variable length, but not longer than the RSA modulus (in bytes)
+ minus 2, minus twice the hash output size.
+ For instance, if you use RSA 2048 and SHA-256, the longest message
+ you can encrypt is 190 byte long.
+ :type message: bytes/bytearray/memoryview
+
+ :returns: The ciphertext, as large as the RSA modulus.
+ :rtype: bytes
+
+ :raises ValueError:
+ if the message is too long.
+ """
+
+ # See 7.1.1 in RFC3447
+ modBits = Cryptodome.Util.number.size(self._key.n)
+ k = ceil_div(modBits, 8) # Convert from bits to bytes
+ hLen = self._hashObj.digest_size
+ mLen = len(message)
+
+ # Step 1b
+ ps_len = k - mLen - 2 * hLen - 2
+ if ps_len < 0:
+ raise ValueError("Plaintext is too long.")
+ # Step 2a
+ lHash = self._hashObj.new(self._label).digest()
+ # Step 2b
+ ps = b'\x00' * ps_len
+ # Step 2c
+ db = lHash + ps + b'\x01' + _copy_bytes(None, None, message)
+ # Step 2d
+ ros = self._randfunc(hLen)
+ # Step 2e
+ dbMask = self._mgf(ros, k-hLen-1)
+ # Step 2f
+ maskedDB = strxor(db, dbMask)
+ # Step 2g
+ seedMask = self._mgf(maskedDB, hLen)
+ # Step 2h
+ maskedSeed = strxor(ros, seedMask)
+ # Step 2i
+ em = b'\x00' + maskedSeed + maskedDB
+ # Step 3a (OS2IP)
+ em_int = bytes_to_long(em)
+ # Step 3b (RSAEP)
+ m_int = self._key._encrypt(em_int)
+ # Step 3c (I2OSP)
+ c = long_to_bytes(m_int, k)
+ return c
+
+ def decrypt(self, ciphertext):
+ """Decrypt a message with PKCS#1 OAEP.
+
+ :param ciphertext: The encrypted message.
+ :type ciphertext: bytes/bytearray/memoryview
+
+ :returns: The original message (plaintext).
+ :rtype: bytes
+
+ :raises ValueError:
+ if the ciphertext has the wrong length, or if decryption
+ fails the integrity check (in which case, the decryption
+ key is probably wrong).
+ :raises TypeError:
+ if the RSA key has no private half (i.e. you are trying
+ to decrypt using a public key).
+ """
+
+ # See 7.1.2 in RFC3447
+ modBits = Cryptodome.Util.number.size(self._key.n)
+ k = ceil_div(modBits,8) # Convert from bits to bytes
+ hLen = self._hashObj.digest_size
+
+ # Step 1b and 1c
+ if len(ciphertext) != k or k<hLen+2:
+ raise ValueError("Ciphertext with incorrect length.")
+ # Step 2a (O2SIP)
+ ct_int = bytes_to_long(ciphertext)
+ # Step 2b (RSADP)
+ m_int = self._key._decrypt(ct_int)
+ # Complete step 2c (I2OSP)
+ em = long_to_bytes(m_int, k)
+ # Step 3a
+ lHash = self._hashObj.new(self._label).digest()
+ # Step 3b
+ y = em[0]
+ # y must be 0, but we MUST NOT check it here in order not to
+ # allow attacks like Manger's (http://dl.acm.org/citation.cfm?id=704143)
+ maskedSeed = em[1:hLen+1]
+ maskedDB = em[hLen+1:]
+ # Step 3c
+ seedMask = self._mgf(maskedDB, hLen)
+ # Step 3d
+ seed = strxor(maskedSeed, seedMask)
+ # Step 3e
+ dbMask = self._mgf(seed, k-hLen-1)
+ # Step 3f
+ db = strxor(maskedDB, dbMask)
+ # Step 3g
+ one_pos = db[hLen:].find(b'\x01')
+ lHash1 = db[:hLen]
+ invalid = bord(y) | int(one_pos < 0)
+ hash_compare = strxor(lHash1, lHash)
+ for x in hash_compare:
+ invalid |= bord(x)
+ for x in db[hLen:one_pos]:
+ invalid |= bord(x)
+ if invalid != 0:
+ raise ValueError("Incorrect decryption.")
+ # Step 4
+ return db[hLen + one_pos + 1:]
+
+def new(key, hashAlgo=None, mgfunc=None, label=b'', randfunc=None):
+ """Return a cipher object :class:`PKCS1OAEP_Cipher` that can be used to perform PKCS#1 OAEP encryption or decryption.
+
+ :param key:
+ The key object to use to encrypt or decrypt the message.
+ Decryption is only possible with a private RSA key.
+ :type key: RSA key object
+
+ :param hashAlgo:
+ The hash function to use. This can be a module under `Cryptodome.Hash`
+ or an existing hash object created from any of such modules.
+ If not specified, `Cryptodome.Hash.SHA1` is used.
+ :type hashAlgo: hash object
+
+ :param mgfunc:
+ A mask generation function that accepts two parameters: a string to
+ use as seed, and the lenth of the mask to generate, in bytes.
+ If not specified, the standard MGF1 consistent with ``hashAlgo`` is used (a safe choice).
+ :type mgfunc: callable
+
+ :param label:
+ A label to apply to this particular encryption. If not specified,
+ an empty string is used. Specifying a label does not improve
+ security.
+ :type label: bytes/bytearray/memoryview
+
+ :param randfunc:
+ A function that returns random bytes.
+ The default is `Random.get_random_bytes`.
+ :type randfunc: callable
+ """
+
+ if randfunc is None:
+ randfunc = Random.get_random_bytes
+ return PKCS1OAEP_Cipher(key, hashAlgo, mgfunc, label, randfunc)
+
diff --git a/frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.pyi b/frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.pyi
new file mode 100644
index 0000000..b54cd3f
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/PKCS1_OAEP.pyi
@@ -0,0 +1,35 @@
+from typing import Optional, Union, Callable, Any, overload
+from typing_extensions import Protocol
+
+from Cryptodome.PublicKey.RSA import RsaKey
+
+class HashLikeClass(Protocol):
+ digest_size : int
+ def new(self, data: Optional[bytes] = ...) -> Any: ...
+
+class HashLikeModule(Protocol):
+ digest_size : int
+ @staticmethod
+ def new(data: Optional[bytes] = ...) -> Any: ...
+
+HashLike = Union[HashLikeClass, HashLikeModule]
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+class PKCS1OAEP_Cipher:
+ def __init__(self,
+ key: RsaKey,
+ hashAlgo: HashLike,
+ mgfunc: Callable[[bytes, int], bytes],
+ label: Buffer,
+ randfunc: Callable[[int], bytes]) -> None: ...
+ def can_encrypt(self) -> bool: ...
+ def can_decrypt(self) -> bool: ...
+ def encrypt(self, message: Buffer) -> bytes: ...
+ def decrypt(self, ciphertext: Buffer) -> bytes: ...
+
+def new(key: RsaKey,
+ hashAlgo: Optional[HashLike] = ...,
+ mgfunc: Optional[Callable[[bytes, int], bytes]] = ...,
+ label: Optional[Buffer] = ...,
+ randfunc: Optional[Callable[[int], bytes]] = ...) -> PKCS1OAEP_Cipher: ...
diff --git a/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.py b/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.py
new file mode 100644
index 0000000..1fd1626
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.py
@@ -0,0 +1,199 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/PKCS1-v1_5.py : PKCS#1 v1.5
+#
+# ===================================================================
+# 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.
+# ===================================================================
+
+__all__ = [ 'new', 'PKCS115_Cipher' ]
+
+from Cryptodome.Util.number import ceil_div, bytes_to_long, long_to_bytes
+from Cryptodome.Util.py3compat import bord, _copy_bytes
+import Cryptodome.Util.number
+from Cryptodome import Random
+
+class PKCS115_Cipher:
+ """This cipher can perform PKCS#1 v1.5 RSA encryption or decryption.
+ Do not instantiate directly. Use :func:`Cryptodome.Cipher.PKCS1_v1_5.new` instead."""
+
+ def __init__(self, key, randfunc):
+ """Initialize this PKCS#1 v1.5 cipher object.
+
+ :Parameters:
+ key : an RSA key object
+ If a private half is given, both encryption and decryption are possible.
+ If a public half is given, only encryption is possible.
+ randfunc : callable
+ Function that returns random bytes.
+ """
+
+ self._key = key
+ self._randfunc = randfunc
+
+ def can_encrypt(self):
+ """Return True if this cipher object can be used for encryption."""
+ return self._key.can_encrypt()
+
+ def can_decrypt(self):
+ """Return True if this cipher object can be used for decryption."""
+ return self._key.can_decrypt()
+
+ def encrypt(self, message):
+ """Produce the PKCS#1 v1.5 encryption of a message.
+
+ This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and it is specified in
+ `section 7.2.1 of RFC8017
+ <https://tools.ietf.org/html/rfc8017#page-28>`_.
+
+ :param message:
+ The message to encrypt, also known as plaintext. It can be of
+ variable length, but not longer than the RSA modulus (in bytes) minus 11.
+ :type message: bytes/bytearray/memoryview
+
+ :Returns: A byte string, the ciphertext in which the message is encrypted.
+ It is as long as the RSA modulus (in bytes).
+
+ :Raises ValueError:
+ If the RSA key length is not sufficiently long to deal with the given
+ message.
+ """
+
+ # See 7.2.1 in RFC8017
+ modBits = Cryptodome.Util.number.size(self._key.n)
+ k = ceil_div(modBits,8) # Convert from bits to bytes
+ mLen = len(message)
+
+ # Step 1
+ if mLen > k - 11:
+ raise ValueError("Plaintext is too long.")
+ # Step 2a
+ ps = []
+ while len(ps) != k - mLen - 3:
+ new_byte = self._randfunc(1)
+ if bord(new_byte[0]) == 0x00:
+ continue
+ ps.append(new_byte)
+ ps = b"".join(ps)
+ assert(len(ps) == k - mLen - 3)
+ # Step 2b
+ em = b'\x00\x02' + ps + b'\x00' + _copy_bytes(None, None, message)
+ # Step 3a (OS2IP)
+ em_int = bytes_to_long(em)
+ # Step 3b (RSAEP)
+ m_int = self._key._encrypt(em_int)
+ # Step 3c (I2OSP)
+ c = long_to_bytes(m_int, k)
+ return c
+
+ def decrypt(self, ciphertext, sentinel):
+ r"""Decrypt a PKCS#1 v1.5 ciphertext.
+
+ This function is named ``RSAES-PKCS1-V1_5-DECRYPT``, and is specified in
+ `section 7.2.2 of RFC8017
+ <https://tools.ietf.org/html/rfc8017#page-29>`_.
+
+ :param ciphertext:
+ The ciphertext that contains the message to recover.
+ :type ciphertext: bytes/bytearray/memoryview
+
+ :param sentinel:
+ The object to return whenever an error is detected.
+ :type sentinel: any type
+
+ :Returns: A byte string. It is either the original message or the ``sentinel`` (in case of an error).
+
+ :Raises ValueError:
+ If the ciphertext length is incorrect
+ :Raises TypeError:
+ If the RSA key has no private half (i.e. it cannot be used for
+ decyption).
+
+ .. warning::
+ You should **never** let the party who submitted the ciphertext know that
+ this function returned the ``sentinel`` value.
+ Armed with such knowledge (for a fair amount of carefully crafted but invalid ciphertexts),
+ an attacker is able to recontruct the plaintext of any other encryption that were carried out
+ with the same RSA public key (see `Bleichenbacher's`__ attack).
+
+ In general, it should not be possible for the other party to distinguish
+ whether processing at the server side failed because the value returned
+ was a ``sentinel`` as opposed to a random, invalid message.
+
+ In fact, the second option is not that unlikely: encryption done according to PKCS#1 v1.5
+ embeds no good integrity check. There is roughly one chance
+ in 2\ :sup:`16` for a random ciphertext to be returned as a valid message
+ (although random looking).
+
+ It is therefore advisabled to:
+
+ 1. Select as ``sentinel`` a value that resembles a plausable random, invalid message.
+ 2. Not report back an error as soon as you detect a ``sentinel`` value.
+ Put differently, you should not explicitly check if the returned value is the ``sentinel`` or not.
+ 3. Cover all possible errors with a single, generic error indicator.
+ 4. Embed into the definition of ``message`` (at the protocol level) a digest (e.g. ``SHA-1``).
+ It is recommended for it to be the rightmost part ``message``.
+ 5. Where possible, monitor the number of errors due to ciphertexts originating from the same party,
+ and slow down the rate of the requests from such party (or even blacklist it altogether).
+
+ **If you are designing a new protocol, consider using the more robust PKCS#1 OAEP.**
+
+ .. __: http://www.bell-labs.com/user/bleichen/papers/pkcs.ps
+
+ """
+
+ # See 7.2.1 in RFC3447
+ modBits = Cryptodome.Util.number.size(self._key.n)
+ k = ceil_div(modBits,8) # Convert from bits to bytes
+
+ # Step 1
+ if len(ciphertext) != k:
+ raise ValueError("Ciphertext with incorrect length.")
+ # Step 2a (O2SIP)
+ ct_int = bytes_to_long(ciphertext)
+ # Step 2b (RSADP)
+ m_int = self._key._decrypt(ct_int)
+ # Complete step 2c (I2OSP)
+ em = long_to_bytes(m_int, k)
+ # Step 3
+ sep = em.find(b'\x00', 2)
+ if not em.startswith(b'\x00\x02') or sep < 10:
+ return sentinel
+ # Step 4
+ return em[sep + 1:]
+
+
+def new(key, randfunc=None):
+ """Create a cipher for performing PKCS#1 v1.5 encryption or decryption.
+
+ :param key:
+ The key to use to encrypt or decrypt the message. This is a `Cryptodome.PublicKey.RSA` object.
+ Decryption is only possible if *key* is a private RSA key.
+ :type key: RSA key object
+
+ :param randfunc:
+ Function that return random bytes.
+ The default is :func:`Cryptodome.Random.get_random_bytes`.
+ :type randfunc: callable
+
+ :returns: A cipher object `PKCS115_Cipher`.
+ """
+
+ if randfunc is None:
+ randfunc = Random.get_random_bytes
+ return PKCS115_Cipher(key, randfunc)
+
diff --git a/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.pyi b/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.pyi
new file mode 100644
index 0000000..ff4e3f2
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/PKCS1_v1_5.pyi
@@ -0,0 +1,17 @@
+from typing import Callable, Union, Any, Optional
+
+from Cryptodome.PublicKey.RSA import RsaKey
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+class PKCS115_Cipher:
+ def __init__(self,
+ key: RsaKey,
+ randfunc: Callable[[int], bytes]) -> None: ...
+ def can_encrypt(self) -> bool: ...
+ def can_decrypt(self) -> bool: ...
+ def encrypt(self, message: Buffer) -> bytes: ...
+ def decrypt(self, ciphertext: Buffer) -> bytes: ...
+
+def new(key: RsaKey,
+ randfunc: Optional[Callable[[int], bytes]] = ...) -> PKCS115_Cipher: ...
diff --git a/frozen_deps/Cryptodome/Cipher/Salsa20.py b/frozen_deps/Cryptodome/Cipher/Salsa20.py
new file mode 100644
index 0000000..79e6701
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/Salsa20.py
@@ -0,0 +1,167 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/Salsa20.py : Salsa20 stream cipher (http://cr.yp.to/snuffle.html)
+#
+# Contributed by Fabrizio Tarizzo <[email protected]>.
+#
+# ===================================================================
+# 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.
+# ===================================================================
+
+from Cryptodome.Util.py3compat import _copy_bytes
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib,
+ create_string_buffer,
+ get_raw_buffer, VoidPointer,
+ SmartPointer, c_size_t,
+ c_uint8_ptr, is_writeable_buffer)
+
+from Cryptodome.Random import get_random_bytes
+
+_raw_salsa20_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._Salsa20",
+ """
+ int Salsa20_stream_init(uint8_t *key, size_t keylen,
+ uint8_t *nonce, size_t nonce_len,
+ void **pSalsaState);
+ int Salsa20_stream_destroy(void *salsaState);
+ int Salsa20_stream_encrypt(void *salsaState,
+ const uint8_t in[],
+ uint8_t out[], size_t len);
+ """)
+
+
+class Salsa20Cipher:
+ """Salsa20 cipher object. Do not create it directly. Use :py:func:`new`
+ instead.
+
+ :var nonce: The nonce with length 8
+ :vartype nonce: byte string
+ """
+
+ def __init__(self, key, nonce):
+ """Initialize a Salsa20 cipher object
+
+ See also `new()` at the module level."""
+
+ if len(key) not in key_size:
+ raise ValueError("Incorrect key length for Salsa20 (%d bytes)" % len(key))
+
+ if len(nonce) != 8:
+ raise ValueError("Incorrect nonce length for Salsa20 (%d bytes)" %
+ len(nonce))
+
+ self.nonce = _copy_bytes(None, None, nonce)
+
+ self._state = VoidPointer()
+ result = _raw_salsa20_lib.Salsa20_stream_init(
+ c_uint8_ptr(key),
+ c_size_t(len(key)),
+ c_uint8_ptr(nonce),
+ c_size_t(len(nonce)),
+ self._state.address_of())
+ if result:
+ raise ValueError("Error %d instantiating a Salsa20 cipher")
+ self._state = SmartPointer(self._state.get(),
+ _raw_salsa20_lib.Salsa20_stream_destroy)
+
+ self.block_size = 1
+ self.key_size = len(key)
+
+ def encrypt(self, plaintext, output=None):
+ """Encrypt a piece of data.
+
+ Args:
+ plaintext(bytes/bytearray/memoryview): The data to encrypt, of any size.
+ Keyword Args:
+ output(bytes/bytearray/memoryview): The location where the ciphertext
+ is written to. If ``None``, the ciphertext is returned.
+ Returns:
+ If ``output`` is ``None``, the ciphertext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if output is None:
+ ciphertext = create_string_buffer(len(plaintext))
+ else:
+ ciphertext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(plaintext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+ result = _raw_salsa20_lib.Salsa20_stream_encrypt(
+ self._state.get(),
+ c_uint8_ptr(plaintext),
+ c_uint8_ptr(ciphertext),
+ c_size_t(len(plaintext)))
+ if result:
+ raise ValueError("Error %d while encrypting with Salsa20" % result)
+
+ if output is None:
+ return get_raw_buffer(ciphertext)
+ else:
+ return None
+
+ def decrypt(self, ciphertext, output=None):
+ """Decrypt a piece of data.
+
+ Args:
+ ciphertext(bytes/bytearray/memoryview): The data to decrypt, of any size.
+ Keyword Args:
+ output(bytes/bytearray/memoryview): The location where the plaintext
+ is written to. If ``None``, the plaintext is returned.
+ Returns:
+ If ``output`` is ``None``, the plaintext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ try:
+ return self.encrypt(ciphertext, output=output)
+ except ValueError as e:
+ raise ValueError(str(e).replace("enc", "dec"))
+
+
+def new(key, nonce=None):
+ """Create a new Salsa20 cipher
+
+ :keyword key: The secret key to use. It must be 16 or 32 bytes long.
+ :type key: bytes/bytearray/memoryview
+
+ :keyword nonce:
+ A value that must never be reused for any other encryption
+ done with this key. It must be 8 bytes long.
+
+ If not provided, a random byte string will be generated (you can read
+ it back via the ``nonce`` attribute of the returned object).
+ :type nonce: bytes/bytearray/memoryview
+
+ :Return: a :class:`Cryptodome.Cipher.Salsa20.Salsa20Cipher` object
+ """
+
+ if nonce is None:
+ nonce = get_random_bytes(8)
+
+ return Salsa20Cipher(key, nonce)
+
+# Size of a data block (in bytes)
+block_size = 1
+
+# Size of a key (in bytes)
+key_size = (16, 32)
+
diff --git a/frozen_deps/Cryptodome/Cipher/Salsa20.pyi b/frozen_deps/Cryptodome/Cipher/Salsa20.pyi
new file mode 100644
index 0000000..9178f0d
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/Salsa20.pyi
@@ -0,0 +1,27 @@
+from typing import Union, Tuple, Optional, overload
+
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+class Salsa20Cipher:
+ nonce: bytes
+ block_size: int
+ key_size: int
+
+ def __init__(self,
+ key: Buffer,
+ nonce: Buffer) -> None: ...
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+
+def new(key: Buffer, nonce: Optional[Buffer] = ...) -> Salsa20Cipher: ...
+
+block_size: int
+key_size: Tuple[int, int]
+
diff --git a/frozen_deps/Cryptodome/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..e4d89af
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_ARC4.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.py b/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.py
new file mode 100644
index 0000000..c1c3249
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.py
@@ -0,0 +1,131 @@
+# ===================================================================
+#
+# Copyright (c) 2019, Legrandin <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+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, c_uint)
+
+_raw_blowfish_lib = load_pycryptodome_raw_lib(
+ "Cryptodome.Cipher._raw_eksblowfish",
+ """
+ int EKSBlowfish_start_operation(const uint8_t key[],
+ size_t key_len,
+ const uint8_t salt[16],
+ size_t salt_len,
+ unsigned cost,
+ unsigned invert,
+ void **pResult);
+ int EKSBlowfish_encrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int EKSBlowfish_decrypt(const void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int EKSBlowfish_stop_operation(void *state);
+ """
+ )
+
+
+def _create_base_cipher(dict_parameters):
+ """This method instantiates and returns a smart pointer to
+ a low-level base cipher. It will absorb named parameters in
+ the process."""
+
+ try:
+ key = dict_parameters.pop("key")
+ salt = dict_parameters.pop("salt")
+ cost = dict_parameters.pop("cost")
+ except KeyError as e:
+ raise TypeError("Missing EKSBlowfish parameter: " + str(e))
+ invert = dict_parameters.pop("invert", True)
+
+ if len(key) not in key_size:
+ raise ValueError("Incorrect EKSBlowfish key length (%d bytes)" % len(key))
+
+ start_operation = _raw_blowfish_lib.EKSBlowfish_start_operation
+ stop_operation = _raw_blowfish_lib.EKSBlowfish_stop_operation
+
+ void_p = VoidPointer()
+ result = start_operation(c_uint8_ptr(key),
+ c_size_t(len(key)),
+ c_uint8_ptr(salt),
+ c_size_t(len(salt)),
+ c_uint(cost),
+ c_uint(int(invert)),
+ void_p.address_of())
+ if result:
+ raise ValueError("Error %X while instantiating the EKSBlowfish cipher"
+ % result)
+ return SmartPointer(void_p.get(), stop_operation)
+
+
+def new(key, mode, salt, cost, invert):
+ """Create a new EKSBlowfish cipher
+
+ Args:
+
+ key (bytes, bytearray, memoryview):
+ The secret key to use in the symmetric cipher.
+ Its length can vary from 0 to 72 bytes.
+
+ mode (one of the supported ``MODE_*`` constants):
+ The chaining mode to use for encryption or decryption.
+
+ salt (bytes, bytearray, memoryview):
+ The salt that bcrypt uses to thwart rainbow table attacks
+
+ cost (integer):
+ The complexity factor in bcrypt
+
+ invert (bool):
+ If ``False``, in the inner loop use ``ExpandKey`` first over the salt
+ and then over the key, as defined in
+ the `original bcrypt specification <https://www.usenix.org/legacy/events/usenix99/provos/provos_html/node4.html>`_.
+ If ``True``, reverse the order, as in the first implementation of
+ `bcrypt` in OpenBSD.
+
+ :Return: an EKSBlowfish object
+ """
+
+ kwargs = { 'salt':salt, 'cost':cost, 'invert':invert }
+ return _create_cipher(sys.modules[__name__], key, mode, **kwargs)
+
+
+MODE_ECB = 1
+
+# Size of a data block (in bytes)
+block_size = 8
+# Size of a key (in bytes)
+key_size = range(0, 72 + 1)
diff --git a/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.pyi b/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.pyi
new file mode 100644
index 0000000..49c8448
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_EKSBlowfish.pyi
@@ -0,0 +1,15 @@
+from typing import Union, Iterable
+
+from Cryptodome.Cipher._mode_ecb import EcbMode
+
+MODE_ECB: int
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+def new(key: Buffer,
+ mode: int,
+ salt: Buffer,
+ cost: int) -> EcbMode: ...
+
+block_size: int
+key_size: Iterable[int]
diff --git a/frozen_deps/Cryptodome/Cipher/_Salsa20.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_Salsa20.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..df9884e
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_Salsa20.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/__init__.py b/frozen_deps/Cryptodome/Cipher/__init__.py
new file mode 100644
index 0000000..9bf067f
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/__init__.py
@@ -0,0 +1,79 @@
+#
+# A block cipher is instantiated as a combination of:
+# 1. A base cipher (such as AES)
+# 2. A mode of operation (such as CBC)
+#
+# Both items are implemented as C modules.
+#
+# The API of #1 is (replace "AES" with the name of the actual cipher):
+# - AES_start_operaion(key) --> base_cipher_state
+# - AES_encrypt(base_cipher_state, in, out, length)
+# - AES_decrypt(base_cipher_state, in, out, length)
+# - AES_stop_operation(base_cipher_state)
+#
+# Where base_cipher_state is AES_State, a struct with BlockBase (set of
+# pointers to encrypt/decrypt/stop) followed by cipher-specific data.
+#
+# The API of #2 is (replace "CBC" with the name of the actual mode):
+# - CBC_start_operation(base_cipher_state) --> mode_state
+# - CBC_encrypt(mode_state, in, out, length)
+# - CBC_decrypt(mode_state, in, out, length)
+# - CBC_stop_operation(mode_state)
+#
+# where mode_state is a a pointer to base_cipher_state plus mode-specific data.
+
+import os
+
+from Cryptodome.Cipher._mode_ecb import _create_ecb_cipher
+from Cryptodome.Cipher._mode_cbc import _create_cbc_cipher
+from Cryptodome.Cipher._mode_cfb import _create_cfb_cipher
+from Cryptodome.Cipher._mode_ofb import _create_ofb_cipher
+from Cryptodome.Cipher._mode_ctr import _create_ctr_cipher
+from Cryptodome.Cipher._mode_openpgp import _create_openpgp_cipher
+from Cryptodome.Cipher._mode_ccm import _create_ccm_cipher
+from Cryptodome.Cipher._mode_eax import _create_eax_cipher
+from Cryptodome.Cipher._mode_siv import _create_siv_cipher
+from Cryptodome.Cipher._mode_gcm import _create_gcm_cipher
+from Cryptodome.Cipher._mode_ocb import _create_ocb_cipher
+
+_modes = { 1:_create_ecb_cipher,
+ 2:_create_cbc_cipher,
+ 3:_create_cfb_cipher,
+ 5:_create_ofb_cipher,
+ 6:_create_ctr_cipher,
+ 7:_create_openpgp_cipher,
+ 9:_create_eax_cipher
+ }
+
+_extra_modes = { 8:_create_ccm_cipher,
+ 10:_create_siv_cipher,
+ 11:_create_gcm_cipher,
+ 12:_create_ocb_cipher
+ }
+
+def _create_cipher(factory, key, mode, *args, **kwargs):
+
+ kwargs["key"] = key
+
+ modes = dict(_modes)
+ if kwargs.pop("add_aes_modes", False):
+ modes.update(_extra_modes)
+ if not mode in modes:
+ raise ValueError("Mode not supported")
+
+ if args:
+ if mode in (8, 9, 10, 11, 12):
+ if len(args) > 1:
+ raise TypeError("Too many arguments for this mode")
+ kwargs["nonce"] = args[0]
+ elif mode in (2, 3, 5, 7):
+ if len(args) > 1:
+ raise TypeError("Too many arguments for this mode")
+ kwargs["IV"] = args[0]
+ elif mode == 6:
+ if len(args) > 0:
+ raise TypeError("Too many arguments for this mode")
+ elif mode == 1:
+ raise TypeError("IV is not meaningful for the ECB mode")
+
+ return modes[mode](factory, **kwargs)
diff --git a/frozen_deps/Cryptodome/Cipher/__init__.pyi b/frozen_deps/Cryptodome/Cipher/__init__.pyi
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/__init__.pyi
diff --git a/frozen_deps/Cryptodome/Cipher/_chacha20.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_chacha20.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..ded8fd8
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_chacha20.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_cbc.py b/frozen_deps/Cryptodome/Cipher/_mode_cbc.py
new file mode 100644
index 0000000..edc29ca
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_cbc.py
@@ -0,0 +1,293 @@
+# ===================================================================
+#
+# Copyright (c) 2014, Legrandin <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+"""
+Ciphertext Block Chaining (CBC) mode.
+"""
+
+__all__ = ['CbcMode']
+
+from Cryptodome.Util.py3compat import _copy_bytes
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer,
+ create_string_buffer, get_raw_buffer,
+ SmartPointer, c_size_t, c_uint8_ptr,
+ is_writeable_buffer)
+
+from Cryptodome.Random import get_random_bytes
+
+raw_cbc_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_cbc", """
+ int CBC_start_operation(void *cipher,
+ const uint8_t iv[],
+ size_t iv_len,
+ void **pResult);
+ int CBC_encrypt(void *cbcState,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int CBC_decrypt(void *cbcState,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int CBC_stop_operation(void *state);
+ """
+ )
+
+
+class CbcMode(object):
+ """*Cipher-Block Chaining (CBC)*.
+
+ Each of the ciphertext blocks depends on the current
+ and all previous plaintext blocks.
+
+ An Initialization Vector (*IV*) is required.
+
+ See `NIST SP800-38A`_ , Section 6.2 .
+
+ .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+
+ :undocumented: __init__
+ """
+
+ def __init__(self, block_cipher, iv):
+ """Create a new block cipher, configured in CBC mode.
+
+ :Parameters:
+ block_cipher : C pointer
+ A smart pointer to the low-level block cipher instance.
+
+ iv : bytes/bytearray/memoryview
+ The initialization vector to use for encryption or decryption.
+ It is as long as the cipher block.
+
+ **The IV must be unpredictable**. Ideally it is picked randomly.
+
+ Reusing the *IV* for encryptions performed with the same key
+ compromises confidentiality.
+ """
+
+ self._state = VoidPointer()
+ result = raw_cbc_lib.CBC_start_operation(block_cipher.get(),
+ c_uint8_ptr(iv),
+ c_size_t(len(iv)),
+ self._state.address_of())
+ if result:
+ raise ValueError("Error %d while instantiating the CBC mode"
+ % result)
+
+ # Ensure that object disposal of this Python object will (eventually)
+ # free the memory allocated by the raw library for the cipher mode
+ self._state = SmartPointer(self._state.get(),
+ raw_cbc_lib.CBC_stop_operation)
+
+ # Memory allocated for the underlying block cipher is now owed
+ # by the cipher mode
+ block_cipher.release()
+
+ self.block_size = len(iv)
+ """The block size of the underlying cipher, in bytes."""
+
+ self.iv = _copy_bytes(None, None, iv)
+ """The Initialization Vector originally used to create the object.
+ The value does not change."""
+
+ self.IV = self.iv
+ """Alias for `iv`"""
+
+ self._next = [ self.encrypt, self.decrypt ]
+
+ def encrypt(self, plaintext, output=None):
+ """Encrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have encrypted a message
+ you cannot encrypt (or decrypt) another message using the same
+ object.
+
+ The data to encrypt can be broken up in two or
+ more pieces and `encrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.encrypt(a) + c.encrypt(b)
+
+ is equivalent to:
+
+ >>> c.encrypt(a+b)
+
+ That also means that you cannot reuse an object for encrypting
+ or decrypting other data with the same key.
+
+ This function does not add any padding to the plaintext.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ Its lenght must be multiple of the cipher block size.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ If ``output`` is ``None``, the ciphertext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.encrypt not in self._next:
+ raise TypeError("encrypt() cannot be called after decrypt()")
+ self._next = [ self.encrypt ]
+
+ if output is None:
+ ciphertext = create_string_buffer(len(plaintext))
+ else:
+ ciphertext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(plaintext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+ result = raw_cbc_lib.CBC_encrypt(self._state.get(),
+ c_uint8_ptr(plaintext),
+ c_uint8_ptr(ciphertext),
+ c_size_t(len(plaintext)))
+ if result:
+ if result == 3:
+ raise ValueError("Data must be padded to %d byte boundary in CBC mode" % self.block_size)
+ raise ValueError("Error %d while encrypting in CBC mode" % result)
+
+ if output is None:
+ return get_raw_buffer(ciphertext)
+ else:
+ return None
+
+ def decrypt(self, ciphertext, output=None):
+ """Decrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have decrypted a message
+ you cannot decrypt (or encrypt) another message with the same
+ object.
+
+ The data to decrypt can be broken up in two or
+ more pieces and `decrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.decrypt(a) + c.decrypt(b)
+
+ is equivalent to:
+
+ >>> c.decrypt(a+b)
+
+ This function does not remove any padding from the plaintext.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ Its length must be multiple of the cipher block size.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext must be written to.
+ If ``None``, the plaintext is returned.
+ :Return:
+ If ``output`` is ``None``, the plaintext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.decrypt not in self._next:
+ raise TypeError("decrypt() cannot be called after encrypt()")
+ self._next = [ self.decrypt ]
+
+ if output is None:
+ plaintext = create_string_buffer(len(ciphertext))
+ else:
+ plaintext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(ciphertext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+ result = raw_cbc_lib.CBC_decrypt(self._state.get(),
+ c_uint8_ptr(ciphertext),
+ c_uint8_ptr(plaintext),
+ c_size_t(len(ciphertext)))
+ if result:
+ if result == 3:
+ raise ValueError("Data must be padded to %d byte boundary in CBC mode" % self.block_size)
+ raise ValueError("Error %d while decrypting in CBC mode" % result)
+
+ if output is None:
+ return get_raw_buffer(plaintext)
+ else:
+ return None
+
+
+def _create_cbc_cipher(factory, **kwargs):
+ """Instantiate a cipher object that performs CBC encryption/decryption.
+
+ :Parameters:
+ factory : module
+ The underlying block cipher, a module from ``Cryptodome.Cipher``.
+
+ :Keywords:
+ iv : bytes/bytearray/memoryview
+ The IV to use for CBC.
+
+ IV : bytes/bytearray/memoryview
+ Alias for ``iv``.
+
+ Any other keyword will be passed to the underlying block cipher.
+ See the relevant documentation for details (at least ``key`` will need
+ to be present).
+ """
+
+ cipher_state = factory._create_base_cipher(kwargs)
+ iv = kwargs.pop("IV", None)
+ IV = kwargs.pop("iv", None)
+
+ if (None, None) == (iv, IV):
+ iv = get_random_bytes(factory.block_size)
+ if iv is not None:
+ if IV is not None:
+ raise TypeError("You must either use 'iv' or 'IV', not both")
+ else:
+ iv = IV
+
+ if len(iv) != factory.block_size:
+ raise ValueError("Incorrect IV length (it must be %d bytes long)" %
+ factory.block_size)
+
+ if kwargs:
+ raise TypeError("Unknown parameters for CBC: %s" % str(kwargs))
+
+ return CbcMode(cipher_state, iv)
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_cbc.pyi b/frozen_deps/Cryptodome/Cipher/_mode_cbc.pyi
new file mode 100644
index 0000000..526632e
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_cbc.pyi
@@ -0,0 +1,25 @@
+from typing import Union, overload
+
+from Cryptodome.Util._raw_api import SmartPointer
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+__all__ = ['CbcMode']
+
+class CbcMode(object):
+ block_size: int
+ iv: Buffer
+ IV: Buffer
+
+ def __init__(self,
+ block_cipher: SmartPointer,
+ iv: Buffer) -> None: ...
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ccm.py b/frozen_deps/Cryptodome/Cipher/_mode_ccm.py
new file mode 100644
index 0000000..0e1c2f6
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_ccm.py
@@ -0,0 +1,650 @@
+# ===================================================================
+#
+# Copyright (c) 2014, Legrandin <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+"""
+Counter with CBC-MAC (CCM) mode.
+"""
+
+__all__ = ['CcmMode']
+
+import struct
+from binascii import unhexlify
+
+from Cryptodome.Util.py3compat import (byte_string, bord,
+ _copy_bytes)
+from Cryptodome.Util._raw_api import is_writeable_buffer
+
+from Cryptodome.Util.strxor import strxor
+from Cryptodome.Util.number import long_to_bytes
+
+from Cryptodome.Hash import BLAKE2s
+from Cryptodome.Random import get_random_bytes
+
+
+def enum(**enums):
+ return type('Enum', (), enums)
+
+MacStatus = enum(NOT_STARTED=0, PROCESSING_AUTH_DATA=1, PROCESSING_PLAINTEXT=2)
+
+
+class CcmMode(object):
+ """Counter with CBC-MAC (CCM).
+
+ This is an Authenticated Encryption with Associated Data (`AEAD`_) mode.
+ It provides both confidentiality and authenticity.
+
+ The header of the message may be left in the clear, if needed, and it will
+ still be subject to authentication. The decryption step tells the receiver
+ if the message comes from a source that really knowns the secret key.
+ Additionally, decryption detects if any part of the message - including the
+ header - has been modified or corrupted.
+
+ This mode requires a nonce. The nonce shall never repeat for two
+ different messages encrypted with the same key, but it does not need
+ to be random.
+ Note that there is a trade-off between the size of the nonce and the
+ maximum size of a single message you can encrypt.
+
+ It is important to use a large nonce if the key is reused across several
+ messages and the nonce is chosen randomly.
+
+ It is acceptable to us a short nonce if the key is only used a few times or
+ if the nonce is taken from a counter.
+
+ The following table shows the trade-off when the nonce is chosen at
+ random. The column on the left shows how many messages it takes
+ for the keystream to repeat **on average**. In practice, you will want to
+ stop using the key way before that.
+
+ +--------------------+---------------+-------------------+
+ | Avg. # of messages | nonce | Max. message |
+ | before keystream | size | size |
+ | repeats | (bytes) | (bytes) |
+ +====================+===============+===================+
+ | 2^52 | 13 | 64K |
+ +--------------------+---------------+-------------------+
+ | 2^48 | 12 | 16M |
+ +--------------------+---------------+-------------------+
+ | 2^44 | 11 | 4G |
+ +--------------------+---------------+-------------------+
+ | 2^40 | 10 | 1T |
+ +--------------------+---------------+-------------------+
+ | 2^36 | 9 | 64P |
+ +--------------------+---------------+-------------------+
+ | 2^32 | 8 | 16E |
+ +--------------------+---------------+-------------------+
+
+ This mode is only available for ciphers that operate on 128 bits blocks
+ (e.g. AES but not TDES).
+
+ See `NIST SP800-38C`_ or RFC3610_.
+
+ .. _`NIST SP800-38C`: http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C.pdf
+ .. _RFC3610: https://tools.ietf.org/html/rfc3610
+ .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html
+
+ :undocumented: __init__
+ """
+
+ def __init__(self, factory, key, nonce, mac_len, msg_len, assoc_len,
+ cipher_params):
+
+ self.block_size = factory.block_size
+ """The block size of the underlying cipher, in bytes."""
+
+ self.nonce = _copy_bytes(None, None, nonce)
+ """The nonce used for this cipher instance"""
+
+ self._factory = factory
+ self._key = _copy_bytes(None, None, key)
+ self._mac_len = mac_len
+ self._msg_len = msg_len
+ self._assoc_len = assoc_len
+ self._cipher_params = cipher_params
+
+ self._mac_tag = None # Cache for MAC tag
+
+ if self.block_size != 16:
+ raise ValueError("CCM mode is only available for ciphers"
+ " that operate on 128 bits blocks")
+
+ # MAC tag length (Tlen)
+ if mac_len not in (4, 6, 8, 10, 12, 14, 16):
+ raise ValueError("Parameter 'mac_len' must be even"
+ " and in the range 4..16 (not %d)" % mac_len)
+
+ # Nonce value
+ if not (nonce and 7 <= len(nonce) <= 13):
+ raise ValueError("Length of parameter 'nonce' must be"
+ " in the range 7..13 bytes")
+
+ # Create MAC object (the tag will be the last block
+ # bytes worth of ciphertext)
+ self._mac = self._factory.new(key,
+ factory.MODE_CBC,
+ iv=b'\x00' * 16,
+ **cipher_params)
+ self._mac_status = MacStatus.NOT_STARTED
+ self._t = None
+
+ # Allowed transitions after initialization
+ self._next = [self.update, self.encrypt, self.decrypt,
+ self.digest, self.verify]
+
+ # Cumulative lengths
+ self._cumul_assoc_len = 0
+ self._cumul_msg_len = 0
+
+ # Cache for unaligned associated data/plaintext.
+ # This is a list with byte strings, but when the MAC starts,
+ # it will become a binary string no longer than the block size.
+ self._cache = []
+
+ # Start CTR cipher, by formatting the counter (A.3)
+ q = 15 - len(nonce) # length of Q, the encoded message length
+ self._cipher = self._factory.new(key,
+ self._factory.MODE_CTR,
+ nonce=struct.pack("B", q - 1) + self.nonce,
+ **cipher_params)
+
+ # S_0, step 6 in 6.1 for j=0
+ self._s_0 = self._cipher.encrypt(b'\x00' * 16)
+
+ # Try to start the MAC
+ if None not in (assoc_len, msg_len):
+ self._start_mac()
+
+ def _start_mac(self):
+
+ assert(self._mac_status == MacStatus.NOT_STARTED)
+ assert(None not in (self._assoc_len, self._msg_len))
+ assert(isinstance(self._cache, list))
+
+ # Formatting control information and nonce (A.2.1)
+ q = 15 - len(self.nonce) # length of Q, the encoded message length
+ flags = (64 * (self._assoc_len > 0) + 8 * ((self._mac_len - 2) // 2) +
+ (q - 1))
+ b_0 = struct.pack("B", flags) + self.nonce + long_to_bytes(self._msg_len, q)
+
+ # Formatting associated data (A.2.2)
+ # Encoded 'a' is concatenated with the associated data 'A'
+ assoc_len_encoded = b''
+ if self._assoc_len > 0:
+ if self._assoc_len < (2 ** 16 - 2 ** 8):
+ enc_size = 2
+ elif self._assoc_len < (2 ** 32):
+ assoc_len_encoded = b'\xFF\xFE'
+ enc_size = 4
+ else:
+ assoc_len_encoded = b'\xFF\xFF'
+ enc_size = 8
+ assoc_len_encoded += long_to_bytes(self._assoc_len, enc_size)
+
+ # b_0 and assoc_len_encoded must be processed first
+ self._cache.insert(0, b_0)
+ self._cache.insert(1, assoc_len_encoded)
+
+ # Process all the data cached so far
+ first_data_to_mac = b"".join(self._cache)
+ self._cache = b""
+ self._mac_status = MacStatus.PROCESSING_AUTH_DATA
+ self._update(first_data_to_mac)
+
+ def _pad_cache_and_update(self):
+
+ assert(self._mac_status != MacStatus.NOT_STARTED)
+ assert(len(self._cache) < self.block_size)
+
+ # Associated data is concatenated with the least number
+ # of zero bytes (possibly none) to reach alignment to
+ # the 16 byte boundary (A.2.3)
+ len_cache = len(self._cache)
+ if len_cache > 0:
+ self._update(b'\x00' * (self.block_size - len_cache))
+
+ def update(self, assoc_data):
+ """Protect associated data
+
+ If there is any associated data, the caller has to invoke
+ this function one or more times, before using
+ ``decrypt`` or ``encrypt``.
+
+ By *associated data* it is meant any data (e.g. packet headers) that
+ will not be encrypted and will be transmitted in the clear.
+ However, the receiver is still able to detect any modification to it.
+ In CCM, the *associated data* is also called
+ *additional authenticated data* (AAD).
+
+ If there is no associated data, this method must not be called.
+
+ The caller may split associated data in segments of any size, and
+ invoke this method multiple times, each time with the next segment.
+
+ :Parameters:
+ assoc_data : bytes/bytearray/memoryview
+ A piece of associated data. There are no restrictions on its size.
+ """
+
+ if self.update not in self._next:
+ raise TypeError("update() can only be called"
+ " immediately after initialization")
+
+ self._next = [self.update, self.encrypt, self.decrypt,
+ self.digest, self.verify]
+
+ self._cumul_assoc_len += len(assoc_data)
+ if self._assoc_len is not None and \
+ self._cumul_assoc_len > self._assoc_len:
+ raise ValueError("Associated data is too long")
+
+ self._update(assoc_data)
+ return self
+
+ def _update(self, assoc_data_pt=b""):
+ """Update the MAC with associated data or plaintext
+ (without FSM checks)"""
+
+ # If MAC has not started yet, we just park the data into a list.
+ # If the data is mutable, we create a copy and store that instead.
+ if self._mac_status == MacStatus.NOT_STARTED:
+ if is_writeable_buffer(assoc_data_pt):
+ assoc_data_pt = _copy_bytes(None, None, assoc_data_pt)
+ self._cache.append(assoc_data_pt)
+ return
+
+ assert(len(self._cache) < self.block_size)
+
+ if len(self._cache) > 0:
+ filler = min(self.block_size - len(self._cache),
+ len(assoc_data_pt))
+ self._cache += _copy_bytes(None, filler, assoc_data_pt)
+ assoc_data_pt = _copy_bytes(filler, None, assoc_data_pt)
+
+ if len(self._cache) < self.block_size:
+ return
+
+ # The cache is exactly one block
+ self._t = self._mac.encrypt(self._cache)
+ self._cache = b""
+
+ update_len = len(assoc_data_pt) // self.block_size * self.block_size
+ self._cache = _copy_bytes(update_len, None, assoc_data_pt)
+ if update_len > 0:
+ self._t = self._mac.encrypt(assoc_data_pt[:update_len])[-16:]
+
+ def encrypt(self, plaintext, output=None):
+ """Encrypt data with the key set at initialization.
+
+ A cipher object is stateful: once you have encrypted a message
+ you cannot encrypt (or decrypt) another message using the same
+ object.
+
+ This method can be called only **once** if ``msg_len`` was
+ not passed at initialization.
+
+ If ``msg_len`` was given, the data to encrypt can be broken
+ up in two or more pieces and `encrypt` can be called
+ multiple times.
+
+ That is, the statement:
+
+ >>> c.encrypt(a) + c.encrypt(b)
+
+ is equivalent to:
+
+ >>> c.encrypt(a+b)
+
+ This function does not add any padding to the plaintext.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ If ``output`` is ``None``, the ciphertext as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.encrypt not in self._next:
+ raise TypeError("encrypt() can only be called after"
+ " initialization or an update()")
+ self._next = [self.encrypt, self.digest]
+
+ # No more associated data allowed from now
+ if self._assoc_len is None:
+ assert(isinstance(self._cache, list))
+ self._assoc_len = sum([len(x) for x in self._cache])
+ if self._msg_len is not None:
+ self._start_mac()
+ else:
+ if self._cumul_assoc_len < self._assoc_len:
+ raise ValueError("Associated data is too short")
+
+ # Only once piece of plaintext accepted if message length was
+ # not declared in advance
+ if self._msg_len is None:
+ self._msg_len = len(plaintext)
+ self._start_mac()
+ self._next = [self.digest]
+
+ self._cumul_msg_len += len(plaintext)
+ if self._cumul_msg_len > self._msg_len:
+ raise ValueError("Message is too long")
+
+ if self._mac_status == MacStatus.PROCESSING_AUTH_DATA:
+ # Associated data is concatenated with the least number
+ # of zero bytes (possibly none) to reach alignment to
+ # the 16 byte boundary (A.2.3)
+ self._pad_cache_and_update()
+ self._mac_status = MacStatus.PROCESSING_PLAINTEXT
+
+ self._update(plaintext)
+ return self._cipher.encrypt(plaintext, output=output)
+
+ def decrypt(self, ciphertext, output=None):
+ """Decrypt data with the key set at initialization.
+
+ A cipher object is stateful: once you have decrypted a message
+ you cannot decrypt (or encrypt) another message with the same
+ object.
+
+ This method can be called only **once** if ``msg_len`` was
+ not passed at initialization.
+
+ If ``msg_len`` was given, the data to decrypt can be
+ broken up in two or more pieces and `decrypt` can be
+ called multiple times.
+
+ That is, the statement:
+
+ >>> c.decrypt(a) + c.decrypt(b)
+
+ is equivalent to:
+
+ >>> c.decrypt(a+b)
+
+ This function does not remove any padding from the plaintext.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext must be written to.
+ If ``None``, the plaintext is returned.
+ :Return:
+ If ``output`` is ``None``, the plaintext as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.decrypt not in self._next:
+ raise TypeError("decrypt() can only be called"
+ " after initialization or an update()")
+ self._next = [self.decrypt, self.verify]
+
+ # No more associated data allowed from now
+ if self._assoc_len is None:
+ assert(isinstance(self._cache, list))
+ self._assoc_len = sum([len(x) for x in self._cache])
+ if self._msg_len is not None:
+ self._start_mac()
+ else:
+ if self._cumul_assoc_len < self._assoc_len:
+ raise ValueError("Associated data is too short")
+
+ # Only once piece of ciphertext accepted if message length was
+ # not declared in advance
+ if self._msg_len is None:
+ self._msg_len = len(ciphertext)
+ self._start_mac()
+ self._next = [self.verify]
+
+ self._cumul_msg_len += len(ciphertext)
+ if self._cumul_msg_len > self._msg_len:
+ raise ValueError("Message is too long")
+
+ if self._mac_status == MacStatus.PROCESSING_AUTH_DATA:
+ # Associated data is concatenated with the least number
+ # of zero bytes (possibly none) to reach alignment to
+ # the 16 byte boundary (A.2.3)
+ self._pad_cache_and_update()
+ self._mac_status = MacStatus.PROCESSING_PLAINTEXT
+
+ # Encrypt is equivalent to decrypt with the CTR mode
+ plaintext = self._cipher.encrypt(ciphertext, output=output)
+ if output is None:
+ self._update(plaintext)
+ else:
+ self._update(output)
+ return plaintext
+
+ def digest(self):
+ """Compute the *binary* MAC tag.
+
+ The caller invokes this function at the very end.
+
+ This method returns the MAC that shall be sent to the receiver,
+ together with the ciphertext.
+
+ :Return: the MAC, as a byte string.
+ """
+
+ if self.digest not in self._next:
+ raise TypeError("digest() cannot be called when decrypting"
+ " or validating a message")
+ self._next = [self.digest]
+ return self._digest()
+
+ def _digest(self):
+ if self._mac_tag:
+ return self._mac_tag
+
+ if self._assoc_len is None:
+ assert(isinstance(self._cache, list))
+ self._assoc_len = sum([len(x) for x in self._cache])
+ if self._msg_len is not None:
+ self._start_mac()
+ else:
+ if self._cumul_assoc_len < self._assoc_len:
+ raise ValueError("Associated data is too short")
+
+ if self._msg_len is None:
+ self._msg_len = 0
+ self._start_mac()
+
+ if self._cumul_msg_len != self._msg_len:
+ raise ValueError("Message is too short")
+
+ # Both associated data and payload are concatenated with the least
+ # number of zero bytes (possibly none) that align it to the
+ # 16 byte boundary (A.2.2 and A.2.3)
+ self._pad_cache_and_update()
+
+ # Step 8 in 6.1 (T xor MSB_Tlen(S_0))
+ self._mac_tag = strxor(self._t, self._s_0)[:self._mac_len]
+
+ return self._mac_tag
+
+ def hexdigest(self):
+ """Compute the *printable* MAC tag.
+
+ This method is like `digest`.
+
+ :Return: the MAC, as a hexadecimal string.
+ """
+ return "".join(["%02x" % bord(x) for x in self.digest()])
+
+ def verify(self, received_mac_tag):
+ """Validate the *binary* MAC tag.
+
+ The caller invokes this function at the very end.
+
+ This method checks if the decrypted message is indeed valid
+ (that is, if the key is correct) and it has not been
+ tampered with while in transit.
+
+ :Parameters:
+ received_mac_tag : bytes/bytearray/memoryview
+ This is the *binary* MAC, as received from the sender.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ if self.verify not in self._next:
+ raise TypeError("verify() cannot be called"
+ " when encrypting a message")
+ self._next = [self.verify]
+
+ self._digest()
+ secret = get_random_bytes(16)
+
+ mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag)
+ mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag)
+
+ if mac1.digest() != mac2.digest():
+ raise ValueError("MAC check failed")
+
+ def hexverify(self, hex_mac_tag):
+ """Validate the *printable* MAC tag.
+
+ This method is like `verify`.
+
+ :Parameters:
+ hex_mac_tag : string
+ This is the *printable* MAC, as received from the sender.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ self.verify(unhexlify(hex_mac_tag))
+
+ def encrypt_and_digest(self, plaintext, output=None):
+ """Perform encrypt() and digest() in one step.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ a tuple with two items:
+
+ - the ciphertext, as ``bytes``
+ - the MAC tag, as ``bytes``
+
+ The first item becomes ``None`` when the ``output`` parameter
+ specified a location for the result.
+ """
+
+ return self.encrypt(plaintext, output=output), self.digest()
+
+ def decrypt_and_verify(self, ciphertext, received_mac_tag, output=None):
+ """Perform decrypt() and verify() in one step.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ received_mac_tag : bytes/bytearray/memoryview
+ This is the *binary* MAC, as received from the sender.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext must be written to.
+ If ``None``, the plaintext is returned.
+ :Return: the plaintext as ``bytes`` or ``None`` when the ``output``
+ parameter specified a location for the result.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ plaintext = self.decrypt(ciphertext, output=output)
+ self.verify(received_mac_tag)
+ return plaintext
+
+
+def _create_ccm_cipher(factory, **kwargs):
+ """Create a new block cipher, configured in CCM mode.
+
+ :Parameters:
+ factory : module
+ A symmetric cipher module from `Cryptodome.Cipher` (like
+ `Cryptodome.Cipher.AES`).
+
+ :Keywords:
+ key : bytes/bytearray/memoryview
+ The secret key to use in the symmetric cipher.
+
+ nonce : bytes/bytearray/memoryview
+ A value that must never be reused for any other encryption.
+
+ Its length must be in the range ``[7..13]``.
+ 11 or 12 bytes are reasonable values in general. Bear in
+ mind that with CCM there is a trade-off between nonce length and
+ maximum message size.
+
+ If not specified, a 11 byte long random string is used.
+
+ mac_len : integer
+ Length of the MAC, in bytes. It must be even and in
+ the range ``[4..16]``. The default is 16.
+
+ msg_len : integer
+ Length of the message to (de)cipher.
+ If not specified, ``encrypt`` or ``decrypt`` may only be called once.
+
+ assoc_len : integer
+ Length of the associated data.
+ If not specified, all data is internally buffered.
+ """
+
+ try:
+ key = key = kwargs.pop("key")
+ except KeyError as e:
+ raise TypeError("Missing parameter: " + str(e))
+
+ nonce = kwargs.pop("nonce", None) # N
+ if nonce is None:
+ nonce = get_random_bytes(11)
+ mac_len = kwargs.pop("mac_len", factory.block_size)
+ msg_len = kwargs.pop("msg_len", None) # p
+ assoc_len = kwargs.pop("assoc_len", None) # a
+ cipher_params = dict(kwargs)
+
+ return CcmMode(factory, key, nonce, mac_len, msg_len,
+ assoc_len, cipher_params)
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ccm.pyi b/frozen_deps/Cryptodome/Cipher/_mode_ccm.pyi
new file mode 100644
index 0000000..4b9f620
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_ccm.pyi
@@ -0,0 +1,47 @@
+from types import ModuleType
+from typing import Union, overload, Dict, Tuple, Optional
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+__all__ = ['CcmMode']
+
+class CcmMode(object):
+ block_size: int
+ nonce: bytes
+
+ def __init__(self,
+ factory: ModuleType,
+ key: Buffer,
+ nonce: Buffer,
+ mac_len: int,
+ msg_len: int,
+ assoc_len: int,
+ cipher_params: Dict) -> None: ...
+
+ def update(self, assoc_data: Buffer) -> CcmMode: ...
+
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+
+ def digest(self) -> bytes: ...
+ def hexdigest(self) -> str: ...
+ def verify(self, received_mac_tag: Buffer) -> None: ...
+ def hexverify(self, hex_mac_tag: str) -> None: ...
+
+ @overload
+ def encrypt_and_digest(self,
+ plaintext: Buffer) -> Tuple[bytes, bytes]: ...
+ @overload
+ def encrypt_and_digest(self,
+ plaintext: Buffer,
+ output: Buffer) -> Tuple[None, bytes]: ...
+ def decrypt_and_verify(self,
+ ciphertext: Buffer,
+ received_mac_tag: Buffer,
+ output: Optional[Union[bytearray, memoryview]] = ...) -> bytes: ...
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_cfb.py b/frozen_deps/Cryptodome/Cipher/_mode_cfb.py
new file mode 100644
index 0000000..b790dd4
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_cfb.py
@@ -0,0 +1,293 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/mode_cfb.py : CFB mode
+#
+# ===================================================================
+# 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.
+# ===================================================================
+
+"""
+Counter Feedback (CFB) mode.
+"""
+
+__all__ = ['CfbMode']
+
+from Cryptodome.Util.py3compat import _copy_bytes
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer,
+ create_string_buffer, get_raw_buffer,
+ SmartPointer, c_size_t, c_uint8_ptr,
+ is_writeable_buffer)
+
+from Cryptodome.Random import get_random_bytes
+
+raw_cfb_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_cfb","""
+ int CFB_start_operation(void *cipher,
+ const uint8_t iv[],
+ size_t iv_len,
+ size_t segment_len, /* In bytes */
+ void **pResult);
+ int CFB_encrypt(void *cfbState,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int CFB_decrypt(void *cfbState,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int CFB_stop_operation(void *state);"""
+ )
+
+
+class CfbMode(object):
+ """*Cipher FeedBack (CFB)*.
+
+ This mode is similar to CFB, but it transforms
+ the underlying block cipher into a stream cipher.
+
+ Plaintext and ciphertext are processed in *segments*
+ of **s** bits. The mode is therefore sometimes
+ labelled **s**-bit CFB.
+
+ An Initialization Vector (*IV*) is required.
+
+ See `NIST SP800-38A`_ , Section 6.3.
+
+ .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+
+ :undocumented: __init__
+ """
+
+ def __init__(self, block_cipher, iv, segment_size):
+ """Create a new block cipher, configured in CFB mode.
+
+ :Parameters:
+ block_cipher : C pointer
+ A smart pointer to the low-level block cipher instance.
+
+ iv : bytes/bytearray/memoryview
+ The initialization vector to use for encryption or decryption.
+ It is as long as the cipher block.
+
+ **The IV must be unpredictable**. Ideally it is picked randomly.
+
+ Reusing the *IV* for encryptions performed with the same key
+ compromises confidentiality.
+
+ segment_size : integer
+ The number of bytes the plaintext and ciphertext are segmented in.
+ """
+
+ self._state = VoidPointer()
+ result = raw_cfb_lib.CFB_start_operation(block_cipher.get(),
+ c_uint8_ptr(iv),
+ c_size_t(len(iv)),
+ c_size_t(segment_size),
+ self._state.address_of())
+ if result:
+ raise ValueError("Error %d while instantiating the CFB mode" % result)
+
+ # Ensure that object disposal of this Python object will (eventually)
+ # free the memory allocated by the raw library for the cipher mode
+ self._state = SmartPointer(self._state.get(),
+ raw_cfb_lib.CFB_stop_operation)
+
+ # Memory allocated for the underlying block cipher is now owed
+ # by the cipher mode
+ block_cipher.release()
+
+ self.block_size = len(iv)
+ """The block size of the underlying cipher, in bytes."""
+
+ self.iv = _copy_bytes(None, None, iv)
+ """The Initialization Vector originally used to create the object.
+ The value does not change."""
+
+ self.IV = self.iv
+ """Alias for `iv`"""
+
+ self._next = [ self.encrypt, self.decrypt ]
+
+ def encrypt(self, plaintext, output=None):
+ """Encrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have encrypted a message
+ you cannot encrypt (or decrypt) another message using the same
+ object.
+
+ The data to encrypt can be broken up in two or
+ more pieces and `encrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.encrypt(a) + c.encrypt(b)
+
+ is equivalent to:
+
+ >>> c.encrypt(a+b)
+
+ This function does not add any padding to the plaintext.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ If ``output`` is ``None``, the ciphertext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.encrypt not in self._next:
+ raise TypeError("encrypt() cannot be called after decrypt()")
+ self._next = [ self.encrypt ]
+
+ if output is None:
+ ciphertext = create_string_buffer(len(plaintext))
+ else:
+ ciphertext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(plaintext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+ result = raw_cfb_lib.CFB_encrypt(self._state.get(),
+ c_uint8_ptr(plaintext),
+ c_uint8_ptr(ciphertext),
+ c_size_t(len(plaintext)))
+ if result:
+ raise ValueError("Error %d while encrypting in CFB mode" % result)
+
+ if output is None:
+ return get_raw_buffer(ciphertext)
+ else:
+ return None
+
+ def decrypt(self, ciphertext, output=None):
+ """Decrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have decrypted a message
+ you cannot decrypt (or encrypt) another message with the same
+ object.
+
+ The data to decrypt can be broken up in two or
+ more pieces and `decrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.decrypt(a) + c.decrypt(b)
+
+ is equivalent to:
+
+ >>> c.decrypt(a+b)
+
+ This function does not remove any padding from the plaintext.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext must be written to.
+ If ``None``, the plaintext is returned.
+ :Return:
+ If ``output`` is ``None``, the plaintext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.decrypt not in self._next:
+ raise TypeError("decrypt() cannot be called after encrypt()")
+ self._next = [ self.decrypt ]
+
+ if output is None:
+ plaintext = create_string_buffer(len(ciphertext))
+ else:
+ plaintext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(ciphertext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+ result = raw_cfb_lib.CFB_decrypt(self._state.get(),
+ c_uint8_ptr(ciphertext),
+ c_uint8_ptr(plaintext),
+ c_size_t(len(ciphertext)))
+ if result:
+ raise ValueError("Error %d while decrypting in CFB mode" % result)
+
+ if output is None:
+ return get_raw_buffer(plaintext)
+ else:
+ return None
+
+
+def _create_cfb_cipher(factory, **kwargs):
+ """Instantiate a cipher object that performs CFB encryption/decryption.
+
+ :Parameters:
+ factory : module
+ The underlying block cipher, a module from ``Cryptodome.Cipher``.
+
+ :Keywords:
+ iv : bytes/bytearray/memoryview
+ The IV to use for CFB.
+
+ IV : bytes/bytearray/memoryview
+ Alias for ``iv``.
+
+ segment_size : integer
+ The number of bit the plaintext and ciphertext are segmented in.
+ If not present, the default is 8.
+
+ Any other keyword will be passed to the underlying block cipher.
+ See the relevant documentation for details (at least ``key`` will need
+ to be present).
+ """
+
+ cipher_state = factory._create_base_cipher(kwargs)
+
+ iv = kwargs.pop("IV", None)
+ IV = kwargs.pop("iv", None)
+
+ if (None, None) == (iv, IV):
+ iv = get_random_bytes(factory.block_size)
+ if iv is not None:
+ if IV is not None:
+ raise TypeError("You must either use 'iv' or 'IV', not both")
+ else:
+ iv = IV
+
+ if len(iv) != factory.block_size:
+ raise ValueError("Incorrect IV length (it must be %d bytes long)" %
+ factory.block_size)
+
+ segment_size_bytes, rem = divmod(kwargs.pop("segment_size", 8), 8)
+ if segment_size_bytes == 0 or rem != 0:
+ raise ValueError("'segment_size' must be positive and multiple of 8 bits")
+
+ if kwargs:
+ raise TypeError("Unknown parameters for CFB: %s" % str(kwargs))
+ return CfbMode(cipher_state, iv, segment_size_bytes)
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_cfb.pyi b/frozen_deps/Cryptodome/Cipher/_mode_cfb.pyi
new file mode 100644
index 0000000..228e464
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_cfb.pyi
@@ -0,0 +1,26 @@
+from typing import Union, overload
+
+from Cryptodome.Util._raw_api import SmartPointer
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+__all__ = ['CfbMode']
+
+
+class CfbMode(object):
+ block_size: int
+ iv: Buffer
+ IV: Buffer
+
+ def __init__(self,
+ block_cipher: SmartPointer,
+ iv: Buffer,
+ segment_size: int) -> None: ...
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ctr.py b/frozen_deps/Cryptodome/Cipher/_mode_ctr.py
new file mode 100644
index 0000000..99712d0
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_ctr.py
@@ -0,0 +1,393 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/mode_ctr.py : CTR mode
+#
+# ===================================================================
+# 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.
+# ===================================================================
+
+"""
+Counter (CTR) mode.
+"""
+
+__all__ = ['CtrMode']
+
+import struct
+
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer,
+ create_string_buffer, get_raw_buffer,
+ SmartPointer, c_size_t, c_uint8_ptr,
+ is_writeable_buffer)
+
+from Cryptodome.Random import get_random_bytes
+from Cryptodome.Util.py3compat import _copy_bytes, is_native_int
+from Cryptodome.Util.number import long_to_bytes
+
+raw_ctr_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_ctr", """
+ int CTR_start_operation(void *cipher,
+ uint8_t initialCounterBlock[],
+ size_t initialCounterBlock_len,
+ size_t prefix_len,
+ unsigned counter_len,
+ unsigned littleEndian,
+ void **pResult);
+ int CTR_encrypt(void *ctrState,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int CTR_decrypt(void *ctrState,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int CTR_stop_operation(void *ctrState);"""
+ )
+
+
+class CtrMode(object):
+ """*CounTeR (CTR)* mode.
+
+ This mode is very similar to ECB, in that
+ encryption of one block is done independently of all other blocks.
+
+ Unlike ECB, the block *position* contributes to the encryption
+ and no information leaks about symbol frequency.
+
+ Each message block is associated to a *counter* which
+ must be unique across all messages that get encrypted
+ with the same key (not just within the same message).
+ The counter is as big as the block size.
+
+ Counters can be generated in several ways. The most
+ straightword one is to choose an *initial counter block*
+ (which can be made public, similarly to the *IV* for the
+ other modes) and increment its lowest **m** bits by one
+ (modulo *2^m*) for each block. In most cases, **m** is
+ chosen to be half the block size.
+
+ See `NIST SP800-38A`_, Section 6.5 (for the mode) and
+ Appendix B (for how to manage the *initial counter block*).
+
+ .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+
+ :undocumented: __init__
+ """
+
+ def __init__(self, block_cipher, initial_counter_block,
+ prefix_len, counter_len, little_endian):
+ """Create a new block cipher, configured in CTR mode.
+
+ :Parameters:
+ block_cipher : C pointer
+ A smart pointer to the low-level block cipher instance.
+
+ initial_counter_block : bytes/bytearray/memoryview
+ The initial plaintext to use to generate the key stream.
+
+ It is as large as the cipher block, and it embeds
+ the initial value of the counter.
+
+ This value must not be reused.
+ It shall contain a nonce or a random component.
+ Reusing the *initial counter block* for encryptions
+ performed with the same key compromises confidentiality.
+
+ prefix_len : integer
+ The amount of bytes at the beginning of the counter block
+ that never change.
+
+ counter_len : integer
+ The length in bytes of the counter embedded in the counter
+ block.
+
+ little_endian : boolean
+ True if the counter in the counter block is an integer encoded
+ in little endian mode. If False, it is big endian.
+ """
+
+ if len(initial_counter_block) == prefix_len + counter_len:
+ self.nonce = _copy_bytes(None, prefix_len, initial_counter_block)
+ """Nonce; not available if there is a fixed suffix"""
+
+ self._state = VoidPointer()
+ result = raw_ctr_lib.CTR_start_operation(block_cipher.get(),
+ c_uint8_ptr(initial_counter_block),
+ c_size_t(len(initial_counter_block)),
+ c_size_t(prefix_len),
+ counter_len,
+ little_endian,
+ self._state.address_of())
+ if result:
+ raise ValueError("Error %X while instantiating the CTR mode"
+ % result)
+
+ # Ensure that object disposal of this Python object will (eventually)
+ # free the memory allocated by the raw library for the cipher mode
+ self._state = SmartPointer(self._state.get(),
+ raw_ctr_lib.CTR_stop_operation)
+
+ # Memory allocated for the underlying block cipher is now owed
+ # by the cipher mode
+ block_cipher.release()
+
+ self.block_size = len(initial_counter_block)
+ """The block size of the underlying cipher, in bytes."""
+
+ self._next = [self.encrypt, self.decrypt]
+
+ def encrypt(self, plaintext, output=None):
+ """Encrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have encrypted a message
+ you cannot encrypt (or decrypt) another message using the same
+ object.
+
+ The data to encrypt can be broken up in two or
+ more pieces and `encrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.encrypt(a) + c.encrypt(b)
+
+ is equivalent to:
+
+ >>> c.encrypt(a+b)
+
+ This function does not add any padding to the plaintext.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ If ``output`` is ``None``, the ciphertext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.encrypt not in self._next:
+ raise TypeError("encrypt() cannot be called after decrypt()")
+ self._next = [self.encrypt]
+
+ if output is None:
+ ciphertext = create_string_buffer(len(plaintext))
+ else:
+ ciphertext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(plaintext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+ result = raw_ctr_lib.CTR_encrypt(self._state.get(),
+ c_uint8_ptr(plaintext),
+ c_uint8_ptr(ciphertext),
+ c_size_t(len(plaintext)))
+ if result:
+ if result == 0x60002:
+ raise OverflowError("The counter has wrapped around in"
+ " CTR mode")
+ raise ValueError("Error %X while encrypting in CTR mode" % result)
+
+ if output is None:
+ return get_raw_buffer(ciphertext)
+ else:
+ return None
+
+ def decrypt(self, ciphertext, output=None):
+ """Decrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have decrypted a message
+ you cannot decrypt (or encrypt) another message with the same
+ object.
+
+ The data to decrypt can be broken up in two or
+ more pieces and `decrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.decrypt(a) + c.decrypt(b)
+
+ is equivalent to:
+
+ >>> c.decrypt(a+b)
+
+ This function does not remove any padding from the plaintext.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext must be written to.
+ If ``None``, the plaintext is returned.
+ :Return:
+ If ``output`` is ``None``, the plaintext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.decrypt not in self._next:
+ raise TypeError("decrypt() cannot be called after encrypt()")
+ self._next = [self.decrypt]
+
+ if output is None:
+ plaintext = create_string_buffer(len(ciphertext))
+ else:
+ plaintext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(ciphertext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+
+ result = raw_ctr_lib.CTR_decrypt(self._state.get(),
+ c_uint8_ptr(ciphertext),
+ c_uint8_ptr(plaintext),
+ c_size_t(len(ciphertext)))
+ if result:
+ if result == 0x60002:
+ raise OverflowError("The counter has wrapped around in"
+ " CTR mode")
+ raise ValueError("Error %X while decrypting in CTR mode" % result)
+
+ if output is None:
+ return get_raw_buffer(plaintext)
+ else:
+ return None
+
+
+def _create_ctr_cipher(factory, **kwargs):
+ """Instantiate a cipher object that performs CTR encryption/decryption.
+
+ :Parameters:
+ factory : module
+ The underlying block cipher, a module from ``Cryptodome.Cipher``.
+
+ :Keywords:
+ nonce : bytes/bytearray/memoryview
+ The fixed part at the beginning of the counter block - the rest is
+ the counter number that gets increased when processing the next block.
+ The nonce must be such that no two messages are encrypted under the
+ same key and the same nonce.
+
+ The nonce must be shorter than the block size (it can have
+ zero length; the counter is then as long as the block).
+
+ If this parameter is not present, a random nonce will be created with
+ length equal to half the block size. No random nonce shorter than
+ 64 bits will be created though - you must really think through all
+ security consequences of using such a short block size.
+
+ initial_value : posive integer or bytes/bytearray/memoryview
+ 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``.
+
+ Any other keyword will be passed to the underlying block cipher.
+ See the relevant documentation for details (at least ``key`` will need
+ to be present).
+ """
+
+ cipher_state = factory._create_base_cipher(kwargs)
+
+ counter = kwargs.pop("counter", None)
+ nonce = kwargs.pop("nonce", None)
+ initial_value = kwargs.pop("initial_value", None)
+ if kwargs:
+ raise TypeError("Invalid parameters for CTR mode: %s" % str(kwargs))
+
+ if counter is not None and (nonce, initial_value) != (None, None):
+ raise TypeError("'counter' and 'nonce'/'initial_value'"
+ " are mutually exclusive")
+
+ if counter is None:
+ # Cryptodome.Util.Counter is not used
+ if nonce is None:
+ if factory.block_size < 16:
+ raise TypeError("Impossible to create a safe nonce for short"
+ " block sizes")
+ nonce = get_random_bytes(factory.block_size // 2)
+ else:
+ if len(nonce) >= factory.block_size:
+ raise ValueError("Nonce is too long")
+
+ # What is not nonce is counter
+ counter_len = factory.block_size - len(nonce)
+
+ if initial_value is None:
+ initial_value = 0
+
+ if is_native_int(initial_value):
+ if (1 << (counter_len * 8)) - 1 < initial_value:
+ raise ValueError("Initial counter value is too large")
+ initial_counter_block = nonce + long_to_bytes(initial_value, counter_len)
+ else:
+ if len(initial_value) != counter_len:
+ raise ValueError("Incorrect length for counter byte string (%d bytes, expected %d)" % (len(initial_value), counter_len))
+ initial_counter_block = nonce + initial_value
+
+ return CtrMode(cipher_state,
+ initial_counter_block,
+ len(nonce), # prefix
+ counter_len,
+ False) # little_endian
+
+ # Cryptodome.Util.Counter is used
+
+ # 'counter' used to be a callable object, but now it is
+ # just a dictionary for backward compatibility.
+ _counter = dict(counter)
+ try:
+ counter_len = _counter.pop("counter_len")
+ prefix = _counter.pop("prefix")
+ suffix = _counter.pop("suffix")
+ initial_value = _counter.pop("initial_value")
+ little_endian = _counter.pop("little_endian")
+ except KeyError:
+ raise TypeError("Incorrect counter object"
+ " (use Cryptodome.Util.Counter.new)")
+
+ # Compute initial counter block
+ words = []
+ while initial_value > 0:
+ words.append(struct.pack('B', initial_value & 255))
+ initial_value >>= 8
+ words += [ b'\x00' ] * max(0, counter_len - len(words))
+ if not little_endian:
+ words.reverse()
+ initial_counter_block = prefix + b"".join(words) + suffix
+
+ if len(initial_counter_block) != factory.block_size:
+ raise ValueError("Size of the counter block (%d bytes) must match"
+ " block size (%d)" % (len(initial_counter_block),
+ factory.block_size))
+
+ return CtrMode(cipher_state, initial_counter_block,
+ len(prefix), counter_len, little_endian)
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ctr.pyi b/frozen_deps/Cryptodome/Cipher/_mode_ctr.pyi
new file mode 100644
index 0000000..a68a890
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_ctr.pyi
@@ -0,0 +1,27 @@
+from typing import Union, overload
+
+from Cryptodome.Util._raw_api import SmartPointer
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+__all__ = ['CtrMode']
+
+class CtrMode(object):
+ block_size: int
+ nonce: bytes
+
+ def __init__(self,
+ block_cipher: SmartPointer,
+ initial_counter_block: Buffer,
+ prefix_len: int,
+ counter_len: int,
+ little_endian: bool) -> None: ...
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_eax.py b/frozen_deps/Cryptodome/Cipher/_mode_eax.py
new file mode 100644
index 0000000..8efb77a
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_eax.py
@@ -0,0 +1,408 @@
+# ===================================================================
+#
+# Copyright (c) 2014, Legrandin <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+"""
+EAX mode.
+"""
+
+__all__ = ['EaxMode']
+
+import struct
+from binascii import unhexlify
+
+from Cryptodome.Util.py3compat import byte_string, bord, _copy_bytes
+
+from Cryptodome.Util._raw_api import is_buffer
+
+from Cryptodome.Util.strxor import strxor
+from Cryptodome.Util.number import long_to_bytes, bytes_to_long
+
+from Cryptodome.Hash import CMAC, BLAKE2s
+from Cryptodome.Random import get_random_bytes
+
+
+class EaxMode(object):
+ """*EAX* mode.
+
+ This is an Authenticated Encryption with Associated Data
+ (`AEAD`_) mode. It provides both confidentiality and authenticity.
+
+ The header of the message may be left in the clear, if needed,
+ and it will still be subject to authentication.
+
+ The decryption step tells the receiver if the message comes
+ from a source that really knowns the secret key.
+ Additionally, decryption detects if any part of the message -
+ including the header - has been modified or corrupted.
+
+ This mode requires a *nonce*.
+
+ This mode is only available for ciphers that operate on 64 or
+ 128 bits blocks.
+
+ There are no official standards defining EAX.
+ The implementation is based on `a proposal`__ that
+ was presented to NIST.
+
+ .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html
+ .. __: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/eax/eax-spec.pdf
+
+ :undocumented: __init__
+ """
+
+ def __init__(self, factory, key, nonce, mac_len, cipher_params):
+ """EAX cipher mode"""
+
+ self.block_size = factory.block_size
+ """The block size of the underlying cipher, in bytes."""
+
+ self.nonce = _copy_bytes(None, None, nonce)
+ """The nonce originally used to create the object."""
+
+ self._mac_len = mac_len
+ self._mac_tag = None # Cache for MAC tag
+
+ # Allowed transitions after initialization
+ self._next = [self.update, self.encrypt, self.decrypt,
+ self.digest, self.verify]
+
+ # MAC tag length
+ if not (4 <= self._mac_len <= self.block_size):
+ raise ValueError("Parameter 'mac_len' must not be larger than %d"
+ % self.block_size)
+
+ # Nonce cannot be empty and must be a byte string
+ if len(self.nonce) == 0:
+ raise ValueError("Nonce cannot be empty in EAX mode")
+ if not is_buffer(nonce):
+ raise TypeError("nonce must be bytes, bytearray or memoryview")
+
+ self._omac = [
+ CMAC.new(key,
+ b'\x00' * (self.block_size - 1) + struct.pack('B', i),
+ ciphermod=factory,
+ cipher_params=cipher_params)
+ for i in range(0, 3)
+ ]
+
+ # Compute MAC of nonce
+ self._omac[0].update(self.nonce)
+ self._signer = self._omac[1]
+
+ # MAC of the nonce is also the initial counter for CTR encryption
+ counter_int = bytes_to_long(self._omac[0].digest())
+ self._cipher = factory.new(key,
+ factory.MODE_CTR,
+ initial_value=counter_int,
+ nonce=b"",
+ **cipher_params)
+
+ def update(self, assoc_data):
+ """Protect associated data
+
+ If there is any associated data, the caller has to invoke
+ this function one or more times, before using
+ ``decrypt`` or ``encrypt``.
+
+ By *associated data* it is meant any data (e.g. packet headers) that
+ will not be encrypted and will be transmitted in the clear.
+ However, the receiver is still able to detect any modification to it.
+
+ If there is no associated data, this method must not be called.
+
+ The caller may split associated data in segments of any size, and
+ invoke this method multiple times, each time with the next segment.
+
+ :Parameters:
+ assoc_data : bytes/bytearray/memoryview
+ A piece of associated data. There are no restrictions on its size.
+ """
+
+ if self.update not in self._next:
+ raise TypeError("update() can only be called"
+ " immediately after initialization")
+
+ self._next = [self.update, self.encrypt, self.decrypt,
+ self.digest, self.verify]
+
+ self._signer.update(assoc_data)
+ return self
+
+ def encrypt(self, plaintext, output=None):
+ """Encrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have encrypted a message
+ you cannot encrypt (or decrypt) another message using the same
+ object.
+
+ The data to encrypt can be broken up in two or
+ more pieces and `encrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.encrypt(a) + c.encrypt(b)
+
+ is equivalent to:
+
+ >>> c.encrypt(a+b)
+
+ This function does not add any padding to the plaintext.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ If ``output`` is ``None``, the ciphertext as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.encrypt not in self._next:
+ raise TypeError("encrypt() can only be called after"
+ " initialization or an update()")
+ self._next = [self.encrypt, self.digest]
+ ct = self._cipher.encrypt(plaintext, output=output)
+ if output is None:
+ self._omac[2].update(ct)
+ else:
+ self._omac[2].update(output)
+ return ct
+
+ def decrypt(self, ciphertext, output=None):
+ """Decrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have decrypted a message
+ you cannot decrypt (or encrypt) another message with the same
+ object.
+
+ The data to decrypt can be broken up in two or
+ more pieces and `decrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.decrypt(a) + c.decrypt(b)
+
+ is equivalent to:
+
+ >>> c.decrypt(a+b)
+
+ This function does not remove any padding from the plaintext.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext must be written to.
+ If ``None``, the plaintext is returned.
+ :Return:
+ If ``output`` is ``None``, the plaintext as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.decrypt not in self._next:
+ raise TypeError("decrypt() can only be called"
+ " after initialization or an update()")
+ self._next = [self.decrypt, self.verify]
+ self._omac[2].update(ciphertext)
+ return self._cipher.decrypt(ciphertext, output=output)
+
+ def digest(self):
+ """Compute the *binary* MAC tag.
+
+ The caller invokes this function at the very end.
+
+ This method returns the MAC that shall be sent to the receiver,
+ together with the ciphertext.
+
+ :Return: the MAC, as a byte string.
+ """
+
+ if self.digest not in self._next:
+ raise TypeError("digest() cannot be called when decrypting"
+ " or validating a message")
+ self._next = [self.digest]
+
+ if not self._mac_tag:
+ tag = b'\x00' * self.block_size
+ for i in range(3):
+ tag = strxor(tag, self._omac[i].digest())
+ self._mac_tag = tag[:self._mac_len]
+
+ return self._mac_tag
+
+ def hexdigest(self):
+ """Compute the *printable* MAC tag.
+
+ This method is like `digest`.
+
+ :Return: the MAC, as a hexadecimal string.
+ """
+ return "".join(["%02x" % bord(x) for x in self.digest()])
+
+ def verify(self, received_mac_tag):
+ """Validate the *binary* MAC tag.
+
+ The caller invokes this function at the very end.
+
+ This method checks if the decrypted message is indeed valid
+ (that is, if the key is correct) and it has not been
+ tampered with while in transit.
+
+ :Parameters:
+ received_mac_tag : bytes/bytearray/memoryview
+ This is the *binary* MAC, as received from the sender.
+ :Raises MacMismatchError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ if self.verify not in self._next:
+ raise TypeError("verify() cannot be called"
+ " when encrypting a message")
+ self._next = [self.verify]
+
+ if not self._mac_tag:
+ tag = b'\x00' * self.block_size
+ for i in range(3):
+ tag = strxor(tag, self._omac[i].digest())
+ self._mac_tag = tag[:self._mac_len]
+
+ secret = get_random_bytes(16)
+
+ mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag)
+ mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag)
+
+ if mac1.digest() != mac2.digest():
+ raise ValueError("MAC check failed")
+
+ def hexverify(self, hex_mac_tag):
+ """Validate the *printable* MAC tag.
+
+ This method is like `verify`.
+
+ :Parameters:
+ hex_mac_tag : string
+ This is the *printable* MAC, as received from the sender.
+ :Raises MacMismatchError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ self.verify(unhexlify(hex_mac_tag))
+
+ def encrypt_and_digest(self, plaintext, output=None):
+ """Perform encrypt() and digest() in one step.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ a tuple with two items:
+
+ - the ciphertext, as ``bytes``
+ - the MAC tag, as ``bytes``
+
+ The first item becomes ``None`` when the ``output`` parameter
+ specified a location for the result.
+ """
+
+ return self.encrypt(plaintext, output=output), self.digest()
+
+ def decrypt_and_verify(self, ciphertext, received_mac_tag, output=None):
+ """Perform decrypt() and verify() in one step.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ received_mac_tag : bytes/bytearray/memoryview
+ This is the *binary* MAC, as received from the sender.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext must be written to.
+ If ``None``, the plaintext is returned.
+ :Return: the plaintext as ``bytes`` or ``None`` when the ``output``
+ parameter specified a location for the result.
+ :Raises MacMismatchError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ pt = self.decrypt(ciphertext, output=output)
+ self.verify(received_mac_tag)
+ return pt
+
+
+def _create_eax_cipher(factory, **kwargs):
+ """Create a new block cipher, configured in EAX mode.
+
+ :Parameters:
+ factory : module
+ A symmetric cipher module from `Cryptodome.Cipher` (like
+ `Cryptodome.Cipher.AES`).
+
+ :Keywords:
+ key : bytes/bytearray/memoryview
+ The secret key to use in the symmetric cipher.
+
+ nonce : bytes/bytearray/memoryview
+ A value that must never be reused for any other encryption.
+ There are no restrictions on its length, but it is recommended to use
+ at least 16 bytes.
+
+ The nonce shall never repeat for two different messages encrypted with
+ the same key, but it does not need to be random.
+
+ If not specified, a 16 byte long random string is used.
+
+ mac_len : integer
+ Length of the MAC, in bytes. It must be no larger than the cipher
+ block bytes (which is the default).
+ """
+
+ try:
+ key = kwargs.pop("key")
+ nonce = kwargs.pop("nonce", None)
+ if nonce is None:
+ nonce = get_random_bytes(16)
+ mac_len = kwargs.pop("mac_len", factory.block_size)
+ except KeyError as e:
+ raise TypeError("Missing parameter: " + str(e))
+
+ return EaxMode(factory, key, nonce, mac_len, kwargs)
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_eax.pyi b/frozen_deps/Cryptodome/Cipher/_mode_eax.pyi
new file mode 100644
index 0000000..cbfa467
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_eax.pyi
@@ -0,0 +1,45 @@
+from types import ModuleType
+from typing import Any, Union, Tuple, Dict, overload, Optional
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+__all__ = ['EaxMode']
+
+class EaxMode(object):
+ block_size: int
+ nonce: bytes
+
+ def __init__(self,
+ factory: ModuleType,
+ key: Buffer,
+ nonce: Buffer,
+ mac_len: int,
+ cipher_params: Dict) -> None: ...
+
+ def update(self, assoc_data: Buffer) -> EaxMode: ...
+
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+
+ def digest(self) -> bytes: ...
+ def hexdigest(self) -> str: ...
+ def verify(self, received_mac_tag: Buffer) -> None: ...
+ def hexverify(self, hex_mac_tag: str) -> None: ...
+
+ @overload
+ def encrypt_and_digest(self,
+ plaintext: Buffer) -> Tuple[bytes, bytes]: ...
+ @overload
+ def encrypt_and_digest(self,
+ plaintext: Buffer,
+ output: Buffer) -> Tuple[None, bytes]: ...
+ def decrypt_and_verify(self,
+ ciphertext: Buffer,
+ received_mac_tag: Buffer,
+ output: Optional[Union[bytearray, memoryview]] = ...) -> bytes: ...
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ecb.py b/frozen_deps/Cryptodome/Cipher/_mode_ecb.py
new file mode 100644
index 0000000..4c381f7
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_ecb.py
@@ -0,0 +1,218 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/mode_ecb.py : ECB mode
+#
+# ===================================================================
+# 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.
+# ===================================================================
+
+"""
+Electronic Code Book (ECB) mode.
+"""
+
+__all__ = [ 'EcbMode' ]
+
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib,
+ VoidPointer, create_string_buffer,
+ get_raw_buffer, SmartPointer,
+ c_size_t, c_uint8_ptr,
+ is_writeable_buffer)
+
+raw_ecb_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_ecb", """
+ int ECB_start_operation(void *cipher,
+ void **pResult);
+ int ECB_encrypt(void *ecbState,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int ECB_decrypt(void *ecbState,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int ECB_stop_operation(void *state);
+ """
+ )
+
+
+class EcbMode(object):
+ """*Electronic Code Book (ECB)*.
+
+ This is the simplest encryption mode. Each of the plaintext blocks
+ is directly encrypted into a ciphertext block, independently of
+ any other block.
+
+ This mode is dangerous because it exposes frequency of symbols
+ in your plaintext. Other modes (e.g. *CBC*) should be used instead.
+
+ See `NIST SP800-38A`_ , Section 6.1.
+
+ .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+
+ :undocumented: __init__
+ """
+
+ def __init__(self, block_cipher):
+ """Create a new block cipher, configured in ECB mode.
+
+ :Parameters:
+ block_cipher : C pointer
+ A smart pointer to the low-level block cipher instance.
+ """
+
+ self._state = VoidPointer()
+ result = raw_ecb_lib.ECB_start_operation(block_cipher.get(),
+ self._state.address_of())
+ if result:
+ raise ValueError("Error %d while instantiating the ECB mode"
+ % result)
+
+ # Ensure that object disposal of this Python object will (eventually)
+ # free the memory allocated by the raw library for the cipher
+ # mode
+ self._state = SmartPointer(self._state.get(),
+ raw_ecb_lib.ECB_stop_operation)
+
+ # Memory allocated for the underlying block cipher is now owned
+ # by the cipher mode
+ block_cipher.release()
+
+ def encrypt(self, plaintext, output=None):
+ """Encrypt data with the key set at initialization.
+
+ The data to encrypt can be broken up in two or
+ more pieces and `encrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.encrypt(a) + c.encrypt(b)
+
+ is equivalent to:
+
+ >>> c.encrypt(a+b)
+
+ This function does not add any padding to the plaintext.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ The length must be multiple of the cipher block length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ If ``output`` is ``None``, the ciphertext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if output is None:
+ ciphertext = create_string_buffer(len(plaintext))
+ else:
+ ciphertext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(plaintext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+ result = raw_ecb_lib.ECB_encrypt(self._state.get(),
+ c_uint8_ptr(plaintext),
+ c_uint8_ptr(ciphertext),
+ c_size_t(len(plaintext)))
+ if result:
+ if result == 3:
+ raise ValueError("Data must be aligned to block boundary in ECB mode")
+ raise ValueError("Error %d while encrypting in ECB mode" % result)
+
+ if output is None:
+ return get_raw_buffer(ciphertext)
+ else:
+ return None
+
+ def decrypt(self, ciphertext, output=None):
+ """Decrypt data with the key set at initialization.
+
+ The data to decrypt can be broken up in two or
+ more pieces and `decrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.decrypt(a) + c.decrypt(b)
+
+ is equivalent to:
+
+ >>> c.decrypt(a+b)
+
+ This function does not remove any padding from the plaintext.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ The length must be multiple of the cipher block length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext must be written to.
+ If ``None``, the plaintext is returned.
+ :Return:
+ If ``output`` is ``None``, the plaintext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if output is None:
+ plaintext = create_string_buffer(len(ciphertext))
+ else:
+ plaintext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(ciphertext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+ result = raw_ecb_lib.ECB_decrypt(self._state.get(),
+ c_uint8_ptr(ciphertext),
+ c_uint8_ptr(plaintext),
+ c_size_t(len(ciphertext)))
+ if result:
+ if result == 3:
+ raise ValueError("Data must be aligned to block boundary in ECB mode")
+ raise ValueError("Error %d while decrypting in ECB mode" % result)
+
+ if output is None:
+ return get_raw_buffer(plaintext)
+ else:
+ return None
+
+
+def _create_ecb_cipher(factory, **kwargs):
+ """Instantiate a cipher object that performs ECB encryption/decryption.
+
+ :Parameters:
+ factory : module
+ The underlying block cipher, a module from ``Cryptodome.Cipher``.
+
+ All keywords are passed to the underlying block cipher.
+ See the relevant documentation for details (at least ``key`` will need
+ to be present"""
+
+ cipher_state = factory._create_base_cipher(kwargs)
+ if kwargs:
+ raise TypeError("Unknown parameters for ECB: %s" % str(kwargs))
+ return EcbMode(cipher_state)
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ecb.pyi b/frozen_deps/Cryptodome/Cipher/_mode_ecb.pyi
new file mode 100644
index 0000000..936195f
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_ecb.pyi
@@ -0,0 +1,19 @@
+from typing import Union, overload
+
+from Cryptodome.Util._raw_api import SmartPointer
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+__all__ = [ 'EcbMode' ]
+
+class EcbMode(object):
+ def __init__(self, block_cipher: SmartPointer) -> None: ...
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_gcm.py b/frozen_deps/Cryptodome/Cipher/_mode_gcm.py
new file mode 100644
index 0000000..c90061b
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_gcm.py
@@ -0,0 +1,620 @@
+# ===================================================================
+#
+# Copyright (c) 2014, Legrandin <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+"""
+Galois/Counter Mode (GCM).
+"""
+
+__all__ = ['GcmMode']
+
+from binascii import unhexlify
+
+from Cryptodome.Util.py3compat import bord, _copy_bytes
+
+from Cryptodome.Util._raw_api import is_buffer
+
+from Cryptodome.Util.number import long_to_bytes, bytes_to_long
+from Cryptodome.Hash import BLAKE2s
+from Cryptodome.Random import get_random_bytes
+
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer,
+ create_string_buffer, get_raw_buffer,
+ SmartPointer, c_size_t, c_uint8_ptr)
+
+from Cryptodome.Util import _cpu_features
+
+
+# C API by module implementing GHASH
+_ghash_api_template = """
+ int ghash_%imp%(uint8_t y_out[16],
+ const uint8_t block_data[],
+ size_t len,
+ const uint8_t y_in[16],
+ const void *exp_key);
+ int ghash_expand_%imp%(const uint8_t h[16],
+ void **ghash_tables);
+ int ghash_destroy_%imp%(void *ghash_tables);
+"""
+
+def _build_impl(lib, postfix):
+ from collections import namedtuple
+
+ funcs = ( "ghash", "ghash_expand", "ghash_destroy" )
+ GHASH_Imp = namedtuple('_GHash_Imp', funcs)
+ try:
+ imp_funcs = [ getattr(lib, x + "_" + postfix) for x in funcs ]
+ except AttributeError: # Make sphinx stop complaining with its mocklib
+ imp_funcs = [ None ] * 3
+ params = dict(zip(funcs, imp_funcs))
+ return GHASH_Imp(**params)
+
+
+def _get_ghash_portable():
+ api = _ghash_api_template.replace("%imp%", "portable")
+ lib = load_pycryptodome_raw_lib("Cryptodome.Hash._ghash_portable", api)
+ result = _build_impl(lib, "portable")
+ return result
+_ghash_portable = _get_ghash_portable()
+
+
+def _get_ghash_clmul():
+ """Return None if CLMUL implementation is not available"""
+
+ if not _cpu_features.have_clmul():
+ return None
+ try:
+ api = _ghash_api_template.replace("%imp%", "clmul")
+ lib = load_pycryptodome_raw_lib("Cryptodome.Hash._ghash_clmul", api)
+ result = _build_impl(lib, "clmul")
+ except OSError:
+ result = None
+ return result
+_ghash_clmul = _get_ghash_clmul()
+
+
+class _GHASH(object):
+ """GHASH function defined in NIST SP 800-38D, Algorithm 2.
+
+ If X_1, X_2, .. X_m are the blocks of input data, the function
+ computes:
+
+ X_1*H^{m} + X_2*H^{m-1} + ... + X_m*H
+
+ in the Galois field GF(2^256) using the reducing polynomial
+ (x^128 + x^7 + x^2 + x + 1).
+ """
+
+ def __init__(self, subkey, ghash_c):
+ assert len(subkey) == 16
+
+ self.ghash_c = ghash_c
+
+ self._exp_key = VoidPointer()
+ result = ghash_c.ghash_expand(c_uint8_ptr(subkey),
+ self._exp_key.address_of())
+ if result:
+ raise ValueError("Error %d while expanding the GHASH key" % result)
+
+ self._exp_key = SmartPointer(self._exp_key.get(),
+ ghash_c.ghash_destroy)
+
+ # create_string_buffer always returns a string of zeroes
+ self._last_y = create_string_buffer(16)
+
+ def update(self, block_data):
+ assert len(block_data) % 16 == 0
+
+ result = self.ghash_c.ghash(self._last_y,
+ c_uint8_ptr(block_data),
+ c_size_t(len(block_data)),
+ self._last_y,
+ self._exp_key.get())
+ if result:
+ raise ValueError("Error %d while updating GHASH" % result)
+
+ return self
+
+ def digest(self):
+ return get_raw_buffer(self._last_y)
+
+
+def enum(**enums):
+ return type('Enum', (), enums)
+
+
+MacStatus = enum(PROCESSING_AUTH_DATA=1, PROCESSING_CIPHERTEXT=2)
+
+
+class GcmMode(object):
+ """Galois Counter Mode (GCM).
+
+ This is an Authenticated Encryption with Associated Data (`AEAD`_) mode.
+ It provides both confidentiality and authenticity.
+
+ The header of the message may be left in the clear, if needed, and it will
+ still be subject to authentication. The decryption step tells the receiver
+ if the message comes from a source that really knowns the secret key.
+ Additionally, decryption detects if any part of the message - including the
+ header - has been modified or corrupted.
+
+ This mode requires a *nonce*.
+
+ This mode is only available for ciphers that operate on 128 bits blocks
+ (e.g. AES but not TDES).
+
+ See `NIST SP800-38D`_.
+
+ .. _`NIST SP800-38D`: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
+ .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html
+
+ :undocumented: __init__
+ """
+
+ def __init__(self, factory, key, nonce, mac_len, cipher_params, ghash_c):
+
+ self.block_size = factory.block_size
+ if self.block_size != 16:
+ raise ValueError("GCM mode is only available for ciphers"
+ " that operate on 128 bits blocks")
+
+ if len(nonce) == 0:
+ raise ValueError("Nonce cannot be empty")
+
+ if not is_buffer(nonce):
+ raise TypeError("Nonce must be bytes, bytearray or memoryview")
+
+ # See NIST SP 800 38D, 5.2.1.1
+ if len(nonce) > 2**64 - 1:
+ raise ValueError("Nonce exceeds maximum length")
+
+
+ self.nonce = _copy_bytes(None, None, nonce)
+ """Nonce"""
+
+ self._factory = factory
+ self._key = _copy_bytes(None, None, key)
+ self._tag = None # Cache for MAC tag
+
+ self._mac_len = mac_len
+ if not (4 <= mac_len <= 16):
+ raise ValueError("Parameter 'mac_len' must be in the range 4..16")
+
+ # Allowed transitions after initialization
+ self._next = [self.update, self.encrypt, self.decrypt,
+ self.digest, self.verify]
+
+ self._no_more_assoc_data = False
+
+ # Length of associated data
+ self._auth_len = 0
+
+ # Length of the ciphertext or plaintext
+ self._msg_len = 0
+
+ # Step 1 in SP800-38D, Algorithm 4 (encryption) - Compute H
+ # See also Algorithm 5 (decryption)
+ hash_subkey = factory.new(key,
+ self._factory.MODE_ECB,
+ **cipher_params
+ ).encrypt(b'\x00' * 16)
+
+ # Step 2 - Compute J0
+ if len(self.nonce) == 12:
+ j0 = self.nonce + b"\x00\x00\x00\x01"
+ else:
+ fill = (16 - (len(nonce) % 16)) % 16 + 8
+ ghash_in = (self.nonce +
+ b'\x00' * fill +
+ long_to_bytes(8 * len(nonce), 8))
+ j0 = _GHASH(hash_subkey, ghash_c).update(ghash_in).digest()
+
+ # Step 3 - Prepare GCTR cipher for encryption/decryption
+ nonce_ctr = j0[:12]
+ iv_ctr = (bytes_to_long(j0) + 1) & 0xFFFFFFFF
+ self._cipher = factory.new(key,
+ self._factory.MODE_CTR,
+ initial_value=iv_ctr,
+ nonce=nonce_ctr,
+ **cipher_params)
+
+ # Step 5 - Bootstrat GHASH
+ self._signer = _GHASH(hash_subkey, ghash_c)
+
+ # Step 6 - Prepare GCTR cipher for GMAC
+ self._tag_cipher = factory.new(key,
+ self._factory.MODE_CTR,
+ initial_value=j0,
+ nonce=b"",
+ **cipher_params)
+
+ # Cache for data to authenticate
+ self._cache = b""
+
+ self._status = MacStatus.PROCESSING_AUTH_DATA
+
+ def update(self, assoc_data):
+ """Protect associated data
+
+ If there is any associated data, the caller has to invoke
+ this function one or more times, before using
+ ``decrypt`` or ``encrypt``.
+
+ By *associated data* it is meant any data (e.g. packet headers) that
+ will not be encrypted and will be transmitted in the clear.
+ However, the receiver is still able to detect any modification to it.
+ In GCM, the *associated data* is also called
+ *additional authenticated data* (AAD).
+
+ If there is no associated data, this method must not be called.
+
+ The caller may split associated data in segments of any size, and
+ invoke this method multiple times, each time with the next segment.
+
+ :Parameters:
+ assoc_data : bytes/bytearray/memoryview
+ A piece of associated data. There are no restrictions on its size.
+ """
+
+ if self.update not in self._next:
+ raise TypeError("update() can only be called"
+ " immediately after initialization")
+
+ self._next = [self.update, self.encrypt, self.decrypt,
+ self.digest, self.verify]
+
+ self._update(assoc_data)
+ self._auth_len += len(assoc_data)
+
+ # See NIST SP 800 38D, 5.2.1.1
+ if self._auth_len > 2**64 - 1:
+ raise ValueError("Additional Authenticated Data exceeds maximum length")
+
+ return self
+
+ def _update(self, data):
+ assert(len(self._cache) < 16)
+
+ if len(self._cache) > 0:
+ filler = min(16 - len(self._cache), len(data))
+ self._cache += _copy_bytes(None, filler, data)
+ data = data[filler:]
+
+ if len(self._cache) < 16:
+ return
+
+ # The cache is exactly one block
+ self._signer.update(self._cache)
+ self._cache = b""
+
+ update_len = len(data) // 16 * 16
+ self._cache = _copy_bytes(update_len, None, data)
+ if update_len > 0:
+ self._signer.update(data[:update_len])
+
+ def _pad_cache_and_update(self):
+ assert(len(self._cache) < 16)
+
+ # The authenticated data A is concatenated to the minimum
+ # number of zero bytes (possibly none) such that the
+ # - ciphertext C is aligned to the 16 byte boundary.
+ # See step 5 in section 7.1
+ # - ciphertext C is aligned to the 16 byte boundary.
+ # See step 6 in section 7.2
+ len_cache = len(self._cache)
+ if len_cache > 0:
+ self._update(b'\x00' * (16 - len_cache))
+
+ def encrypt(self, plaintext, output=None):
+ """Encrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have encrypted a message
+ you cannot encrypt (or decrypt) another message using the same
+ object.
+
+ The data to encrypt can be broken up in two or
+ more pieces and `encrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.encrypt(a) + c.encrypt(b)
+
+ is equivalent to:
+
+ >>> c.encrypt(a+b)
+
+ This function does not add any padding to the plaintext.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ If ``output`` is ``None``, the ciphertext as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.encrypt not in self._next:
+ raise TypeError("encrypt() can only be called after"
+ " initialization or an update()")
+ self._next = [self.encrypt, self.digest]
+
+ ciphertext = self._cipher.encrypt(plaintext, output=output)
+
+ if self._status == MacStatus.PROCESSING_AUTH_DATA:
+ self._pad_cache_and_update()
+ self._status = MacStatus.PROCESSING_CIPHERTEXT
+
+ self._update(ciphertext if output is None else output)
+ self._msg_len += len(plaintext)
+
+ # See NIST SP 800 38D, 5.2.1.1
+ if self._msg_len > 2**39 - 256:
+ raise ValueError("Plaintext exceeds maximum length")
+
+ return ciphertext
+
+ def decrypt(self, ciphertext, output=None):
+ """Decrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have decrypted a message
+ you cannot decrypt (or encrypt) another message with the same
+ object.
+
+ The data to decrypt can be broken up in two or
+ more pieces and `decrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.decrypt(a) + c.decrypt(b)
+
+ is equivalent to:
+
+ >>> c.decrypt(a+b)
+
+ This function does not remove any padding from the plaintext.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext must be written to.
+ If ``None``, the plaintext is returned.
+ :Return:
+ If ``output`` is ``None``, the plaintext as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.decrypt not in self._next:
+ raise TypeError("decrypt() can only be called"
+ " after initialization or an update()")
+ self._next = [self.decrypt, self.verify]
+
+ if self._status == MacStatus.PROCESSING_AUTH_DATA:
+ self._pad_cache_and_update()
+ self._status = MacStatus.PROCESSING_CIPHERTEXT
+
+ self._update(ciphertext)
+ self._msg_len += len(ciphertext)
+
+ return self._cipher.decrypt(ciphertext, output=output)
+
+ def digest(self):
+ """Compute the *binary* MAC tag in an AEAD mode.
+
+ The caller invokes this function at the very end.
+
+ This method returns the MAC that shall be sent to the receiver,
+ together with the ciphertext.
+
+ :Return: the MAC, as a byte string.
+ """
+
+ if self.digest not in self._next:
+ raise TypeError("digest() cannot be called when decrypting"
+ " or validating a message")
+ self._next = [self.digest]
+
+ return self._compute_mac()
+
+ def _compute_mac(self):
+ """Compute MAC without any FSM checks."""
+
+ if self._tag:
+ return self._tag
+
+ # Step 5 in NIST SP 800-38D, Algorithm 4 - Compute S
+ self._pad_cache_and_update()
+ self._update(long_to_bytes(8 * self._auth_len, 8))
+ self._update(long_to_bytes(8 * self._msg_len, 8))
+ s_tag = self._signer.digest()
+
+ # Step 6 - Compute T
+ self._tag = self._tag_cipher.encrypt(s_tag)[:self._mac_len]
+
+ return self._tag
+
+ def hexdigest(self):
+ """Compute the *printable* MAC tag.
+
+ This method is like `digest`.
+
+ :Return: the MAC, as a hexadecimal string.
+ """
+ return "".join(["%02x" % bord(x) for x in self.digest()])
+
+ def verify(self, received_mac_tag):
+ """Validate the *binary* MAC tag.
+
+ The caller invokes this function at the very end.
+
+ This method checks if the decrypted message is indeed valid
+ (that is, if the key is correct) and it has not been
+ tampered with while in transit.
+
+ :Parameters:
+ received_mac_tag : bytes/bytearray/memoryview
+ This is the *binary* MAC, as received from the sender.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ if self.verify not in self._next:
+ raise TypeError("verify() cannot be called"
+ " when encrypting a message")
+ self._next = [self.verify]
+
+ secret = get_random_bytes(16)
+
+ mac1 = BLAKE2s.new(digest_bits=160, key=secret,
+ data=self._compute_mac())
+ mac2 = BLAKE2s.new(digest_bits=160, key=secret,
+ data=received_mac_tag)
+
+ if mac1.digest() != mac2.digest():
+ raise ValueError("MAC check failed")
+
+ def hexverify(self, hex_mac_tag):
+ """Validate the *printable* MAC tag.
+
+ This method is like `verify`.
+
+ :Parameters:
+ hex_mac_tag : string
+ This is the *printable* MAC, as received from the sender.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ self.verify(unhexlify(hex_mac_tag))
+
+ def encrypt_and_digest(self, plaintext, output=None):
+ """Perform encrypt() and digest() in one step.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ a tuple with two items:
+
+ - the ciphertext, as ``bytes``
+ - the MAC tag, as ``bytes``
+
+ The first item becomes ``None`` when the ``output`` parameter
+ specified a location for the result.
+ """
+
+ return self.encrypt(plaintext, output=output), self.digest()
+
+ def decrypt_and_verify(self, ciphertext, received_mac_tag, output=None):
+ """Perform decrypt() and verify() in one step.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ received_mac_tag : byte string
+ This is the *binary* MAC, as received from the sender.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext must be written to.
+ If ``None``, the plaintext is returned.
+ :Return: the plaintext as ``bytes`` or ``None`` when the ``output``
+ parameter specified a location for the result.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ plaintext = self.decrypt(ciphertext, output=output)
+ self.verify(received_mac_tag)
+ return plaintext
+
+
+def _create_gcm_cipher(factory, **kwargs):
+ """Create a new block cipher, configured in Galois Counter Mode (GCM).
+
+ :Parameters:
+ factory : module
+ A block cipher module, taken from `Cryptodome.Cipher`.
+ The cipher must have block length of 16 bytes.
+ GCM has been only defined for `Cryptodome.Cipher.AES`.
+
+ :Keywords:
+ key : bytes/bytearray/memoryview
+ The secret key to use in the symmetric cipher.
+ It must be 16 (e.g. *AES-128*), 24 (e.g. *AES-192*)
+ or 32 (e.g. *AES-256*) bytes long.
+
+ nonce : bytes/bytearray/memoryview
+ A value that must never be reused for any other encryption.
+
+ There are no restrictions on its length,
+ but it is recommended to use at least 16 bytes.
+
+ The nonce shall never repeat for two
+ different messages encrypted with the same key,
+ but it does not need to be random.
+
+ If not provided, a 16 byte nonce will be randomly created.
+
+ mac_len : integer
+ Length of the MAC, in bytes.
+ It must be no larger than 16 bytes (which is the default).
+ """
+
+ try:
+ key = kwargs.pop("key")
+ except KeyError as e:
+ raise TypeError("Missing parameter:" + str(e))
+
+ nonce = kwargs.pop("nonce", None)
+ if nonce is None:
+ nonce = get_random_bytes(16)
+ mac_len = kwargs.pop("mac_len", 16)
+
+ # Not documented - only used for testing
+ use_clmul = kwargs.pop("use_clmul", True)
+ if use_clmul and _ghash_clmul:
+ ghash_c = _ghash_clmul
+ else:
+ ghash_c = _ghash_portable
+
+ return GcmMode(factory, key, nonce, mac_len, kwargs, ghash_c)
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_gcm.pyi b/frozen_deps/Cryptodome/Cipher/_mode_gcm.pyi
new file mode 100644
index 0000000..8912955
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_gcm.pyi
@@ -0,0 +1,45 @@
+from types import ModuleType
+from typing import Union, Tuple, Dict, overload, Optional
+
+__all__ = ['GcmMode']
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+class GcmMode(object):
+ block_size: int
+ nonce: Buffer
+
+ def __init__(self,
+ factory: ModuleType,
+ key: Buffer,
+ nonce: Buffer,
+ mac_len: int,
+ cipher_params: Dict) -> None: ...
+
+ def update(self, assoc_data: Buffer) -> GcmMode: ...
+
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+
+ def digest(self) -> bytes: ...
+ def hexdigest(self) -> str: ...
+ def verify(self, received_mac_tag: Buffer) -> None: ...
+ def hexverify(self, hex_mac_tag: str) -> None: ...
+
+ @overload
+ def encrypt_and_digest(self,
+ plaintext: Buffer) -> Tuple[bytes, bytes]: ...
+ @overload
+ def encrypt_and_digest(self,
+ plaintext: Buffer,
+ output: Buffer) -> Tuple[None, bytes]: ...
+ def decrypt_and_verify(self,
+ ciphertext: Buffer,
+ received_mac_tag: Buffer,
+ output: Optional[Union[bytearray, memoryview]] = ...) -> bytes: ...
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ocb.py b/frozen_deps/Cryptodome/Cipher/_mode_ocb.py
new file mode 100644
index 0000000..27c2797
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_ocb.py
@@ -0,0 +1,525 @@
+# ===================================================================
+#
+# Copyright (c) 2014, Legrandin <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+"""
+Offset Codebook (OCB) mode.
+
+OCB is Authenticated Encryption with Associated Data (AEAD) cipher mode
+designed by Prof. Phillip Rogaway and specified in `RFC7253`_.
+
+The algorithm provides both authenticity and privacy, it is very efficient,
+it uses only one key and it can be used in online mode (so that encryption
+or decryption can start before the end of the message is available).
+
+This module implements the third and last variant of OCB (OCB3) and it only
+works in combination with a 128-bit block symmetric cipher, like AES.
+
+OCB is patented in US but `free licenses`_ exist for software implementations
+meant for non-military purposes.
+
+Example:
+ >>> from Cryptodome.Cipher import AES
+ >>> from Cryptodome.Random import get_random_bytes
+ >>>
+ >>> key = get_random_bytes(32)
+ >>> cipher = AES.new(key, AES.MODE_OCB)
+ >>> plaintext = b"Attack at dawn"
+ >>> ciphertext, mac = cipher.encrypt_and_digest(plaintext)
+ >>> # Deliver cipher.nonce, ciphertext and mac
+ ...
+ >>> cipher = AES.new(key, AES.MODE_OCB, nonce=nonce)
+ >>> try:
+ >>> plaintext = cipher.decrypt_and_verify(ciphertext, mac)
+ >>> except ValueError:
+ >>> print "Invalid message"
+ >>> else:
+ >>> print plaintext
+
+:undocumented: __package__
+
+.. _RFC7253: http://www.rfc-editor.org/info/rfc7253
+.. _free licenses: http://web.cs.ucdavis.edu/~rogaway/ocb/license.htm
+"""
+
+import struct
+from binascii import unhexlify
+
+from Cryptodome.Util.py3compat import bord, _copy_bytes
+from Cryptodome.Util.number import long_to_bytes, bytes_to_long
+from Cryptodome.Util.strxor import strxor
+
+from Cryptodome.Hash import BLAKE2s
+from Cryptodome.Random import get_random_bytes
+
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer,
+ create_string_buffer, get_raw_buffer,
+ SmartPointer, c_size_t, c_uint8_ptr,
+ is_buffer)
+
+_raw_ocb_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_ocb", """
+ int OCB_start_operation(void *cipher,
+ const uint8_t *offset_0,
+ size_t offset_0_len,
+ void **pState);
+ int OCB_encrypt(void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int OCB_decrypt(void *state,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int OCB_update(void *state,
+ const uint8_t *in,
+ size_t data_len);
+ int OCB_digest(void *state,
+ uint8_t *tag,
+ size_t tag_len);
+ int OCB_stop_operation(void *state);
+ """)
+
+
+class OcbMode(object):
+ """Offset Codebook (OCB) mode.
+
+ :undocumented: __init__
+ """
+
+ def __init__(self, factory, nonce, mac_len, cipher_params):
+
+ if factory.block_size != 16:
+ raise ValueError("OCB mode is only available for ciphers"
+ " that operate on 128 bits blocks")
+
+ self.block_size = 16
+ """The block size of the underlying cipher, in bytes."""
+
+ self.nonce = _copy_bytes(None, None, nonce)
+ """Nonce used for this session."""
+ if len(nonce) not in range(1, 16):
+ raise ValueError("Nonce must be at most 15 bytes long")
+ if not is_buffer(nonce):
+ raise TypeError("Nonce must be bytes, bytearray or memoryview")
+
+ self._mac_len = mac_len
+ if not 8 <= mac_len <= 16:
+ raise ValueError("MAC tag must be between 8 and 16 bytes long")
+
+ # Cache for MAC tag
+ self._mac_tag = None
+
+ # Cache for unaligned associated data
+ self._cache_A = b""
+
+ # Cache for unaligned ciphertext/plaintext
+ self._cache_P = b""
+
+ # Allowed transitions after initialization
+ self._next = [self.update, self.encrypt, self.decrypt,
+ self.digest, self.verify]
+
+ # Compute Offset_0
+ params_without_key = dict(cipher_params)
+ key = params_without_key.pop("key")
+ nonce = (struct.pack('B', self._mac_len << 4 & 0xFF) +
+ b'\x00' * (14 - len(nonce)) +
+ b'\x01' + self.nonce)
+
+ bottom_bits = bord(nonce[15]) & 0x3F # 6 bits, 0..63
+ top_bits = bord(nonce[15]) & 0xC0 # 2 bits
+
+ ktop_cipher = factory.new(key,
+ factory.MODE_ECB,
+ **params_without_key)
+ ktop = ktop_cipher.encrypt(struct.pack('15sB',
+ nonce[:15],
+ top_bits))
+
+ stretch = ktop + strxor(ktop[:8], ktop[1:9]) # 192 bits
+ offset_0 = long_to_bytes(bytes_to_long(stretch) >>
+ (64 - bottom_bits), 24)[8:]
+
+ # Create low-level cipher instance
+ raw_cipher = factory._create_base_cipher(cipher_params)
+ if cipher_params:
+ raise TypeError("Unknown keywords: " + str(cipher_params))
+
+ self._state = VoidPointer()
+ result = _raw_ocb_lib.OCB_start_operation(raw_cipher.get(),
+ offset_0,
+ c_size_t(len(offset_0)),
+ self._state.address_of())
+ if result:
+ raise ValueError("Error %d while instantiating the OCB mode"
+ % result)
+
+ # Ensure that object disposal of this Python object will (eventually)
+ # free the memory allocated by the raw library for the cipher mode
+ self._state = SmartPointer(self._state.get(),
+ _raw_ocb_lib.OCB_stop_operation)
+
+ # Memory allocated for the underlying block cipher is now owed
+ # by the cipher mode
+ raw_cipher.release()
+
+ def _update(self, assoc_data, assoc_data_len):
+ result = _raw_ocb_lib.OCB_update(self._state.get(),
+ c_uint8_ptr(assoc_data),
+ c_size_t(assoc_data_len))
+ if result:
+ raise ValueError("Error %d while computing MAC in OCB mode" % result)
+
+ def update(self, assoc_data):
+ """Process the associated data.
+
+ If there is any associated data, the caller has to invoke
+ this method one or more times, before using
+ ``decrypt`` or ``encrypt``.
+
+ By *associated data* it is meant any data (e.g. packet headers) that
+ will not be encrypted and will be transmitted in the clear.
+ However, the receiver shall still able to detect modifications.
+
+ If there is no associated data, this method must not be called.
+
+ The caller may split associated data in segments of any size, and
+ invoke this method multiple times, each time with the next segment.
+
+ :Parameters:
+ assoc_data : bytes/bytearray/memoryview
+ A piece of associated data.
+ """
+
+ if self.update not in self._next:
+ raise TypeError("update() can only be called"
+ " immediately after initialization")
+
+ self._next = [self.encrypt, self.decrypt, self.digest,
+ self.verify, self.update]
+
+ if len(self._cache_A) > 0:
+ filler = min(16 - len(self._cache_A), len(assoc_data))
+ self._cache_A += _copy_bytes(None, filler, assoc_data)
+ assoc_data = assoc_data[filler:]
+
+ if len(self._cache_A) < 16:
+ return self
+
+ # Clear the cache, and proceeding with any other aligned data
+ self._cache_A, seg = b"", self._cache_A
+ self.update(seg)
+
+ update_len = len(assoc_data) // 16 * 16
+ self._cache_A = _copy_bytes(update_len, None, assoc_data)
+ self._update(assoc_data, update_len)
+ return self
+
+ def _transcrypt_aligned(self, in_data, in_data_len,
+ trans_func, trans_desc):
+
+ out_data = create_string_buffer(in_data_len)
+ result = trans_func(self._state.get(),
+ in_data,
+ out_data,
+ c_size_t(in_data_len))
+ if result:
+ raise ValueError("Error %d while %sing in OCB mode"
+ % (result, trans_desc))
+ return get_raw_buffer(out_data)
+
+ def _transcrypt(self, in_data, trans_func, trans_desc):
+ # Last piece to encrypt/decrypt
+ if in_data is None:
+ out_data = self._transcrypt_aligned(self._cache_P,
+ len(self._cache_P),
+ trans_func,
+ trans_desc)
+ self._cache_P = b""
+ return out_data
+
+ # Try to fill up the cache, if it already contains something
+ prefix = b""
+ if len(self._cache_P) > 0:
+ filler = min(16 - len(self._cache_P), len(in_data))
+ self._cache_P += _copy_bytes(None, filler, in_data)
+ in_data = in_data[filler:]
+
+ if len(self._cache_P) < 16:
+ # We could not manage to fill the cache, so there is certainly
+ # no output yet.
+ return b""
+
+ # Clear the cache, and proceeding with any other aligned data
+ prefix = self._transcrypt_aligned(self._cache_P,
+ len(self._cache_P),
+ trans_func,
+ trans_desc)
+ self._cache_P = b""
+
+ # Process data in multiples of the block size
+ trans_len = len(in_data) // 16 * 16
+ result = self._transcrypt_aligned(c_uint8_ptr(in_data),
+ trans_len,
+ trans_func,
+ trans_desc)
+ if prefix:
+ result = prefix + result
+
+ # Left-over
+ self._cache_P = _copy_bytes(trans_len, None, in_data)
+
+ return result
+
+ def encrypt(self, plaintext=None):
+ """Encrypt the next piece of plaintext.
+
+ After the entire plaintext has been passed (but before `digest`),
+ you **must** call this method one last time with no arguments to collect
+ the final piece of ciphertext.
+
+ If possible, use the method `encrypt_and_digest` instead.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The next piece of data to encrypt or ``None`` to signify
+ that encryption has finished and that any remaining ciphertext
+ has to be produced.
+ :Return:
+ the ciphertext, as a byte string.
+ Its length may not match the length of the *plaintext*.
+ """
+
+ if self.encrypt not in self._next:
+ raise TypeError("encrypt() can only be called after"
+ " initialization or an update()")
+
+ if plaintext is None:
+ self._next = [self.digest]
+ else:
+ self._next = [self.encrypt]
+ return self._transcrypt(plaintext, _raw_ocb_lib.OCB_encrypt, "encrypt")
+
+ def decrypt(self, ciphertext=None):
+ """Decrypt the next piece of ciphertext.
+
+ After the entire ciphertext has been passed (but before `verify`),
+ you **must** call this method one last time with no arguments to collect
+ the remaining piece of plaintext.
+
+ If possible, use the method `decrypt_and_verify` instead.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The next piece of data to decrypt or ``None`` to signify
+ that decryption has finished and that any remaining plaintext
+ has to be produced.
+ :Return:
+ the plaintext, as a byte string.
+ Its length may not match the length of the *ciphertext*.
+ """
+
+ if self.decrypt not in self._next:
+ raise TypeError("decrypt() can only be called after"
+ " initialization or an update()")
+
+ if ciphertext is None:
+ self._next = [self.verify]
+ else:
+ self._next = [self.decrypt]
+ return self._transcrypt(ciphertext,
+ _raw_ocb_lib.OCB_decrypt,
+ "decrypt")
+
+ def _compute_mac_tag(self):
+
+ if self._mac_tag is not None:
+ return
+
+ if self._cache_A:
+ self._update(self._cache_A, len(self._cache_A))
+ self._cache_A = b""
+
+ mac_tag = create_string_buffer(16)
+ result = _raw_ocb_lib.OCB_digest(self._state.get(),
+ mac_tag,
+ c_size_t(len(mac_tag))
+ )
+ if result:
+ raise ValueError("Error %d while computing digest in OCB mode"
+ % result)
+ self._mac_tag = get_raw_buffer(mac_tag)[:self._mac_len]
+
+ def digest(self):
+ """Compute the *binary* MAC tag.
+
+ Call this method after the final `encrypt` (the one with no arguments)
+ to obtain the MAC tag.
+
+ The MAC tag is needed by the receiver to determine authenticity
+ of the message.
+
+ :Return: the MAC, as a byte string.
+ """
+
+ if self.digest not in self._next:
+ raise TypeError("digest() cannot be called now for this cipher")
+
+ assert(len(self._cache_P) == 0)
+
+ self._next = [self.digest]
+
+ if self._mac_tag is None:
+ self._compute_mac_tag()
+
+ return self._mac_tag
+
+ def hexdigest(self):
+ """Compute the *printable* MAC tag.
+
+ This method is like `digest`.
+
+ :Return: the MAC, as a hexadecimal string.
+ """
+ return "".join(["%02x" % bord(x) for x in self.digest()])
+
+ def verify(self, received_mac_tag):
+ """Validate the *binary* MAC tag.
+
+ Call this method after the final `decrypt` (the one with no arguments)
+ to check if the message is authentic and valid.
+
+ :Parameters:
+ received_mac_tag : bytes/bytearray/memoryview
+ This is the *binary* MAC, as received from the sender.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ if self.verify not in self._next:
+ raise TypeError("verify() cannot be called now for this cipher")
+
+ assert(len(self._cache_P) == 0)
+
+ self._next = [self.verify]
+
+ if self._mac_tag is None:
+ self._compute_mac_tag()
+
+ secret = get_random_bytes(16)
+ mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag)
+ mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag)
+
+ if mac1.digest() != mac2.digest():
+ raise ValueError("MAC check failed")
+
+ def hexverify(self, hex_mac_tag):
+ """Validate the *printable* MAC tag.
+
+ This method is like `verify`.
+
+ :Parameters:
+ hex_mac_tag : string
+ This is the *printable* MAC, as received from the sender.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ self.verify(unhexlify(hex_mac_tag))
+
+ def encrypt_and_digest(self, plaintext):
+ """Encrypt the message and create the MAC tag in one step.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The entire message to encrypt.
+ :Return:
+ a tuple with two byte strings:
+
+ - the encrypted data
+ - the MAC
+ """
+
+ return self.encrypt(plaintext) + self.encrypt(), self.digest()
+
+ def decrypt_and_verify(self, ciphertext, received_mac_tag):
+ """Decrypted the message and verify its authenticity in one step.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The entire message to decrypt.
+ received_mac_tag : byte string
+ This is the *binary* MAC, as received from the sender.
+
+ :Return: the decrypted data (byte string).
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ plaintext = self.decrypt(ciphertext) + self.decrypt()
+ self.verify(received_mac_tag)
+ return plaintext
+
+
+def _create_ocb_cipher(factory, **kwargs):
+ """Create a new block cipher, configured in OCB mode.
+
+ :Parameters:
+ factory : module
+ A symmetric cipher module from `Cryptodome.Cipher`
+ (like `Cryptodome.Cipher.AES`).
+
+ :Keywords:
+ nonce : bytes/bytearray/memoryview
+ A value that must never be reused for any other encryption.
+ Its length can vary from 1 to 15 bytes.
+ If not specified, a random 15 bytes long nonce is generated.
+
+ mac_len : integer
+ Length of the MAC, in bytes.
+ It must be in the range ``[8..16]``.
+ The default is 16 (128 bits).
+
+ Any other keyword will be passed to the underlying block cipher.
+ See the relevant documentation for details (at least ``key`` will need
+ to be present).
+ """
+
+ try:
+ nonce = kwargs.pop("nonce", None)
+ if nonce is None:
+ nonce = get_random_bytes(15)
+ mac_len = kwargs.pop("mac_len", 16)
+ except KeyError as e:
+ raise TypeError("Keyword missing: " + str(e))
+
+ return OcbMode(factory, nonce, mac_len, kwargs)
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ocb.pyi b/frozen_deps/Cryptodome/Cipher/_mode_ocb.pyi
new file mode 100644
index 0000000..a1909fc
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_ocb.pyi
@@ -0,0 +1,36 @@
+from types import ModuleType
+from typing import Union, Any, Optional, Tuple, Dict, overload
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+class OcbMode(object):
+ block_size: int
+ nonce: Buffer
+
+ def __init__(self,
+ factory: ModuleType,
+ nonce: Buffer,
+ mac_len: int,
+ cipher_params: Dict) -> None: ...
+
+ def update(self, assoc_data: Buffer) -> OcbMode: ...
+
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+
+ def digest(self) -> bytes: ...
+ def hexdigest(self) -> str: ...
+ def verify(self, received_mac_tag: Buffer) -> None: ...
+ def hexverify(self, hex_mac_tag: str) -> None: ...
+
+ def encrypt_and_digest(self,
+ plaintext: Buffer) -> Tuple[bytes, bytes]: ...
+ def decrypt_and_verify(self,
+ ciphertext: Buffer,
+ received_mac_tag: Buffer) -> bytes: ...
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ofb.py b/frozen_deps/Cryptodome/Cipher/_mode_ofb.py
new file mode 100644
index 0000000..04aaccf
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_ofb.py
@@ -0,0 +1,282 @@
+# -*- coding: utf-8 -*-
+#
+# Cipher/mode_ofb.py : OFB mode
+#
+# ===================================================================
+# 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.
+# ===================================================================
+
+"""
+Output Feedback (CFB) mode.
+"""
+
+__all__ = ['OfbMode']
+
+from Cryptodome.Util.py3compat import _copy_bytes
+from Cryptodome.Util._raw_api import (load_pycryptodome_raw_lib, VoidPointer,
+ create_string_buffer, get_raw_buffer,
+ SmartPointer, c_size_t, c_uint8_ptr,
+ is_writeable_buffer)
+
+from Cryptodome.Random import get_random_bytes
+
+raw_ofb_lib = load_pycryptodome_raw_lib("Cryptodome.Cipher._raw_ofb", """
+ int OFB_start_operation(void *cipher,
+ const uint8_t iv[],
+ size_t iv_len,
+ void **pResult);
+ int OFB_encrypt(void *ofbState,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int OFB_decrypt(void *ofbState,
+ const uint8_t *in,
+ uint8_t *out,
+ size_t data_len);
+ int OFB_stop_operation(void *state);
+ """
+ )
+
+
+class OfbMode(object):
+ """*Output FeedBack (OFB)*.
+
+ This mode is very similar to CBC, but it
+ transforms the underlying block cipher into a stream cipher.
+
+ The keystream is the iterated block encryption of the
+ previous ciphertext block.
+
+ An Initialization Vector (*IV*) is required.
+
+ See `NIST SP800-38A`_ , Section 6.4.
+
+ .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+
+ :undocumented: __init__
+ """
+
+ def __init__(self, block_cipher, iv):
+ """Create a new block cipher, configured in OFB mode.
+
+ :Parameters:
+ block_cipher : C pointer
+ A smart pointer to the low-level block cipher instance.
+
+ iv : bytes/bytearray/memoryview
+ The initialization vector to use for encryption or decryption.
+ It is as long as the cipher block.
+
+ **The IV must be a nonce, to to be reused for any other
+ message**. It shall be a nonce or a random value.
+
+ Reusing the *IV* for encryptions performed with the same key
+ compromises confidentiality.
+ """
+
+ self._state = VoidPointer()
+ result = raw_ofb_lib.OFB_start_operation(block_cipher.get(),
+ c_uint8_ptr(iv),
+ c_size_t(len(iv)),
+ self._state.address_of())
+ if result:
+ raise ValueError("Error %d while instantiating the OFB mode"
+ % result)
+
+ # Ensure that object disposal of this Python object will (eventually)
+ # free the memory allocated by the raw library for the cipher mode
+ self._state = SmartPointer(self._state.get(),
+ raw_ofb_lib.OFB_stop_operation)
+
+ # Memory allocated for the underlying block cipher is now owed
+ # by the cipher mode
+ block_cipher.release()
+
+ self.block_size = len(iv)
+ """The block size of the underlying cipher, in bytes."""
+
+ self.iv = _copy_bytes(None, None, iv)
+ """The Initialization Vector originally used to create the object.
+ The value does not change."""
+
+ self.IV = self.iv
+ """Alias for `iv`"""
+
+ self._next = [ self.encrypt, self.decrypt ]
+
+ def encrypt(self, plaintext, output=None):
+ """Encrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have encrypted a message
+ you cannot encrypt (or decrypt) another message using the same
+ object.
+
+ The data to encrypt can be broken up in two or
+ more pieces and `encrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.encrypt(a) + c.encrypt(b)
+
+ is equivalent to:
+
+ >>> c.encrypt(a+b)
+
+ This function does not add any padding to the plaintext.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ If ``output`` is ``None``, the ciphertext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.encrypt not in self._next:
+ raise TypeError("encrypt() cannot be called after decrypt()")
+ self._next = [ self.encrypt ]
+
+ if output is None:
+ ciphertext = create_string_buffer(len(plaintext))
+ else:
+ ciphertext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(plaintext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+ result = raw_ofb_lib.OFB_encrypt(self._state.get(),
+ c_uint8_ptr(plaintext),
+ c_uint8_ptr(ciphertext),
+ c_size_t(len(plaintext)))
+ if result:
+ raise ValueError("Error %d while encrypting in OFB mode" % result)
+
+ if output is None:
+ return get_raw_buffer(ciphertext)
+ else:
+ return None
+
+ def decrypt(self, ciphertext, output=None):
+ """Decrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have decrypted a message
+ you cannot decrypt (or encrypt) another message with the same
+ object.
+
+ The data to decrypt can be broken up in two or
+ more pieces and `decrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.decrypt(a) + c.decrypt(b)
+
+ is equivalent to:
+
+ >>> c.decrypt(a+b)
+
+ This function does not remove any padding from the plaintext.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ It can be of any length.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext is written to.
+ If ``None``, the plaintext is returned.
+ :Return:
+ If ``output`` is ``None``, the plaintext is returned as ``bytes``.
+ Otherwise, ``None``.
+ """
+
+ if self.decrypt not in self._next:
+ raise TypeError("decrypt() cannot be called after encrypt()")
+ self._next = [ self.decrypt ]
+
+ if output is None:
+ plaintext = create_string_buffer(len(ciphertext))
+ else:
+ plaintext = output
+
+ if not is_writeable_buffer(output):
+ raise TypeError("output must be a bytearray or a writeable memoryview")
+
+ if len(ciphertext) != len(output):
+ raise ValueError("output must have the same length as the input"
+ " (%d bytes)" % len(plaintext))
+
+ result = raw_ofb_lib.OFB_decrypt(self._state.get(),
+ c_uint8_ptr(ciphertext),
+ c_uint8_ptr(plaintext),
+ c_size_t(len(ciphertext)))
+ if result:
+ raise ValueError("Error %d while decrypting in OFB mode" % result)
+
+ if output is None:
+ return get_raw_buffer(plaintext)
+ else:
+ return None
+
+
+def _create_ofb_cipher(factory, **kwargs):
+ """Instantiate a cipher object that performs OFB encryption/decryption.
+
+ :Parameters:
+ factory : module
+ The underlying block cipher, a module from ``Cryptodome.Cipher``.
+
+ :Keywords:
+ iv : bytes/bytearray/memoryview
+ The IV to use for OFB.
+
+ IV : bytes/bytearray/memoryview
+ Alias for ``iv``.
+
+ Any other keyword will be passed to the underlying block cipher.
+ See the relevant documentation for details (at least ``key`` will need
+ to be present).
+ """
+
+ cipher_state = factory._create_base_cipher(kwargs)
+ iv = kwargs.pop("IV", None)
+ IV = kwargs.pop("iv", None)
+
+ if (None, None) == (iv, IV):
+ iv = get_random_bytes(factory.block_size)
+ if iv is not None:
+ if IV is not None:
+ raise TypeError("You must either use 'iv' or 'IV', not both")
+ else:
+ iv = IV
+
+ if len(iv) != factory.block_size:
+ raise ValueError("Incorrect IV length (it must be %d bytes long)" %
+ factory.block_size)
+
+ if kwargs:
+ raise TypeError("Unknown parameters for OFB: %s" % str(kwargs))
+
+ return OfbMode(cipher_state, iv)
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_ofb.pyi b/frozen_deps/Cryptodome/Cipher/_mode_ofb.pyi
new file mode 100644
index 0000000..d28608e
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_ofb.pyi
@@ -0,0 +1,25 @@
+from typing import Union, overload
+
+from Cryptodome.Util._raw_api import SmartPointer
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+__all__ = ['OfbMode']
+
+class OfbMode(object):
+ block_size: int
+ iv: Buffer
+ IV: Buffer
+
+ def __init__(self,
+ block_cipher: SmartPointer,
+ iv: Buffer) -> None: ...
+ @overload
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def encrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+ @overload
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+ @overload
+ def decrypt(self, plaintext: Buffer, output: Union[bytearray, memoryview]) -> None: ...
+
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_openpgp.py b/frozen_deps/Cryptodome/Cipher/_mode_openpgp.py
new file mode 100644
index 0000000..d86ed19
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_openpgp.py
@@ -0,0 +1,206 @@
+# ===================================================================
+#
+# Copyright (c) 2014, Legrandin <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+"""
+OpenPGP mode.
+"""
+
+__all__ = ['OpenPgpMode']
+
+from Cryptodome.Util.py3compat import _copy_bytes
+from Cryptodome.Random import get_random_bytes
+
+class OpenPgpMode(object):
+ """OpenPGP mode.
+
+ This mode is a variant of CFB, and it is only used in PGP and
+ OpenPGP_ applications. If in doubt, use another mode.
+
+ An Initialization Vector (*IV*) is required.
+
+ Unlike CFB, the *encrypted* IV (not the IV itself) is
+ transmitted to the receiver.
+
+ The IV is a random data block. For legacy reasons, two of its bytes are
+ duplicated to act as a checksum for the correctness of the key, which is now
+ known to be insecure and is ignored. The encrypted IV is therefore 2 bytes
+ longer than the clean IV.
+
+ .. _OpenPGP: http://tools.ietf.org/html/rfc4880
+
+ :undocumented: __init__
+ """
+
+ def __init__(self, factory, key, iv, cipher_params):
+
+ #: The block size of the underlying cipher, in bytes.
+ self.block_size = factory.block_size
+
+ self._done_first_block = False # True after the first encryption
+
+ # Instantiate a temporary cipher to process the IV
+ IV_cipher = factory.new(
+ key,
+ factory.MODE_CFB,
+ IV=b'\x00' * self.block_size,
+ segment_size=self.block_size * 8,
+ **cipher_params)
+
+ iv = _copy_bytes(None, None, iv)
+
+ # The cipher will be used for...
+ if len(iv) == self.block_size:
+ # ... encryption
+ self._encrypted_IV = IV_cipher.encrypt(iv + iv[-2:])
+ elif len(iv) == self.block_size + 2:
+ # ... decryption
+ self._encrypted_IV = iv
+ # Last two bytes are for a deprecated "quick check" feature that
+ # should not be used. (https://eprint.iacr.org/2005/033)
+ iv = IV_cipher.decrypt(iv)[:-2]
+ else:
+ raise ValueError("Length of IV must be %d or %d bytes"
+ " for MODE_OPENPGP"
+ % (self.block_size, self.block_size + 2))
+
+ self.iv = self.IV = iv
+
+ # Instantiate the cipher for the real PGP data
+ self._cipher = factory.new(
+ key,
+ factory.MODE_CFB,
+ IV=self._encrypted_IV[-self.block_size:],
+ segment_size=self.block_size * 8,
+ **cipher_params)
+
+ def encrypt(self, plaintext):
+ """Encrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have encrypted a message
+ you cannot encrypt (or decrypt) another message using the same
+ object.
+
+ The data to encrypt can be broken up in two or
+ more pieces and `encrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.encrypt(a) + c.encrypt(b)
+
+ is equivalent to:
+
+ >>> c.encrypt(a+b)
+
+ This function does not add any padding to the plaintext.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+
+ :Return:
+ the encrypted data, as a byte string.
+ It is as long as *plaintext* with one exception:
+ when encrypting the first message chunk,
+ the encypted IV is prepended to the returned ciphertext.
+ """
+
+ res = self._cipher.encrypt(plaintext)
+ if not self._done_first_block:
+ res = self._encrypted_IV + res
+ self._done_first_block = True
+ return res
+
+ def decrypt(self, ciphertext):
+ """Decrypt data with the key and the parameters set at initialization.
+
+ A cipher object is stateful: once you have decrypted a message
+ you cannot decrypt (or encrypt) another message with the same
+ object.
+
+ The data to decrypt can be broken up in two or
+ more pieces and `decrypt` can be called multiple times.
+
+ That is, the statement:
+
+ >>> c.decrypt(a) + c.decrypt(b)
+
+ is equivalent to:
+
+ >>> c.decrypt(a+b)
+
+ This function does not remove any padding from the plaintext.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+
+ :Return: the decrypted data (byte string).
+ """
+
+ return self._cipher.decrypt(ciphertext)
+
+
+def _create_openpgp_cipher(factory, **kwargs):
+ """Create a new block cipher, configured in OpenPGP mode.
+
+ :Parameters:
+ factory : module
+ The module.
+
+ :Keywords:
+ key : bytes/bytearray/memoryview
+ The secret key to use in the symmetric cipher.
+
+ IV : bytes/bytearray/memoryview
+ The initialization vector to use for encryption or decryption.
+
+ For encryption, the IV must be as long as the cipher block size.
+
+ For decryption, it must be 2 bytes longer (it is actually the
+ *encrypted* IV which was prefixed to the ciphertext).
+ """
+
+ iv = kwargs.pop("IV", None)
+ IV = kwargs.pop("iv", None)
+
+ if (None, None) == (iv, IV):
+ iv = get_random_bytes(factory.block_size)
+ if iv is not None:
+ if IV is not None:
+ raise TypeError("You must either use 'iv' or 'IV', not both")
+ else:
+ iv = IV
+
+ try:
+ key = kwargs.pop("key")
+ except KeyError as e:
+ raise TypeError("Missing component: " + str(e))
+
+ return OpenPgpMode(factory, key, iv, kwargs)
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_openpgp.pyi b/frozen_deps/Cryptodome/Cipher/_mode_openpgp.pyi
new file mode 100644
index 0000000..14b8105
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_openpgp.pyi
@@ -0,0 +1,20 @@
+from types import ModuleType
+from typing import Union, Dict
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+__all__ = ['OpenPgpMode']
+
+class OpenPgpMode(object):
+ block_size: int
+ iv: Union[bytes, bytearray, memoryview]
+ IV: Union[bytes, bytearray, memoryview]
+
+ def __init__(self,
+ factory: ModuleType,
+ key: Buffer,
+ iv: Buffer,
+ cipher_params: Dict) -> None: ...
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_siv.py b/frozen_deps/Cryptodome/Cipher/_mode_siv.py
new file mode 100644
index 0000000..d10c4dc
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_siv.py
@@ -0,0 +1,392 @@
+# ===================================================================
+#
+# Copyright (c) 2014, Legrandin <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+# ===================================================================
+
+"""
+Synthetic Initialization Vector (SIV) mode.
+"""
+
+__all__ = ['SivMode']
+
+from binascii import hexlify, unhexlify
+
+from Cryptodome.Util.py3compat import bord, _copy_bytes
+
+from Cryptodome.Util._raw_api import is_buffer
+
+from Cryptodome.Util.number import long_to_bytes, bytes_to_long
+from Cryptodome.Protocol.KDF import _S2V
+from Cryptodome.Hash import BLAKE2s
+from Cryptodome.Random import get_random_bytes
+
+
+class SivMode(object):
+ """Synthetic Initialization Vector (SIV).
+
+ This is an Authenticated Encryption with Associated Data (`AEAD`_) mode.
+ It provides both confidentiality and authenticity.
+
+ The header of the message may be left in the clear, if needed, and it will
+ still be subject to authentication. The decryption step tells the receiver
+ if the message comes from a source that really knowns the secret key.
+ Additionally, decryption detects if any part of the message - including the
+ header - has been modified or corrupted.
+
+ Unlike other AEAD modes such as CCM, EAX or GCM, accidental reuse of a
+ nonce is not catastrophic for the confidentiality of the message. The only
+ effect is that an attacker can tell when the same plaintext (and same
+ associated data) is protected with the same key.
+
+ The length of the MAC is fixed to the block size of the underlying cipher.
+ The key size is twice the length of the key of the underlying cipher.
+
+ This mode is only available for AES ciphers.
+
+ +--------------------+---------------+-------------------+
+ | Cipher | SIV MAC size | SIV key length |
+ | | (bytes) | (bytes) |
+ +====================+===============+===================+
+ | AES-128 | 16 | 32 |
+ +--------------------+---------------+-------------------+
+ | AES-192 | 16 | 48 |
+ +--------------------+---------------+-------------------+
+ | AES-256 | 16 | 64 |
+ +--------------------+---------------+-------------------+
+
+ See `RFC5297`_ and the `original paper`__.
+
+ .. _RFC5297: https://tools.ietf.org/html/rfc5297
+ .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html
+ .. __: http://www.cs.ucdavis.edu/~rogaway/papers/keywrap.pdf
+
+ :undocumented: __init__
+ """
+
+ def __init__(self, factory, key, nonce, kwargs):
+
+ self.block_size = factory.block_size
+ """The block size of the underlying cipher, in bytes."""
+
+ self._factory = factory
+
+ self._cipher_params = kwargs
+
+ if len(key) not in (32, 48, 64):
+ raise ValueError("Incorrect key length (%d bytes)" % len(key))
+
+ if nonce is not None:
+ if not is_buffer(nonce):
+ raise TypeError("When provided, the nonce must be bytes, bytearray or memoryview")
+
+ if len(nonce) == 0:
+ raise ValueError("When provided, the nonce must be non-empty")
+
+ self.nonce = _copy_bytes(None, None, nonce)
+ """Public attribute is only available in case of non-deterministic
+ encryption."""
+
+ subkey_size = len(key) // 2
+
+ self._mac_tag = None # Cache for MAC tag
+ self._kdf = _S2V(key[:subkey_size],
+ ciphermod=factory,
+ cipher_params=self._cipher_params)
+ self._subkey_cipher = key[subkey_size:]
+
+ # Purely for the purpose of verifying that cipher_params are OK
+ factory.new(key[:subkey_size], factory.MODE_ECB, **kwargs)
+
+ # Allowed transitions after initialization
+ self._next = [self.update, self.encrypt, self.decrypt,
+ self.digest, self.verify]
+
+ def _create_ctr_cipher(self, v):
+ """Create a new CTR cipher from V in SIV mode"""
+
+ v_int = bytes_to_long(v)
+ q = v_int & 0xFFFFFFFFFFFFFFFF7FFFFFFF7FFFFFFF
+ return self._factory.new(
+ self._subkey_cipher,
+ self._factory.MODE_CTR,
+ initial_value=q,
+ nonce=b"",
+ **self._cipher_params)
+
+ def update(self, component):
+ """Protect one associated data component
+
+ For SIV, the associated data is a sequence (*vector*) of non-empty
+ byte strings (*components*).
+
+ This method consumes the next component. It must be called
+ once for each of the components that constitue the associated data.
+
+ Note that the components have clear boundaries, so that:
+
+ >>> cipher.update(b"builtin")
+ >>> cipher.update(b"securely")
+
+ is not equivalent to:
+
+ >>> cipher.update(b"built")
+ >>> cipher.update(b"insecurely")
+
+ If there is no associated data, this method must not be called.
+
+ :Parameters:
+ component : bytes/bytearray/memoryview
+ The next associated data component.
+ """
+
+ if self.update not in self._next:
+ raise TypeError("update() can only be called"
+ " immediately after initialization")
+
+ self._next = [self.update, self.encrypt, self.decrypt,
+ self.digest, self.verify]
+
+ return self._kdf.update(component)
+
+ def encrypt(self, plaintext):
+ """
+ For SIV, encryption and MAC authentication must take place at the same
+ point. This method shall not be used.
+
+ Use `encrypt_and_digest` instead.
+ """
+
+ raise TypeError("encrypt() not allowed for SIV mode."
+ " Use encrypt_and_digest() instead.")
+
+ def decrypt(self, ciphertext):
+ """
+ For SIV, decryption and verification must take place at the same
+ point. This method shall not be used.
+
+ Use `decrypt_and_verify` instead.
+ """
+
+ raise TypeError("decrypt() not allowed for SIV mode."
+ " Use decrypt_and_verify() instead.")
+
+ def digest(self):
+ """Compute the *binary* MAC tag.
+
+ The caller invokes this function at the very end.
+
+ This method returns the MAC that shall be sent to the receiver,
+ together with the ciphertext.
+
+ :Return: the MAC, as a byte string.
+ """
+
+ if self.digest not in self._next:
+ raise TypeError("digest() cannot be called when decrypting"
+ " or validating a message")
+ self._next = [self.digest]
+ if self._mac_tag is None:
+ self._mac_tag = self._kdf.derive()
+ return self._mac_tag
+
+ def hexdigest(self):
+ """Compute the *printable* MAC tag.
+
+ This method is like `digest`.
+
+ :Return: the MAC, as a hexadecimal string.
+ """
+ return "".join(["%02x" % bord(x) for x in self.digest()])
+
+ def verify(self, received_mac_tag):
+ """Validate the *binary* MAC tag.
+
+ The caller invokes this function at the very end.
+
+ This method checks if the decrypted message is indeed valid
+ (that is, if the key is correct) and it has not been
+ tampered with while in transit.
+
+ :Parameters:
+ received_mac_tag : bytes/bytearray/memoryview
+ This is the *binary* MAC, as received from the sender.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ if self.verify not in self._next:
+ raise TypeError("verify() cannot be called"
+ " when encrypting a message")
+ self._next = [self.verify]
+
+ if self._mac_tag is None:
+ self._mac_tag = self._kdf.derive()
+
+ secret = get_random_bytes(16)
+
+ mac1 = BLAKE2s.new(digest_bits=160, key=secret, data=self._mac_tag)
+ mac2 = BLAKE2s.new(digest_bits=160, key=secret, data=received_mac_tag)
+
+ if mac1.digest() != mac2.digest():
+ raise ValueError("MAC check failed")
+
+ def hexverify(self, hex_mac_tag):
+ """Validate the *printable* MAC tag.
+
+ This method is like `verify`.
+
+ :Parameters:
+ hex_mac_tag : string
+ This is the *printable* MAC, as received from the sender.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ self.verify(unhexlify(hex_mac_tag))
+
+ def encrypt_and_digest(self, plaintext, output=None):
+ """Perform encrypt() and digest() in one step.
+
+ :Parameters:
+ plaintext : bytes/bytearray/memoryview
+ The piece of data to encrypt.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the ciphertext must be written to.
+ If ``None``, the ciphertext is returned.
+ :Return:
+ a tuple with two items:
+
+ - the ciphertext, as ``bytes``
+ - the MAC tag, as ``bytes``
+
+ The first item becomes ``None`` when the ``output`` parameter
+ specified a location for the result.
+ """
+
+ if self.encrypt not in self._next:
+ raise TypeError("encrypt() can only be called after"
+ " initialization or an update()")
+
+ self._next = [ self.digest ]
+
+ # Compute V (MAC)
+ if hasattr(self, 'nonce'):
+ self._kdf.update(self.nonce)
+ self._kdf.update(plaintext)
+ self._mac_tag = self._kdf.derive()
+
+ cipher = self._create_ctr_cipher(self._mac_tag)
+
+ return cipher.encrypt(plaintext, output=output), self._mac_tag
+
+ def decrypt_and_verify(self, ciphertext, mac_tag, output=None):
+ """Perform decryption and verification in one step.
+
+ A cipher object is stateful: once you have decrypted a message
+ you cannot decrypt (or encrypt) another message with the same
+ object.
+
+ You cannot reuse an object for encrypting
+ or decrypting other data with the same key.
+
+ This function does not remove any padding from the plaintext.
+
+ :Parameters:
+ ciphertext : bytes/bytearray/memoryview
+ The piece of data to decrypt.
+ It can be of any length.
+ mac_tag : bytes/bytearray/memoryview
+ This is the *binary* MAC, as received from the sender.
+ :Keywords:
+ output : bytearray/memoryview
+ The location where the plaintext must be written to.
+ If ``None``, the plaintext is returned.
+ :Return: the plaintext as ``bytes`` or ``None`` when the ``output``
+ parameter specified a location for the result.
+ :Raises ValueError:
+ if the MAC does not match. The message has been tampered with
+ or the key is incorrect.
+ """
+
+ if self.decrypt not in self._next:
+ raise TypeError("decrypt() can only be called"
+ " after initialization or an update()")
+ self._next = [ self.verify ]
+
+ # Take the MAC and start the cipher for decryption
+ self._cipher = self._create_ctr_cipher(mac_tag)
+
+ plaintext = self._cipher.decrypt(ciphertext, output=output)
+
+ if hasattr(self, 'nonce'):
+ self._kdf.update(self.nonce)
+ self._kdf.update(plaintext if output is None else output)
+ self.verify(mac_tag)
+
+ return plaintext
+
+
+def _create_siv_cipher(factory, **kwargs):
+ """Create a new block cipher, configured in
+ Synthetic Initializaton Vector (SIV) mode.
+
+ :Parameters:
+
+ factory : object
+ A symmetric cipher module from `Cryptodome.Cipher`
+ (like `Cryptodome.Cipher.AES`).
+
+ :Keywords:
+
+ key : bytes/bytearray/memoryview
+ The secret key to use in the symmetric cipher.
+ It must be 32, 48 or 64 bytes long.
+ If AES is the chosen cipher, the variants *AES-128*,
+ *AES-192* and or *AES-256* will be used internally.
+
+ nonce : bytes/bytearray/memoryview
+ For deterministic encryption, it is not present.
+
+ Otherwise, it is a value that must never be reused
+ for encrypting message under this key.
+
+ There are no restrictions on its length,
+ but it is recommended to use at least 16 bytes.
+ """
+
+ try:
+ key = kwargs.pop("key")
+ except KeyError as e:
+ raise TypeError("Missing parameter: " + str(e))
+
+ nonce = kwargs.pop("nonce", None)
+
+ return SivMode(factory, key, nonce, kwargs)
diff --git a/frozen_deps/Cryptodome/Cipher/_mode_siv.pyi b/frozen_deps/Cryptodome/Cipher/_mode_siv.pyi
new file mode 100644
index 0000000..2934f23
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_mode_siv.pyi
@@ -0,0 +1,38 @@
+from types import ModuleType
+from typing import Union, Tuple, Dict, Optional, overload
+
+Buffer = Union[bytes, bytearray, memoryview]
+
+__all__ = ['SivMode']
+
+class SivMode(object):
+ block_size: int
+ nonce: bytes
+
+ def __init__(self,
+ factory: ModuleType,
+ key: Buffer,
+ nonce: Buffer,
+ kwargs: Dict) -> None: ...
+
+ def update(self, component: Buffer) -> SivMode: ...
+
+ def encrypt(self, plaintext: Buffer) -> bytes: ...
+ def decrypt(self, plaintext: Buffer) -> bytes: ...
+
+ def digest(self) -> bytes: ...
+ def hexdigest(self) -> str: ...
+ def verify(self, received_mac_tag: Buffer) -> None: ...
+ def hexverify(self, hex_mac_tag: str) -> None: ...
+
+ @overload
+ def encrypt_and_digest(self,
+ plaintext: Buffer) -> Tuple[bytes, bytes]: ...
+ @overload
+ def encrypt_and_digest(self,
+ plaintext: Buffer,
+ output: Buffer) -> Tuple[None, bytes]: ...
+ def decrypt_and_verify(self,
+ ciphertext: Buffer,
+ received_mac_tag: Buffer,
+ output: Optional[Union[bytearray, memoryview]] = ...) -> bytes: ...
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_aes.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_aes.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..e62f4d1
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_aes.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_aesni.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_aesni.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..b92e170
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_aesni.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_arc2.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_arc2.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..07a720a
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_arc2.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_blowfish.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_blowfish.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..05abfd1
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_blowfish.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_cast.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_cast.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..2523fcb
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_cast.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_cbc.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_cbc.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..1b013f3
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_cbc.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_cfb.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_cfb.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..6a28991
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_cfb.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_ctr.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_ctr.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..0529cf8
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_ctr.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_des.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_des.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..1d73854
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_des.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_des3.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_des3.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..8c4afa5
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_des3.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_ecb.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_ecb.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..0775c0b
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_ecb.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_eksblowfish.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_eksblowfish.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..979fe63
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_eksblowfish.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_ocb.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_ocb.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..d545618
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_ocb.cpython-38-x86_64-linux-gnu.so
Binary files differ
diff --git a/frozen_deps/Cryptodome/Cipher/_raw_ofb.cpython-38-x86_64-linux-gnu.so b/frozen_deps/Cryptodome/Cipher/_raw_ofb.cpython-38-x86_64-linux-gnu.so
new file mode 100755
index 0000000..7157784
--- /dev/null
+++ b/frozen_deps/Cryptodome/Cipher/_raw_ofb.cpython-38-x86_64-linux-gnu.so
Binary files differ