Coverage Report

Created: 2026-01-09 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/build/include/public/botan/pubkey.h
Line
Count
Source
1
/*
2
* Public Key Interface
3
* (C) 1999-2010 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#ifndef BOTAN_PUBKEY_H_
9
#define BOTAN_PUBKEY_H_
10
11
#include <botan/pk_keys.h>
12
#include <botan/pk_ops_fwd.h>
13
#include <botan/symkey.h>
14
#include <span>
15
#include <string>
16
#include <string_view>
17
#include <utility>
18
19
namespace Botan {
20
21
class RandomNumberGenerator;
22
23
/**
24
* Public Key Encryptor
25
* This is the primary interface for public key encryption
26
*/
27
class BOTAN_PUBLIC_API(2, 0) PK_Encryptor {
28
   public:
29
      /**
30
      * Encrypt a message.
31
      * @param in the message as a byte array
32
      * @param length the length of the above byte array
33
      * @param rng the random number source to use
34
      * @return encrypted message
35
      */
36
0
      std::vector<uint8_t> encrypt(const uint8_t in[], size_t length, RandomNumberGenerator& rng) const {
37
0
         return enc(in, length, rng);
38
0
      }
39
40
      /**
41
      * Encrypt a message.
42
      * @param in the message
43
      * @param rng the random number source to use
44
      * @return encrypted message
45
      */
46
99
      std::vector<uint8_t> encrypt(std::span<const uint8_t> in, RandomNumberGenerator& rng) const {
47
99
         return enc(in.data(), in.size(), rng);
48
99
      }
49
50
      /**
51
      * Return the maximum allowed message size in bytes.
52
      * @return maximum message size in bytes
53
      */
54
      virtual size_t maximum_input_size() const = 0;
55
56
      /**
57
      * Return an upper bound on the ciphertext length
58
      */
59
      virtual size_t ciphertext_length(size_t ctext_len) const = 0;
60
61
99
      PK_Encryptor() = default;
62
99
      virtual ~PK_Encryptor() = default;
63
64
      PK_Encryptor(const PK_Encryptor&) = delete;
65
      PK_Encryptor& operator=(const PK_Encryptor&) = delete;
66
67
0
      PK_Encryptor(PK_Encryptor&&) noexcept = default;
68
0
      PK_Encryptor& operator=(PK_Encryptor&&) noexcept = default;
69
70
   private:
71
      virtual std::vector<uint8_t> enc(const uint8_t[], size_t, RandomNumberGenerator&) const = 0;
72
};
73
74
/**
75
* Public Key Decryptor
76
*/
77
class BOTAN_PUBLIC_API(2, 0) PK_Decryptor {
78
   public:
79
      /**
80
      * Decrypt a ciphertext, throwing an exception if the input
81
      * seems to be invalid (eg due to an accidental or malicious
82
      * error in the ciphertext).
83
      *
84
      * @param in the ciphertext as a byte array
85
      * @param length the length of the above byte array
86
      * @return decrypted message
87
      */
88
      secure_vector<uint8_t> decrypt(const uint8_t in[], size_t length) const;
89
90
      /**
91
      * Same as above, but taking a vector
92
      * @param in the ciphertext
93
      * @return decrypted message
94
      */
95
0
      secure_vector<uint8_t> decrypt(std::span<const uint8_t> in) const { return decrypt(in.data(), in.size()); }
96
97
      /**
98
      * Decrypt a ciphertext. If the ciphertext is invalid (eg due to
99
      * invalid padding) or is not the expected length, instead
100
      * returns a random string of the expected length. Use to avoid
101
      * oracle attacks, especially against PKCS #1 v1.5 decryption.
102
      */
103
      secure_vector<uint8_t> decrypt_or_random(const uint8_t in[],
104
                                               size_t length,
105
                                               size_t expected_pt_len,
106
                                               RandomNumberGenerator& rng) const;
107
108
      /**
109
      * Decrypt a ciphertext. If the ciphertext is invalid (eg due to
110
      * invalid padding) or is not the expected length, instead
111
      * returns a random string of the expected length. Use to avoid
112
      * oracle attacks, especially against PKCS #1 v1.5 decryption.
113
      *
114
      * Additionally checks (also in const time) that:
115
      *    contents[required_content_offsets[i]] == required_content_bytes[i]
116
      * for 0 <= i < required_contents
117
      *
118
      * Used for example in TLS, which encodes the client version in
119
      * the content bytes: if there is any timing variation the version
120
      * check can be used as an oracle to recover the key.
121
      */
122
      secure_vector<uint8_t> decrypt_or_random(const uint8_t in[],
123
                                               size_t length,
124
                                               size_t expected_pt_len,
125
                                               RandomNumberGenerator& rng,
126
                                               const uint8_t required_content_bytes[],
127
                                               const uint8_t required_content_offsets[],
128
                                               size_t required_contents) const;
129
130
      /**
131
      * Return an upper bound on the plaintext length for a particular
132
      * ciphertext input length
133
      */
134
      virtual size_t plaintext_length(size_t ctext_len) const = 0;
135
136
0
      PK_Decryptor() = default;
137
0
      virtual ~PK_Decryptor() = default;
138
139
      PK_Decryptor(const PK_Decryptor&) = delete;
140
      PK_Decryptor& operator=(const PK_Decryptor&) = delete;
141
142
0
      PK_Decryptor(PK_Decryptor&&) noexcept = default;
143
0
      PK_Decryptor& operator=(PK_Decryptor&&) noexcept = default;
144
145
   private:
146
      virtual secure_vector<uint8_t> do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const = 0;
147
};
148
149
/**
150
* Public Key Signer. Use the sign_message() functions for small
151
* messages. Use multiple calls update() to process large messages and
152
* generate the signature by finally calling signature().
153
*/
154
class BOTAN_PUBLIC_API(2, 0) PK_Signer final {
155
   public:
156
      /**
157
      * Construct a PK Signer.
158
      * @param key the key to use inside this signer
159
      * @param rng the random generator to use
160
      * @param padding the padding/hash to use, eg "SHA-512" or "PSS(SHA-256)"
161
      * @param format the signature format to use
162
      * @param provider the provider to use
163
      */
164
      PK_Signer(const Private_Key& key,
165
                RandomNumberGenerator& rng,
166
                std::string_view padding,
167
                Signature_Format format = Signature_Format::Standard,
168
                std::string_view provider = "");
169
170
      ~PK_Signer();
171
172
      PK_Signer(const PK_Signer&) = delete;
173
      PK_Signer& operator=(const PK_Signer&) = delete;
174
175
      PK_Signer(PK_Signer&&) noexcept;
176
      PK_Signer& operator=(PK_Signer&&) noexcept;
177
178
      /**
179
      * Sign a message all in one go
180
      * @param in the message to sign as a byte array
181
      * @param length the length of the above byte array
182
      * @param rng the rng to use
183
      * @return signature
184
      */
185
0
      std::vector<uint8_t> sign_message(const uint8_t in[], size_t length, RandomNumberGenerator& rng) {
186
0
         this->update(in, length);
187
0
         return this->signature(rng);
188
0
      }
189
190
      /**
191
      * Sign a message.
192
      * @param in the message to sign
193
      * @param rng the rng to use
194
      * @return signature
195
      */
196
0
      std::vector<uint8_t> sign_message(std::span<const uint8_t> in, RandomNumberGenerator& rng) {
197
0
         return sign_message(in.data(), in.size(), rng);
198
0
      }
199
200
      /**
201
      * Add a message part (single byte).
202
      * @param in the byte to add
203
      */
204
0
      void update(uint8_t in) { update(&in, 1); }
205
206
      /**
207
      * Add a message part.
208
      * @param in the message part to add as a byte array
209
      * @param length the length of the above byte array
210
      */
211
      void update(const uint8_t in[], size_t length);
212
213
      /**
214
      * Add a message part.
215
      * @param in the message part to add
216
      */
217
0
      void update(std::span<const uint8_t> in) { update(in.data(), in.size()); }
218
219
      /**
220
      * Add a message part.
221
      * @param in the message part to add
222
      */
223
      void update(std::string_view in);
224
225
      /**
226
      * Get the signature of the so far processed message (provided by the
227
      * calls to update()).
228
      * @param rng the rng to use
229
      * @return signature of the total message
230
      */
231
      std::vector<uint8_t> signature(RandomNumberGenerator& rng);
232
233
      /**
234
      * Set the output format of the signature.
235
      * @param format the signature format to use
236
      */
237
0
      void set_output_format(Signature_Format format) { m_sig_format = format; }
238
239
      /**
240
      * Return an upper bound on the length of the signatures this
241
      * PK_Signer will produce
242
      */
243
      size_t signature_length() const;
244
245
      /**
246
      * Return an AlgorithmIdentifier appropriate for identifying the signature
247
      * method being generated by this PK_Signer. Throws an exception if this
248
      * is not available for the current signature scheme.
249
      */
250
      AlgorithmIdentifier algorithm_identifier() const;
251
252
      /**
253
      * Return the hash function which is being used to create signatures.
254
      * This should never return an empty string however it may return a string
255
      * which does not map directly to a hash function, in particular if "Raw"
256
      * (unhashed) encoding is being used.
257
      */
258
      std::string hash_function() const;
259
260
   private:
261
      std::unique_ptr<PK_Ops::Signature> m_op;
262
      Signature_Format m_sig_format;
263
      std::optional<size_t> m_sig_element_size;
264
};
265
266
/**
267
* Public Key Verifier. Use the verify_message() functions for small
268
* messages. Use multiple calls update() to process large messages and
269
* verify the signature by finally calling check_signature().
270
*/
271
class BOTAN_PUBLIC_API(2, 0) PK_Verifier final {
272
   public:
273
      /**
274
      * Construct a PK Verifier.
275
      * @param pub_key the public key to verify against
276
      * @param padding the padding/hash to use (eg "SHA-512" or "PSS(SHA-256)")
277
      * @param format the signature format to use
278
      * @param provider the provider to use
279
      */
280
      PK_Verifier(const Public_Key& pub_key,
281
                  std::string_view padding,
282
                  Signature_Format format = Signature_Format::Standard,
283
                  std::string_view provider = "");
284
285
      /**
286
      * Construct a PK Verifier (X.509 specific)
287
      *
288
      * This constructor will attempt to decode signature_format relative
289
      * to the public key provided. If they seem to be inconsistent or
290
      * otherwise unsupported, a Decoding_Error is thrown.
291
      *
292
      * @param pub_key the public key to verify against
293
      * @param signature_algorithm the supposed signature algorithm
294
      * @param provider the provider to use
295
      */
296
      PK_Verifier(const Public_Key& pub_key,
297
                  const AlgorithmIdentifier& signature_algorithm,
298
                  std::string_view provider = "");
299
300
      ~PK_Verifier();
301
302
      PK_Verifier(const PK_Verifier&) = delete;
303
      PK_Verifier& operator=(const PK_Verifier&) = delete;
304
305
      PK_Verifier(PK_Verifier&&) noexcept;
306
      PK_Verifier& operator=(PK_Verifier&&) noexcept;
307
308
      /**
309
      * Verify a signature.
310
      * @param msg the message that the signature belongs to, as a byte array
311
      * @param msg_length the length of the above byte array msg
312
      * @param sig the signature as a byte array
313
      * @param sig_length the length of the above byte array sig
314
      * @return true if the signature is valid
315
      */
316
      bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length);
