Coverage Report

Created: 2025-12-31 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/src/lib/pubkey/pubkey.cpp
Line
Count
Source
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/mem_utils.h>
19
#include <botan/internal/parsing.h>
20
21
namespace Botan {
22
23
0
secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const {
24
0
   uint8_t valid_mask = 0;
25
26
0
   secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
27
28
0
   if(valid_mask == 0) {
29
0
      throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
30
0
   }
31
32
0
   return decoded;
33
0
}
34
35
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
36
                                                       size_t length,
37
                                                       size_t expected_pt_len,
38
                                                       RandomNumberGenerator& rng,
39
                                                       const uint8_t required_content_bytes[],
40
                                                       const uint8_t required_content_offsets[],
41
0
                                                       size_t required_contents_length) const {
42
0
   const secure_vector<uint8_t> fake_pms = [&]() {
43
0
      auto pms = rng.random_vec(expected_pt_len);
44
45
0
      for(size_t i = 0; i != required_contents_length; ++i) {
46
0
         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
0
         const uint8_t off = required_content_offsets[i];
55
0
         BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
56
0
         pms[off] = exp;
57
0
      }
58
59
0
      return pms;
60
0
   }();
61
62
0
   uint8_t decrypt_valid = 0;
63
0
   secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
64
65
0
   auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF);
66
0
   valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_equal(decoded.size(), expected_pt_len));
67
68
0
   decoded.resize(expected_pt_len);
69
70
0
   for(size_t i = 0; i != required_contents_length; ++i) {
71
0
      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
0
      const uint8_t off = required_content_offsets[i];
75
76
0
      auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
77
78
0
      valid_mask &= eq;
79
0
   }
80
81
   // If valid_mask is false, assign fake pre master instead
82
0
   valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
83
84
0
   return decoded;
85
0
}
86
87
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
88
                                                       size_t length,
89
                                                       size_t expected_pt_len,
90
0
                                                       RandomNumberGenerator& rng) const {
91
0
   return decrypt_or_random(in, length, expected_pt_len, rng, nullptr, nullptr, 0);
92
0
}
93
94
PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
95
                                   RandomNumberGenerator& rng,
96
                                   std::string_view padding,
97
0
                                   std::string_view provider) {
98
0
   m_op = key.create_encryption_op(rng, padding, provider);
99
0
   if(!m_op) {
100
0
      throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
101
0
   }
102
0
}
103
104
0
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
105
106
0
PK_Encryptor_EME::PK_Encryptor_EME(PK_Encryptor_EME&&) noexcept = default;
107
0
PK_Encryptor_EME& PK_Encryptor_EME::operator=(PK_Encryptor_EME&&) noexcept = default;
108
109
0
size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
110
0
   return m_op->ciphertext_length(ptext_len);
111
0
}
112
113
0
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t ptext[], size_t len, RandomNumberGenerator& rng) const {
114
0
   return m_op->encrypt(std::span{ptext, len}, rng);
115
0
}
116
117
0
size_t PK_Encryptor_EME::maximum_input_size() const {
118
0
   return m_op->max_input_bits() / 8;
119
0
}
120
121
PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
122
                                   RandomNumberGenerator& rng,
123
                                   std::string_view padding,
124
0
                                   std::string_view provider) {
125
0
   m_op = key.create_decryption_op(rng, padding, provider);
126
0
   if(!m_op) {
127
0
      throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
128
0
   }
129
0
}
130
131
0
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
132
133
0
PK_Decryptor_EME::PK_Decryptor_EME(PK_Decryptor_EME&&) noexcept = default;
134
0
PK_Decryptor_EME& PK_Decryptor_EME::operator=(PK_Decryptor_EME&&) noexcept = default;
135
136
0
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
137
0
   return m_op->plaintext_length(ctext_len);
138
0
}
139
140
0
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
141
0
   return m_op->decrypt(valid_mask, {in, in_len});
142
0
}
143
144
0
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
145
0
   m_op = key.create_kem_encryption_op(param, provider);
146
0
   if(!m_op) {
147
0
      throw Invalid_Argument(fmt("Key type {} does not support KEM encryption", key.algo_name()));
148
0
   }
149
0
}
150
151
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key,
152
                                   RandomNumberGenerator& rng,
153
                                   std::string_view kem_param,
154
                                   std::string_view provider) :
155
0
      PK_KEM_Encryptor(key, kem_param, provider) {
156
0
   BOTAN_UNUSED(rng);
157
0
}
158
159
0
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
160
161
0
PK_KEM_Encryptor::PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept = default;
162
0
PK_KEM_Encryptor& PK_KEM_Encryptor::operator=(PK_KEM_Encryptor&&) noexcept = default;
163
164
0
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
165
0
   return m_op->shared_key_length(desired_shared_key_len);
166
0
}
167
168
0
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
169
0
   return m_op->encapsulated_key_length();
170
0
}
171
172
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
173
                               std::span<uint8_t> out_shared_key,
174
                               RandomNumberGenerator& rng,
175
                               size_t desired_shared_key_len,
