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