Botan 3.11.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
138secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
139 return m_op->decrypt(valid_mask, {in, in_len});
140}
141
142PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
143 m_op = key.create_kem_encryption_op(param, provider);
144 if(!m_op) {
145 throw Invalid_Argument(fmt("Key type {} does not support KEM encryption", key.algo_name()));
146 }
147}
148
151 std::string_view kem_param,
152 std::string_view provider) :
153 PK_KEM_Encryptor(key, kem_param, provider) {
154 BOTAN_UNUSED(rng);
155}
156
158
160PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
161
162size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
163 return m_op->shared_key_length(desired_shared_key_len);
164}
165
167 return m_op->encapsulated_key_length();
168}
169
170void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
171 std::span<uint8_t> out_shared_key,
173 size_t desired_shared_key_len,
174 std::span<const uint8_t> salt) {
175 BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
176 BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
177 "not enough space for shared key");
178 m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
179}
180
181size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
182 return m_op->shared_key_length(desired_shared_key_len);
183}
184
186 return m_op->encapsulated_key_length();
187}
188
191 std::string_view param,
192 std::string_view provider) {
193 m_op = key.create_kem_decryption_op(rng, param, provider);
194 if(!m_op) {
195 throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
196 }
197}
198
200
202PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
203
204void PK_KEM_Decryptor::decrypt(std::span<uint8_t> out_shared_key,
205 std::span<const uint8_t> encap_key,
206 size_t desired_shared_key_len,
207 std::span<const uint8_t> salt) {
208 BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
209 "inconsistent size of shared key output buffer");
210 m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
211}
212
215 std::string_view kdf,
216 std::string_view provider) {
217 m_op = key.create_key_agreement_op(rng, kdf, provider);
218 if(!m_op) {
219 throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
220 }
221}
222
224
226PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
227
229 return m_op->agreed_value_size();
230}
231
233 const uint8_t peer_key[],
234 size_t peer_key_len,
235 std::string_view salt) const {
236 return this->derive_key(key_len, {peer_key, peer_key_len}, as_span_of_bytes(salt));
237}
238
240 const std::span<const uint8_t> peer_key,
241 std::string_view salt) const {
242 return this->derive_key(key_len, peer_key, as_span_of_bytes(salt));
243}
244
246 std::span<const uint8_t> peer_key,
247 std::span<const uint8_t> salt) const {
248 return SymmetricKey(m_op->agree(key_len, peer_key, salt));
249}
250
253 std::string_view padding,
254 Signature_Format format,
255 std::string_view provider) :
256 m_sig_format(format), m_sig_element_size(key._signature_element_size_for_DER_encoding()) {
257 if(m_sig_format == Signature_Format::DerSequence) {
258 BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
259 }
260
261 m_op = key.create_signature_op(rng, padding, provider);
262 if(!m_op) {
263 throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
264 }
265}
266
268 return m_op->algorithm_identifier();
269}
270
271std::string PK_Signer::hash_function() const {
272 return m_op->hash_function();
273}
274
275PK_Signer::~PK_Signer() = default;
276
277PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
278PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
279
280void PK_Signer::update(std::string_view in) {
281 this->update(as_span_of_bytes(in));
282}
283
284void PK_Signer::update(const uint8_t in[], size_t length) {
285 m_op->update({in, length});
286}
287
288namespace {
289
290std::vector<uint8_t> der_encode_signature(std::span<const uint8_t> sig, size_t parts, size_t part_size) {
291 if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
292 throw Encoding_Error("Unexpected size for DER signature");
293 }
294
295 BufferSlicer bs_sig(sig);
296 std::vector<BigInt> sig_parts;
297 sig_parts.reserve(parts);
298 for(size_t i = 0; i != parts; ++i) {
299 sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
300 }
301
302 std::vector<uint8_t> output;
303 DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
304 return output;
305}
306
307} // namespace
308
310 if(m_sig_format == Signature_Format::Standard) {
311 return m_op->signature_length();
312 } else if(m_sig_format == Signature_Format::DerSequence) {
313 const size_t sig_len = m_op->signature_length();
314
315 const size_t der_overhead = [sig_len]() {
316 /*
317 This was computed by DER encoding of some maximal value signatures
318 (since DER is variable length)
319
320 The first two cases covers all EC schemes since groups are at most 521
321 bits.
322
323 The other cases are only for finite field DSA which practically is only
324 used up to 3072 bit groups but the calculation is correct up to a
325 262096 (!) bit group so allow it. There are some intermediate sizes but
326 this function is allowed to (and indeed must) return an over-estimate
327 rather than an exact value since the actual length will change based on
328 the computed signature.
329 */
330
331 if(sig_len <= 120) {
332 // EC signatures <= 480 bits
333 return 8;
334 } else if(sig_len <= 248) {
335 // EC signatures > 480 bits (or very small DSA groups...)
336 return 9;
337 } else {
338 // Everything else. This is an over-estimate for groups under
339 // 2040 bits but exact otherwise
340
341 // This requires 15 bytes DER overhead and should never happen
342 BOTAN_ASSERT_NOMSG(sig_len < 65524);
343 return 14;
344 }
345 }();
346
347 return sig_len + der_overhead;
348 } else {
349 throw Internal_Error("PK_Signer: Invalid signature format enum");
350 }
351}
352
353std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
354 std::vector<uint8_t> sig = m_op->sign(rng);
355
356 if(m_sig_format == Signature_Format::Standard) {
357 return sig;
358 } else if(m_sig_format == Signature_Format::DerSequence) {
359 BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
360 return der_encode_signature(sig, 2, m_sig_element_size.value());
361 } else {
362 throw Internal_Error("PK_Signer: Invalid signature format enum");
363 }
364}
365
367 std::string_view padding,
368 Signature_Format format,
369 std::string_view provider) {
370 m_op = key.create_verification_op(padding, provider);
371 if(!m_op) {
372 throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
373 }
374
375 m_sig_format = format;
376 m_sig_element_size = key._signature_element_size_for_DER_encoding();
377
378 if(m_sig_format == Signature_Format::DerSequence) {
379 BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
380 }
381}
382
384 const AlgorithmIdentifier& signature_algorithm,
385 std::string_view provider) {
386 m_op = key.create_x509_verification_op(signature_algorithm, provider);
387 if(!m_op) {
388 throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
389 }
390
391 m_sig_format = key._default_x509_signature_format();
392 m_sig_element_size = key._signature_element_size_for_DER_encoding();
393}
394
395PK_Verifier::~PK_Verifier() = default;
396
397PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
398PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
399
400std::string PK_Verifier::hash_function() const {
401 return m_op->hash_function();
402}
403
405 if(format == Signature_Format::DerSequence) {
406 BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
407 }
408 m_sig_format = format;
409}
410
411bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
412 update(msg, msg_length);
413 return check_signature(sig, sig_length);
414}
415
416void PK_Verifier::update(std::string_view in) {
417 this->update(as_span_of_bytes(in));
418}
419
420void PK_Verifier::update(const uint8_t in[], size_t length) {
421 m_op->update({in, length});
422}
423
424namespace {
425
426std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
427 std::vector<uint8_t> real_sig;
428 BER_Decoder decoder(sig, length);
429 BER_Decoder ber_sig = decoder.start_sequence();
430
431 BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
432
433 size_t count = 0;
434
435 while(ber_sig.more_items()) {
436 BigInt sig_part;
437 ber_sig.decode(sig_part);
438 real_sig += sig_part.serialize(sig_part_size);
439 ++count;
440 }
441
442 if(count != sig_parts) {
443 throw Decoding_Error("PK_Verifier: signature size invalid");
444 }
445
446 const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
447
448 if(!CT::is_equal<uint8_t>(reencoded, std::span{sig, length}).as_bool()) {
449 throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
450 }
451 return real_sig;
452}
453
454} // namespace
455
456bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
457 try {
458 if(m_sig_format == Signature_Format::Standard) {
459 return m_op->is_valid_signature({sig, length});
460 } else if(m_sig_format == Signature_Format::DerSequence) {
461 bool decoding_success = false;
462 std::vector<uint8_t> real_sig;
463
464 BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
465
466 try {
467 real_sig = decode_der_signature(sig, length, 2, m_sig_element_size.value());
468 decoding_success = true;
469 } catch(Decoding_Error&) {}
470
471 const bool accept = m_op->is_valid_signature(real_sig);
472
473 return accept && decoding_success;
474 } else {
475 throw Internal_Error("PK_Verifier: Invalid signature format enum");
476 }
477 } catch(Invalid_Argument&) {
478 return false;
479 } catch(Decoding_Error&) {
480 return false;
481 } catch(Encoding_Error&) {
482 return false;
483 }
484}
485
486} // 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:137
virtual Signature_Format _default_x509_signature_format() const
Definition pk_keys.cpp:30
BER_Decoder & decode(bool &out)
Definition ber_dec.h:188
bool more_items() const
Definition ber_dec.cpp:207
BER_Decoder start_sequence()
Definition ber_dec.h:128
static BigInt from_bytes(std::span< const uint8_t > bytes)
Definition bigint.cpp:83
T serialize(size_t len) const
Definition bigint.h:727
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:140
DER_Encoder & start_sequence()
Definition der_enc.h:67
DER_Encoder & end_cons()
Definition der_enc.cpp:173
~PK_Decryptor_EME() override
size_t plaintext_length(size_t ptext_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
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:185
PK_KEM_Decryptor(const Private_Key &key, RandomNumberGenerator &rng, std::string_view kem_param="", std::string_view provider="")
Definition pubkey.cpp:189
size_t shared_key_length(size_t desired_shared_key_len) const
Definition pubkey.cpp:181
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:204
BOTAN_FUTURE_EXPLICIT PK_KEM_Encryptor(const Public_Key &key, std::string_view kem_param="", std::string_view provider="")
Definition pubkey.cpp:142
KEM_Encapsulation encrypt(RandomNumberGenerator &rng, size_t desired_shared_key_len=32, std::span< const uint8_t > salt={})
Definition pubkey.h:664
size_t shared_key_length(size_t desired_shared_key_len) const
Definition pubkey.cpp:162
size_t encapsulated_key_length() const
Definition pubkey.cpp:166
SymmetricKey derive_key(size_t key_len, std::span< const uint8_t > peer_key, std::span< const uint8_t > salt) const
Definition pubkey.cpp:245
size_t agreed_value_size() const
Definition pubkey.cpp:228
PK_Key_Agreement(const Private_Key &key, RandomNumberGenerator &rng, std::string_view kdf, std::string_view provider="")
Definition pubkey.cpp:213
void update(uint8_t in)
Definition pubkey.h:204
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:251
size_t signature_length() const
Definition pubkey.cpp:309
std::vector< uint8_t > signature(RandomNumberGenerator &rng)
Definition pubkey.cpp:353
std::string hash_function() const
Definition pubkey.cpp:271
AlgorithmIdentifier algorithm_identifier() const
Definition pubkey.cpp:267
void set_input_format(Signature_Format format)
Definition pubkey.cpp:404
void update(uint8_t in)
Definition pubkey.h:333
bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length)
Definition pubkey.cpp:411
std::string hash_function() const
Definition pubkey.cpp:400
PK_Verifier(const Public_Key &pub_key, std::string_view padding, Signature_Format format=Signature_Format::Standard, std::string_view provider="")
Definition pubkey.cpp:366
bool check_signature(const uint8_t sig[], size_t length)
Definition pubkey.cpp:456
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:204
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
Definition ct_utils.h:798
OctetString SymmetricKey
Definition symkey.h:140
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:68