Coverage Report

Created: 2023-09-25 06:34

/src/botan/build/include/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
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
0
      std::vector<uint8_t> encrypt(std::span<const uint8_t> in, RandomNumberGenerator& rng) const {
47
0
         return enc(in.data(), in.size(), rng);
48
0
      }
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
0
      PK_Encryptor() = default;
62
0
      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 "EMSA_PKCS1(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
603
      std::vector<uint8_t> sign_message(const uint8_t in[], size_t length, RandomNumberGenerator& rng) {
186
603
         this->update(in, length);
187
603
         return this->signature(rng);
188
603
      }
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
603
      std::vector<uint8_t> sign_message(std::span<const uint8_t> in, RandomNumberGenerator& rng) {
197
603
         return sign_message(in.data(), in.size(), rng);
198
603
      }
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
0
      void update(std::string_view in) { update(cast_char_ptr_to_uint8(in.data()), in.size()); }
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
      size_t m_parts, m_part_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 "EMSA_PKCS1(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
883
      bool verify_message(std::span<const uint8_t> msg, std::span<const uint8_t> sig) {
325
883
         return verify_message(msg.data(), msg.size(), sig.data(), sig.size());
326
883
      }
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
340
      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
0
      void update(std::string_view in) { update(cast_char_ptr_to_uint8(in.data()), in.size()); }
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
340
      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
      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
      size_t m_parts, m_part_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 in the other parties key
422
      * @param in_len the length of in in bytes
423
      * @param params extra derivation params
424
      * @param params_len the length of params in bytes
425
      */
426
      SymmetricKey derive_key(
427
         size_t key_len, const uint8_t in[], size_t in_len, const uint8_t params[], size_t params_len) const;
428
429
      /**
430
      * Perform Key Agreement Operation
431
      * @param key_len the desired key output size (ignored if "Raw" KDF is used)
432
      * @param in the other parties key
433
      * @param params extra derivation params
434
      * @param params_len the length of params in bytes
435
      */
436
      SymmetricKey derive_key(size_t key_len,
437
                              std::span<const uint8_t> in,
438
                              const uint8_t params[],
439
0
                              size_t params_len) const {
440
0
         return derive_key(key_len, in.data(), in.size(), params, params_len);
441
0
      }
442
443
      /**
444
      * Perform Key Agreement Operation
445
      * @param key_len the desired key output size (ignored if "Raw" KDF is used)
446
      * @param in the other parties key
447
      * @param in_len the length of in in bytes
448
      * @param params extra derivation params
449
      */
450
0
      SymmetricKey derive_key(size_t key_len, const uint8_t in[], size_t in_len, std::string_view params = "") const {
451
0
         return derive_key(key_len, in, in_len, cast_char_ptr_to_uint8(params.data()), params.length());
452
0
      }
453
454
      /**
455
      * Perform Key Agreement Operation
456
      * @param key_len the desired key output size (ignored if "Raw" KDF is used)
457
      * @param in the other parties key
458
      * @param params extra derivation params
459
      */
460
86
      SymmetricKey derive_key(size_t key_len, const std::span<const uint8_t> in, std::string_view params = "") const {
461
86
         return derive_key(key_len, in.data(), in.size(), cast_char_ptr_to_uint8(params.data()), params.length());
462
86
      }
463
464
      /**
465
      * Return the underlying size of the value that is agreed.
466
      * If derive_key is called with a length of 0 with a "Raw"
467
      * KDF, it will return a value of this size.
468
      */
469
      size_t agreed_value_size() const;
470
471
   private:
472
      std::unique_ptr<PK_Ops::Key_Agreement> m_op;
