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