Coverage Report

Created: 2020-11-21 08:34

/src/botan/build/include/botan/xmss.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * XMSS Keys
3
 * (C) 2016,2017 Matthias Gierlings
4
 * (C) 2019 René Korthaus, Rohde & Schwarz Cybersecurity
5
 *
6
 * Botan is released under the Simplified BSD License (see license.txt)
7
 **/
8
9
#ifndef BOTAN_XMSS_H_
10
#define BOTAN_XMSS_H_
11
12
#include <botan/pk_keys.h>
13
#include <botan/exceptn.h>
14
#include <botan/xmss_parameters.h>
15
#include <botan/xmss_wots.h>
16
17
namespace Botan {
18
19
class RandomNumberGenerator;
20
class XMSS_Verification_Operation;
21
22
/**
23
 * An XMSS: Extended Hash-Based Signature public key.
24
 *
25
 * [1] XMSS: Extended Hash-Based Signatures,
26
 *     Request for Comments: 8391
27
 *     Release: May 2018.
28
 *     https://datatracker.ietf.org/doc/rfc8391/
29
 **/
30
class BOTAN_PUBLIC_API(2,0) XMSS_PublicKey : public virtual Public_Key
31
   {
32
   public:
33
      /**
34
       * Creates a new XMSS public key for the chosen XMSS signature method.
35
       * New public and prf seeds are generated using rng. The appropriate WOTS
36
       * signature method will be automatically set based on the chosen XMSS
37
       * signature method.
38
       *
39
       * @param xmss_oid Identifier for the selected XMSS signature method.
40
       * @param rng A random number generator to use for key generation.
41
       **/
42
      XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,
43
                     RandomNumberGenerator& rng);
44
45
      /**
46
       * Loads a public key.
47
       *
48
       * Public key must be encoded as in RFC
49
       * draft-vangeest-x509-hash-sigs-03.
50
       *
51
       * @param key_bits DER encoded public key bits
52
       */
53
      XMSS_PublicKey(const std::vector<uint8_t>& key_bits);
54
55
      /**
56
       * Creates a new XMSS public key for a chosen XMSS signature method as
57
       * well as pre-computed root node and public_seed values.
58
       *
59
       * @param xmss_oid Identifier for the selected XMSS signature method.
60
       * @param root Root node value.
61
       * @param public_seed Public seed value.
62
       **/
63
      XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,
64
                     const secure_vector<uint8_t>& root,
65
                     const secure_vector<uint8_t>& public_seed)
66
         : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),
67
0
           m_root(root), m_public_seed(public_seed) {}
68
69
      /**
70
       * Creates a new XMSS public key for a chosen XMSS signature method as
71
       * well as pre-computed root node and public_seed values.
72
       *
73
       * @param xmss_oid Identifier for the selected XMSS signature method.
74
       * @param root Root node value.
75
       * @param public_seed Public seed value.
76
       **/
77
      XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,
78
                     secure_vector<uint8_t>&& root,
79
                     secure_vector<uint8_t>&& public_seed)
80
         : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),
81
0
           m_root(std::move(root)), m_public_seed(std::move(public_seed)) {}
82
83
      /**
84
       * Retrieves the chosen XMSS signature method.
85
       *
86
       * @return XMSS signature method identifier.
87
       **/
88
      XMSS_Parameters::xmss_algorithm_t xmss_oid() const
89
0
         {
90
0
         return m_xmss_params.oid();
91
0
         }
92
93
      /**
94
       * Sets the chosen XMSS signature method
95
       **/
96
      void set_xmss_oid(XMSS_Parameters::xmss_algorithm_t xmss_oid)
97
0
         {
98
0
         m_xmss_params = XMSS_Parameters(xmss_oid);
99
0
         m_wots_params = XMSS_WOTS_Parameters(m_xmss_params.ots_oid());
100
0
         }
101
102
      /**
103
       * Retrieves the XMSS parameters determined by the chosen XMSS Signature
104
       * method.
105
       *
106
       * @return XMSS parameters.
107
       **/
108
      const XMSS_Parameters& xmss_parameters() const