176
0
                               std::span<const uint8_t> salt) {
177
0
   BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
178
0
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
179
0
                   "not enough space for shared key");
180
0
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
181
0
}
182
183
0
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
184
0
   return m_op->shared_key_length(desired_shared_key_len);
185
0
}
186
187
0
size_t PK_KEM_Decryptor::encapsulated_key_length() const {
188
0
   return m_op->encapsulated_key_length();
189
0
}
190
191
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
192
                                   RandomNumberGenerator& rng,
193
                                   std::string_view param,
194
0
                                   std::string_view provider) {
195
0
   m_op = key.create_kem_decryption_op(rng, param, provider);
196
0
   if(!m_op) {
197
0
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
198
0
   }
199
0
}
200
201
0
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
202
203
0
PK_KEM_Decryptor::PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept = default;
204
0
PK_KEM_Decryptor& PK_KEM_Decryptor::operator=(PK_KEM_Decryptor&&) noexcept = default;
205
206
void 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
0
                               std::span<const uint8_t> salt) {
210
0
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
211
0
                   "inconsistent size of shared key output buffer");
212
0
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
213
0
}
214
215
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
216
                                   RandomNumberGenerator& rng,
217
                                   std::string_view kdf,
218
0
                                   std::string_view provider) {
219
0
   m_op = key.create_key_agreement_op(rng, kdf, provider);
220
0
   if(!m_op) {
221
0
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
222
0
   }
223
0
}
224
225
0
PK_Key_Agreement::~PK_Key_Agreement() = default;
226
227
0
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
228
0
PK_Key_Agreement& PK_Key_Agreement::operator=(PK_Key_Agreement&&) noexcept = default;
229
230
0
size_t PK_Key_Agreement::agreed_value_size() const {
231
0
   return m_op->agreed_value_size();
232
0
}
233
234
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
235
                                          const uint8_t peer_key[],
236
                                          size_t peer_key_len,
237
0
                                          std::string_view salt) const {
238
0
   return this->derive_key(key_len, {peer_key, peer_key_len}, as_span_of_bytes(salt));
239
0
}
240
241
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
242
                                          const std::span<const uint8_t> peer_key,
243
0
                                          std::string_view salt) const {
244
0
   return this->derive_key(key_len, peer_key, as_span_of_bytes(salt));
245
0
}
246
247
SymmetricKey PK_Key_Agreement::derive_key(size_t key_len,
248
                                          std::span<const uint8_t> peer_key,
249
0
                                          std::span<const uint8_t> salt) const {
250
0
   return SymmetricKey(m_op->agree(key_len, peer_key, salt));
251
0
}
252
253
PK_Signer::PK_Signer(const Private_Key& key,
254
                     RandomNumberGenerator& rng,
255
                     std::string_view padding,
256
                     Signature_Format format,
257
                     std::string_view provider) :
258
484
      m_sig_format(format), m_sig_element_size(key._signature_element_size_for_DER_encoding()) {
259
484
   if(m_sig_format == Signature_Format::DerSequence) {
260
484
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
261
484
   }
262
263
484
   m_op = key.create_signature_op(rng, padding, provider);
264
484
   if(!m_op) {
265
0
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
266
0
   }
267
484
}
268
269
0
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
270
0
   return m_op->algorithm_identifier();
271
0
}
272
273
0
std::string PK_Signer::hash_function() const {
274
0
   return m_op->hash_function();
275
0
}
276
277
484
PK_Signer::~PK_Signer() = default;
278
279
0
PK_Signer::PK_Signer(PK_Signer&&) noexcept = default;
280
0
PK_Signer& PK_Signer::operator=(PK_Signer&&) noexcept = default;
281
282
0
void PK_Signer::update(std::string_view in) {
283
0
   this->update(as_span_of_bytes(in));
284
0
}
285
286
484
void PK_Signer::update(const uint8_t in[], size_t length) {
287
484
   m_op->update({in, length});
288
484
}
289
290
namespace {
291
292
484
std::vector<uint8_t> der_encode_signature(std::span<const uint8_t> sig, size_t parts, size_t part_size) {
293
484
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
294
0
      throw Encoding_Error("Unexpected size for DER signature");
295
0
   }
296
297
484
   BufferSlicer bs_sig(sig);
298
484
   std::vector<BigInt> sig_parts;
299
484
   sig_parts.reserve(parts);
300
1.45k
   for(size_t i = 0; i != parts; ++i) {
301
968
      sig_parts.emplace_back(BigInt::from_bytes(bs_sig.take(part_size)));
302
968
   }
303
304
484
   std::vector<uint8_t> output;
305
484
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
306
484
   return output;
307
484
}
308
309
}  // namespace
310
311
0
size_t PK_Signer::signature_length() const {
312
0
   if(m_sig_format == Signature_Format::Standard) {
313
0
      return m_op->signature_length();
314
0
   } else if(m_sig_format == Signature_Format::DerSequence) {
315
0
      const size_t sig_len = m_op->signature_length();
316
317
0
      const 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
0
         if(sig_len <= 120) {
334
            // EC signatures <= 480 bits
335
0
            return 8;
336
0
         } else if(sig_len <= 248) {
337
            // EC signatures > 480 bits (or very small DSA groups...)
338
0
            return 9;
339
0
         } 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
0
            BOTAN_ASSERT_NOMSG(sig_len < 65524);
345
0
            return 14;
346
0
         }
347
0
      }();