317
318
      /**
319
      * Verify a signature.
320
      * @param msg the message that the signature belongs to
321
      * @param sig the signature
322
      * @return true if the signature is valid
323
      */
324
6.60k
      bool verify_message(std::span<const uint8_t> msg, std::span<const uint8_t> sig) {
325
6.60k
         return verify_message(msg.data(), msg.size(), sig.data(), sig.size());
326
6.60k
      }
327
328
      /**
329
      * Add a message part (single byte) of the message corresponding to the
330
      * signature to be verified.
331
      * @param in the byte to add
332
      */
333
0
      void update(uint8_t in) { update(&in, 1); }
334
335
      /**
336
      * Add a message part of the message corresponding to the
337
      * signature to be verified.
338
      * @param msg_part the new message part as a byte array
339
      * @param length the length of the above byte array
340
      */
341
      void update(const uint8_t msg_part[], size_t length);
342
343
      /**
344
      * Add a message part of the message corresponding to the
345
      * signature to be verified.
346
      * @param in the new message part
347
      */
348
0
      void update(std::span<const uint8_t> in) { update(in.data(), in.size()); }
349
350
      /**
351
      * Add a message part of the message corresponding to the
352
      * signature to be verified.
353
      */
354
      void update(std::string_view in);
355
356
      /**
357
      * Check the signature of the buffered message, i.e. the one build
358
      * by successive calls to update.
359
      * @param sig the signature to be verified as a byte array
360
      * @param length the length of the above byte array
361
      * @return true if the signature is valid, false otherwise
362
      */