473
};
474
475
/**
476
* Encryption using a standard message recovery algorithm like RSA or
477
* ElGamal, paired with an encoding scheme like OAEP.
478
*/
479
class BOTAN_PUBLIC_API(2, 0) PK_Encryptor_EME final : public PK_Encryptor {
480
   public:
481
      size_t maximum_input_size() const override;
482
483
      /**
484
      * Construct an instance.
485
      * @param key the key to use inside the encryptor
486
      * @param rng the RNG to use
487
      * @param padding the message encoding scheme to use (eg "OAEP(SHA-256)")
488
      * @param provider the provider to use
489
      */
490
      PK_Encryptor_EME(const Public_Key& key,
491
                       RandomNumberGenerator& rng,
492
                       std::string_view padding,
493
                       std::string_view provider = "");
494
495
      ~PK_Encryptor_EME() override;
496
497
      PK_Encryptor_EME(const PK_Encryptor_EME&) = delete;
498
      PK_Encryptor_EME& operator=(const PK_Encryptor_EME&) = delete;
499
500
      PK_Encryptor_EME(PK_Encryptor_EME&&) noexcept;
501
      PK_Encryptor_EME& operator=(PK_Encryptor_EME&&) noexcept;
502
503
      /**
504
      * Return an upper bound on the ciphertext length for a particular
505
      * plaintext input length
506
      */
507
      size_t ciphertext_length(size_t ptext_len) const override;
508
509
   private:
510
      std::vector<uint8_t> enc(const uint8_t[], size_t, RandomNumberGenerator& rng) const override;
511
512
      std::unique_ptr<PK_Ops::Encryption> m_op;
513
};
514
515
/**
516
* Decryption with an MR algorithm and an EME.
517
*/
518
class BOTAN_PUBLIC_API(2, 0) PK_Decryptor_EME final : public PK_Decryptor {
519
   public:
520
      /**
521
      * Construct an instance.
522
      * @param key the key to use inside the decryptor
523
      * @param rng the random generator to use
524
      * @param eme the EME to use
525
      * @param provider the provider to use
526
      */
527
      PK_Decryptor_EME(const Private_Key& key,
528
                       RandomNumberGenerator& rng,
529
                       std::string_view eme,
530
                       std::string_view provider = "");
531
532
      size_t plaintext_length(size_t ptext_len) const override;
533
534
      ~PK_Decryptor_EME() override;
535
536
      PK_Decryptor_EME(const PK_Decryptor_EME&) = delete;
537
      PK_Decryptor_EME& operator=(const PK_Decryptor_EME&) = delete;
538
539
      PK_Decryptor_EME(PK_Decryptor_EME&&) noexcept;
540
      PK_Decryptor_EME& operator=(PK_Decryptor_EME&&) noexcept;
541
542
   private:
543
      secure_vector<uint8_t> do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const override;
544
545
      std::unique_ptr<PK_Ops::Decryption> m_op;
546
};
547
548
/**
549
   * Result of a key encapsulation operation.
550
   */
