9#include <botan/dlies.h>
10#include <botan/internal/ct_utils.h>
11#include <botan/internal/stl_util.h>
18 std::unique_ptr<KDF> kdf,
19 std::unique_ptr<MessageAuthenticationCode> mac,
20 size_t mac_key_length) :
21 DLIES_Encryptor(own_priv_key, rng, std::move(kdf), nullptr, 0, std::move(mac), mac_key_length) {}
25 std::unique_ptr<KDF> kdf,
26 std::unique_ptr<Cipher_Mode> cipher,
27 size_t cipher_key_len,
28 std::unique_ptr<MessageAuthenticationCode> mac,
29 size_t mac_key_length) :
31 m_own_pub_key(own_priv_key.public_value()),
32 m_ka(own_priv_key, rng,
"Raw"),
33 m_kdf(std::move(kdf)),
34 m_cipher(std::move(cipher)),
35 m_cipher_key_len(cipher_key_len),
36 m_mac(std::move(mac)),
37 m_mac_keylen(mac_key_length),
43std::vector<uint8_t> DLIES_Encryptor::enc(
const uint8_t in[],
size_t length,
RandomNumberGenerator& )
const {
44 if(m_other_pub_key.empty()) {
52 const size_t required_key_length = m_cipher ? m_cipher_key_len + m_mac_keylen : length + m_mac_keylen;
55 if(secret_keys.size() != required_key_length) {
56 throw Encoding_Error(
"DLIES: KDF did not provide sufficient output");
60 const size_t cipher_key_len = m_cipher ? m_cipher_key_len : length;
63 SymmetricKey enc_key(secret_keys.data(), cipher_key_len);
64 m_cipher->set_key(enc_key);
66 if(m_iv.
empty() && !m_cipher->valid_nonce_length(m_iv.
size())) {
67 throw Invalid_Argument(
"DLIES with " + m_cipher->name() +
" requires an IV be set");
69 m_cipher->start(m_iv.
bits_of());
70 m_cipher->finish(ciphertext);
72 xor_buf(ciphertext, secret_keys, cipher_key_len);
76 m_mac->set_key(secret_keys.data() + cipher_key_len, m_mac_keylen);
77 const auto tag = m_mac->process(ciphertext);
80 return concat(m_own_pub_key, ciphertext, tag);
88size_t DLIES_Encryptor::maximum_input_size()
const {
92size_t DLIES_Encryptor::ciphertext_length(
size_t ptext_len)
const {
93 return m_own_pub_key.size() + m_mac->output_length() + m_cipher->output_length(ptext_len);
98 std::unique_ptr<KDF> kdf,
99 std::unique_ptr<Cipher_Mode> cipher,
100 size_t cipher_key_len,
101 std::unique_ptr<MessageAuthenticationCode> mac,
102 size_t mac_key_length) :
103 m_pub_key_size(own_priv_key.public_value().size()),
104 m_ka(own_priv_key, rng,
"Raw"),
105 m_kdf(std::move(kdf)),
106 m_cipher(std::move(cipher)),
107 m_cipher_key_len(cipher_key_len),
108 m_mac(std::move(mac)),
109 m_mac_keylen(mac_key_length),
117 std::unique_ptr<KDF> kdf,
118 std::unique_ptr<MessageAuthenticationCode> mac,
119 size_t mac_key_length) :
120 DLIES_Decryptor(own_priv_key, rng, std::move(kdf), nullptr, 0, std::move(mac), mac_key_length) {}
122size_t DLIES_Decryptor::plaintext_length(
size_t ctext_len)
const {
123 if(ctext_len < m_pub_key_size + m_mac->output_length()) {
127 return ctext_len - (m_pub_key_size + m_mac->output_length());
130secure_vector<uint8_t> DLIES_Decryptor::do_decrypt(uint8_t& valid_mask,
const uint8_t msg[],
size_t length)
const {
131 if(length < m_pub_key_size + m_mac->output_length()) {
132 throw Decoding_Error(
"DLIES decryption: ciphertext is too short");
136 std::vector<uint8_t> other_pub_key(msg, msg + m_pub_key_size);
139 const size_t ciphertext_len = length - m_pub_key_size - m_mac->output_length();
140 size_t cipher_key_len = m_cipher ? m_cipher_key_len : ciphertext_len;
143 const size_t required_key_length = cipher_key_len + m_mac_keylen;
146 if(secret_keys.size() != required_key_length) {
147 throw Encoding_Error(
"DLIES: KDF did not provide sufficient output");
153 m_mac->set_key(secret_keys.data() + cipher_key_len, m_mac_keylen);
158 msg + m_pub_key_size + ciphertext_len + m_mac->output_length());
160 valid_mask =
CT::is_equal(tag.data(), calculated_tag.data(), tag.size()).value();
165 SymmetricKey dec_key(secret_keys.data(), cipher_key_len);
166 m_cipher->set_key(dec_key);
172 if(m_iv.
empty() && !m_cipher->valid_nonce_length(m_iv.
size())) {
173 throw Invalid_Argument(
"DLIES with " + m_cipher->name() +
" requires an IV be set");
175 m_cipher->start(m_iv.
bits_of());
176 m_cipher->finish(ciphertext);
185 xor_buf(ciphertext, secret_keys.data(), cipher_key_len);
#define BOTAN_ASSERT_NONNULL(ptr)
DLIES_Decryptor(const DH_PrivateKey &own_priv_key, RandomNumberGenerator &rng, std::unique_ptr< KDF > kdf, std::unique_ptr< MessageAuthenticationCode > mac, size_t mac_key_len=20)
DLIES_Encryptor(const DH_PrivateKey &own_priv_key, RandomNumberGenerator &rng, std::unique_ptr< KDF > kdf, std::unique_ptr< MessageAuthenticationCode > mac, size_t mac_key_len=20)
secure_vector< uint8_t > bits_of() const
SymmetricKey derive_key(size_t key_len, const uint8_t in[], size_t in_len, const uint8_t params[], size_t params_len) const
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
constexpr auto concat(Rs &&... ranges)
constexpr void xor_buf(ranges::contiguous_output_range< uint8_t > auto &&out, ranges::contiguous_range< uint8_t > auto &&in)
std::vector< T, secure_allocator< T > > secure_vector