109
0
         {
110
0
         return m_xmss_params;
111
0
         }
112
113
      /**
114
       * Retrieves the XMSS parameters determined by the chosen XMSS Signature
115
       * method.
116
       *
117
       * @return XMSS parameters.
118
       **/
119
      std::string xmss_hash_function() const
120
0
         {
121
0
         return m_xmss_params.hash_function_name();
122
0
         }
123
124
      /**
125
       * Retrieves the Winternitz One Time Signature (WOTS) method,
126
       * corresponding to the chosen XMSS signature method.
127
       *
128
       * @return XMSS WOTS signature method identifier.
129
       **/
130
      XMSS_WOTS_Parameters::ots_algorithm_t wots_oid() const
131
0
         {
132
0
         return m_wots_params.oid();
133
0
         }
134
135
      /**
136
       * Retrieves the Winternitz One Time Signature (WOTS) parameters
137
       * corresponding to the chosen XMSS signature method.
138
       *
139
       * @return XMSS WOTS signature method parameters.
140
       **/
141
      const XMSS_WOTS_Parameters& wots_parameters() const
142
0
         {
143
0
         return m_wots_params;
144
0
         }
145
146
      secure_vector<uint8_t>& root()
147
0
         {
148
0
         return m_root;
149
0
         }
150
151
      void set_root(const secure_vector<uint8_t>& root)
152
0
         {
153
0
         m_root = root;
154
0
         }
155
156
      void set_root(secure_vector<uint8_t>&& root)
157
0
         {
158
0
         m_root = std::move(root);
159
0
         }
160
161
      const secure_vector<uint8_t>& root() const
162
0
         {
163
0
         return m_root;
164
0
         }
165
166
      virtual secure_vector<uint8_t>& public_seed()
167
0
         {
168
0
         return m_public_seed;
169
0
         }
170
171
      virtual void set_public_seed(const secure_vector<uint8_t>& public_seed)
172
0
         {
173
0
         m_public_seed = public_seed;
174
0
         }
175
176
      virtual void set_public_seed(secure_vector<uint8_t>&& public_seed)
177
0
         {
178
0
         m_public_seed = std::move(public_seed);
179
0
         }
180
181
      virtual const secure_vector<uint8_t>& public_seed() const
182
0
         {
183
0
         return m_public_seed;
184
0
         }
185
186
      std::string algo_name() const override
187
0
         {
188
0
         return "XMSS";
189
0
         }
190
191
      AlgorithmIdentifier algorithm_identifier() const override
192
0
         {
193
0
         return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_EMPTY_PARAM);
194
0
         }
195
196
      bool check_key(RandomNumberGenerator&, bool) const override
197
0
         {
198
0
         return true;
199
0
         }
200
201
      std::unique_ptr<PK_Ops::Verification>
202
      create_verification_op(const std::string&,
203
                             const std::string& provider) const override;
204
205
      size_t estimated_strength() const override
206
0
         {
207
0
         return m_xmss_params.estimated_strength();
208
0
         }
209
210
      size_t key_length() const override
211
0
         {
212
0
         return m_xmss_params.estimated_strength();
213
0
         }
214
215
      /**
216
       * Returns the encoded public key as defined in RFC
217
       * draft-vangeest-x509-hash-sigs-03.
218
       *
219
       * @return encoded public key bits
220
       **/
221
      std::vector<uint8_t> public_key_bits() const override;
222
223
      /**
224
       * Size in bytes of the serialized XMSS public key produced by
225
       * raw_public_key().
226
       *
227
       * @return size in bytes of serialized Public Key.
228
       **/
229
      virtual size_t size() const
230
0
         {
231
0
         return sizeof(uint32_t) + 2 * m_xmss_params.element_size();
232
0
         }
233
234
      /**
235
       * Generates a byte sequence representing the XMSS
236
       * public key, as defined in [1] (p. 23, "XMSS Public Key")
237
       *
238
       * @return 4-byte OID, followed by n-byte root node, followed by
239
       *         public seed.
240
       **/