551
class KEM_Encapsulation final {
552
   public:
553
      KEM_Encapsulation(std::vector<uint8_t> encapsulated_shared_key, secure_vector<uint8_t> shared_key) :
554
0
            m_encapsulated_shared_key(std::move(encapsulated_shared_key)), m_shared_key(std::move(shared_key)) {}
555
556
      /**
557
         * @returns the encapsulated shared secret (encrypted with the public key)
558
         */
559
0
      const std::vector<uint8_t>& encapsulated_shared_key() const { return m_encapsulated_shared_key; }
560
561
      /**
562
         * @returns the plaintext shared secret
563
         */
564
0
      const secure_vector<uint8_t>& shared_key() const { return m_shared_key; }
565
566
   private:
567
      friend class PK_KEM_Encryptor;
568
569
      KEM_Encapsulation(size_t encapsulated_size, size_t shared_key_size) :
570
0
            m_encapsulated_shared_key(encapsulated_size), m_shared_key(shared_key_size) {}
571
572
0
      std::vector<uint8_t>& encapsulated_shared_key() { return m_encapsulated_shared_key; }
573
574
0
      secure_vector<uint8_t>& shared_key() { return m_shared_key; }
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
603
      PK_KEM_Encryptor(const Public_Key& key,
604
                       RandomNumberGenerator& rng,
605
                       std::string_view kem_param = "",
606
                       std::string_view provider = "") :
607
0
            PK_KEM_Encryptor(key, kem_param, provider) {
608
0
         BOTAN_UNUSED(rng);
609
0
      }
610
611
      ~PK_KEM_Encryptor();
612
613
      PK_KEM_Encryptor(const PK_KEM_Encryptor&) = delete;
614
      PK_KEM_Encryptor& operator=(const PK_KEM_Encryptor&) = delete;
615
616
      PK_KEM_Encryptor(PK_KEM_Encryptor&&) noexcept;
617
      PK_KEM_Encryptor& operator=(PK_KEM_Encryptor&&) noexcept;
618
619
      /**
620
      * Return the length of the shared key returned by this KEM
621
      *
622
      * If this KEM was used with a KDF, then it will always return
623
      * exactly the desired key length, because the output of the KEM
624
      * will be hashed by the KDF.
625
      *
626
      * However if the KEM was used with "Raw" kdf, to request the
627
      * algorithmic output of the KEM directly, then the desired key
628
      * length will be ignored and a bytestring that depends on the
629
      * algorithm is returned
630
      *
631
      * @param desired_shared_key_len is the requested length
632
      */
633
      size_t shared_key_length(size_t desired_shared_key_len) const;
634
635
      /**
636
      * Return the length in bytes of encapsulated keys returned by this KEM
637
      */
638
      size_t encapsulated_key_length() const;
639
640
      /**
641
      * Generate a shared key for data encryption.
642
      *
643
      * @param rng                    the RNG to use
644
      * @param desired_shared_key_len desired size of the shared key in bytes for the KDF
645
      *                               (ignored if no KDF is used)
646
      * @param salt                   a salt value used in the KDF
647
      *                               (ignored if no KDF is used)
648
      *
649
      * @returns a struct with both the shared secret and its encapsulation
650
      */
651
      KEM_Encapsulation encrypt(RandomNumberGenerator& rng,
652
                                size_t desired_shared_key_len = 32,
653
0
                                std::span<const uint8_t> salt = {}) {
654
0
         KEM_Encapsulation result(encapsulated_key_length(), shared_key_length(desired_shared_key_len));
655
0
         encrypt(std::span{result.encapsulated_shared_key()},
656
0
                 std::span{result.shared_key()},
657
0
                 rng,
658
0
                 desired_shared_key_len,
659
0
                 salt);
660
0
         return result;
661
0
      }
662
663
      /**
664
      * Generate a shared key for data encryption.
665
      * @param out_encapsulated_key   the generated encapsulated key
666
      * @param out_shared_key         the generated shared key
667
      * @param rng                    the RNG to use
668
      * @param desired_shared_key_len desired size of the shared key in bytes
669
      *                               (ignored if no KDF is used)
670
      * @param salt                   a salt value used in the KDF
671
      *                               (ignored if no KDF is used)
672
      */
673
      void encrypt(secure_vector<uint8_t>& out_encapsulated_key,
674
                   secure_vector<uint8_t>& out_shared_key,
675
                   RandomNumberGenerator& rng,
676
                   size_t desired_shared_key_len = 32,
677
0
                   std::span<const uint8_t> salt = {}) {
678
0
         out_encapsulated_key.resize(encapsulated_key_length());
679
0
         out_shared_key.resize(shared_key_length(desired_shared_key_len));
680
0
         encrypt(std::span{out_encapsulated_key}, std::span{out_shared_key}, rng, desired_shared_key_len, salt);
681
0
      }
682
683
      /**
684
      * Generate a shared key for data encryption.
685
      * @param out_encapsulated_key   the generated encapsulated key
686
      * @param out_shared_key         the generated shared key
687
      * @param rng                    the RNG to use
688
      * @param desired_shared_key_len desired size of the shared key in bytes
689
      *                               (ignored if no KDF is used)
690
      * @param salt                   a salt value used in the KDF
691
      *                               (ignored if no KDF is used)
692
      */
693
      void encrypt(std::span<uint8_t> out_encapsulated_key,
694
                   std::span<uint8_t> out_shared_key,
695
                   RandomNumberGenerator& rng,
696
                   size_t desired_shared_key_len = 32,
697
                   std::span<const uint8_t> salt = {});
698
699
      BOTAN_DEPRECATED("use overload with salt as std::span<>")
700
701
      void encrypt(secure_vector<uint8_t>& out_encapsulated_key,
702
                   secure_vector<uint8_t>& out_shared_key,
703
                   size_t desired_shared_key_len,
704
                   RandomNumberGenerator& rng,
705
                   const uint8_t salt[],
706
0
                   size_t salt_len) {
707
0
         this->encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, {salt, salt_len});
708
0
      }
709
710
      BOTAN_DEPRECATED("use overload where rng comes after the out-paramters")
711
712
      void encrypt(secure_vector<uint8_t>& out_encapsulated_key,
713
                   secure_vector<uint8_t>& out_shared_key,
714
                   size_t desired_shared_key_len,
715
                   RandomNumberGenerator& rng,
716
0
                   std::span<const uint8_t> salt = {}) {
717
0
         out_encapsulated_key.resize(encapsulated_key_length());
718
0
         out_shared_key.resize(shared_key_length(desired_shared_key_len));
719
0
         encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
720
0
      }
721
722
   private:
723
      std::unique_ptr<PK_Ops::KEM_Encryption> m_op;
