• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5454043422

04 Jul 2023 11:13AM CUT coverage: 91.659% (-0.07%) from 91.732%
5454043422

Pull #3609

github

web-flow
Merge 5741e183c into cf8d8a6ca
Pull Request #3609: [TLS 1.3] Hybrid PQ/T key establishment

78635 of 85791 relevant lines covered (91.66%)

12300857.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.87
/src/lib/pubkey/pubkey.cpp
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/rng.h>
13
#include <botan/internal/ct_utils.h>
14
#include <botan/internal/fmt.h>
15
#include <botan/internal/parsing.h>
16
#include <botan/internal/pk_ops.h>
17
#include <botan/internal/pss_params.h>
18

19
namespace Botan {
20

21
secure_vector<uint8_t> PK_Decryptor::decrypt(const uint8_t in[], size_t length) const {
5,541✔
22
   uint8_t valid_mask = 0;
5,541✔
23

24
   secure_vector<uint8_t> decoded = do_decrypt(valid_mask, in, length);
5,541✔
25

26
   if(valid_mask == 0) {
5,510✔
27
      throw Decoding_Error("Invalid public key ciphertext, cannot decrypt");
3,180✔
28
   }
29

30
   return decoded;
2,330✔
31
}
3,180✔
32

33
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
135✔
34
                                                       size_t length,
35
                                                       size_t expected_pt_len,
36
                                                       RandomNumberGenerator& rng,
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 = rng.random_vec(expected_pt_len);
135✔
41

42
   uint8_t decrypt_valid = 0;
135✔
43
   secure_vector<uint8_t> decoded = do_decrypt(decrypt_valid, in, length);
135✔
44

45
   auto valid_mask = CT::Mask<uint8_t>::is_equal(decrypt_valid, 0xFF);
135✔
46
   valid_mask &= CT::Mask<uint8_t>(CT::Mask<size_t>::is_zero(decoded.size() ^ expected_pt_len));
135✔
47

48
   decoded.resize(expected_pt_len);
135✔
49

50
   for(size_t i = 0; i != required_contents_length; ++i) {
251✔
51
      /*
52
      These values are chosen by the application and for TLS are constants,
53
      so this early failure via assert is fine since we know 0,1 < 48
54

55
      If there is a protocol that has content checks on the key where
56
      the expected offsets are controllable by the attacker this could
57
      still leak.
58

59
      Alternately could always reduce the offset modulo the length?
60
      */
61

62
      const uint8_t exp = required_content_bytes[i];
116✔
63
      const uint8_t off = required_content_offsets[i];
116✔
64

65
      BOTAN_ASSERT(off < expected_pt_len, "Offset in range of plaintext");
116✔
66

67
      auto eq = CT::Mask<uint8_t>::is_equal(decoded[off], exp);
116✔
68

69
      valid_mask &= eq;
116✔
70
   }
71

72
   // If valid_mask is false, assign fake pre master instead
73
   valid_mask.select_n(decoded.data(), decoded.data(), fake_pms.data(), expected_pt_len);
135✔
74

75
   return decoded;
135✔
76
}
135✔
77

78
secure_vector<uint8_t> PK_Decryptor::decrypt_or_random(const uint8_t in[],
77✔
79
                                                       size_t length,
80
                                                       size_t expected_pt_len,
81
                                                       RandomNumberGenerator& rng) const {
82
   return decrypt_or_random(in, length, expected_pt_len, rng, nullptr, nullptr, 0);
77✔
83
}
84

85
PK_Encryptor_EME::PK_Encryptor_EME(const Public_Key& key,
611✔
86
                                   RandomNumberGenerator& rng,
87
                                   std::string_view padding,
88
                                   std::string_view provider) {
611✔
89
   m_op = key.create_encryption_op(rng, padding, provider);
611✔
90
   if(!m_op) {
209✔
91
      throw Invalid_Argument(fmt("Key type {} does not support encryption", key.algo_name()));
×
92
   }
93
}
611✔
94

95
PK_Encryptor_EME::~PK_Encryptor_EME() = default;
348✔
96

97
size_t PK_Encryptor_EME::ciphertext_length(size_t ptext_len) const {
139✔
98
   return m_op->ciphertext_length(ptext_len);
139✔
99
}
100

