Botan 3.6.1
Crypto and TLS for C&
hss_lms.cpp
Go to the documentation of this file.
1/**
2* HSS-LMS
3* (C) 2023 Jack Lloyd
4* 2023 Fabian Albert, René Meusel, Amos Treiber - Rohde & Schwarz Cybersecurity
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/hss_lms.h>
10
11#include <botan/rng.h>
12#include <botan/internal/hss.h>
13#include <botan/internal/pk_ops_impl.h>
14
15namespace Botan {
16
17HSS_LMS_PublicKey::HSS_LMS_PublicKey(std::span<const uint8_t> pub_key) :
18 m_public(HSS_LMS_PublicKeyInternal::from_bytes_or_throw(pub_key)) {}
19
21
23 return m_public->size();
24}
25
27 // draft-fluhrer-lms-more-parm-sets-11 Section 9.
28 // As shown in [Katz16], if we assume that the hash function can be
29 // modeled as a random oracle, then the security of the system is at
30 // least 8N-1 bits (where N is the size of the hash output in bytes);
31 return 8 * m_public->lms_pub_key().lms_params().m() - 1;
32}
33
34std::string HSS_LMS_PublicKey::algo_name() const {
35 return m_public->algo_name();
36}
37
39 return m_public->algorithm_identifier();
40}
41
43 return m_public->object_identifier();
44}
45
47 // Nothing to check. Only useful checks are already done during parsing.
48 return true;
49}
50
51std::vector<uint8_t> HSS_LMS_PublicKey::raw_public_key_bits() const {
52 return m_public->to_bytes();
53}
54
55std::vector<uint8_t> HSS_LMS_PublicKey::public_key_bits() const {
56 // The raw encoding of HSS/LMS public keys always contains the necessary
57 // algorithm information.
58 return raw_public_key_bits();
59}
60
61class HSS_LMS_Verification_Operation final : public PK_Ops::Verification {
62 public:
63 HSS_LMS_Verification_Operation(std::shared_ptr<HSS_LMS_PublicKeyInternal> pub_key) :
64 m_public(std::move(pub_key)) {}
65
66 void update(std::span<const uint8_t> msg) override {
67 m_msg_buffer.insert(m_msg_buffer.end(), msg.begin(), msg.end());
68 }
69
70 bool is_valid_signature(std::span<const uint8_t> sig) override {
71 std::vector<uint8_t> message_to_verify = std::exchange(m_msg_buffer, {});
72 try {
73 const auto signature = HSS_Signature::from_bytes_or_throw(sig);
74 return m_public->verify_signature(message_to_verify, signature);
75 } catch(const Decoding_Error&) {
76 // Signature could not be decoded
77 return false;
78 }
79 }
80
81 std::string hash_function() const override { return m_public->lms_pub_key().lms_params().hash_name(); }
82
83 private:
84 std::shared_ptr<HSS_LMS_PublicKeyInternal> m_public;
85 std::vector<uint8_t> m_msg_buffer;
86};
87
88std::unique_ptr<PK_Ops::Verification> HSS_LMS_PublicKey::create_verification_op(std::string_view /*params*/,
89 std::string_view provider) const {
90 if(provider.empty() || provider == "base") {
91 return std::make_unique<HSS_LMS_Verification_Operation>(m_public);
92 }
93 throw Provider_Not_Found(algo_name(), provider);
94}
95
96std::unique_ptr<PK_Ops::Verification> HSS_LMS_PublicKey::create_x509_verification_op(
97 const AlgorithmIdentifier& signature_algorithm, std::string_view provider) const {
98 if(provider.empty() || provider == "base") {
99 if(signature_algorithm != this->algorithm_identifier()) {
100 throw Decoding_Error("Unexpected AlgorithmIdentifier for HSS-LMS signature");
101 }
102 return std::make_unique<HSS_LMS_Verification_Operation>(m_public);
103 }
104 throw Provider_Not_Found(algo_name(), provider);
105}
106
110
111std::unique_ptr<Private_Key> HSS_LMS_PublicKey::generate_another(RandomNumberGenerator&) const {
112 // For this key type we cannot derive all required parameters from just
113 // the public key. It is however possible to call HSS_LMS_PrivateKey::generate_another().
114 throw Not_Implemented("Cannot generate a new HSS/LMS keypair from a public key");
115}
116
117HSS_LMS_PrivateKey::HSS_LMS_PrivateKey(std::span<const uint8_t> private_key) {
119 auto scope = CT::scoped_poison(*m_private);
120 m_public = std::make_shared<HSS_LMS_PublicKeyInternal>(HSS_LMS_PublicKeyInternal::create(*m_private));
122}
123
125 HSS_LMS_Params hss_params(algo_params);
126 m_private = std::make_shared<HSS_LMS_PrivateKeyInternal>(hss_params, rng);
127 auto scope = CT::scoped_poison(*m_private);
128 m_public = std::make_shared<HSS_LMS_PublicKeyInternal>(HSS_LMS_PublicKeyInternal::create(*m_private));
130}
131
132HSS_LMS_PrivateKey::HSS_LMS_PrivateKey(std::shared_ptr<HSS_LMS_PrivateKeyInternal> sk) : m_private(std::move(sk)) {
133 auto scope = CT::scoped_poison(*m_private);
134 m_public = std::make_shared<HSS_LMS_PublicKeyInternal>(HSS_LMS_PublicKeyInternal::create(*m_private));
136}
137
139
141 auto scope = CT::scoped_poison(*m_private);
142 return CT::driveby_unpoison(m_private->to_bytes());
143}
144
148
149std::unique_ptr<Public_Key> HSS_LMS_PrivateKey::public_key() const {
150 return std::make_unique<HSS_LMS_PublicKey>(*this);
151}
152
153// We use a separate algorithm identifier for the private key since we use a Botan scoped OID for it.
154// This is necessary since the private key format is implementation specific, since it is not defined
155// in RFC 8554.
159
160std::optional<uint64_t> HSS_LMS_PrivateKey::remaining_operations() const {
161 return (m_private->hss_params().max_sig_count() - m_private->get_idx()).get();
162}
163
164std::unique_ptr<Private_Key> HSS_LMS_PrivateKey::generate_another(RandomNumberGenerator& rng) const {
165 // Cannot use std::make_unique because the utilized constructor is private.
166 return std::unique_ptr<HSS_LMS_PrivateKey>(
167 new HSS_LMS_PrivateKey(std::make_shared<HSS_LMS_PrivateKeyInternal>(m_private->hss_params(), rng)));
168}
169
170class HSS_LMS_Signature_Operation final : public PK_Ops::Signature {
171 public:
172 HSS_LMS_Signature_Operation(std::shared_ptr<HSS_LMS_PrivateKeyInternal> private_key,
173 std::shared_ptr<HSS_LMS_PublicKeyInternal> public_key) :
174 m_private(std::move(private_key)), m_public(std::move(public_key)) {}
175
176 void update(std::span<const uint8_t> msg) override {
177 m_msg_buffer.insert(m_msg_buffer.end(), msg.begin(), msg.end());
178 }
179
180 std::vector<uint8_t> sign(RandomNumberGenerator&) override {
181 std::vector<uint8_t> message_to_sign = std::exchange(m_msg_buffer, {});
182 auto scope = CT::scoped_poison(*m_private);
183 return CT::driveby_unpoison(m_private->sign(message_to_sign));
184 }
185
186 size_t signature_length() const override { return m_private->signature_size(); }
187
188 AlgorithmIdentifier algorithm_identifier() const override { return m_public->algorithm_identifier(); }
189
190 std::string hash_function() const override { return m_public->lms_pub_key().lms_params().hash_name(); }
191
192 private:
193 std::shared_ptr<HSS_LMS_PrivateKeyInternal> m_private;
194 std::shared_ptr<HSS_LMS_PublicKeyInternal> m_public;
195 std::vector<uint8_t> m_msg_buffer;
196};
197
199 std::string_view params,
200 std::string_view provider) const {
201 BOTAN_UNUSED(rng);
202 BOTAN_ARG_CHECK(params.empty(), "Unexpected parameters for signing with HSS-LMS");
203
204 if(provider.empty() || provider == "base") {
205 return std::make_unique<HSS_LMS_Signature_Operation>(m_private, m_public);
206 }
207 throw Provider_Not_Found(algo_name(), provider);
208}
209
210} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:118
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29
The HSS-LMS parameters.
Definition hss.h:41
static std::shared_ptr< HSS_LMS_PrivateKeyInternal > from_bytes_or_throw(std::span< const uint8_t > key_bytes)
Parse a private HSS-LMS key.
Definition hss.cpp:120
std::unique_ptr< Public_Key > public_key() const override
Definition hss_lms.cpp:149
AlgorithmIdentifier pkcs8_algorithm_identifier() const override
Definition hss_lms.cpp:156
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const override
Definition hss_lms.cpp:164
secure_vector< uint8_t > raw_private_key_bits() const override
Definition hss_lms.cpp:145
std::optional< uint64_t > remaining_operations() const override
Definition hss_lms.cpp:160
HSS_LMS_PrivateKey(std::span< const uint8_t > private_key_bytes)
Load an existing LMS private key using its bytes.
Definition hss_lms.cpp:117
secure_vector< uint8_t > private_key_bits() const override
Definition hss_lms.cpp:140
std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
Definition hss_lms.cpp:198
The internal HSS-LMS public key.
Definition hss.h:245
static HSS_LMS_PublicKeyInternal create(const HSS_LMS_PrivateKeyInternal &hss_sk)
Create the public HSS-LMS key from its private key.
Definition hss.cpp:298
std::unique_ptr< PK_Ops::Verification > create_verification_op(std::string_view params, std::string_view provider) const override
Definition hss_lms.cpp:88
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const override
Definition hss_lms.cpp:111
size_t key_length() const override
Definition hss_lms.cpp:22
bool supports_operation(PublicKeyOperation op) const override
Definition hss_lms.cpp:107
std::vector< uint8_t > raw_public_key_bits() const override
Definition hss_lms.cpp:51
std::string algo_name() const override
Definition hss_lms.cpp:34
OID object_identifier() const override
Definition hss_lms.cpp:42
size_t estimated_strength() const override
Definition hss_lms.cpp:26
std::unique_ptr< PK_Ops::Verification > create_x509_verification_op(const AlgorithmIdentifier &signature_algorithm, std::string_view provider) const override
Definition hss_lms.cpp:96
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition hss_lms.cpp:46
std::vector< uint8_t > public_key_bits() const override
Definition hss_lms.cpp:55
std::shared_ptr< HSS_LMS_PublicKeyInternal > m_public
Definition hss_lms.h:70
AlgorithmIdentifier algorithm_identifier() const override
Definition hss_lms.cpp:38
static HSS_Signature from_bytes_or_throw(std::span< const uint8_t > sig_bytes)
Parse a HSS-LMS signature.
Definition hss.cpp:373
static OID from_string(std::string_view str)
Definition asn1_oid.cpp:86
int(* update)(CTX *, const void *, CC_LONG len)
int(* final)(unsigned char *, CTX *)
decltype(auto) driveby_unpoison(T &&v)
Definition ct_utils.h:237
constexpr auto scoped_poison(const Ts &... xs)
Definition ct_utils.h:216
constexpr void unpoison(const T *p, size_t n)
Definition ct_utils.h:64
PublicKeyOperation
Definition pk_keys.h:45
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61