724
};
725
726
/**
727
* Public Key Key Encapsulation Mechanism Decryption.
728
*/
729
class BOTAN_PUBLIC_API(2, 0) PK_KEM_Decryptor final {
730
   public:
731
      /**
732
      * Construct an instance.
733
      * @param key the key to use inside the decryptor
734
      * @param rng the RNG to use
735
      * @param kem_param additional KEM parameters
736
      * @param provider the provider to use
737
      */
738
      PK_KEM_Decryptor(const Private_Key& key,
739
                       RandomNumberGenerator& rng,
740
                       std::string_view kem_param = "",
741
                       std::string_view provider = "");
742
743
      ~PK_KEM_Decryptor();
744
      PK_KEM_Decryptor(const PK_KEM_Decryptor&) = delete;
745
      PK_KEM_Decryptor& operator=(const PK_KEM_Decryptor&) = delete;
746
747
      PK_KEM_Decryptor(PK_KEM_Decryptor&&) noexcept;
748
      PK_KEM_Decryptor& operator=(PK_KEM_Decryptor&&) noexcept;
749
750
      /**
751
      * Return the length of the shared key returned by this KEM
752
      *
753
      * If this KEM was used with a KDF, then it will always return
754
      * exactly the desired key length, because the output of the KEM
755
      * will be hashed by the KDF.
756
      *
757
      * However if the KEM was used with "Raw" kdf, to request the
758
      * algorithmic output of the KEM directly, then the desired key
759
      * length will be ignored and a bytestring that depends on the
760
      * algorithm is returned
761
      *
762
      * @param desired_shared_key_len is the requested length.
763
      */
764
      size_t shared_key_length(size_t desired_shared_key_len) const;
765
766
      /**
767
      * Return the length of the encapsulated key expected by this KEM
768
      */
769
      size_t encapsulated_key_length() const;
770
771
      /**
772
      * Decrypts the shared key for data encryption.
773
      *
774
      * @param out_shared_key         the generated shared key
775
      * @param encap_key              the encapsulated key
776
      * @param desired_shared_key_len desired size of the shared key in bytes
777
      *                               (ignored if no KDF is used)
778
      * @param salt                   a salt value used in the KDF
779
      *                               (ignored if no KDF is used)
780
      */
781
      void decrypt(std::span<uint8_t> out_shared_key,
782
                   std::span<const uint8_t> encap_key,
783
                   size_t desired_shared_key_len = 32,
784
                   std::span<const uint8_t> salt = {});
785
786
      /**
787
      * Decrypts the shared key for data encryption.
788
      *
789
      * @param encap_key              the encapsulated key
790
      * @param encap_key_len          size of the encapsulated key in bytes
791
      * @param desired_shared_key_len desired size of the shared key in bytes
792
      *                               (ignored if no KDF is used)
793
      * @param salt                   a salt value used in the KDF
794
      *                               (ignored if no KDF is used)
795
      * @param salt_len               size of the salt value in bytes
796
      *                               (ignored if no KDF is used)
797
      *
798
      * @return the shared data encryption key
799
      */
800
      secure_vector<uint8_t> decrypt(const uint8_t encap_key[],
801
                                     size_t encap_key_len,
802
                                     size_t desired_shared_key_len,
803
                                     const uint8_t salt[] = nullptr,
804
0
                                     size_t salt_len = 0) {
805
0
         secure_vector<uint8_t> shared_key(shared_key_length(desired_shared_key_len));
806
0
         decrypt(shared_key, {encap_key, encap_key_len}, desired_shared_key_len, {salt, salt_len});
807
0
         return shared_key;
808
0
      }
809
810
      /**
811
      * Decrypts the shared key for data encryption.
812
      *
813
      * @param encap_key              the encapsulated key
814
      * @param desired_shared_key_len desired size of the shared key in bytes
815
      *                               (ignored if no KDF is used)
816
      * @param salt                   a salt value used in the KDF
817
      *                               (ignored if no KDF is used)
818
      *
819
      * @return the shared data encryption key
820
      */
821
      secure_vector<uint8_t> decrypt(std::span<const uint8_t> encap_key,
822
                                     size_t desired_shared_key_len = 32,
823
0
                                     std::span<const uint8_t> salt = {}) {
824
0
         secure_vector<uint8_t> shared_key(shared_key_length(desired_shared_key_len));
825
0
         decrypt(shared_key, encap_key, desired_shared_key_len, salt);
826
0
         return shared_key;
827
0
      }
828
829
   private:
830
      std::unique_ptr<PK_Ops::KEM_Decryption> m_op;
831
};
832
833
}  // namespace Botan
834
835
#endif