Coverage Report

Created: 2024-06-28 06:19

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