Botan 3.7.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
230size_t PK_Key_Agreement::agreed_value_size() const {
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) {
259 if(m_sig_format == Signature_Format::DerSequence) {
260 m_sig_element_size = key._signature_element_size_for_DER_encoding();
261 BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
262 }
263
264 m_op = key.create_signature_op(rng, emsa, provider);
265 if(!m_op) {
266 throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
267 }
268}
269
271 return m_op->algorithm_identifier();
272}
273
274std::string PK_Signer::hash_function() const {
275 return m_op->hash_function();
276}
277
278PK_Signer::~PK_Signer() = default;
279
280PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
281PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
282
283void PK_Signer::update(std::string_view in) {
284 this->update(cast_char_ptr_to_uint8(in.data()), in.size());
285}
286
287void PK_Signer::update(const uint8_t in[], size_t length) {
288 m_op->update({in, length});
289}
290
291namespace {
292
293std::vector<uint8_t> der_encode_signature(std::span<const uint8_t> sig, size_t parts, size_t part_size) {
294 if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
295 throw Encoding_Error("Unexpected size for DER signature");
296 }
297
298 BufferSlicer bs_sig(sig);
299 std::vector<BigInt> sig_parts;
300 sig_parts.reserve(parts);
301 for(size_t i = 0; i != parts; ++i) {
302 sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
303 }
304
305 std::vector<uint8_t> output;
306 DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
307 return output;
308}
309
310} // namespace
311
313 if(m_sig_format == Signature_Format::Standard) {
314 return m_op->signature_length();
315 } else if(m_sig_format == Signature_Format::DerSequence) {
316 size_t sig_len = m_op->signature_length();
317
318 size_t der_overhead = [sig_len]() {
319 /*
320 This was computed by DER encoding of some maximal value signatures
321 (since DER is variable length)
322
323 The first two cases covers all EC schemes since groups are at most 521
324 bits.
325
326 The other cases are only for finite field DSA which practically is only
327 used up to 3072 bit groups but the calculation is correct up to a
328 262096 (!) bit group so allow it. There are some intermediate sizes but
329 this function is allowed to (and indeed must) return an over-estimate
330 rather than an exact value since the actual length will change based on
331 the computed signature.
332 */
333
334 if(sig_len <= 120) {
335 // EC signatures <= 480 bits
336 return 8;
337 } else if(sig_len <= 248) {
338 // EC signatures > 480 bits (or very small DSA groups...)
339 return 9;
340 } else {
341 // Everything else. This is an over-estimate for groups under
342 // 2040 bits but exact otherwise
343
344 // This requires 15 bytes DER overhead and should never happen
345 BOTAN_ASSERT_NOMSG(sig_len < 65524);
346 return 14;
347 }
348 }();
349
350 return sig_len + der_overhead;
351 } else {
352 throw Internal_Error("PK_Signer: Invalid signature format enum");
353 }
354}
355
356std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
357 std::vector<uint8_t> sig = m_op->sign(rng);
358
359 if(m_sig_format == Signature_Format::Standard) {
360 return sig;
361 } else if(m_sig_format == Signature_Format::DerSequence) {
362 BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
363 return der_encode_signature(sig, 2, m_sig_element_size.value());
364 } else {
365 throw Internal_Error("PK_Signer: Invalid signature format enum");
366 }
367}
368
370 std::string_view emsa,
371 Signature_Format format,
372 std::string_view provider) {
373 m_op = key.create_verification_op(emsa, provider);
374 if(!m_op) {
375 throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
376 }
377
378 m_sig_format = format;
379 m_sig_element_size = key._signature_element_size_for_DER_encoding();
380
381 if(m_sig_format == Signature_Format::DerSequence) {
382 BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
383 }
384}
385
387 const AlgorithmIdentifier& signature_algorithm,
388 std::string_view provider) {
389 m_op = key.create_x509_verification_op(signature_algorithm, provider);
390 if(!m_op) {
391 throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
392 }
393
394 m_sig_format = key._default_x509_signature_format();
395 m_sig_element_size = key._signature_element_size_for_DER_encoding();
396}
397
398PK_Verifier::~PK_Verifier() = default;
399
400PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
401PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
402
403std::string PK_Verifier::hash_function() const {
404 return m_op->hash_function();
405}
406
408 if(format == Signature_Format::DerSequence) {
409 BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
410 }
411 m_sig_format = format;
412}
413
414bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
415 update(msg, msg_length);
416 return check_signature(sig, sig_length);
417}
418
419void PK_Verifier::update(std::string_view in) {
420 this->update(cast_char_ptr_to_uint8(in.data()), in.size());
421}
422
423void PK_Verifier::update(const uint8_t in[], size_t length) {
424 m_op->update({in, length});
425}
426
427namespace {
428
429std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
430 std::vector<uint8_t> real_sig;
431 BER_Decoder decoder(sig, length);
432 BER_Decoder ber_sig = decoder.start_sequence();
433
434 BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
435
436 size_t count = 0;
437
438 while(ber_sig.more_items()) {
439 BigInt sig_part;
440 ber_sig.decode(sig_part);
441 real_sig += sig_part.serialize(sig_part_size);
442 ++count;
443 }
444
445 if(count != sig_parts) {
446 throw Decoding_Error("PK_Verifier: signature size invalid");
447 }
448
449 const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
450
451 if(reencoded.size() != length || CT::is_equal(reencoded.data(), sig, reencoded.size()).as_bool() == false) {
452 throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
453 }
454 return real_sig;
455}
456
457} // namespace
458
459bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
460 try {
461 if(m_sig_format == Signature_Format::Standard) {
462 return m_op->is_valid_signature({sig, length});
463 } else if(m_sig_format == Signature_Format::DerSequence) {
464 bool decoding_success = false;
465 std::vector<uint8_t> real_sig;
466
467 BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
468
469 try {
470 real_sig = decode_der_signature(sig, length, 2, m_sig_element_size.value());
471 decoding_success = true;
472 } catch(Decoding_Error&) {}
473
474 bool accept = m_op->is_valid_signature(real_sig);
475
476 return accept && decoding_success;
477 } else {
478 throw Internal_Error("PK_Verifier: Invalid signature format enum");
479 }
480 } catch(Invalid_Argument&) {
481 return false;
482 } catch(Decoding_Error&) {
483 return false;
484 } catch(Encoding_Error&) {
485 return false;
486 }
487}
488
489} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:118
#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
virtual std::optional< size_t > _signature_element_size_for_DER_encoding() const
Definition pk_keys.h:136
virtual Signature_Format _default_x509_signature_format() const
Definition pk_keys.cpp:30
BER_Decoder & decode(bool &out)
Definition ber_dec.h:186
bool more_items() const
Definition ber_dec.cpp:201
BER_Decoder start_sequence()
Definition ber_dec.h:123
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:95
T serialize(size_t len) const
Definition bigint.h:712
static constexpr Mask< T > is_equal(T x, T y)
Definition ct_utils.h:453
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
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:312
std::vector< uint8_t > signature(RandomNumberGenerator &rng)
Definition pubkey.cpp:356
std::string hash_function() const
Definition pubkey.cpp:274
AlgorithmIdentifier algorithm_identifier() const
Definition pubkey.cpp:270
void set_input_format(Signature_Format format)
Definition pubkey.cpp:407
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:414
std::string hash_function() const
Definition pubkey.cpp:403
PK_Verifier(const Public_Key &pub_key, std::string_view padding, Signature_Format format=Signature_Format::Standard, std::string_view provider="")
Definition pubkey.cpp:369
bool check_signature(const uint8_t sig[], size_t length)
Definition pubkey.cpp:459
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:180
int(* update)(CTX *, const void *, CC_LONG len)
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
Definition ct_utils.h:788
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:61
Signature_Format
Definition pk_keys.h:31
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition mem_ops.h:274