101
std::vector<uint8_t> PK_Encryptor_EME::enc(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const {
277✔
102
   return unlock(m_op->encrypt(in, length, rng));
554✔
103
}
104

105
size_t PK_Encryptor_EME::maximum_input_size() const {
144✔
106
   return m_op->max_input_bits() / 8;
144✔
107
}
108

109
PK_Decryptor_EME::PK_Decryptor_EME(const Private_Key& key,
785✔
110
                                   RandomNumberGenerator& rng,
111
                                   std::string_view padding,
112
                                   std::string_view provider) {
785✔
113
   m_op = key.create_decryption_op(rng, padding, provider);
785✔
114
   if(!m_op) {
257✔
115
      throw Invalid_Argument(fmt("Key type {} does not support decryption", key.algo_name()));
×
116
   }
117
}
785✔
118

119
PK_Decryptor_EME::~PK_Decryptor_EME() = default;
438✔
120

121
size_t PK_Decryptor_EME::plaintext_length(size_t ctext_len) const {
138✔
122
   return m_op->plaintext_length(ctext_len);
138✔
123
}
124

125
secure_vector<uint8_t> PK_Decryptor_EME::do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const {
3,953✔
126
   return m_op->decrypt(valid_mask, in, in_len);
3,953✔
127
}
128

129
PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, std::string_view param, std::string_view provider) {
766✔
130
   m_op = key.create_kem_encryption_op(param, provider);
766✔
131
   if(!m_op) {
766✔
132
      throw Invalid_Argument(fmt("Key type {} does not support KEM encryption", key.algo_name()));
×
133
   }
134
}
766✔
135

136
PK_KEM_Encryptor::~PK_KEM_Encryptor() = default;
766✔
137

138
size_t PK_KEM_Encryptor::shared_key_length(size_t desired_shared_key_len) const {
6,524✔
139
   return m_op->shared_key_length(desired_shared_key_len);
6,524✔
140
}
141

142
size_t PK_KEM_Encryptor::encapsulated_key_length() const {
6,537✔
143
   return m_op->encapsulated_key_length();
6,537✔
144
}
145

146
void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
3,218✔
147
                               std::span<uint8_t> out_shared_key,
148
                               RandomNumberGenerator& rng,
149
                               size_t desired_shared_key_len,
150
                               std::span<const uint8_t> salt) {
151
   BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
3,218✔
152
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,218✔
153
                   "not enough space for shared key");
154
   m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
3,218✔
155
}
3,218✔
156

157
size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
6,555✔
158
   return m_op->shared_key_length(desired_shared_key_len);
6,555✔
159
}
160

161
PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key,
743✔
162
                                   RandomNumberGenerator& rng,
163
                                   std::string_view param,
164
                                   std::string_view provider) {
743✔
165
   m_op = key.create_kem_decryption_op(rng, param, provider);
743✔
166
   if(!m_op) {
743✔
167
      throw Invalid_Argument(fmt("Key type {} does not support KEM decryption", key.algo_name()));
×
168
   }
169
}
743✔
170

171
PK_KEM_Decryptor::~PK_KEM_Decryptor() = default;
743✔
172

173
void PK_KEM_Decryptor::decrypt(std::span<uint8_t> out_shared_key,
3,236✔
174
                               std::span<const uint8_t> encap_key,
175
                               size_t desired_shared_key_len,
176
                               std::span<const uint8_t> salt) {
177
   BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
3,236✔
178
                   "inconsistent size of shared key output buffer");
179
   m_op->kem_decrypt(out_shared_key, encap_key, desired_shared_key_len, salt);
3,236✔
180
}
3,230✔
181

182
PK_Key_Agreement::PK_Key_Agreement(PK_Key_Agreement&&) noexcept = default;
×
183

184
PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key,
3,439✔
185
                                   RandomNumberGenerator& rng,
186
                                   std::string_view kdf,
187
                                   std::string_view provider) {
3,439✔
188
   m_op = key.create_key_agreement_op(rng, kdf, provider);
3,439✔
189
   if(!m_op) {
2,635✔
190
      throw Invalid_Argument(fmt("Key type {} does not support key agreement", key.algo_name()));
×
191
   }
192
}
3,439✔
193

194
PK_Key_Agreement::~PK_Key_Agreement() = default;
2,635✔
195

196
size_t PK_Key_Agreement::agreed_value_size() const {
333✔
197
   return m_op->agreed_value_size();
333✔
198
}
199

