Botan 3.1.1
Crypto and TLS for C&
pubkey.cpp
Go to the documentation of this file.
1/*
2* (C) 1999-2010,2015,2018 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/pubkey.h>
8
9#include <botan/ber_dec.h>
10#include <botan/bigint.h>
11#include <botan/der_enc.h>
12#include <botan/rng.h>
13#include <botan/internal/ct_utils.h>
14#include <botan/internal/fmt.h>
15#include <botan/internal/parsing.h>
16#include <botan/internal/pk_ops.h>
17#include <botan/internal/pss_params.h>
18
19namespace Botan {
20
21secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const {
22 uint8_t valid_mask = 0;
23
24 secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
25
26 if(valid_mask == 0) {
27 throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
28 }
29
30 return decoded;
31}
32
34 size_t length,
35 size_t expected_pt_len,
37 const uint8_t required_content_bytes[],
38 const uint8_t required_content_offsets[],
39 size_t required_contents_length) const {
40 const secure_vector<uint8_t> fake_pms = rng.random_vec(expected_pt_len);
41
42 uint8_t decrypt_valid = 0;
43 secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
44
45 auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF);
46 valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_zero(decoded.size() ^ expected_pt_len));
47
48 decoded.resize(expected_pt_len);
49
50 for(size_t i = 0; i != required_contents_length; ++i) {
51 /*
52 These values are chosen by the application and for TLS are constants,
53 so this early failure via assert is fine since we know 0,1 < 48
54
55 If there is a protocol that has content checks on the key where
56 the expected offsets are controllable by the attacker this could
57 still leak.
58
59 Alternately could always reduce the offset modulo the length?
60 */
61
62 const uint8_t exp = required_content_bytes[i];
63 const uint8_t off = required_content_offsets[i];
64
65 BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
66
67 auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
68
69 valid_mask &= eq;
70 }
71
72 // If valid_mask is false, assign fake pre master instead
73 valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
74
75 return decoded;
76}
77
79 size_t length,
80 size_t expected_pt_len,
81 RandomNumberGenerator& rng) const {
82 return decrypt_or_random(in, length, expected_pt_len, rng, nullptr, nullptr, 0);
83}
84
87 std::string_view padding,
88 std::string_view provider) {
89 m_op = key.create_encryption_op(rng, padding, provider);
90 if(!m_op) {
91 throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
92 }
93}
94
96
97size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
98 return m_op->ciphertext_length(ptext_len);
99}
100
101std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const {
102 return unlock(m_op->encrypt(in, length, rng));
103}
104
106 return m_op->max_input_bits() / 8;
107}
108
111 std::string_view padding,
112 std::string_view provider) {
113 m_op = key.create_decryption_op(rng, padding, provider);
114 if(!m_op) {
115 throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
116 }
117}
118
120
121size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
122 return m_op->plaintext_length(ctext_len);
123}
124
125secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
126 return m_op->decrypt(valid_mask, in, in_len);
127}
128
129PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
130 m_op = key.create_kem_encryption_op(param, provider);
131 if(!m_op) {
132 throw Invalid_Argument(fmt("Key type {} does not support KEM encryption"));
133 }
134}
135
137
138size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
139 return m_op->shared_key_length(desired_shared_key_len);
140}
141
143 return m_op->encapsulated_key_length();
144}
145
147 secure_vector<uint8_t>& out_shared_key,
148 size_t desired_shared_key_len,
150 const uint8_t salt[],
151 size_t salt_len) {
152 m_op->kem_encrypt(out_encapsulated_key, out_shared_key, desired_shared_key_len, rng, salt, salt_len);
153}
154
155size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
156 return m_op->shared_key_length(desired_shared_key_len);
157}
158
161 std::string_view param,
162 std::string_view provider) {
163 m_op = key.create_kem_decryption_op(rng, param, provider);
164 if(!m_op) {
165 throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
166 }
167}
168
170
172 size_t encap_key_len,
173 size_t desired_shared_key_len,
174 const uint8_t salt[],
175 size_t salt_len) {
176 return m_op->kem_decrypt(encap_key, encap_key_len, desired_shared_key_len, salt, salt_len);
177}
178
180
183 std::string_view kdf,
184 std::string_view provider) {
185 m_op = key.create_key_agreement_op(rng, kdf, provider);
186 if(!m_op) {
187 throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
188 }
189}
190
192
194 return m_op->agreed_value_size();
195}
196
198 size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], size_t salt_len) const {
199 return SymmetricKey(m_op->agree(key_len, in, in_len, salt, salt_len));
200}
201
202static void check_der_format_supported(Signature_Format format, size_t parts) {
203 if(format != Signature_Format::Standard && parts == 1) {
204 throw Invalid_Argument("This algorithm does not support DER encoding");
205 }
206}
207
210 std::string_view emsa,
211 Signature_Format format,
212 std::string_view provider) {
213 m_op = key.create_signature_op(rng, emsa, provider);
214 if(!m_op) {
215 throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
216 }
217 m_sig_format = format;
218 m_parts = key.message_parts();
219 m_part_size = key.message_part_size();
220 check_der_format_supported(format, m_parts);
221}
222
224 return m_op->algorithm_identifier();
225}
226
227std::string PK_Signer::hash_function() const {
228 return m_op->hash_function();
229}
230
231PK_Signer::~PK_Signer() = default;
232
233void PK_Signer::update(const uint8_t in[], size_t length) {
234 m_op->update(in, length);
235}
236
237namespace {
238
239std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig, size_t parts, size_t part_size) {
240 if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
241 throw Encoding_Error("Unexpected size for DER signature");
242 }
243
244 std::vector<BigInt> sig_parts(parts);
245 for(size_t i = 0; i != sig_parts.size(); ++i) {
246 sig_parts[i].binary_decode(&sig[part_size * i], part_size);
247 }
248
249 std::vector<uint8_t> output;
250 DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
251 return output;
252}
253
254} // namespace
255
257 if(m_sig_format == Signature_Format::Standard) {
258 return m_op->signature_length();
259 } else if(m_sig_format == Signature_Format::DerSequence) {
260 // This is a large over-estimate but its easier than computing
261 // the exact value
262 return m_op->signature_length() + (8 + 4 * m_parts);
263 } else {
264 throw Internal_Error("PK_Signer: Invalid signature format enum");
265 }
266}
267
268std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
269 std::vector<uint8_t> sig = unlock(m_op->sign(rng));
270
271 if(m_sig_format == Signature_Format::Standard) {
272 return sig;
273 } else if(m_sig_format == Signature_Format::DerSequence) {
274 return der_encode_signature(sig, m_parts, m_part_size);
275 } else {
276 throw Internal_Error("PK_Signer: Invalid signature format enum");
277 }
278}
279
281 std::string_view emsa,
282 Signature_Format format,
283 std::string_view provider) {
284 m_op = key.create_verification_op(emsa, provider);
285 if(!m_op) {
286 throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
287 }
288 m_sig_format = format;
289 m_parts = key.message_parts();
290 m_part_size = key.message_part_size();
291 check_der_format_supported(format, m_parts);
292}
293
295 const AlgorithmIdentifier& signature_algorithm,
296 std::string_view provider) {
297 m_op = key.create_x509_verification_op(signature_algorithm, provider);
298
299 if(!m_op) {
300 throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
301 }
302
303 m_sig_format = key.default_x509_signature_format();
304 m_parts = key.message_parts();
305 m_part_size = key.message_part_size();
306 check_der_format_supported(m_sig_format, m_parts);
307}
308
309PK_Verifier::~PK_Verifier() = default;
310
311std::string PK_Verifier::hash_function() const {
312 return m_op->hash_function();
313}
314
316 check_der_format_supported(format, m_parts);
317 m_sig_format = format;
318}
319
320bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
321 update(msg, msg_length);
322 return check_signature(sig, sig_length);
323}
324
325void PK_Verifier::update(const uint8_t in[], size_t length) {
326 m_op->update(in, length);
327}
328
329namespace {
330
331std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
332 std::vector<uint8_t> real_sig;
333 BER_Decoder decoder(sig, length);
334 BER_Decoder ber_sig = decoder.start_sequence();
335
336 BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
337
338 size_t count = 0;
339
340 while(ber_sig.more_items()) {
341 BigInt sig_part;
342 ber_sig.decode(sig_part);
343 real_sig += BigInt::encode_1363(sig_part, sig_part_size);
344 ++count;
345 }
346
347 if(count != sig_parts) {
348 throw Decoding_Error("PK_Verifier: signature size invalid");
349 }
350
351 const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
352
353 if(reencoded.size() != length || same_mem(reencoded.data(), sig, reencoded.size()) == false) {
354 throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
355 }
356 return real_sig;
357}
358
359} // namespace
360
361bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
362 try {
363 if(m_sig_format == Signature_Format::Standard) {
364 return m_op->is_valid_signature(sig, length);
365 } else if(m_sig_format == Signature_Format::DerSequence) {
366 bool decoding_success = false;
367 std::vector<uint8_t> real_sig;
368
369 try {
370 real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
371 decoding_success = true;
372 } catch(Decoding_Error&) {}
373
374 bool accept = m_op->is_valid_signature(real_sig.data(), real_sig.size());
375
376 return accept && decoding_success;
377 } else {
378 throw Internal_Error("PK_Verifier: Invalid signature format enum");
379 }
380 } catch(Invalid_Argument&) {
381 return false;
382 } catch(Decoding_Error&) {
383 return false;
384 } catch(Encoding_Error&) {
385 return false;
386 }
387}
388
389} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:59
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:50
virtual std::string algo_name() const =0
BER_Decoder & decode(bool &out)
Definition: ber_dec.h:173
bool more_items() const
Definition: ber_dec.cpp:195
BER_Decoder start_sequence()
Definition: ber_dec.h:112
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:105
static Mask< T > is_equal(T x, T y)
Definition: ct_utils.h:128
PK_Decryptor_EME(const Private_Key &key, RandomNumberGenerator &rng, std::string_view eme, std::string_view provider="")
Definition: pubkey.cpp:109
size_t plaintext_length(size_t ptext_len) const override
Definition: pubkey.cpp:121
secure_vector< uint8_t > decrypt_or_random(const uint8_t in[], size_t length, size_t expected_pt_len, RandomNumberGenerator &rng) const
Definition: pubkey.cpp:78
secure_vector< uint8_t > decrypt(const uint8_t in[], size_t length) const
Definition: pubkey.cpp:21
PK_Encryptor_EME(const Public_Key &key, RandomNumberGenerator &rng, std::string_view padding, std::string_view provider="")
Definition: pubkey.cpp:85
size_t maximum_input_size() const override
Definition: pubkey.cpp:105
size_t ciphertext_length(size_t ptext_len) const override
Definition: pubkey.cpp:97
PK_KEM_Decryptor(const Private_Key &key, RandomNumberGenerator &rng, std::string_view kem_param="", std::string_view provider="")
Definition: pubkey.cpp:159
size_t shared_key_length(size_t desired_shared_key_len) const
Definition: pubkey.cpp:155
secure_vector< uint8_t > decrypt(const uint8_t encap_key[], size_t encap_key_len, size_t desired_shared_key_len, const uint8_t salt[], size_t salt_len)
Definition: pubkey.cpp:171
void encrypt(secure_vector< uint8_t > &out_encapsulated_key, secure_vector< uint8_t > &out_shared_key, size_t desired_shared_key_len, RandomNumberGenerator &rng, const uint8_t salt[], size_t salt_len)
Definition: pubkey.cpp:146
PK_KEM_Encryptor(const Public_Key &key, std::string_view kem_param="", std::string_view provider="")
Definition: pubkey.cpp:129
size_t shared_key_length(size_t desired_shared_key_len) const
Definition: pubkey.cpp:138
size_t encapsulated_key_length() const
Definition: pubkey.cpp:142
size_t agreed_value_size() const
Definition: pubkey.cpp:193
PK_Key_Agreement(const Private_Key &key, RandomNumberGenerator &rng, std::string_view kdf, std::string_view provider="")
Definition: pubkey.cpp:181
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:197
void update(uint8_t in)
Definition: pubkey.h:201
PK_Signer(const Private_Key &key, RandomNumberGenerator &rng, std::string_view padding, Signature_Format format=Signature_Format::Standard, std::string_view provider="")
Definition: pubkey.cpp:208
size_t signature_length() const
Definition: pubkey.cpp:256
std::vector< uint8_t > signature(RandomNumberGenerator &rng)
Definition: pubkey.cpp:268
std::string hash_function() const
Definition: pubkey.cpp:227
AlgorithmIdentifier algorithm_identifier() const
Definition: pubkey.cpp:223
void set_input_format(Signature_Format format)
Definition: pubkey.cpp:315
void update(uint8_t in)
Definition: pubkey.h:329
bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length)
Definition: pubkey.cpp:320
std::string hash_function() const
Definition: pubkey.cpp:311
PK_Verifier(const Public_Key &pub_key, std::string_view padding, Signature_Format format=Signature_Format::Standard, std::string_view provider="")
Definition: pubkey.cpp:280
bool check_signature(const uint8_t sig[], size_t length)
Definition: pubkey.cpp:361
virtual std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const
Definition: pk_keys.cpp:123
virtual std::unique_ptr< PK_Ops::Decryption > create_decryption_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const
Definition: pk_keys.cpp:111
virtual std::unique_ptr< PK_Ops::KEM_Decryption > create_kem_decryption_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const
Definition: pk_keys.cpp:117
virtual Signature_Format default_x509_signature_format() const
Definition: pk_keys.h:178
virtual std::unique_ptr< PK_Ops::Encryption > create_encryption_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const
Definition: pk_keys.cpp:90
virtual std::unique_ptr< PK_Ops::Verification > create_verification_op(std::string_view params, std::string_view provider) const
Definition: pk_keys.cpp:101
virtual std::unique_ptr< PK_Ops::Verification > create_x509_verification_op(const AlgorithmIdentifier &signature_algorithm, std::string_view provider) const
Definition: pk_keys.cpp:106
virtual std::unique_ptr< PK_Ops::KEM_Encryption > create_kem_encryption_op(std::string_view params, std::string_view provider) const
Definition: pk_keys.cpp:96
virtual size_t message_part_size() const
Definition: pk_keys.h:176
virtual size_t message_parts() const
Definition: pk_keys.h:165
void random_vec(std::span< uint8_t > v)
Definition: rng.h:180
int(* update)(CTX *, const void *, CC_LONG len)
Definition: alg_id.cpp:13
std::string fmt(std::string_view format, const T &... args)
Definition: fmt.h:53
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:75
OctetString SymmetricKey
Definition: symkey.h:141
bool same_mem(const T *p1, const T *p2, size_t n)
Definition: mem_ops.h:201
Signature_Format
Definition: pk_keys.h:29
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:61
Definition: bigint.h:1030