20 #ifndef CS_CRYPTO_SYM_ENCRYPT_DECRYPT_H
21 #define CS_CRYPTO_SYM_ENCRYPT_DECRYPT_H
23 #include <core/cipher/sym_process_msg.h>
24 #include <core/cipher/sym_secret_key.h>
25 #include <core/cipher/sym_init_vector.h>
26 #include <core/cipher/sym_traits.h>
27 #include <util/tools/crypto_traits.h>
28 #include <util/tools/is_detected_traits.h>
30 #include <type_traits>
32 namespace cs_crypto::cipher {
35 using finalize_member_fn =
decltype(std::declval<T &&>().finalize());
38 using finalize_free_fn =
decltype(finalize(std::declval<T &&>()));
40 struct finalize_dispatch_internal {
41 template <
typename CipherContext>
42 constexpr auto operator()(CipherContext &&ctx)
const
44 if constexpr (cs_crypto::traits::is_detected<finalize_member_fn, CipherContext>{}) {
45 return std::move(ctx).finalize();
47 }
else if constexpr (cs_crypto::traits::is_detected<finalize_free_fn, CipherContext>{}) {
48 return finalize(std::move(ctx));
51 static_assert(cs_crypto::traits::always_false<CipherContext>{},
52 "Driver incomplete, unable to locate finalize() as a method or free function");
57 inline constexpr finalize_dispatch_internal finalize{};
59 template <
typename Ctx>
60 [[maybe_unused]]
constexpr static bool is_cipher_context_v = is_appendable_cipher_context_v<Ctx> &&
61 (cs_crypto::traits::is_detected_v<finalize_free_fn, Ctx> || cs_crypto::traits::is_detected_v<finalize_member_fn, Ctx>);
63 template <
typename CipherContext>
64 struct encrypt_operation {
65 using key_type =
typename CipherContext::key_type;
66 using iv_type =
typename CipherContext::iv_type;
68 using result_type = std::optional<cs_crypto::traits::remove_optional_t<
decltype(finalize(std::declval<CipherContext>()))>>;
70 template <
typename... Ts>
71 constexpr auto operator()(key_type &&secret_key, iv_type &&iv, Ts &&... args)
const -> result_type
73 static_assert(! std::is_same_v<CipherContext, cs_crypto::traits::nonesuch>,
74 "Selected driver does not support this operation");
76 static_assert(is_cipher_context_v<CipherContext>,
77 "Cipher context does not satisfy is_cipher_context_v type trait");
79 auto maybe_context = CipherContext::make_context(std::move(secret_key), std::move(iv));
80 if (! maybe_context.has_value()) {
84 auto context = std::move(maybe_context).value();
85 cipher_append(context, std::forward<Ts>(args)...);
87 return finalize(std::move(context));
91 template <
typename CipherDriver,
typename Cipher,
typename Mode>
92 inline constexpr encrypt_operation<
typename CipherDriver::
template encrypt<Cipher, Mode>> encrypt;
94 template <
typename CipherDriver,
typename Cipher,
typename Mode>
95 inline constexpr encrypt_operation<
typename CipherDriver::
template decrypt<Cipher, Mode>> decrypt;