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: utils.Buffer 
    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( 
    50    algorithm: CipherAlgorithm, key: utils.Buffer 
    51) -> utils.Buffer: 
    52    # Verify that the key is instance of bytes 
    53    utils._check_byteslike("key", key) 
    54 
    55    # Verify that the key size matches the expected key size 
    56    if len(key) * 8 not in algorithm.key_sizes: 
    57        raise ValueError( 
    58            f"Invalid key size ({len(key) * 8}) for {algorithm.name}." 
    59        ) 
    60    return key