363
      bool check_signature(const uint8_t sig[], size_t length);
364
365
      /**
366
      * Check the signature of the buffered message, i.e. the one build
367
      * by successive calls to update.
368
      * @param sig the signature to be verified
369
      * @return true if the signature is valid, false otherwise
370
      */
371
0
      bool check_signature(std::span<const uint8_t> sig) { return check_signature(sig.data(), sig.size()); }
372
373
      /**
374
      * Set the format of the signatures fed to this verifier.
375
      * @param format the signature format to use
376
      */
377
      BOTAN_DEPRECATED("Provide Signature_Format to the constructor") void set_input_format(Signature_Format format);
378
379
      /**
380
      * Return the hash function which is being used to verify signatures.
381
      * This should never return an empty string however it may return a string
382
      * which does not map directly to a hash function, in particular if "Raw"
383
      * (unhashed) encoding is being used.
384
      */
385
      std::string hash_function() const;
386
387
   private:
388
      std::unique_ptr<PK_Ops::Verification> m_op;
389
      Signature_Format m_sig_format;
390
      std::optional<size_t> m_sig_element_size;
391
};
392
393
/**
394
* Object used for key agreement
395
*/
396
class BOTAN_PUBLIC_API(2, 0) PK_Key_Agreement final {
397
   public:
398
      /**
399
      * Construct a PK Key Agreement.
400
      * @param key the key to use
401
      * @param rng the random generator to use
402
      * @param kdf name of the KDF to use (or 'Raw' for no KDF)
403
      * @param provider the algo provider to use (or empty for default)
404
      */
405
      PK_Key_Agreement(const Private_Key& key,
406
                       RandomNumberGenerator& rng,
407
                       std::string_view kdf,
408
                       std::string_view provider = "");
409
410
      ~PK_Key_Agreement();
411
412
      PK_Key_Agreement(const PK_Key_Agreement&) = delete;
413
      PK_Key_Agreement& operator=(const PK_Key_Agreement&) = delete;
414
415
      PK_Key_Agreement(PK_Key_Agreement&&) noexcept;
416
      PK_Key_Agreement& operator=(PK_Key_Agreement&&) noexcept;
417
418
      /**
419
      * Perform Key Agreement Operation
420
      * @param key_len the desired key output size (ignored if "Raw" KDF is used)
421
      * @param peer_key the other parties key
422
      * @param salt extra derivation salt
423
      */
424
      SymmetricKey derive_key(size_t key_len, std::span<const uint8_t> peer_key, std::span<const uint8_t> salt) const;
425
426
      /**
427
      * Perform Key Agreement Operation
428
      * @param key_len the desired key output size (ignored if "Raw" KDF is used)
429
      * @param peer_key the other parties key
430
      * @param peer_key_len the length of peer_key in bytes
431
      * @param salt extra derivation salt
432
      * @param salt_len the length of salt in bytes
433
      */
434
      SymmetricKey derive_key(
435
0
         size_t key_len, const uint8_t peer_key[], size_t peer_key_len, const uint8_t salt[], size_t salt_len) const {
436
0
         return this->derive_key(key_len, {peer_key, peer_key_len}, {salt, salt_len});
437
0
      }
438
439
      /**
440
      * Perform Key Agreement Operation
441
      * @param key_len the desired key output size (ignored if "Raw" KDF is used)
442
      * @param peer_key the other parties key
443
      * @param salt extra derivation salt
444
      * @param salt_len the length of salt in bytes
445
      */
446
      SymmetricKey derive_key(size_t key_len,
447
                              std::span<const uint8_t> peer_key,
448
                              const uint8_t salt[],
449
0
                              size_t salt_len) const {
450
0
         return derive_key(key_len, peer_key.data(), peer_key.size(), salt, salt_len);
451
0
      }
452
453
      /**
454
      * Perform Key Agreement Operation
455
      * @param key_len the desired key output size (ignored if "Raw" KDF is used)
456
      * @param peer_key the other parties key
457
      * @param peer_key_len the length of peer_key in bytes
458
      * @param salt extra derivation info
459
      */
460
      SymmetricKey derive_key(size_t key_len,
461
                              const uint8_t peer_key[],
462
                              size_t peer_key_len,
463
                              std::string_view salt = "") const;
464
465
      /**
466
      * Perform Key Agreement Operation
467
      * @param key_len the desired key output size (ignored if "Raw" KDF is used)
468
      * @param peer_key the other parties key
469
      * @param salt extra derivation info
470
      */
471
      SymmetricKey derive_key(size_t key_len, std::span<const uint8_t> peer_key, std::string_view salt = "") const;
472
473
      /**
474
      * Return the underlying size of the value that is agreed.
475
      * If derive_key is called with a length of 0 with a "Raw"
476
      * KDF, it will return a value of this size.
477
      */
478
      size_t agreed_value_size() const;
479
480
   private:
481
      std::unique_ptr<PK_Ops::Key_Agreement> m_op;
482
};
483
484
/**
485
* Encryption using a standard message recovery algorithm like RSA or
486
* ElGamal, paired with an encoding scheme like OAEP.
487
*/
488
class BOTAN_PUBLIC_API(2, 0) PK_Encryptor_EME final : public PK_Encryptor {
489
   public:
490
      size_t maximum_input_size() const override;
491
492
      /**
493
      * Construct an instance.
494
      * @param key the key to use inside the encryptor
495
      * @param rng the RNG to use
496
      * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)")
497
      * @param provider the provider to use
498
      */
499
      PK_Encryptor_EME(const Public_Key& key,
500
                       RandomNumberGenerator& rng,
501
                       std::string_view padding,
502
                       std::string_view provider = "");
503
504
      ~PK_Encryptor_EME() override;
505
506
      PK_Encryptor_EME(const PK_Encryptor_EME&) = delete;
507
      PK_Encryptor_EME& operator=(const PK_Encryptor_EME&) = delete;
508
509
      PK_Encryptor_EME(PK_Encryptor_EME&&) noexcept;
510
      PK_Encryptor_EME& operator=(PK_Encryptor_EME&&) noexcept;
511
512
      /**
513
      * Return an upper bound on the ciphertext length for a particular
514
      * plaintext input length
515
      */
516
      size_t ciphertext_length(size_t ptext_len) const override;
517
518
   private:
519
      std::vector<uint8_t> enc(const uint8_t ptext[], size_t len, RandomNumberGenerator& rng) const override;
520
521
      std::unique_ptr<PK_Ops::Encryption> m_op;
522
};
523
524
/**
525
* Decryption with a padding scheme.
526
*
527
* This is typically only used with RSA
528
*/
529
class BOTAN_PUBLIC_API(2, 0) PK_Decryptor_EME final : public PK_Decryptor {
530
   public:
531
      /**
532
      * Construct an instance.
533
      * @param key the key to use inside the decryptor
534
      * @param rng the random generator to use
535
      * @param padding the padding scheme to use
536
      * @param provider the provider to use
537
      */
538
      PK_Decryptor_EME(const Private_Key& key,
539
                       RandomNumberGenerator& rng,
540
                       std::string_view padding,
541
                       std::string_view provider = "");
542
543
      size_t plaintext_length(size_t ptext_len) const override;
544
545
      ~PK_Decryptor_EME() override;
546
547
      PK_Decryptor_EME(const PK_Decryptor_EME&) = delete;
548
      PK_Decryptor_EME& operator=(const PK_Decryptor_EME&) = delete;
549
550
      PK_Decryptor_EME(PK_Decryptor_EME&&) noexcept;
551
      PK_Decryptor_EME& operator=(PK_Decryptor_EME&&) noexcept;
552
553
   private:
554
      secure_vector<uint8_t> do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const override;
555
556
      std::unique_ptr<PK_Ops::Decryption> m_op;
557
};
558
559
/**
560
* Result of a key encapsulation operation.
561
*/
562
class KEM_Encapsulation final {
563
   public:
564
      KEM_Encapsulation(std::vector<uint8_t> encapsulated_shared_key, secure_vector<uint8_t> shared_key) :
565
0
            m_encapsulated_shared_key(std::move(encapsulated_shared_key)), m_shared_key(std::move(shared_key)) {}
566
567
      /**
568
      * @returns the encapsulated shared secret (encrypted with the public key)
569
      */
570
0
      const std::vector<uint8_t>& encapsulated_shared_key() const { return m_encapsulated_shared_key; }
571
572
      /**
573
      * @returns the plaintext shared secret
574
      */
575
0
      const secure_vector<uint8_t>& shared_key() const { return m_shared_key; }
576
577
      /**
578
       * @returns the pair (encapsulated key, key) extracted from @p kem
579
       */
580
      static std::pair<std::vector<uint8_t>, secure_vector<uint8_t>> destructure(
581
0
         KEM_Encapsulation&& kem) /* NOLINT(*param-not-moved*) */ {
582
0
         return std::make_pair(std::exchange(kem.m_encapsulated_shared_key, {}), std::exchange(kem.m_shared_key, {}));
583
0
      }
584
585
   private:
586
      friend class PK_KEM_Encryptor;
587
588
      KEM_Encapsulation(size_t encapsulated_size, size_t shared_key_size) :
589
0
            m_encapsulated_shared_key(encapsulated_size), m_shared_key(shared_key_size) {}
590
591
   private:
592
      std::vector<uint8_t> m_encapsulated_shared_key;
593
      secure_vector<uint8_t> m_shared_key;
594
};
595
596
/**
597
* Public Key Key Encapsulation Mechanism Encryption.
598
*/
599
class BOTAN_PUBLIC_API(2, 0) PK_KEM_Encryptor final {
600
   public:
601
      /**
602
      * Construct an instance.
603
      * @param key the key to encrypt to
604
      * @param kem_param additional KEM parameters
605
      * @param provider the provider to use
606
      */
607
      BOTAN_FUTURE_EXPLICIT PK_KEM_Encryptor(const Public_Key& key,
608
                                             std::string_view kem_param = "",
609
                                             std::string_view provider = "");
610
611
      /**
612
      * Construct an instance.
613
      * @param key the key to encrypt to
614
      * @param rng the RNG to use
615
      * @param kem_param additional KEM parameters
616
      * @param provider the provider to use
617
      */
618
      BOTAN_DEPRECATED("Use constructor that does not take RNG")
619
      PK_KEM_Encryptor(const Public_Key& key,
620
                       RandomNumberGenerator& rng,
621
                       std::string_view kem_param = "",
622
                       std::string_view provider = "");
623
624
      ~PK_KEM_Encryptor();
625
626
      PK_KEM_Encryptor(const PK_KEM_Encryptor&) = delete;
627
      PK_KEM_Encryptor& operator=(const PK_KEM_Encryptor&) = delete;
628
629
      PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept;
630
      PK_KEM_Encryptor& operator=(PK_KEM_Encryptor&&) noexcept;
631
632
      /**
633
      * Return the length of the shared key returned by this KEM
634
      *
635
      * If this KEM was used with a KDF, then it will always return
636
      * exactly the desired key length, because the output of the KEM
637
      * will be hashed by the KDF.
638
      *
639
      * However if the KEM was used with "Raw" kdf, to request the
640
      * algorithmic output of the KEM directly, then the desired key
641
      * length will be ignored and a bytestring that depends on the
642
      * algorithm is returned
643
      *
644
      * @param desired_shared_key_len is the requested length
645
      */
646
      size_t shared_key_length(size_t desired_shared_key_len) const;
647
648
      /**
649
      * Return the length in bytes of encapsulated keys returned by this KEM
650
      */
651
      size_t encapsulated_key_length() const;
652
653
      /**
654
      * Generate a shared key for data encryption.
655
      *
656
      * @param rng                    the RNG to use
657
      * @param desired_shared_key_len desired size of the shared key in bytes for the KDF
658
      *                               (ignored if no KDF is used)
659
      * @param salt                   a salt value used in the KDF
660
      *                               (ignored if no KDF is used)
661
      *
662
      * @returns a struct with both the shared secret and its encapsulation
663
      */
664
      KEM_Encapsulation encrypt(RandomNumberGenerator& rng,
665
                                size_t desired_shared_key_len = 32,
666
0
                                std::span<const uint8_t> salt = {}) {
667
0
         std::vector<uint8_t> encapsulated_shared_key(encapsulated_key_length());
668
0
         secure_vector<uint8_t> shared_key(shared_key_length(desired_shared_key_len));
669
670
0
         encrypt(std::span{encapsulated_shared_key}, std::span{shared_key}, rng, desired_shared_key_len, salt);
671
0
         return KEM_Encapsulation(std::move(encapsulated_shared_key), std::move(shared_key));
672
0
      }
673
674
      /**
675
      * Generate a shared key for data encryption.
676
      * @param out_encapsulated_key   the generated encapsulated key
677
      * @param out_shared_key         the generated shared key
678
      * @param rng                    the RNG to use
679
      * @param desired_shared_key_len desired size of the shared key in bytes
680
      *                               (ignored if no KDF is used)
681
      * @param salt                   a salt value used in the KDF
682
      *                               (ignored if no KDF is used)
683
      */
684
      void encrypt(secure_vector<uint8_t>& out_encapsulated_key,
685
                   secure_vector<uint8_t>& out_shared_key,
686
                   RandomNumberGenerator& rng,
687
                   size_t desired_shared_key_len = 32,
688
0
                   std::span<const uint8_t> salt = {}) {
689
0
         out_encapsulated_key.resize(encapsulated_key_length());
690
0
         out_shared_key.resize(shared_key_length(desired_shared_key_len));
691
0
         encrypt(std::span{out_encapsulated_key}, std::span{out_shared_key}, rng, desired_shared_key_len, salt);
692
0
      }
693
694
      /**
695
      * Generate a shared key for data encryption.
696
      * @param out_encapsulated_key   the generated encapsulated key
697
      * @param out_shared_key         the generated shared key
698
      * @param rng                    the RNG to use
699
      * @param desired_shared_key_len desired size of the shared key in bytes
700
      *                               (ignored if no KDF is used)
701
      * @param salt                   a salt value used in the KDF
702
      *                               (ignored if no KDF is used)
703
      */
704
      void encrypt(std::span<uint8_t> out_encapsulated_key,
705
                   std::span<uint8_t> out_shared_key,
706
                   RandomNumberGenerator& rng,
707
                   size_t desired_shared_key_len = 32,
708
                   std::span<const uint8_t> salt = {});
709
710
      BOTAN_DEPRECATED("use overload with salt as std::span<>")
711
      void encrypt(secure_vector<uint8_t>& out_encapsulated_key,
712
                   secure_vector<uint8_t>& out_shared_key,
713
                   size_t desired_shared_key_len,
714
                   RandomNumberGenerator& rng,
715
                   const uint8_t salt[],
716
0
                   size_t salt_len) {
717
0
         this->encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, {salt, salt_len});
718
0
      }