241
      virtual std::vector<uint8_t> raw_public_key() const;
242
243
   protected:
244
      std::vector<uint8_t> m_raw_key;
245
      XMSS_Parameters m_xmss_params;
246
      XMSS_WOTS_Parameters m_wots_params;
247
      secure_vector<uint8_t> m_root;
248
      secure_vector<uint8_t> m_public_seed;
249
250
   private:
251
      XMSS_Parameters::xmss_algorithm_t deserialize_xmss_oid(
252
         const std::vector<uint8_t>& raw_key);
253
   };
254
255
template<typename> class Atomic;
256
257
class XMSS_Index_Registry;
258
259
/**
260
 * An XMSS: Extended Hash-Based Signature private key.
261
 * The XMSS private key does not support the X509 and PKCS7 standard. Instead
262
 * the raw format described in [1] is used.
263
 *
264
 * [1] XMSS: Extended Hash-Based Signatures,
265
 *     Request for Comments: 8391
266
 *     Release: May 2018.
267
 *     https://datatracker.ietf.org/doc/rfc8391/
268
 **/
269
class BOTAN_PUBLIC_API(2,0) XMSS_PrivateKey final : public virtual XMSS_PublicKey,
270
   public virtual Private_Key
271
   {
272
   public:
273
      /**
274
      * Creates a new XMSS private key for the chosen XMSS signature method.
275
      * New seeds for public/private key and pseudo random function input are
276
      * generated using the provided RNG. The appropriate WOTS signature method
277
      * will be automatically set based on the chosen XMSS signature method.
278
      *
279
      * @param xmss_algo_id Identifier for the selected XMSS signature method.
280
      * @param rng A random number generator to use for key generation.
281
      **/
282
      XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,
283
                      RandomNumberGenerator& rng);
284
285
      /**
286
       * Creates an XMSS_PrivateKey from a byte sequence produced by
287
       * raw_private_key().
288
       *
289
       * @param raw_key An XMSS private key serialized using raw_private_key().
290
       **/
291
      XMSS_PrivateKey(const secure_vector<uint8_t>& raw_key);
292
293
      /**
294
       * Creates a new XMSS private key for the chosen XMSS signature method
295
       * using precomputed seeds for public/private keys and pseudo random
296
       * function input. The appropriate WOTS signature method will be
297
       * automatically set, based on the chosen XMSS signature method.
298
       *
299
       * @param xmss_algo_id Identifier for the selected XMSS signature method.
300
       * @param idx_leaf Index of the next unused leaf.
301
       * @param wots_priv_seed A seed to generate a Winternitz-One-Time-
302
       *                      Signature private key from.
303
       * @param prf a secret n-byte key sourced from a secure source
304
       *        of uniformly random data.
305
       * @param root Root node of the binary hash tree.
306
       * @param public_seed The public seed.
307
       **/
308
      XMSS_PrivateKey(XMSS_Parameters::xmss_algorithm_t xmss_algo_id,
309
                      size_t idx_leaf,
310
                      const secure_vector<uint8_t>& wots_priv_seed,
311
                      const secure_vector<uint8_t>& prf,
312
                      const secure_vector<uint8_t>& root,
313
                      const secure_vector<uint8_t>& public_seed);
314
315
0
      bool stateful_operation() const override { return true; }
316
317
      /**
318
       * Retrieves the last unused leaf index of the private key. Reusing a leaf
319
       * by utilizing leaf indices lower than the last unused leaf index will
320
       * compromise security.
321
       *
322
       * @return Index of the last unused leaf.
323
       **/
324
      size_t unused_leaf_index() const;
325
326
      /**
327
       * Sets the last unused leaf index of the private key. The leaf index
328
       * will be updated automatically during every signing operation, and
329
       * should not be set manually.
330
       *
331
       * @param idx Index of the last unused leaf.
332
       **/
333
      void set_unused_leaf_index(size_t idx);
334
335
      size_t reserve_unused_leaf_index();
336
337
      /**
338
       * Winternitz One Time Signature Scheme key utilized for signing
339
       * operations.
340
       *
341
       * @return WOTS+ private key.
342
       **/
