Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

dlies.cpp
Go to the documentation of this file.
1 /*
2 * DLIES
3 * (C) 1999-2007 Jack Lloyd
4 * (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8
9 #include <botan/dlies.h>
10 #include <botan/internal/ct_utils.h>
11
12 namespace Botan {
13
14 DLIES_Encryptor::DLIES_Encryptor(const DH_PrivateKey& own_priv_key,
15 RandomNumberGenerator& rng,
16 KDF* kdf,
17 MessageAuthenticationCode* mac,
18 size_t mac_key_length) :
19 DLIES_Encryptor(own_priv_key, rng, kdf, nullptr, 0, mac, mac_key_length)
20 {
21 }
22
23 DLIES_Encryptor::DLIES_Encryptor(const DH_PrivateKey& own_priv_key,
24 RandomNumberGenerator& rng,
25 KDF* kdf,
26 Cipher_Mode* cipher,
27 size_t cipher_key_len,
28 MessageAuthenticationCode* mac,
29 size_t mac_key_length) :
30 m_other_pub_key(),
31 m_own_pub_key(own_priv_key.public_value()),
32 m_ka(own_priv_key, rng, "Raw"),
33 m_kdf(kdf),
34 m_cipher(cipher),
35 m_cipher_key_len(cipher_key_len),
36 m_mac(mac),
37 m_mac_keylen(mac_key_length),
38 m_iv()
39 {
40 BOTAN_ASSERT_NONNULL(kdf);
41 BOTAN_ASSERT_NONNULL(mac);
42 }
43
44 std::vector<uint8_t> DLIES_Encryptor::enc(const uint8_t in[], size_t length,
45 RandomNumberGenerator&) const
46 {
47 if(m_other_pub_key.empty())
48 {
49 throw Invalid_State("DLIES: The other key was never set");
50 }
51
52 // calculate secret value
53 const SymmetricKey secret_value = m_ka.derive_key(0, m_other_pub_key);
54
55 // derive secret key from secret value
56 const size_t required_key_length = m_cipher ? m_cipher_key_len + m_mac_keylen : length + m_mac_keylen;
57 const secure_vector<uint8_t> secret_keys = m_kdf->derive_key(required_key_length, secret_value.bits_of());
58
59 if(secret_keys.size() != required_key_length)
60 {
61 throw Encoding_Error("DLIES: KDF did not provide sufficient output");
62 }
63
64 secure_vector<uint8_t> ciphertext(in, in + length);
65 const size_t cipher_key_len = m_cipher ? m_cipher_key_len : length;
66
67 if(m_cipher)
68 {
69 SymmetricKey enc_key(secret_keys.data(), cipher_key_len);
70 m_cipher->set_key(enc_key);
71
72 if(m_iv.size())
73 {
74 m_cipher->start(m_iv.bits_of());
75 }
76
77 m_cipher->finish(ciphertext);
78 }
79 else
80 {
81 xor_buf(ciphertext, secret_keys, cipher_key_len);
82 }
83
84 // calculate MAC
85 m_mac->set_key(secret_keys.data() + cipher_key_len, m_mac_keylen);
86 secure_vector<uint8_t> tag = m_mac->process(ciphertext);
87
88 // out = (ephemeral) public key + ciphertext + tag
89 secure_vector<uint8_t> out(m_own_pub_key.size() + ciphertext.size() + tag.size());
90 buffer_insert(out, 0, m_own_pub_key);
91 buffer_insert(out, 0 + m_own_pub_key.size(), ciphertext);
92 buffer_insert(out, 0 + m_own_pub_key.size() + ciphertext.size(), tag);
93
94 return unlock(out);
95 }
96
97 /**
98 * Return the max size, in bytes, of a message
99 * Not_Implemented if DLIES is used in XOR encryption mode
100 */
101 size_t DLIES_Encryptor::maximum_input_size() const
102 {
103 if(m_cipher)
104 {
105 // no limit in block cipher mode
106 return std::numeric_limits<size_t>::max();
107 }
108 else
109 {
110 // No way to determine if the KDF will output enough bits for XORing with the plaintext?!
111 throw Not_Implemented("Not implemented for XOR encryption mode");
112 }
113 }
114
115 DLIES_Decryptor::DLIES_Decryptor(const DH_PrivateKey& own_priv_key,
116 RandomNumberGenerator& rng,
117 KDF* kdf,
118 Cipher_Mode* cipher,
119 size_t cipher_key_len,
120 MessageAuthenticationCode* mac,
121 size_t mac_key_length) :
122 m_pub_key_size(own_priv_key.public_value().size()),
123 m_ka(own_priv_key, rng, "Raw"),
124 m_kdf(kdf),
125 m_cipher(cipher),
126 m_cipher_key_len(cipher_key_len),
127 m_mac(mac),
128 m_mac_keylen(mac_key_length),
129 m_iv()
130 {
131 BOTAN_ASSERT_NONNULL(kdf);
132 BOTAN_ASSERT_NONNULL(mac);
133 }
134
135 DLIES_Decryptor::DLIES_Decryptor(const DH_PrivateKey& own_priv_key,
136 RandomNumberGenerator& rng,
137 KDF* kdf,
138 MessageAuthenticationCode* mac,
139 size_t mac_key_length) :
140 DLIES_Decryptor(own_priv_key, rng, kdf, nullptr, 0, mac, mac_key_length)
141 {}
142
143 secure_vector<uint8_t> DLIES_Decryptor::do_decrypt(uint8_t& valid_mask,
144 const uint8_t msg[], size_t length) const
145 {
146 if(length < m_pub_key_size + m_mac->output_length())
147 {
148 throw Decoding_Error("DLIES decryption: ciphertext is too short");
149 }
150
151 // calculate secret value
152 std::vector<uint8_t> other_pub_key(msg, msg + m_pub_key_size);
153 const SymmetricKey secret_value = m_ka.derive_key(0, other_pub_key);
154
155 const size_t ciphertext_len = length - m_pub_key_size - m_mac->output_length();
156 size_t cipher_key_len = m_cipher ? m_cipher_key_len : ciphertext_len;
157
158 // derive secret key from secret value
159 const size_t required_key_length = cipher_key_len + m_mac_keylen;
160 secure_vector<uint8_t> secret_keys = m_kdf->derive_key(required_key_length, secret_value.bits_of());
161
162 if(secret_keys.size() != required_key_length)
163 {
164 throw Encoding_Error("DLIES: KDF did not provide sufficient output");
165 }
166
167 secure_vector<uint8_t> ciphertext(msg + m_pub_key_size, msg + m_pub_key_size + ciphertext_len);
168
169 // calculate MAC
170 m_mac->set_key(secret_keys.data() + cipher_key_len, m_mac_keylen);
171 secure_vector<uint8_t> calculated_tag = m_mac->process(ciphertext);
172
173 // calculated tag == received tag ?
174 secure_vector<uint8_t> tag(msg + m_pub_key_size + ciphertext_len,
175 msg + m_pub_key_size + ciphertext_len + m_mac->output_length());
176
177 valid_mask = CT::expand_mask<uint8_t>(same_mem(tag.data(), calculated_tag.data(), tag.size()));
178
179 // decrypt
180 if(m_cipher)
181 {
182 if(valid_mask)
183 {
184 SymmetricKey dec_key(secret_keys.data(), cipher_key_len);
185 m_cipher->set_key(dec_key);
186
187 try
188 {
189 // the decryption can fail:
190 // e.g. Integrity_Failure is thrown if GCM is used and the message does not have a valid tag
191
192 if(m_iv.size())
193 {
194 m_cipher->start(m_iv.bits_of());
195 }
196
197 m_cipher->finish(ciphertext);
198 }
199 catch(...)
200 {
201 valid_mask = 0;
202 }
203
204 }
205 else
206 {
207 return secure_vector<uint8_t>();
208 }
209 }
210 else
211 {
212 xor_buf(ciphertext, secret_keys.data(), cipher_key_len);
213 }
214
215 return ciphertext;
216 }
217
218 }
Botan::xor_buf
void xor_buf(T out[], const T in[], size_t length)
Definition: mem_ops.h:115
Botan::OctetString::bits_of
secure_vector< uint8_t > bits_of() const
Definition: symkey.h:31
Botan::same_mem
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:98
m_mac
std::unique_ptr< MessageAuthenticationCode > m_mac
Definition: fpe_fe1.cpp:88
Botan::RandomNumberGenerator
Definition: rng.h:25
Botan::PK_Key_Agreement::derive_key
SymmetricKey derive_key(size_t key_len, const uint8_t in[], size_t in_len, const uint8_t params[], size_t params_len) const
Definition: pubkey.cpp:202
Botan::Invalid_State
Definition: exceptn.h:61
Botan::MessageAuthenticationCode
Definition: mac.h:20
Botan::DLIES_Decryptor::DLIES_Decryptor
DLIES_Decryptor(const DH_PrivateKey &own_priv_key, RandomNumberGenerator &rng, KDF *kdf, MessageAuthenticationCode *mac, size_t mac_key_len=20)
Definition: dlies.cpp:135
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
BOTAN_ASSERT_NONNULL
#define BOTAN_ASSERT_NONNULL(ptr)
Definition: assert.h:79
Botan::Decoding_Error
Definition: exceptn.h:189
Botan
Definition: alg_id.cpp:13
Botan::SymmetricKey
OctetString SymmetricKey
Definition: symkey.h:136
Botan::DLIES_Encryptor
Definition: dlies.h:23
Botan::CT::max
T max(T a, T b)
Definition: ct_utils.h:173
Botan::unlock
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:125
Botan::KDF
Definition: kdf.h:20
Botan::Cipher_Mode
Definition: cipher_mode.h:23
Botan::buffer_insert
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:133
Botan::DH_PrivateKey
Definition: dh.h:49
Botan::DLIES_Decryptor
Definition: dlies.h:96
Botan::DLIES_Encryptor::DLIES_Encryptor
DLIES_Encryptor(const DH_PrivateKey &own_priv_key, RandomNumberGenerator &rng, KDF *kdf, MessageAuthenticationCode *mac, size_t mac_key_len=20)
Definition: dlies.cpp:14
Botan::OctetString::size
size_t size() const
Definition: symkey.h:26