719
720
      BOTAN_DEPRECATED("use overload where rng comes after the out-parameters")
721
      void encrypt(secure_vector<uint8_t>& out_encapsulated_key,
722
                   secure_vector<uint8_t>& out_shared_key,
723
                   size_t desired_shared_key_len,
724
                   RandomNumberGenerator& rng,
725
0
                   std::span<const uint8_t> salt = {}) {
726
0
         out_encapsulated_key.resize(encapsulated_key_length());
727
0
         out_shared_key.resize(shared_key_length(desired_shared_key_len));
728
0
         encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
729
0
      }
730
731
   private:
732
      std::unique_ptr<PK_Ops::KEM_Encryption> m_op;
733
};
734
735
/**
736
* Public Key Key Encapsulation Mechanism Decryption.
737
*/
738
class BOTAN_PUBLIC_API(2, 0) PK_KEM_Decryptor final {
739
   public:
740
      /**
741
      * Construct an instance.
742
      * @param key the key to use inside the decryptor
743
      * @param rng the RNG to use
744
      * @param kem_param additional KEM parameters
745
      * @param provider the provider to use
746
      */
747
      PK_KEM_Decryptor(const Private_Key& key,
748
                       RandomNumberGenerator& rng,
749
                       std::string_view kem_param = "",
750
                       std::string_view provider = "");
751
752
      ~PK_KEM_Decryptor();
753
      PK_KEM_Decryptor(const PK_KEM_Decryptor&) = delete;
754
      PK_KEM_Decryptor& operator=(const PK_KEM_Decryptor&) = delete;
755
756
      PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept;
757
      PK_KEM_Decryptor& operator=(PK_KEM_Decryptor&&) noexcept;
758
759
      /**
760
      * Return the length of the shared key returned by this KEM
761
      *
762
      * If this KEM was used with a KDF, then it will always return
763
      * exactly the desired key length, because the output of the KEM
764
      * will be hashed by the KDF.
765
      *
766
      * However if the KEM was used with "Raw" kdf, to request the
767
      * algorithmic output of the KEM directly, then the desired key
768
      * length will be ignored and a bytestring that depends on the
769
      * algorithm is returned
770
      *
771
      * @param desired_shared_key_len is the requested length.
772
      */
773
      size_t shared_key_length(size_t desired_shared_key_len) const;
774
775
      /**
776
      * Return the length of the encapsulated key expected by this KEM
777
      */
778
      size_t encapsulated_key_length() const;
779
780
      /**
781
      * Decrypts the shared key for data encryption.
782
      *
783
      * @param out_shared_key         the generated shared key
784
      * @param encap_key              the encapsulated key
785
      * @param desired_shared_key_len desired size of the shared key in bytes
786
      *                               (ignored if no KDF is used)
787
      * @param salt                   a salt value used in the KDF
788
      *                               (ignored if no KDF is used)
789
      */
790
      void decrypt(std::span<uint8_t> out_shared_key,
791
                   std::span<const uint8_t> encap_key,
792
                   size_t desired_shared_key_len = 32,
793
                   std::span<const uint8_t> salt = {});
794
795
      /**
796
      * Decrypts the shared key for data encryption.
797
      *
798
      * @param encap_key              the encapsulated key
799
      * @param encap_key_len          size of the encapsulated key in bytes
800
      * @param desired_shared_key_len desired size of the shared key in bytes
801
      *                               (ignored if no KDF is used)
802
      * @param salt                   a salt value used in the KDF
803
      *                               (ignored if no KDF is used)
804
      * @param salt_len               size of the salt value in bytes
805
      *                               (ignored if no KDF is used)
806
      *
807
      * @return the shared data encryption key
808
      */
809
      secure_vector<uint8_t> decrypt(const uint8_t encap_key[],
810
                                     size_t encap_key_len,
811
                                     size_t desired_shared_key_len,
812
                                     const uint8_t salt[] = nullptr,
813
0
                                     size_t salt_len = 0) {
814
0
         secure_vector<uint8_t> shared_key(shared_key_length(desired_shared_key_len));
815
0
         decrypt(shared_key, {encap_key, encap_key_len}, desired_shared_key_len, {salt, salt_len});
816
0
         return shared_key;
817
0
      }
818
819
      /**
820
      * Decrypts the shared key for data encryption.
821
      *
822
      * @param encap_key              the encapsulated key
823
      * @param desired_shared_key_len desired size of the shared key in bytes
824
      *                               (ignored if no KDF is used)
825
      * @param salt                   a salt value used in the KDF
826
      *                               (ignored if no KDF is used)
827
      *
828
      * @return the shared data encryption key
829
      */
830
      secure_vector<uint8_t> decrypt(std::span<const uint8_t> encap_key,
831
                                     size_t desired_shared_key_len = 32,
832
0
                                     std::span<const uint8_t> salt = {}) {
833
0
         secure_vector<uint8_t> shared_key(shared_key_length(desired_shared_key_len));
834
0
         decrypt(shared_key, encap_key, desired_shared_key_len, salt);
835
0
         return shared_key;
836
0
      }
837
838
   private:
839
      std::unique_ptr<PK_Ops::KEM_Decryption> m_op;
840
};
841
842
}  // namespace Botan
843
844
#endif