mirror of
				https://gitlab.sectorq.eu/jaydee/omv_backup.git
				synced 2025-10-31 10:31:11 +01:00 
			
		
		
		
	added v3
This commit is contained in:
		| @@ -0,0 +1,27 @@ | ||||
| # This file is dual licensed under the terms of the Apache License, Version | ||||
| # 2.0, and the BSD License. See the LICENSE file in the root of this repository | ||||
| # for complete details. | ||||
|  | ||||
| from __future__ import annotations | ||||
|  | ||||
| from cryptography.hazmat.primitives._cipheralgorithm import ( | ||||
|     BlockCipherAlgorithm, | ||||
|     CipherAlgorithm, | ||||
| ) | ||||
| from cryptography.hazmat.primitives.ciphers.base import ( | ||||
|     AEADCipherContext, | ||||
|     AEADDecryptionContext, | ||||
|     AEADEncryptionContext, | ||||
|     Cipher, | ||||
|     CipherContext, | ||||
| ) | ||||
|  | ||||
| __all__ = [ | ||||
|     "AEADCipherContext", | ||||
|     "AEADDecryptionContext", | ||||
|     "AEADEncryptionContext", | ||||
|     "BlockCipherAlgorithm", | ||||
|     "Cipher", | ||||
|     "CipherAlgorithm", | ||||
|     "CipherContext", | ||||
| ] | ||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -0,0 +1,23 @@ | ||||
| # This file is dual licensed under the terms of the Apache License, Version | ||||
| # 2.0, and the BSD License. See the LICENSE file in the root of this repository | ||||
| # for complete details. | ||||
|  | ||||
| from __future__ import annotations | ||||
|  | ||||
| from cryptography.hazmat.bindings._rust import openssl as rust_openssl | ||||
|  | ||||
| __all__ = [ | ||||
|     "AESCCM", | ||||
|     "AESGCM", | ||||
|     "AESGCMSIV", | ||||
|     "AESOCB3", | ||||
|     "AESSIV", | ||||
|     "ChaCha20Poly1305", | ||||
| ] | ||||
|  | ||||
| AESGCM = rust_openssl.aead.AESGCM | ||||
| ChaCha20Poly1305 = rust_openssl.aead.ChaCha20Poly1305 | ||||
| AESCCM = rust_openssl.aead.AESCCM | ||||
| AESSIV = rust_openssl.aead.AESSIV | ||||
| AESOCB3 = rust_openssl.aead.AESOCB3 | ||||
| AESGCMSIV = rust_openssl.aead.AESGCMSIV | ||||
| @@ -0,0 +1,183 @@ | ||||
| # This file is dual licensed under the terms of the Apache License, Version | ||||
| # 2.0, and the BSD License. See the LICENSE file in the root of this repository | ||||
| # for complete details. | ||||
|  | ||||
| from __future__ import annotations | ||||
|  | ||||
| from cryptography import utils | ||||
| from cryptography.hazmat.decrepit.ciphers.algorithms import ( | ||||
|     ARC4 as ARC4, | ||||
| ) | ||||
| from cryptography.hazmat.decrepit.ciphers.algorithms import ( | ||||
|     CAST5 as CAST5, | ||||
| ) | ||||
| from cryptography.hazmat.decrepit.ciphers.algorithms import ( | ||||
|     IDEA as IDEA, | ||||
| ) | ||||
| from cryptography.hazmat.decrepit.ciphers.algorithms import ( | ||||
|     SEED as SEED, | ||||
| ) | ||||
| from cryptography.hazmat.decrepit.ciphers.algorithms import ( | ||||
|     Blowfish as Blowfish, | ||||
| ) | ||||
| from cryptography.hazmat.decrepit.ciphers.algorithms import ( | ||||
|     TripleDES as TripleDES, | ||||
| ) | ||||
| from cryptography.hazmat.primitives._cipheralgorithm import _verify_key_size | ||||
| from cryptography.hazmat.primitives.ciphers import ( | ||||
|     BlockCipherAlgorithm, | ||||
|     CipherAlgorithm, | ||||
| ) | ||||
|  | ||||
|  | ||||
| class AES(BlockCipherAlgorithm): | ||||
|     name = "AES" | ||||
|     block_size = 128 | ||||
|     # 512 added to support AES-256-XTS, which uses 512-bit keys | ||||
|     key_sizes = frozenset([128, 192, 256, 512]) | ||||
|  | ||||
|     def __init__(self, key: bytes): | ||||
|         self.key = _verify_key_size(self, key) | ||||
|  | ||||
|     @property | ||||
|     def key_size(self) -> int: | ||||
|         return len(self.key) * 8 | ||||
|  | ||||
|  | ||||
| class AES128(BlockCipherAlgorithm): | ||||
|     name = "AES" | ||||
|     block_size = 128 | ||||
|     key_sizes = frozenset([128]) | ||||
|     key_size = 128 | ||||
|  | ||||
|     def __init__(self, key: bytes): | ||||
|         self.key = _verify_key_size(self, key) | ||||
|  | ||||
|  | ||||
| class AES256(BlockCipherAlgorithm): | ||||
|     name = "AES" | ||||
|     block_size = 128 | ||||
|     key_sizes = frozenset([256]) | ||||
|     key_size = 256 | ||||
|  | ||||
|     def __init__(self, key: bytes): | ||||
|         self.key = _verify_key_size(self, key) | ||||
|  | ||||
|  | ||||
| class Camellia(BlockCipherAlgorithm): | ||||
|     name = "camellia" | ||||
|     block_size = 128 | ||||
|     key_sizes = frozenset([128, 192, 256]) | ||||
|  | ||||
|     def __init__(self, key: bytes): | ||||
|         self.key = _verify_key_size(self, key) | ||||
|  | ||||
|     @property | ||||
|     def key_size(self) -> int: | ||||
|         return len(self.key) * 8 | ||||
|  | ||||
|  | ||||
| utils.deprecated( | ||||
|     ARC4, | ||||
|     __name__, | ||||
|     "ARC4 has been moved to " | ||||
|     "cryptography.hazmat.decrepit.ciphers.algorithms.ARC4 and " | ||||
|     "will be removed from " | ||||
|     "cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0.", | ||||
|     utils.DeprecatedIn43, | ||||
|     name="ARC4", | ||||
| ) | ||||
|  | ||||
|  | ||||
| utils.deprecated( | ||||
|     TripleDES, | ||||
|     __name__, | ||||
|     "TripleDES has been moved to " | ||||
|     "cryptography.hazmat.decrepit.ciphers.algorithms.TripleDES and " | ||||
|     "will be removed from " | ||||
|     "cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0.", | ||||
|     utils.DeprecatedIn43, | ||||
|     name="TripleDES", | ||||
| ) | ||||
|  | ||||
| utils.deprecated( | ||||
|     Blowfish, | ||||
|     __name__, | ||||
|     "Blowfish has been moved to " | ||||
|     "cryptography.hazmat.decrepit.ciphers.algorithms.Blowfish and " | ||||
|     "will be removed from " | ||||
|     "cryptography.hazmat.primitives.ciphers.algorithms in 45.0.0.", | ||||
|     utils.DeprecatedIn37, | ||||
|     name="Blowfish", | ||||
| ) | ||||
|  | ||||
|  | ||||
| utils.deprecated( | ||||
|     CAST5, | ||||
|     __name__, | ||||
|     "CAST5 has been moved to " | ||||
|     "cryptography.hazmat.decrepit.ciphers.algorithms.CAST5 and " | ||||
|     "will be removed from " | ||||
|     "cryptography.hazmat.primitives.ciphers.algorithms in 45.0.0.", | ||||
|     utils.DeprecatedIn37, | ||||
|     name="CAST5", | ||||
| ) | ||||
|  | ||||
|  | ||||
| utils.deprecated( | ||||
|     IDEA, | ||||
|     __name__, | ||||
|     "IDEA has been moved to " | ||||
|     "cryptography.hazmat.decrepit.ciphers.algorithms.IDEA and " | ||||
|     "will be removed from " | ||||
|     "cryptography.hazmat.primitives.ciphers.algorithms in 45.0.0.", | ||||
|     utils.DeprecatedIn37, | ||||
|     name="IDEA", | ||||
| ) | ||||
|  | ||||
|  | ||||
| utils.deprecated( | ||||
|     SEED, | ||||
|     __name__, | ||||
|     "SEED has been moved to " | ||||
|     "cryptography.hazmat.decrepit.ciphers.algorithms.SEED and " | ||||
|     "will be removed from " | ||||
|     "cryptography.hazmat.primitives.ciphers.algorithms in 45.0.0.", | ||||
|     utils.DeprecatedIn37, | ||||
|     name="SEED", | ||||
| ) | ||||
|  | ||||
|  | ||||
| class ChaCha20(CipherAlgorithm): | ||||
|     name = "ChaCha20" | ||||
|     key_sizes = frozenset([256]) | ||||
|  | ||||
|     def __init__(self, key: bytes, nonce: bytes): | ||||
|         self.key = _verify_key_size(self, key) | ||||
|         utils._check_byteslike("nonce", nonce) | ||||
|  | ||||
|         if len(nonce) != 16: | ||||
|             raise ValueError("nonce must be 128-bits (16 bytes)") | ||||
|  | ||||
|         self._nonce = nonce | ||||
|  | ||||
|     @property | ||||
|     def nonce(self) -> bytes: | ||||
|         return self._nonce | ||||
|  | ||||
|     @property | ||||
|     def key_size(self) -> int: | ||||
|         return len(self.key) * 8 | ||||
|  | ||||
|  | ||||
| class SM4(BlockCipherAlgorithm): | ||||
|     name = "SM4" | ||||
|     block_size = 128 | ||||
|     key_sizes = frozenset([128]) | ||||
|  | ||||
|     def __init__(self, key: bytes): | ||||
|         self.key = _verify_key_size(self, key) | ||||
|  | ||||
|     @property | ||||
|     def key_size(self) -> int: | ||||
|         return len(self.key) * 8 | ||||
| @@ -0,0 +1,145 @@ | ||||
| # This file is dual licensed under the terms of the Apache License, Version | ||||
| # 2.0, and the BSD License. See the LICENSE file in the root of this repository | ||||
| # for complete details. | ||||
|  | ||||
| from __future__ import annotations | ||||
|  | ||||
| import abc | ||||
| import typing | ||||
|  | ||||
| from cryptography.hazmat.bindings._rust import openssl as rust_openssl | ||||
| from cryptography.hazmat.primitives._cipheralgorithm import CipherAlgorithm | ||||
| from cryptography.hazmat.primitives.ciphers import modes | ||||
|  | ||||
|  | ||||
| class CipherContext(metaclass=abc.ABCMeta): | ||||
|     @abc.abstractmethod | ||||
|     def update(self, data: bytes) -> bytes: | ||||
|         """ | ||||
|         Processes the provided bytes through the cipher and returns the results | ||||
|         as bytes. | ||||
|         """ | ||||
|  | ||||
|     @abc.abstractmethod | ||||
|     def update_into(self, data: bytes, buf: bytes) -> int: | ||||
|         """ | ||||
|         Processes the provided bytes and writes the resulting data into the | ||||
|         provided buffer. Returns the number of bytes written. | ||||
|         """ | ||||
|  | ||||
|     @abc.abstractmethod | ||||
|     def finalize(self) -> bytes: | ||||
|         """ | ||||
|         Returns the results of processing the final block as bytes. | ||||
|         """ | ||||
|  | ||||
|     @abc.abstractmethod | ||||
|     def reset_nonce(self, nonce: bytes) -> None: | ||||
|         """ | ||||
|         Resets the nonce for the cipher context to the provided value. | ||||
|         Raises an exception if it does not support reset or if the | ||||
|         provided nonce does not have a valid length. | ||||
|         """ | ||||
|  | ||||
|  | ||||
| class AEADCipherContext(CipherContext, metaclass=abc.ABCMeta): | ||||
|     @abc.abstractmethod | ||||
|     def authenticate_additional_data(self, data: bytes) -> None: | ||||
|         """ | ||||
|         Authenticates the provided bytes. | ||||
|         """ | ||||
|  | ||||
|  | ||||
| class AEADDecryptionContext(AEADCipherContext, metaclass=abc.ABCMeta): | ||||
|     @abc.abstractmethod | ||||
|     def finalize_with_tag(self, tag: bytes) -> bytes: | ||||
|         """ | ||||
|         Returns the results of processing the final block as bytes and allows | ||||
|         delayed passing of the authentication tag. | ||||
|         """ | ||||
|  | ||||
|  | ||||
| class AEADEncryptionContext(AEADCipherContext, metaclass=abc.ABCMeta): | ||||
|     @property | ||||
|     @abc.abstractmethod | ||||
|     def tag(self) -> bytes: | ||||
|         """ | ||||
|         Returns tag bytes. This is only available after encryption is | ||||
|         finalized. | ||||
|         """ | ||||
|  | ||||
|  | ||||
| Mode = typing.TypeVar( | ||||
|     "Mode", bound=typing.Optional[modes.Mode], covariant=True | ||||
| ) | ||||
|  | ||||
|  | ||||
| class Cipher(typing.Generic[Mode]): | ||||
|     def __init__( | ||||
|         self, | ||||
|         algorithm: CipherAlgorithm, | ||||
|         mode: Mode, | ||||
|         backend: typing.Any = None, | ||||
|     ) -> None: | ||||
|         if not isinstance(algorithm, CipherAlgorithm): | ||||
|             raise TypeError("Expected interface of CipherAlgorithm.") | ||||
|  | ||||
|         if mode is not None: | ||||
|             # mypy needs this assert to narrow the type from our generic | ||||
|             # type. Maybe it won't some time in the future. | ||||
|             assert isinstance(mode, modes.Mode) | ||||
|             mode.validate_for_algorithm(algorithm) | ||||
|  | ||||
|         self.algorithm = algorithm | ||||
|         self.mode = mode | ||||
|  | ||||
|     @typing.overload | ||||
|     def encryptor( | ||||
|         self: Cipher[modes.ModeWithAuthenticationTag], | ||||
|     ) -> AEADEncryptionContext: ... | ||||
|  | ||||
|     @typing.overload | ||||
|     def encryptor( | ||||
|         self: _CIPHER_TYPE, | ||||
|     ) -> CipherContext: ... | ||||
|  | ||||
|     def encryptor(self): | ||||
|         if isinstance(self.mode, modes.ModeWithAuthenticationTag): | ||||
|             if self.mode.tag is not None: | ||||
|                 raise ValueError( | ||||
|                     "Authentication tag must be None when encrypting." | ||||
|                 ) | ||||
|  | ||||
|         return rust_openssl.ciphers.create_encryption_ctx( | ||||
|             self.algorithm, self.mode | ||||
|         ) | ||||
|  | ||||
|     @typing.overload | ||||
|     def decryptor( | ||||
|         self: Cipher[modes.ModeWithAuthenticationTag], | ||||
|     ) -> AEADDecryptionContext: ... | ||||
|  | ||||
|     @typing.overload | ||||
|     def decryptor( | ||||
|         self: _CIPHER_TYPE, | ||||
|     ) -> CipherContext: ... | ||||
|  | ||||
|     def decryptor(self): | ||||
|         return rust_openssl.ciphers.create_decryption_ctx( | ||||
|             self.algorithm, self.mode | ||||
|         ) | ||||
|  | ||||
|  | ||||
| _CIPHER_TYPE = Cipher[ | ||||
|     typing.Union[ | ||||
|         modes.ModeWithNonce, | ||||
|         modes.ModeWithTweak, | ||||
|         None, | ||||
|         modes.ECB, | ||||
|         modes.ModeWithInitializationVector, | ||||
|     ] | ||||
| ] | ||||
|  | ||||
| CipherContext.register(rust_openssl.ciphers.CipherContext) | ||||
| AEADEncryptionContext.register(rust_openssl.ciphers.AEADEncryptionContext) | ||||
| AEADDecryptionContext.register(rust_openssl.ciphers.AEADDecryptionContext) | ||||
| @@ -0,0 +1,268 @@ | ||||
| # This file is dual licensed under the terms of the Apache License, Version | ||||
| # 2.0, and the BSD License. See the LICENSE file in the root of this repository | ||||
| # for complete details. | ||||
|  | ||||
| from __future__ import annotations | ||||
|  | ||||
| import abc | ||||
|  | ||||
| from cryptography import utils | ||||
| from cryptography.exceptions import UnsupportedAlgorithm, _Reasons | ||||
| from cryptography.hazmat.primitives._cipheralgorithm import ( | ||||
|     BlockCipherAlgorithm, | ||||
|     CipherAlgorithm, | ||||
| ) | ||||
| from cryptography.hazmat.primitives.ciphers import algorithms | ||||
|  | ||||
|  | ||||
| class Mode(metaclass=abc.ABCMeta): | ||||
|     @property | ||||
|     @abc.abstractmethod | ||||
|     def name(self) -> str: | ||||
|         """ | ||||
|         A string naming this mode (e.g. "ECB", "CBC"). | ||||
|         """ | ||||
|  | ||||
|     @abc.abstractmethod | ||||
|     def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None: | ||||
|         """ | ||||
|         Checks that all the necessary invariants of this (mode, algorithm) | ||||
|         combination are met. | ||||
|         """ | ||||
|  | ||||
|  | ||||
| class ModeWithInitializationVector(Mode, metaclass=abc.ABCMeta): | ||||
|     @property | ||||
|     @abc.abstractmethod | ||||
|     def initialization_vector(self) -> bytes: | ||||
|         """ | ||||
|         The value of the initialization vector for this mode as bytes. | ||||
|         """ | ||||
|  | ||||
|  | ||||
| class ModeWithTweak(Mode, metaclass=abc.ABCMeta): | ||||
|     @property | ||||
|     @abc.abstractmethod | ||||
|     def tweak(self) -> bytes: | ||||
|         """ | ||||
|         The value of the tweak for this mode as bytes. | ||||
|         """ | ||||
|  | ||||
|  | ||||
| class ModeWithNonce(Mode, metaclass=abc.ABCMeta): | ||||
|     @property | ||||
|     @abc.abstractmethod | ||||
|     def nonce(self) -> bytes: | ||||
|         """ | ||||
|         The value of the nonce for this mode as bytes. | ||||
|         """ | ||||
|  | ||||
|  | ||||
| class ModeWithAuthenticationTag(Mode, metaclass=abc.ABCMeta): | ||||
|     @property | ||||
|     @abc.abstractmethod | ||||
|     def tag(self) -> bytes | None: | ||||
|         """ | ||||
|         The value of the tag supplied to the constructor of this mode. | ||||
|         """ | ||||
|  | ||||
|  | ||||
| def _check_aes_key_length(self: Mode, algorithm: CipherAlgorithm) -> None: | ||||
|     if algorithm.key_size > 256 and algorithm.name == "AES": | ||||
|         raise ValueError( | ||||
|             "Only 128, 192, and 256 bit keys are allowed for this AES mode" | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def _check_iv_length( | ||||
|     self: ModeWithInitializationVector, algorithm: BlockCipherAlgorithm | ||||
| ) -> None: | ||||
|     iv_len = len(self.initialization_vector) | ||||
|     if iv_len * 8 != algorithm.block_size: | ||||
|         raise ValueError(f"Invalid IV size ({iv_len}) for {self.name}.") | ||||
|  | ||||
|  | ||||
| def _check_nonce_length( | ||||
|     nonce: bytes, name: str, algorithm: CipherAlgorithm | ||||
| ) -> None: | ||||
|     if not isinstance(algorithm, BlockCipherAlgorithm): | ||||
|         raise UnsupportedAlgorithm( | ||||
|             f"{name} requires a block cipher algorithm", | ||||
|             _Reasons.UNSUPPORTED_CIPHER, | ||||
|         ) | ||||
|     if len(nonce) * 8 != algorithm.block_size: | ||||
|         raise ValueError(f"Invalid nonce size ({len(nonce)}) for {name}.") | ||||
|  | ||||
|  | ||||
| def _check_iv_and_key_length( | ||||
|     self: ModeWithInitializationVector, algorithm: CipherAlgorithm | ||||
| ) -> None: | ||||
|     if not isinstance(algorithm, BlockCipherAlgorithm): | ||||
|         raise UnsupportedAlgorithm( | ||||
|             f"{self} requires a block cipher algorithm", | ||||
|             _Reasons.UNSUPPORTED_CIPHER, | ||||
|         ) | ||||
|     _check_aes_key_length(self, algorithm) | ||||
|     _check_iv_length(self, algorithm) | ||||
|  | ||||
|  | ||||
| class CBC(ModeWithInitializationVector): | ||||
|     name = "CBC" | ||||
|  | ||||
|     def __init__(self, initialization_vector: bytes): | ||||
|         utils._check_byteslike("initialization_vector", initialization_vector) | ||||
|         self._initialization_vector = initialization_vector | ||||
|  | ||||
|     @property | ||||
|     def initialization_vector(self) -> bytes: | ||||
|         return self._initialization_vector | ||||
|  | ||||
|     validate_for_algorithm = _check_iv_and_key_length | ||||
|  | ||||
|  | ||||
| class XTS(ModeWithTweak): | ||||
|     name = "XTS" | ||||
|  | ||||
|     def __init__(self, tweak: bytes): | ||||
|         utils._check_byteslike("tweak", tweak) | ||||
|  | ||||
|         if len(tweak) != 16: | ||||
|             raise ValueError("tweak must be 128-bits (16 bytes)") | ||||
|  | ||||
|         self._tweak = tweak | ||||
|  | ||||
|     @property | ||||
|     def tweak(self) -> bytes: | ||||
|         return self._tweak | ||||
|  | ||||
|     def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None: | ||||
|         if isinstance(algorithm, (algorithms.AES128, algorithms.AES256)): | ||||
|             raise TypeError( | ||||
|                 "The AES128 and AES256 classes do not support XTS, please use " | ||||
|                 "the standard AES class instead." | ||||
|             ) | ||||
|  | ||||
|         if algorithm.key_size not in (256, 512): | ||||
|             raise ValueError( | ||||
|                 "The XTS specification requires a 256-bit key for AES-128-XTS" | ||||
|                 " and 512-bit key for AES-256-XTS" | ||||
|             ) | ||||
|  | ||||
|  | ||||
| class ECB(Mode): | ||||
|     name = "ECB" | ||||
|  | ||||
|     validate_for_algorithm = _check_aes_key_length | ||||
|  | ||||
|  | ||||
| class OFB(ModeWithInitializationVector): | ||||
|     name = "OFB" | ||||
|  | ||||
|     def __init__(self, initialization_vector: bytes): | ||||
|         utils._check_byteslike("initialization_vector", initialization_vector) | ||||
|         self._initialization_vector = initialization_vector | ||||
|  | ||||
|     @property | ||||
|     def initialization_vector(self) -> bytes: | ||||
|         return self._initialization_vector | ||||
|  | ||||
|     validate_for_algorithm = _check_iv_and_key_length | ||||
|  | ||||
|  | ||||
| class CFB(ModeWithInitializationVector): | ||||
|     name = "CFB" | ||||
|  | ||||
|     def __init__(self, initialization_vector: bytes): | ||||
|         utils._check_byteslike("initialization_vector", initialization_vector) | ||||
|         self._initialization_vector = initialization_vector | ||||
|  | ||||
|     @property | ||||
|     def initialization_vector(self) -> bytes: | ||||
|         return self._initialization_vector | ||||
|  | ||||
|     validate_for_algorithm = _check_iv_and_key_length | ||||
|  | ||||
|  | ||||
| class CFB8(ModeWithInitializationVector): | ||||
|     name = "CFB8" | ||||
|  | ||||
|     def __init__(self, initialization_vector: bytes): | ||||
|         utils._check_byteslike("initialization_vector", initialization_vector) | ||||
|         self._initialization_vector = initialization_vector | ||||
|  | ||||
|     @property | ||||
|     def initialization_vector(self) -> bytes: | ||||
|         return self._initialization_vector | ||||
|  | ||||
|     validate_for_algorithm = _check_iv_and_key_length | ||||
|  | ||||
|  | ||||
| class CTR(ModeWithNonce): | ||||
|     name = "CTR" | ||||
|  | ||||
|     def __init__(self, nonce: bytes): | ||||
|         utils._check_byteslike("nonce", nonce) | ||||
|         self._nonce = nonce | ||||
|  | ||||
|     @property | ||||
|     def nonce(self) -> bytes: | ||||
|         return self._nonce | ||||
|  | ||||
|     def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None: | ||||
|         _check_aes_key_length(self, algorithm) | ||||
|         _check_nonce_length(self.nonce, self.name, algorithm) | ||||
|  | ||||
|  | ||||
| class GCM(ModeWithInitializationVector, ModeWithAuthenticationTag): | ||||
|     name = "GCM" | ||||
|     _MAX_ENCRYPTED_BYTES = (2**39 - 256) // 8 | ||||
|     _MAX_AAD_BYTES = (2**64) // 8 | ||||
|  | ||||
|     def __init__( | ||||
|         self, | ||||
|         initialization_vector: bytes, | ||||
|         tag: bytes | None = None, | ||||
|         min_tag_length: int = 16, | ||||
|     ): | ||||
|         # OpenSSL 3.0.0 constrains GCM IVs to [64, 1024] bits inclusive | ||||
|         # This is a sane limit anyway so we'll enforce it here. | ||||
|         utils._check_byteslike("initialization_vector", initialization_vector) | ||||
|         if len(initialization_vector) < 8 or len(initialization_vector) > 128: | ||||
|             raise ValueError( | ||||
|                 "initialization_vector must be between 8 and 128 bytes (64 " | ||||
|                 "and 1024 bits)." | ||||
|             ) | ||||
|         self._initialization_vector = initialization_vector | ||||
|         if tag is not None: | ||||
|             utils._check_bytes("tag", tag) | ||||
|             if min_tag_length < 4: | ||||
|                 raise ValueError("min_tag_length must be >= 4") | ||||
|             if len(tag) < min_tag_length: | ||||
|                 raise ValueError( | ||||
|                     f"Authentication tag must be {min_tag_length} bytes or " | ||||
|                     "longer." | ||||
|                 ) | ||||
|         self._tag = tag | ||||
|         self._min_tag_length = min_tag_length | ||||
|  | ||||
|     @property | ||||
|     def tag(self) -> bytes | None: | ||||
|         return self._tag | ||||
|  | ||||
|     @property | ||||
|     def initialization_vector(self) -> bytes: | ||||
|         return self._initialization_vector | ||||
|  | ||||
|     def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None: | ||||
|         _check_aes_key_length(self, algorithm) | ||||
|         if not isinstance(algorithm, BlockCipherAlgorithm): | ||||
|             raise UnsupportedAlgorithm( | ||||
|                 "GCM requires a block cipher algorithm", | ||||
|                 _Reasons.UNSUPPORTED_CIPHER, | ||||
|             ) | ||||
|         block_size_bytes = algorithm.block_size // 8 | ||||
|         if self._tag is not None and len(self._tag) > block_size_bytes: | ||||
|             raise ValueError( | ||||
|                 f"Authentication tag cannot be more than {block_size_bytes} " | ||||
|                 "bytes." | ||||
|             ) | ||||
		Reference in New Issue
	
	Block a user