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