200
SymmetricKey PK_Key_Agreement::derive_key(
4,212✔
201
   size_t key_len, const uint8_t in[], size_t in_len, const uint8_t salt[], size_t salt_len) const {
202
   return SymmetricKey(m_op->agree(key_len, in, in_len, salt, salt_len));
4,212✔
203
}
204

205
static void check_der_format_supported(Signature_Format format, size_t parts) {
28,350✔
206
   if(format != Signature_Format::Standard && parts == 1) {
28,350✔
207
      throw Invalid_Argument("This algorithm does not support DER encoding");
×
208
   }
209
}
28,350✔
210

211
PK_Signer::PK_Signer(const Private_Key& key,
7,324✔
212
                     RandomNumberGenerator& rng,
213
                     std::string_view emsa,
214
                     Signature_Format format,
215
                     std::string_view provider) {
7,324✔
216
   m_op = key.create_signature_op(rng, emsa, provider);
7,324✔
217
   if(!m_op) {
3,839✔
218
      throw Invalid_Argument(fmt("Key type {} does not support signature generation", key.algo_name()));
×
219
   }
220
   m_sig_format = format;
3,839✔
221
   m_parts = key.message_parts();
3,839✔
222
   m_part_size = key.message_part_size();
3,839✔
223
   check_der_format_supported(format, m_parts);
3,839✔
224
}
7,324✔
225

226
AlgorithmIdentifier PK_Signer::algorithm_identifier() const {
368✔
227
   return m_op->algorithm_identifier();
368✔
228
}
229

230
std::string PK_Signer::hash_function() const {
561✔
231
   return m_op->hash_function();
561✔
232
}
233

234
PK_Signer::~PK_Signer() = default;
3,839✔
235

236
void PK_Signer::update(const uint8_t in[], size_t length) {
4,563✔
237
   m_op->update(in, length);
4,563✔
238
}
4,562✔
239

240
namespace {
241

242
std::vector<uint8_t> der_encode_signature(const std::vector<uint8_t>& sig, size_t parts, size_t part_size) {
8,121✔
243
   if(sig.size() % parts != 0 || sig.size() != parts * part_size) {
8,121✔
244
      throw Encoding_Error("Unexpected size for DER signature");
×
245
   }
246

247
   std::vector<BigInt> sig_parts(parts);
8,121✔
248
   for(size_t i = 0; i != sig_parts.size(); ++i) {
24,363✔
249
      sig_parts[i].binary_decode(&sig[part_size * i], part_size);
16,242✔
250
   }
251

252
   std::vector<uint8_t> output;
8,121✔
253
   DER_Encoder(output).start_sequence().encode_list(sig_parts).end_cons();
32,484✔
254
   return output;
8,121✔
255
}
8,121✔
256

257
}  // namespace
258

259
size_t PK_Signer::signature_length() const {
1,172✔
260
   if(m_sig_format == Signature_Format::Standard) {
1,172✔
261
      return m_op->signature_length();
1,169✔
262
   } else if(m_sig_format == Signature_Format::DerSequence) {
3✔
263
      // This is a large over-estimate but its easier than computing
264
      // the exact value
265
      return m_op->signature_length() + (8 + 4 * m_parts);
3✔
266
   } else {
267
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
268
   }
269
}
270

271
std::vector<uint8_t> PK_Signer::signature(RandomNumberGenerator& rng) {
4,306✔
272
   std::vector<uint8_t> sig = unlock(m_op->sign(rng));
8,611✔
273

274
   if(m_sig_format == Signature_Format::Standard) {
4,305✔
275
      return sig;
4,305✔
276
   } else if(m_sig_format == Signature_Format::DerSequence) {
389✔
277
      return der_encode_signature(sig, m_parts, m_part_size);
389✔
278
   } else {
279
      throw Internal_Error("PK_Signer: Invalid signature format enum");
×
280
   }
281
}
4,305✔
282

283
PK_Verifier::PK_Verifier(const Public_Key& key,
60,682✔
284
                         std::string_view emsa,
285
                         Signature_Format format,
286
                         std::string_view provider) {
60,682✔
287
   m_op = key.create_verification_op(emsa, provider);
60,682✔
288
   if(!m_op) {
12,947✔
289
      throw Invalid_Argument(fmt("Key type {} does not support signature verification", key.algo_name()));
×
290
   }
291
   m_sig_format = format;
12,947✔
292
   m_parts = key.message_parts();
12,947✔
293
   m_part_size = key.message_part_size();
12,947✔
294
   check_der_format_supported(format, m_parts);
12,947✔
295
}
60,682✔
296

