_modes.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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. from __future__ import annotations
  5. import abc
  6. from cryptography import utils
  7. from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
  8. from cryptography.hazmat.primitives._cipheralgorithm import (
  9. BlockCipherAlgorithm,
  10. CipherAlgorithm,
  11. )
  12. class Mode(metaclass=abc.ABCMeta):
  13. @property
  14. @abc.abstractmethod
  15. def name(self) -> str:
  16. """
  17. A string naming this mode (e.g. "ECB", "CBC").
  18. """
  19. @abc.abstractmethod
  20. def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None:
  21. """
  22. Checks that all the necessary invariants of this (mode, algorithm)
  23. combination are met.
  24. """
  25. class ModeWithInitializationVector(Mode, metaclass=abc.ABCMeta):
  26. @property
  27. @abc.abstractmethod
  28. def initialization_vector(self) -> utils.Buffer:
  29. """
  30. The value of the initialization vector for this mode as bytes.
  31. """
  32. class ModeWithTweak(Mode, metaclass=abc.ABCMeta):
  33. @property
  34. @abc.abstractmethod
  35. def tweak(self) -> utils.Buffer:
  36. """
  37. The value of the tweak for this mode as bytes.
  38. """
  39. class ModeWithNonce(Mode, metaclass=abc.ABCMeta):
  40. @property
  41. @abc.abstractmethod
  42. def nonce(self) -> utils.Buffer:
  43. """
  44. The value of the nonce for this mode as bytes.
  45. """
  46. class ModeWithAuthenticationTag(Mode, metaclass=abc.ABCMeta):
  47. @property
  48. @abc.abstractmethod
  49. def tag(self) -> bytes | None:
  50. """
  51. The value of the tag supplied to the constructor of this mode.
  52. """
  53. def _check_aes_key_length(self: Mode, algorithm: CipherAlgorithm) -> None:
  54. if algorithm.key_size > 256 and algorithm.name == "AES":
  55. raise ValueError(
  56. "Only 128, 192, and 256 bit keys are allowed for this AES mode"
  57. )
  58. def _check_iv_length(
  59. self: ModeWithInitializationVector, algorithm: BlockCipherAlgorithm
  60. ) -> None:
  61. iv_len = len(self.initialization_vector)
  62. if iv_len * 8 != algorithm.block_size:
  63. raise ValueError(f"Invalid IV size ({iv_len}) for {self.name}.")
  64. def _check_nonce_length(
  65. nonce: utils.Buffer, name: str, algorithm: CipherAlgorithm
  66. ) -> None:
  67. if not isinstance(algorithm, BlockCipherAlgorithm):
  68. raise UnsupportedAlgorithm(
  69. f"{name} requires a block cipher algorithm",
  70. _Reasons.UNSUPPORTED_CIPHER,
  71. )
  72. if len(nonce) * 8 != algorithm.block_size:
  73. raise ValueError(f"Invalid nonce size ({len(nonce)}) for {name}.")
  74. def _check_iv_and_key_length(
  75. self: ModeWithInitializationVector, algorithm: CipherAlgorithm
  76. ) -> None:
  77. if not isinstance(algorithm, BlockCipherAlgorithm):
  78. raise UnsupportedAlgorithm(
  79. f"{self} requires a block cipher algorithm",
  80. _Reasons.UNSUPPORTED_CIPHER,
  81. )
  82. _check_aes_key_length(self, algorithm)
  83. _check_iv_length(self, algorithm)