348
349
0
      return sig_len + der_overhead;
350
0
   } else {
351
0
      throw Internal_Error("PK_Signer: Invalid signature format enum");
352
0
   }
353
0
}
354
355
484
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
356
484
   std::vector<uint8_t> sig = m_op->sign(rng);
357
358
484
   if(m_sig_format == Signature_Format::Standard) {
359
0
      return sig;
360
484
   } else if(m_sig_format == Signature_Format::DerSequence) {
361
484
      BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
362
484
      return der_encode_signature(sig, 2, m_sig_element_size.value());
363
484
   } else {
364
0
      throw Internal_Error("PK_Signer: Invalid signature format enum");
365
0
   }
366
484
}
367
368
PK_Verifier::PK_Verifier(const Public_Key& key,
369
                         std::string_view padding,
370
                         Signature_Format format,
371
772
                         std::string_view provider) {
372
772
   m_op = key.create_verification_op(padding, provider);
373
772
   if(!m_op) {
374
0
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
375
0
   }
376
377
772
   m_sig_format = format;
378
772
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
379
380
772
   if(m_sig_format == Signature_Format::DerSequence) {
381
0
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
382
0
   }
383
772
}
384
385
PK_Verifier::PK_Verifier(const Public_Key& key,
386
                         const AlgorithmIdentifier& signature_algorithm,
387
0
                         std::string_view provider) {
388
0
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
389
0
   if(!m_op) {
390
0
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
391
0
   }
392
393
0
   m_sig_format = key._default_x509_signature_format();
394
0
   m_sig_element_size = key._signature_element_size_for_DER_encoding();
395
0
}
396
397
772
PK_Verifier::~PK_Verifier() = default;
398
399
0
PK_Verifier::PK_Verifier(PK_Verifier&&) noexcept = default;
400
0
PK_Verifier& PK_Verifier::operator=(PK_Verifier&&) noexcept = default;
401
402
0
std::string PK_Verifier::hash_function() const {
403
0
   return m_op->hash_function();
404
0
}
405
406
0
void PK_Verifier::set_input_format(Signature_Format format) {
407
0
   if(format == Signature_Format::DerSequence) {
408
0
      BOTAN_ARG_CHECK(m_sig_element_size.has_value(), "This key does not support DER signatures");
409
0
   }
410
0
   m_sig_format = format;
411
0
}
412
413
772
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
414
772
   update(msg, msg_length);
415
772
   return check_signature(sig, sig_length);
416
772
}
417
418
0
void PK_Verifier::update(std::string_view in) {
419
0
   this->update(as_span_of_bytes(in));
420
0
}
421
422
772
void PK_Verifier::update(const uint8_t in[], size_t length) {
423
772
   m_op->update({in, length});
424
772
}
425
426
namespace {
427
428
0
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
429
0
   std::vector<uint8_t> real_sig;
430
0
   BER_Decoder decoder(sig, length);
431
0
   BER_Decoder ber_sig = decoder.start_sequence();
432
433
0
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
434
435
0
   size_t count = 0;
436
437
0
   while(ber_sig.more_items()) {
438
0
      BigInt sig_part;
439
0
      ber_sig.decode(sig_part);
440
0
      real_sig += sig_part.serialize(sig_part_size);
441
0
      ++count;
442
0
   }
443
444
0
   if(count != sig_parts) {
445
0
      throw Decoding_Error("PK_Verifier: signature size invalid");
446
0
   }
447
448
0
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
449
450
0
   if(reencoded.size() != length || CT::is_equal(reencoded.data(), sig, reencoded.size()).as_bool() == false) {
451
0
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
452
0
   }
453
0
   return real_sig;
454
0
}
455
456
}  // namespace
457
458
772
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
459
772
   try {
460
772
      if(m_sig_format == Signature_Format::Standard) {
461
772
         return m_op->is_valid_signature({sig, length});
462
772
      } else if(m_sig_format == Signature_Format::DerSequence) {
463
0
         bool decoding_success = false;
464
0
         std::vector<uint8_t> real_sig;
465
466
0
         BOTAN_ASSERT_NOMSG(m_sig_element_size.has_value());
467
468
0
         try {
469
0
            real_sig = decode_der_signature(sig, length, 2, m_sig_element_size.value());
470
0
            decoding_success = true;
471
0
         } catch(Decoding_Error&) {}
472
473
0
         const bool accept = m_op->is_valid_signature(real_sig);
474
475
0
         return accept && decoding_success;
476
0
      } else {
477
0
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
478
0
      }
479
772
   } catch(Invalid_Argument&) {
480
0
      return false;
481
0
   } catch(Decoding_Error&) {
482
0
      return false;
483
0
   } catch(Encoding_Error&) {
484
0
      return false;
485
0
   }
486
772
}
487
488
}  // namespace Botan