297
PK_Verifier::PK_Verifier(const Public_Key& key,
11,620✔
298
                         const AlgorithmIdentifier& signature_algorithm,
299
                         std::string_view provider) {
11,620✔
300
   m_op = key.create_x509_verification_op(signature_algorithm, provider);
11,620✔
301

302
   if(!m_op) {
11,564✔
303
      throw Invalid_Argument(fmt("Key type {} does not support X.509 signature verification", key.algo_name()));
×
304
   }
305

306
   m_sig_format = key.default_x509_signature_format();
11,564✔
307
   m_parts = key.message_parts();
11,564✔
308
   m_part_size = key.message_part_size();
11,564✔
309
   check_der_format_supported(m_sig_format, m_parts);
11,564✔
310
}
11,620✔
311

312
PK_Verifier::~PK_Verifier() = default;
24,511✔
313

314
std::string PK_Verifier::hash_function() const {
10,887✔
315
   return m_op->hash_function();
10,887✔
316
}
317

318
void PK_Verifier::set_input_format(Signature_Format format) {
×
319
   check_der_format_supported(format, m_parts);
×
320
   m_sig_format = format;
×
321
}
×
322

323
bool PK_Verifier::verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length) {
63,941✔
324
   update(msg, msg_length);
63,941✔
325
   return check_signature(sig, sig_length);
63,941✔
326
}
327

328
void PK_Verifier::update(const uint8_t in[], size_t length) {
67,431✔
329
   m_op->update(in, length);
67,431✔
330
}
67,431✔
331

332
namespace {
333

334
std::vector<uint8_t> decode_der_signature(const uint8_t sig[], size_t length, size_t sig_parts, size_t sig_part_size) {
10,026✔
335
   std::vector<uint8_t> real_sig;
10,026✔
336
   BER_Decoder decoder(sig, length);
10,026✔
337
   BER_Decoder ber_sig = decoder.start_sequence();
10,026✔
338

339
   BOTAN_ASSERT_NOMSG(sig_parts != 0 && sig_part_size != 0);
9,684✔
340

341
   size_t count = 0;
342

343
   while(ber_sig.more_items()) {
26,963✔
344
      BigInt sig_part;
19,116✔
345
      ber_sig.decode(sig_part);
19,116✔
346
      real_sig += BigInt::encode_1363(sig_part, sig_part_size);
19,116✔
347
      ++count;
17,279✔
348
   }
19,116✔
349

350
   if(count != sig_parts) {
7,847✔
351
      throw Decoding_Error("PK_Verifier: signature size invalid");
115✔
352
   }
353

354
   const std::vector<uint8_t> reencoded = der_encode_signature(real_sig, sig_parts, sig_part_size);
7,732✔
355

356
   if(reencoded.size() != length || same_mem(reencoded.data(), sig, reencoded.size()) == false) {
15,026✔
357
      throw Decoding_Error("PK_Verifier: signature is not the canonical DER encoding");
926✔
358
   }
359
   return real_sig;
13,612✔
360
}
12,904✔
361

362
}  // namespace
363

364
bool PK_Verifier::check_signature(const uint8_t sig[], size_t length) {
67,818✔
365
   try {
67,818✔
366
      if(m_sig_format == Signature_Format::Standard) {
67,818✔
367
         return m_op->is_valid_signature(sig, length);
57,792✔
368
      } else if(m_sig_format == Signature_Format::DerSequence) {
10,026✔
369
         bool decoding_success = false;
10,026✔
370
         std::vector<uint8_t> real_sig;
10,026✔
371

372
         try {
10,026✔
373
            real_sig = decode_der_signature(sig, length, m_parts, m_part_size);
16,832✔
374
            decoding_success = true;
6,806✔
375
         } catch(Decoding_Error&) {}
3,220✔
376

377
         bool accept = m_op->is_valid_signature(real_sig.data(), real_sig.size());
9,802✔
378

379
         return accept && decoding_success;
9,802✔
380
      } else {
10,026✔
381
         throw Internal_Error("PK_Verifier: Invalid signature format enum");
×
382
      }
383
   } catch(Invalid_Argument&) {
321✔
384
      return false;
×
385
   } catch(Decoding_Error&) {
97✔
386
      return false;
97✔
387
   } catch(Encoding_Error&) {
321✔
388
      return false;
224✔
389
   }
224✔
390
}
391

392
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc