1# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
4
5from __future__ import annotations
6
7import abc
8
9from cryptography import utils
10
11# This exists to break an import cycle. It is normally accessible from the
12# ciphers module.
13
14
15class CipherAlgorithm(metaclass=abc.ABCMeta):
16 @property
17 @abc.abstractmethod
18 def name(self) -> str:
19 """
20 A string naming this mode (e.g. "AES", "Camellia").
21 """
22
23 @property
24 @abc.abstractmethod
25 def key_sizes(self) -> frozenset[int]:
26 """
27 Valid key sizes for this algorithm in bits
28 """
29
30 @property
31 @abc.abstractmethod
32 def key_size(self) -> int:
33 """
34 The size of the key being used as an integer in bits (e.g. 128, 256).
35 """
36
37
38class BlockCipherAlgorithm(CipherAlgorithm):
39 key: bytes
40
41 @property
42 @abc.abstractmethod
43 def block_size(self) -> int:
44 """
45 The size of a block as an integer in bits (e.g. 64, 128).
46 """
47
48
49def _verify_key_size(algorithm: CipherAlgorithm, key: bytes) -> bytes:
50 # Verify that the key is instance of bytes
51 utils._check_byteslike("key", key)
52
53 # Verify that the key size matches the expected key size
54 if len(key) * 8 not in algorithm.key_sizes:
55 raise ValueError(
56 f"Invalid key size ({len(key) * 8}) for {algorithm.name}."
57 )
58 return key