343
      const XMSS_WOTS_PrivateKey& wots_private_key() const
344
0
         {
345
0
         return m_wots_priv_key;
346
0
         }
347
348
      /**
349
       * Winternitz One Time Signature Scheme key utilized for signing
350
       * operations.
351
       *
352
       * @return WOTS+ private key.
353
       **/
354
      XMSS_WOTS_PrivateKey& wots_private_key()
355
0
         {
356
0
         return m_wots_priv_key;
357
0
         }
358
359
      const secure_vector<uint8_t>& prf() const
360
0
         {
361
0
         return m_prf;
362
0
         }
363
364
      secure_vector<uint8_t>& prf()
365
0
         {
366
0
         return m_prf;
367
0
         }
368
369
      void set_public_seed(
370
         const secure_vector<uint8_t>& public_seed) override
371
0
         {
372
0
         m_public_seed = public_seed;
373
0
         m_wots_priv_key.set_public_seed(public_seed);
374
0
         }
375
376
      void set_public_seed(secure_vector<uint8_t>&& public_seed) override
377
0
         {
378
0
         m_public_seed = std::move(public_seed);
379
0
         m_wots_priv_key.set_public_seed(m_public_seed);
380
0
         }
381
382
      const secure_vector<uint8_t>& public_seed() const override
383
0
         {
384
0
         return m_public_seed;
385
0
         }
386
387
      std::unique_ptr<PK_Ops::Signature>
388
      create_signature_op(RandomNumberGenerator&,
389
                          const std::string&,
390
                          const std::string& provider) const override;
391
392
      secure_vector<uint8_t> private_key_bits() const override;
393
394
      size_t size() const override
395
0
         {
396
0
         return XMSS_PublicKey::size() +
397
0
                sizeof(uint32_t) +
398
0
                2 * XMSS_PublicKey::m_xmss_params.element_size();
399
0
         }
400
401
      /**
402
       * Generates a non standartized byte sequence representing the XMSS
403
       * private key.
404
       *
405
       * @return byte sequence consisting of the following elements in order:
406
       *         4-byte OID, n-byte root node, n-byte public seed,
407
       *         8-byte unused leaf index, n-byte prf seed, n-byte private seed.
408
       **/
409
      secure_vector<uint8_t> raw_private_key() const;
410
      /**
411
       * Algorithm 9: "treeHash"
412
       * Computes the internal n-byte nodes of a Merkle tree.
413
       *
414
       * @param start_idx The start index.
415
       * @param target_node_height Height of the target node.
416
       * @param adrs Address of the tree containing the target node.
417
       *
418
       * @return The root node of a tree of height target_node height with the
419
       *         leftmost leaf being the hash of the WOTS+ pk with index
420
       *         start_idx.
421
       **/
422
      secure_vector<uint8_t> tree_hash(
423
         size_t start_idx,
424
         size_t target_node_height,
425
         XMSS_Address& adrs);
426
427
   private:
428
      /**
429
       * Fetches shared unused leaf index from the index registry
430
       **/
431
      std::shared_ptr<Atomic<size_t>> recover_global_leaf_index() const;
432
433
      inline void tree_hash_subtree(secure_vector<uint8_t>& result,
434
                                    size_t start_idx,
435
                                    size_t target_node_height,
436
                                    XMSS_Address& adrs)
437
0
         {
438
0
         return tree_hash_subtree(result, start_idx, target_node_height, adrs, m_hash);
439
0
         }
440
441
442
      /**
443
       * Helper for multithreaded tree hashing.
444
       */
445
      void tree_hash_subtree(secure_vector<uint8_t>& result,
446
                             size_t start_idx,
447
                             size_t target_node_height,
448
                             XMSS_Address& adrs,
449
                             XMSS_Hash& hash);
450
451
      XMSS_WOTS_PrivateKey m_wots_priv_key;
452
      XMSS_Hash m_hash;
453
      secure_vector<uint8_t> m_prf;
454
      XMSS_Index_Registry& m_index_reg;
455
   };
456
457
}
458
459
#endif