9#include <botan/dlies.h>
10#include <botan/mem_ops.h>
11#include <botan/internal/ct_utils.h>
12#include <botan/internal/stl_util.h>
19 std::unique_ptr<KDF> kdf,
20 std::unique_ptr<MessageAuthenticationCode> mac,
21 size_t mac_key_length) :
22 DLIES_Encryptor(own_priv_key, rng, std::move(kdf), nullptr, 0, std::move(mac), mac_key_length) {}
26 std::unique_ptr<KDF> kdf,
27 std::unique_ptr<Cipher_Mode> cipher,
28 size_t cipher_key_len,
29 std::unique_ptr<MessageAuthenticationCode> mac,
30 size_t mac_key_length) :
32 m_own_pub_key(own_priv_key.public_value()),
33 m_ka(own_priv_key, rng,
"Raw"),
34 m_kdf(std::move(kdf)),
35 m_cipher(std::move(cipher)),
36 m_cipher_key_len(cipher_key_len),
37 m_mac(std::move(mac)),
38 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);
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) {
116 std::unique_ptr<KDF> kdf,
117 std::unique_ptr<MessageAuthenticationCode> mac,
118 size_t mac_key_length) :
119 DLIES_Decryptor(own_priv_key, rng, std::move(kdf), nullptr, 0, std::move(mac), mac_key_length) {}
121size_t DLIES_Decryptor::plaintext_length(
size_t ctext_len)
const {
122 if(ctext_len < m_pub_key_size + m_mac->output_length()) {
126 return ctext_len - (m_pub_key_size + m_mac->output_length());
129secure_vector<uint8_t> DLIES_Decryptor::do_decrypt(uint8_t& valid_mask,
const uint8_t msg[],
size_t length)
const {
130 if(length < m_pub_key_size + m_mac->output_length()) {
131 throw Decoding_Error(
"DLIES decryption: ciphertext is too short");
135 std::vector<uint8_t> other_pub_key(msg, msg + m_pub_key_size);
136 const SymmetricKey secret_value = m_ka.derive_key(0, other_pub_key);
138 const size_t ciphertext_len = length - m_pub_key_size - m_mac->output_length();
139 size_t cipher_key_len = m_cipher ? m_cipher_key_len : ciphertext_len;
142 const size_t required_key_length = cipher_key_len + m_mac_keylen;
145 if(secret_keys.size() != required_key_length) {
146 throw Encoding_Error(
"DLIES: KDF did not provide sufficient output");
152 m_mac->set_key(secret_keys.data() + cipher_key_len, m_mac_keylen);
157 std::span<const uint8_t> tag(msg + m_pub_key_size + ciphertext_len, m_mac->output_length());
159 valid_mask =
CT::is_equal(tag.data(), calculated_tag.data(), tag.size()).value();
163 if(valid_mask == 0xFF) {
164 SymmetricKey dec_key(secret_keys.data(), cipher_key_len);
165 m_cipher->set_key(dec_key);
171 if(m_iv.empty() && !m_cipher->valid_nonce_length(m_iv.size())) {
172 throw Invalid_Argument(
"DLIES with " + m_cipher->name() +
" requires an IV be set");
174 m_cipher->start(m_iv.bits_of());
175 m_cipher->finish(ciphertext);
184 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)
virtual size_t maximum_input_size() const =0
SymmetricKey derive_key(size_t key_len, std::span< const uint8_t > peer_key, std::span< const uint8_t > salt) 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