Botan 3.13.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/pk_ops.h>
13#include <botan/rng.h>
14#include <botan/internal/buffer_slicer.h>
15#include <botan/internal/ct_utils.h>
16#include <botan/internal/fmt.h>
17#include <botan/internal/mem_utils.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 = [&]() {
41 auto pms = rng.random_vec(expected_pt_len);
42
43 for(size_t i = 0; i != required_contents_length; ++i) {
44 const uint8_t exp = required_content_bytes[i];
45
46 /*
47 If an offset repeats we don't detect this and just return a PMS that satisfies
48 the last requested index. If the requested (idx,value) tuple is the same, that's
49 fine and just redundant. If they disagree, decryption will always fail, since the
50 same byte cannot possibly have two distinct values.
51 */
52 const uint8_t off = required_content_offsets[i];
53 BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
54 pms[off] = exp;
55 }
56
57 return pms;
58 }();
59
60 uint8_t decrypt_valid = 0;
61 secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
62
63 auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF);
64 valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_equal(decoded.size(), expected_pt_len));
65
66 decoded.resize(expected_pt_len);
67
68 for(size_t i = 0; i != required_contents_length; ++i) {
69 const uint8_t exp = required_content_bytes[i];
70
71 // We know off is in range because we already checked it when creating the fake premaster above
72 const uint8_t off = required_content_offsets[i];
73
74 auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
75
76 valid_mask &= eq;
77 }
78
79 // If valid_mask is false, assign fake pre master instead
80 valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
81
82 return decoded;
83}
84
86 size_t length,
87 size_t expected_pt_len,
88 RandomNumberGenerator& rng) const {
89 return decrypt_or_random(in, length, expected_pt_len, rng, nullptr, nullptr, 0);
90}
91
94 std::string_view padding,
95 std::string_view provider) {
96 m_op = key.create_encryption_op(rng, padding, provider);
97 if(!m_op) {
98 throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
99 }
100}
101
103
105PK_Encryptor_EME& PK_Encryptor_EME::operator=(PK_Encryptor_EME&&) noexcept = default;
106
107size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
108 return m_op->ciphertext_length(ptext_len);
109}
110
111std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t ptext[], size_t len, RandomNumberGenerator& rng) const {
112 return m_op->encrypt(std::span{ptext, len}, rng);
113}
114
116 return m_op->max_input_bits() / 8;
117}
118
121 std::string_view padding,
122 std::string_view provider) {
123 m_op = key.create_decryption_op(rng, padding, provider);
124 if(!m_op) {
125 throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
126 }
127}
128
130
132PK_Decryptor_EME& PK_Decryptor_EME::operator=(PK_Decryptor_EME&&) noexcept = default;
133
134size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
135 return m_op->plaintext_length(ctext_len);
136}
137
138size_t PK_Decryptor_EME::ciphertext_length(size_t ptext_len) const {
139 return m_op->ciphertext_length(ptext_len);
140}
141
142secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
143 return m_op->decrypt(valid_mask, {in, in_len});
144}
145
146PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
147 m_op = key.create_kem_encryption_op(param, provider);
148 if(!m_op) {
149 throw Invalid_Argument(fmt("Key type {} does not support KEM encryption", key.algo_name()));
150 }
151}
152
155 std::string_view kem_param,
156 std::string_view provider) :
157 PK_KEM_Encryptor(key, kem_param, provider) {
158 BOTAN_UNUSED(rng);
159}
160
162
164PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
165
166size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
167 return m_op->shared_key_length(desired_shared_key_len);
168}
169
171 return m_op->encapsulated_key_length();
172}
173
174void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
175 std::span<uint8_t> out_shared_key,
177 size_t desired_shared_key_len,
178 std::span<const uint8_t> salt) {
179 BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
180 BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
181 "not enough space for shared key");
182 m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
183}
184
185size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
186 return m_op->shared_key_length(desired_shared_key_len);
187}
188
190 return m_op->encapsulated_key_length();
191}
192
195 std::string_view param,
196 std::string_view provider) {
197 m_op = key.create_kem_decryption_op(rng, param, provider);
198 if(!m_op) {
199 throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
200 }
201}
202
204
206PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
207
208void PK_KEM_Decryptor::decrypt(std::span<uint8_t> out_shared_key,
209 std::span<const uint8_t> encap_key,
210 size_t desired_shared_key_len,
211 std::span<const uint8_t> salt) {
212 BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
213 "inconsistent size of shared key output buffer");
214 m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
215}
216
219 std::string_view kdf,
220 std::string_view provider) {
221 m_op = key.create_key_agreement_op(rng, kdf, provider);
222 if(!m_op) {
223 throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
224 }
225}
226
228
230PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
231
233 return m_op->agreed_value_size();
234}
235
237 const uint8_t peer_key[],
238 size_t peer_key_len,
239 std::string_view salt) const {
240 return this->derive_key(key_len, {peer_key, peer_key_len}, as_span_of_bytes(salt));
241}
242
244 const std::span<const uint8_t> peer_key,
245 std::string_view salt) const {
246 return this->derive_key(key_len, peer_key, as_span_of_bytes(salt));
247}
248
250 std::span<const uint8_t> peer_key,
251 std::span<const uint8_t> salt) const {
252 return SymmetricKey(m_op->agree(key_len, peer_key, salt));
253}
254
257 std::string_view padding,
258 Signature_Format format,
259 std::string_view provider) :
260 m_sig_format(format), m_sig_element_size(key._signature_element_size_for_DER_encoding()) {
261 if(m_sig_format == Signature_Format::DerSequence) {
262 BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
263 }
264
265 m_op = key.create_signature_op(rng, padding, provider);
266 if(!m_op) {
267 throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
268 }
269}
270
272 return m_op->algorithm_identifier();
273}
274
275std::string PK_Signer::hash_function() const {
276 return m_op->hash_function();
277}
278
279PK_Signer::~PK_Signer() = default;
280
281PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
282PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
283
284void PK_Signer::update(std::string_view in) {
285 this->update(as_span_of_bytes(in));
286}
287
288void PK_Signer::update(const uint8_t in[], size_t length) {
289 m_op->update({in, length});
290}
291
292namespace {
293
294std::vector<uint8_t> der_encode_signature(std::span<const uint8_t> sig, size_t parts, size_t part_size) {
295 if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
296 throw Encoding_Error("Unexpected size for DER signature");
297 }
298
299 BufferSlicer bs_sig(sig);
300 std::vector<BigInt> sig_parts;
301 sig_parts.reserve(parts);
302 for(size_t i = 0; i != parts; ++i) {
303 sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
304 }
305
306 std::vector<uint8_t> output;
307 DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
308 return output;
309}
310
311} // namespace
312
314 if(m_sig_format == Signature_Format::Standard) {
315 return m_op->signature_length();
316 } else if(m_sig_format == Signature_Format::DerSequence) {
317 const size_t sig_len = m_op->signature_length();
318
319 const size_t der_overhead = [sig_len]() {
320 /*
321 This was computed by DER encoding of some maximal value signatures
322 (since DER is variable length)
323
324 The first two cases covers all EC schemes since groups are at most 521
325 bits.
326
327 The other cases are only for finite field DSA which practically is only
328 used up to 3072 bit groups but the calculation is correct up to a
329 262096 (!) bit group so allow it. There are some intermediate sizes but
330 this function is allowed to (and indeed must) return an over-estimate
331 rather than an exact value since the actual length will change based on
332 the computed signature.
333 */
334
335 if(sig_len <= 120) {
336 // EC signatures <= 480 bits
337 return 8;
338 } else if(sig_len <= 248) {
339 // EC signatures > 480 bits (or very small DSA groups...)
340 return 9;
341 } else {
342 // Everything else. This is an over-estimate for groups under
343 // 2040 bits but exact otherwise
344
345 // This requires 15 bytes DER overhead and should never happen
346 BOTAN_ASSERT_NOMSG(sig_len < 65524);
347 return 14;
348 }
349 }();
350
351 return sig_len + der_overhead;
352 } else {
353 throw Internal_Error("PK_Signer: Invalid signature format enum");
354 }
355}
356
357std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
358 std::vector<uint8_t> sig = m_op->sign(rng);
359
360 if(m_sig_format == Signature_Format::Standard) {
361 return sig;
362 } else if(m_sig_format == Signature_Format::DerSequence) {
363 BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
364 return der_encode_signature(sig, 2, m_sig_element_size.value());
365 } else {
366 throw Internal_Error("PK_Signer: Invalid signature format enum");
367 }
368}
369
371 std::string_view padding,
372 Signature_Format format,
373 std::string_view provider) {
374 m_op = key.create_verification_op(padding, provider);
375 if(!m_op) {
376 throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
377 }
378
379 m_sig_format = format;
380 m_sig_element_size = key._signature_element_size_for_DER_encoding();
381
382 if(m_sig_format == Signature_Format::DerSequence) {
383 BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
384 }
385}
386
388 const AlgorithmIdentifier& signature_algorithm,
389 std::string_view provider) {
390 m_op = key.create_x509_verification_op(signature_algorithm, provider);
391 if(!m_op) {
392 throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
393 }
394
395 m_sig_format = key._default_x509_signature_format();
396 m_sig_element_size = key._signature_element_size_for_DER_encoding();
397}
398
399PK_Verifier::~PK_Verifier() = default;
400
401PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
402PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
403
404std::string PK_Verifier::hash_function() const {
405 return m_op->hash_function();
406}
407
409 if(format == Signature_Format::DerSequence) {
410 BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
411 }
412 m_sig_format = format;
413}
414
415bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
416 update(msg, msg_length);
417 return check_signature(sig, sig_length);
418}
419
420void PK_Verifier::update(std::string_view in) {
421 this->update(as_span_of_bytes(in));
422}
423
424void PK_Verifier::update(const uint8_t in[], size_t length) {
425 m_op->update({in, length});
426}
427
428namespace {
429
430std::vector<uint8_t> decode_der_signature_pair(std::span<const uint8_t> der_sig, size_t sig_part_size) {
431 BOTAN_ASSERT_NOMSG(sig_part_size > 0);
432
433 BigInt r;
434 BigInt s;
435
436 // TODO should be able to just get the integer bytes directly from
437 // BER_Decoder without using BigInt here
439
440 const bool invalid_r = r.is_negative() || r.bytes() > sig_part_size;
441 const bool invalid_s = s.is_negative() || s.bytes() > sig_part_size;
442
443 if(invalid_r || invalid_s) {
444 throw Decoding_Error("Invalid DER encoding of signature");
445 }
446
447 std::vector<uint8_t> sig(2 * sig_part_size);
448 r.serialize_to(std::span{sig}.first(sig_part_size));
449 s.serialize_to(std::span{sig}.last(sig_part_size));
450 return sig;
451}
452
453} // namespace
454
455bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
456 try {
457 if(m_sig_format == Signature_Format::Standard) {
458 return m_op->is_valid_signature({sig, length});
459 } else if(m_sig_format == Signature_Format::DerSequence) {
460 bool decoding_success = false;
461 std::vector<uint8_t> real_sig;
462
463 BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
464
465 try {
466 real_sig = decode_der_signature_pair({sig, length}, m_sig_element_size.value());
467 decoding_success = true;
468 } catch(...) {}
469
470 // It is critical that is_valid_signature is called even if DER decoding failed, since
471 // that is what resets the internal state (message hashes, etc)
472 const bool accept = m_op->is_valid_signature(real_sig);
473
474 return accept && decoding_success;
475 } else {
476 throw Internal_Error("PK_Verifier: Invalid signature format enum");
477 }
478 } catch(Invalid_Argument&) {
479 return false;
480 } catch(Decoding_Error&) {
481 return false;
482 } catch(Encoding_Error&) {
483 return false;
484 }
485}
486
487} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:144
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62
virtual std::string algo_name() const =0
virtual std::optional< size_t > _signature_element_size_for_DER_encoding() const
Definition pk_keys.h:144
virtual Signature_Format _default_x509_signature_format() const
Definition pk_keys.cpp:30
static Limits DER()
Definition ber_dec.h:42
BER_Decoder & decode(bool &out)
Definition ber_dec.h:358
BER_Decoder & verify_end()
Definition ber_dec.cpp:471
BER_Decoder & end_cons()
Definition ber_dec.cpp:630
BER_Decoder start_sequence()
Definition ber_dec.h:275
void serialize_to(std::span< uint8_t > out) const
Definition bigint.cpp:395
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:83
bool is_negative() const
Definition bigint.h:623
size_t bytes() const
Definition bigint.cpp:294
static constexpr Mask< T > is_equal(T x, T y)
Definition ct_utils.h:442
DER_Encoder & encode_list(const std::vector< T > &values)
Definition der_enc.h:327
DER_Encoder & start_sequence()
Definition der_enc.h:86
DER_Encoder & end_cons()
Definition der_enc.cpp:208
~PK_Decryptor_EME() override
size_t plaintext_length(size_t ctext_len) const override
Definition pubkey.cpp:134
PK_Decryptor_EME(const Private_Key &key, RandomNumberGenerator &rng, std::string_view padding, std::string_view provider="")
Definition pubkey.cpp:119
size_t ciphertext_length(size_t ptext_len) const override
Definition pubkey.cpp:138
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:85
secure_vector< uint8_t > decrypt(const uint8_t in[], size_t length) const
Definition pubkey.cpp:21
~PK_Encryptor_EME() override
PK_Encryptor_EME(const Public_Key &key, RandomNumberGenerator &rng, std::string_view padding, std::string_view provider="")
Definition pubkey.cpp:92
size_t maximum_input_size() const override
Definition pubkey.cpp:115
size_t ciphertext_length(size_t ptext_len) const override
Definition pubkey.cpp:107
size_t encapsulated_key_length() const
Definition pubkey.cpp:189
PK_KEM_Decryptor(const Private_Key &key, RandomNumberGenerator &rng, std::string_view kem_param="", std::string_view provider="")
Definition pubkey.cpp:193
size_t shared_key_length(size_t desired_shared_key_len) const
Definition pubkey.cpp:185
void decrypt(std::span< uint8_t > out_shared_key, std::span< const uint8_t > encap_key, size_t desired_shared_key_len=32, std::span< const uint8_t > salt={})
Definition pubkey.cpp:208
BOTAN_FUTURE_EXPLICIT PK_KEM_Encryptor(const Public_Key &key, std::string_view kem_param="", std::string_view provider="")
Definition pubkey.cpp:146
KEM_Encapsulation encrypt(RandomNumberGenerator &rng, size_t desired_shared_key_len=32, std::span< const uint8_t > salt={})
Definition pubkey.h:672
size_t shared_key_length(size_t desired_shared_key_len) const
Definition pubkey.cpp:166
size_t encapsulated_key_length() const
Definition pubkey.cpp:170
SymmetricKey derive_key(size_t key_len, std::span< const uint8_t > peer_key, std::span< const uint8_t > salt) const
Definition pubkey.cpp:249
size_t agreed_value_size() const
Definition pubkey.cpp:232
PK_Key_Agreement(const Private_Key &key, RandomNumberGenerator &rng, std::string_view kdf, std::string_view provider="")
Definition pubkey.cpp:217
void update(uint8_t in)
Definition pubkey.h:210
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:255
size_t signature_length() const
Definition pubkey.cpp:313
std::vector< uint8_t > signature(RandomNumberGenerator &rng)
Definition pubkey.cpp:357
std::string hash_function() const
Definition pubkey.cpp:275
AlgorithmIdentifier algorithm_identifier() const
Definition pubkey.cpp:271
void set_input_format(Signature_Format format)
Definition pubkey.cpp:408
void update(uint8_t in)
Definition pubkey.h:339
bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length)
Definition pubkey.cpp:415
std::string hash_function() const
Definition pubkey.cpp:404
PK_Verifier(const Public_Key &pub_key, std::string_view padding, Signature_Format format=Signature_Format::Standard, std::string_view provider="")
Definition pubkey.cpp:370
bool check_signature(const uint8_t sig[], size_t length)
Definition pubkey.cpp:455
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:138
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:126
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:144
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:132
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:105
virtual std::unique_ptr< PK_Ops::Verification > create_verification_op(std::string_view params, std::string_view provider) const
Definition pk_keys.cpp:116
virtual std::unique_ptr< PK_Ops::Verification > create_x509_verification_op(const AlgorithmIdentifier &signature_algorithm, std::string_view provider) const
Definition pk_keys.cpp:121
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:111
void random_vec(std::span< uint8_t > v)
Definition rng.h:244
OctetString SymmetricKey
Definition symkey.h:153
std::span< const uint8_t > as_span_of_bytes(const char *s, size_t len)
Definition mem_utils.h:59
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
Signature_Format
Definition pk_keys.h:32
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128