Cipher.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
  3. * Copyright (c) 2022, the SerenityOS developers.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/Optional.h>
  9. #include <AK/Span.h>
  10. #include <AK/Types.h>
  11. namespace Crypto {
  12. namespace Cipher {
  13. enum class Intent {
  14. Encryption,
  15. Decryption,
  16. };
  17. enum class PaddingMode {
  18. CMS, // RFC 1423
  19. RFC5246, // very similar to CMS, but filled with |length - 1|, instead of |length|
  20. Null,
  21. // FIXME: We do not implement these yet
  22. Bit,
  23. Random,
  24. Space,
  25. ZeroLength,
  26. };
  27. template<typename B, typename T>
  28. class Cipher;
  29. struct CipherBlock {
  30. public:
  31. explicit CipherBlock(PaddingMode mode)
  32. : m_padding_mode(mode)
  33. {
  34. }
  35. virtual ReadonlyBytes bytes() const = 0;
  36. virtual void overwrite(ReadonlyBytes) = 0;
  37. virtual void overwrite(u8 const* data, size_t size) { overwrite({ data, size }); }
  38. virtual void apply_initialization_vector(ReadonlyBytes ivec) = 0;
  39. PaddingMode padding_mode() const { return m_padding_mode; }
  40. void set_padding_mode(PaddingMode mode) { m_padding_mode = mode; }
  41. template<typename T>
  42. void put(size_t offset, T value)
  43. {
  44. VERIFY(offset + sizeof(T) <= bytes().size());
  45. auto* ptr = bytes().offset_pointer(offset);
  46. auto index { 0 };
  47. VERIFY(sizeof(T) <= 4);
  48. if constexpr (sizeof(T) > 3)
  49. ptr[index++] = (u8)(value >> 24);
  50. if constexpr (sizeof(T) > 2)
  51. ptr[index++] = (u8)(value >> 16);
  52. if constexpr (sizeof(T) > 1)
  53. ptr[index++] = (u8)(value >> 8);
  54. ptr[index] = (u8)value;
  55. }
  56. protected:
  57. virtual ~CipherBlock() = default;
  58. private:
  59. virtual Bytes bytes() = 0;
  60. PaddingMode m_padding_mode;
  61. };
  62. struct CipherKey {
  63. virtual ReadonlyBytes bytes() const = 0;
  64. static bool is_valid_key_size(size_t) { return false; };
  65. virtual ~CipherKey() = default;
  66. protected:
  67. virtual void expand_encrypt_key(ReadonlyBytes user_key, size_t bits) = 0;
  68. virtual void expand_decrypt_key(ReadonlyBytes user_key, size_t bits) = 0;
  69. size_t bits { 0 };
  70. };
  71. template<typename KeyT = CipherKey, typename BlockT = CipherBlock>
  72. class Cipher {
  73. public:
  74. using KeyType = KeyT;
  75. using BlockType = BlockT;
  76. explicit Cipher<KeyT, BlockT>(PaddingMode mode)
  77. : m_padding_mode(mode)
  78. {
  79. }
  80. virtual KeyType const& key() const = 0;
  81. virtual KeyType& key() = 0;
  82. constexpr static size_t block_size() { return BlockType::block_size(); }
  83. PaddingMode padding_mode() const { return m_padding_mode; }
  84. virtual void encrypt_block(BlockType const& in, BlockType& out) = 0;
  85. virtual void decrypt_block(BlockType const& in, BlockType& out) = 0;
  86. #ifndef KERNEL
  87. virtual DeprecatedString class_name() const = 0;
  88. #endif
  89. protected:
  90. virtual ~Cipher() = default;
  91. private:
  92. PaddingMode m_padding_mode;
  93. };
  94. }
  95. }