Botan 2.19.5 Crypto and TLS for C&

xmss.h
Go to the documentation of this file.
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 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 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 {
90 return m_xmss_params.oid();
91 }
92
93 /**
94 * Sets the chosen XMSS signature method
95 **/
96 void set_xmss_oid(XMSS_Parameters::xmss_algorithm_t xmss_oid)
97 {
98 m_xmss_params = XMSS_Parameters(xmss_oid);
99 m_wots_params = XMSS_WOTS_Parameters(m_xmss_params.ots_oid());
100 }
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 {
110 return m_xmss_params;
111 }
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 {
121 return m_xmss_params.hash_function_name();
122 }
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 {
132 return m_wots_params.oid();
133 }
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 {
143 return m_wots_params;
144 }
145
146 secure_vector<uint8_t>& root()
147 {
148 return m_root;
149 }
150
151 void set_root(const secure_vector<uint8_t>& root)
152 {
153 m_root = root;
154 }
155
156 void set_root(secure_vector<uint8_t>&& root)
157 {
158 m_root = std::move(root);
159 }
160
161 const secure_vector<uint8_t>& root() const
162 {
163 return m_root;
164 }
165
166 virtual secure_vector<uint8_t>& public_seed()
167 {
168 return m_public_seed;
169 }
170
171 virtual void set_public_seed(const secure_vector<uint8_t>& public_seed)
172 {
173 m_public_seed = public_seed;
174 }
175
176 virtual void set_public_seed(secure_vector<uint8_t>&& public_seed)
177 {
178 m_public_seed = std::move(public_seed);
179 }
180
181 virtual const secure_vector<uint8_t>& public_seed() const
182 {
183 return m_public_seed;
184 }
185
186 std::string algo_name() const override
187 {
188 return "XMSS";
189 }
190
191 AlgorithmIdentifier algorithm_identifier() const override
192 {
193 return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_EMPTY_PARAM);
194 }
195
196 bool check_key(RandomNumberGenerator&, bool) const override
197 {
198 return true;
199 }
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 {
207 return m_xmss_params.estimated_strength();
208 }
209
210 size_t key_length() const override
211 {
212 return m_xmss_params.estimated_strength();
213 }
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 {
231 return sizeof(uint32_t) + 2 * m_xmss_params.element_size();
232 }
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 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 {
345 return m_wots_priv_key;
346 }
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 {
356 return m_wots_priv_key;
357 }
358
359 const secure_vector<uint8_t>& prf() const
360 {
361 return m_prf;
362 }
363
364 secure_vector<uint8_t>& prf()
365 {
366 return m_prf;
367 }
368
369 void set_public_seed(
370 const secure_vector<uint8_t>& public_seed) override
371 {
372 m_public_seed = public_seed;
373 m_wots_priv_key.set_public_seed(public_seed);
374 }
375
376 void set_public_seed(secure_vector<uint8_t>&& public_seed) override
377 {
378 m_public_seed = std::move(public_seed);
379 m_wots_priv_key.set_public_seed(m_public_seed);
380 }
381
382 const secure_vector<uint8_t>& public_seed() const override
383 {
384 return m_public_seed;
385 }
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 {
396 return XMSS_PublicKey::size() +
397 sizeof(uint32_t) +
398 2 * XMSS_PublicKey::m_xmss_params.element_size();
399 }
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 {
438 return tree_hash_subtree(result, start_idx, target_node_height, adrs, m_hash);
439 }
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
Botan::AlgorithmIdentifier
Definition: asn1_obj.h:430
Botan::AlgorithmIdentifier::USE_EMPTY_PARAM
@ USE_EMPTY_PARAM
Definition: asn1_obj.h:432
Botan::Atomic
Definition: atomic.h:27
Botan::Private_Key
Definition: pk_keys.h:181
Botan::Public_Key
Definition: pk_keys.h:29
Botan::RandomNumberGenerator
Definition: rng.h:26
Botan::XMSS_Address
Definition: xmss_address.h:22
Botan::XMSS_Index_Registry
Definition: xmss_index_registry.h:26
Botan::XMSS_Parameters
Definition: xmss_parameters.h:24
Botan::XMSS_Parameters::xmss_algorithm_t
xmss_algorithm_t
Definition: xmss_parameters.h:27
Botan::XMSS_PrivateKey
Definition: xmss.h:271
Botan::XMSS_PrivateKey::public_seed
const secure_vector< uint8_t > & public_seed() const override
Definition: xmss.h:382
Botan::XMSS_PrivateKey::stateful_operation
bool stateful_operation() const override
Definition: xmss.h:315
Botan::XMSS_PrivateKey::size
size_t size() const override
Definition: xmss.h:394
Botan::XMSS_PrivateKey::prf
secure_vector< uint8_t > & prf()
Definition: xmss.h:364
Botan::XMSS_PrivateKey::wots_private_key
XMSS_WOTS_PrivateKey & wots_private_key()
Definition: xmss.h:354
Botan::XMSS_PrivateKey::set_public_seed
void set_public_seed(secure_vector< uint8_t > &&public_seed) override
Definition: xmss.h:376
Botan::XMSS_PrivateKey::wots_private_key
const XMSS_WOTS_PrivateKey & wots_private_key() const
Definition: xmss.h:343
Botan::XMSS_PrivateKey::prf
const secure_vector< uint8_t > & prf() const
Definition: xmss.h:359
Botan::XMSS_PrivateKey::set_public_seed
void set_public_seed(const secure_vector< uint8_t > &public_seed) override
Definition: xmss.h:369
Botan::XMSS_PublicKey
Definition: xmss.h:31
Botan::XMSS_PublicKey::root
const secure_vector< uint8_t > & root() const
Definition: xmss.h:161
Botan::XMSS_PublicKey::m_root
secure_vector< uint8_t > m_root
Definition: xmss.h:247
Botan::XMSS_PublicKey::wots_parameters
const XMSS_WOTS_Parameters & wots_parameters() const
Definition: xmss.h:141
Botan::XMSS_PublicKey::xmss_hash_function
std::string xmss_hash_function() const
Definition: xmss.h:119
Botan::XMSS_PublicKey::wots_oid
XMSS_WOTS_Parameters::ots_algorithm_t wots_oid() const
Definition: xmss.h:130
Botan::XMSS_PublicKey::set_root
void set_root(secure_vector< uint8_t > &&root)
Definition: xmss.h:156
Botan::XMSS_PublicKey::m_public_seed
secure_vector< uint8_t > m_public_seed
Definition: xmss.h:248
Botan::XMSS_PublicKey::xmss_parameters
const XMSS_Parameters & xmss_parameters() const
Definition: xmss.h:108
Botan::XMSS_PublicKey::set_public_seed
virtual void set_public_seed(secure_vector< uint8_t > &&public_seed)
Definition: xmss.h:176
Botan::XMSS_PublicKey::set_root
void set_root(const secure_vector< uint8_t > &root)
Definition: xmss.h:151
Botan::XMSS_PublicKey::m_xmss_params
XMSS_Parameters m_xmss_params
Definition: xmss.h:245
Botan::XMSS_PublicKey::set_public_seed
virtual void set_public_seed(const secure_vector< uint8_t > &public_seed)
Definition: xmss.h:171
Botan::XMSS_PublicKey::m_raw_key
std::vector< uint8_t > m_raw_key
Definition: xmss.h:244
Botan::XMSS_PublicKey::public_seed
virtual const secure_vector< uint8_t > & public_seed() const
Definition: xmss.h:181
Botan::XMSS_PublicKey::set_xmss_oid
void set_xmss_oid(XMSS_Parameters::xmss_algorithm_t xmss_oid)
Definition: xmss.h:96
Botan::XMSS_PublicKey::XMSS_PublicKey
XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid, secure_vector< uint8_t > &&root, secure_vector< uint8_t > &&public_seed)
Definition: xmss.h:77
Botan::XMSS_PublicKey::xmss_oid
XMSS_Parameters::xmss_algorithm_t xmss_oid() const
Definition: xmss.h:88
Botan::XMSS_PublicKey::estimated_strength
size_t estimated_strength() const override
Definition: xmss.h:205
Botan::XMSS_PublicKey::key_length
size_t key_length() const override
Definition: xmss.h:210
Botan::XMSS_PublicKey::m_wots_params
XMSS_WOTS_Parameters m_wots_params
Definition: xmss.h:246
Botan::XMSS_PublicKey::public_seed
virtual secure_vector< uint8_t > & public_seed()
Definition: xmss.h:166
Botan::XMSS_PublicKey::algo_name
std::string algo_name() const override
Definition: xmss.h:186
Botan::XMSS_PublicKey::algorithm_identifier
AlgorithmIdentifier algorithm_identifier() const override
Definition: xmss.h:191
Botan::XMSS_PublicKey::root
secure_vector< uint8_t > & root()
Definition: xmss.h:146
Botan::XMSS_PublicKey::size
virtual size_t size() const
Definition: xmss.h:229
Botan::XMSS_PublicKey::check_key
bool check_key(RandomNumberGenerator &, bool) const override
Definition: xmss.h:196
Botan::XMSS_PublicKey::XMSS_PublicKey
XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid, const secure_vector< uint8_t > &root, const secure_vector< uint8_t > &public_seed)
Definition: xmss.h:63
Botan::XMSS_WOTS_Parameters
Definition: xmss_wots.h:33
Botan::XMSS_WOTS_Parameters::ots_algorithm_t
ots_algorithm_t
Definition: xmss_wots.h:36
Botan::XMSS_WOTS_PrivateKey
Definition: xmss_wots.h:457
final
int(* final)(unsigned char *, CTX *)
Definition: commoncrypto_hash.cpp:29
BOTAN_PUBLIC_API
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
Botan
Definition: alg_id.cpp:13
Botan::secure_vector
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
std
Definition: bigint.h:1155
hash
MechanismType hash
Definition: p11_mechanism.cpp:64