Botan 3.11.0
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
46bool HSS_LMS_PublicKey::check_key(RandomNumberGenerator& /*rng*/, bool /*strong*/) const {
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
61namespace {
62
63class HSS_LMS_Verification_Operation final : public PK_Ops::Verification {
64 public:
65 explicit HSS_LMS_Verification_Operation(std::shared_ptr<HSS_LMS_PublicKeyInternal> pub_key) :
66 m_public(std::move(pub_key)) {}
67
68 void update(std::span<const uint8_t> msg) override {
69 m_msg_buffer.insert(m_msg_buffer.end(), msg.begin(), msg.end());
70 }
71
72 bool is_valid_signature(std::span<const uint8_t> sig) override {
73 std::vector<uint8_t> message_to_verify = std::exchange(m_msg_buffer, {});
74 try {
75 const auto signature = HSS_Signature::from_bytes_or_throw(sig);
76 return m_public->verify_signature(message_to_verify, signature);
77 } catch(const Decoding_Error&) {
78 // Signature could not be decoded
79 return false;
80 }
81 }
82
83 std::string hash_function() const override { return m_public->lms_pub_key().lms_params().hash_name(); }
84
85 private:
86 std::shared_ptr<HSS_LMS_PublicKeyInternal> m_public;
87 std::vector<uint8_t> m_msg_buffer;
88};
89
90} // namespace
91
92std::unique_ptr<PK_Ops::Verification> HSS_LMS_PublicKey::create_verification_op(std::string_view /*params*/,
93 std::string_view provider) const {
94 if(provider.empty() || provider == "base") {
95 return std::make_unique<HSS_LMS_Verification_Operation>(m_public);
96 }
97 throw Provider_Not_Found(algo_name(), provider);
98}
99
100std::unique_ptr<PK_Ops::Verification> HSS_LMS_PublicKey::create_x509_verification_op(
101 const AlgorithmIdentifier& signature_algorithm, std::string_view provider) const {
102 if(provider.empty() || provider == "base") {
103 if(signature_algorithm != this->algorithm_identifier()) {
104 throw Decoding_Error("Unexpected AlgorithmIdentifier for HSS-LMS signature");
105 }
106 return std::make_unique<HSS_LMS_Verification_Operation>(m_public);
107 }
108 throw Provider_Not_Found(algo_name(), provider);
109}
110
114
115std::unique_ptr<Private_Key> HSS_LMS_PublicKey::generate_another(RandomNumberGenerator& /*rng*/) const {
116 // For this key type we cannot derive all required parameters from just
117 // the public key. It is however possible to call HSS_LMS_PrivateKey::generate_another().
118 throw Not_Implemented("Cannot generate a new HSS/LMS keypair from a public key");
119}
120
121HSS_LMS_PrivateKey::HSS_LMS_PrivateKey(std::span<const uint8_t> private_key) {
123 auto scope = CT::scoped_poison(*m_private);
124 m_public = std::make_shared<HSS_LMS_PublicKeyInternal>(HSS_LMS_PublicKeyInternal::create(*m_private));
126}
127
129 const HSS_LMS_Params hss_params(algo_params);
130 m_private = std::make_shared<HSS_LMS_PrivateKeyInternal>(hss_params, rng);
131 auto scope = CT::scoped_poison(*m_private);
132 m_public = std::make_shared<HSS_LMS_PublicKeyInternal>(HSS_LMS_PublicKeyInternal::create(*m_private));
134}
135
136HSS_LMS_PrivateKey::HSS_LMS_PrivateKey(std::shared_ptr<HSS_LMS_PrivateKeyInternal> sk) : m_private(std::move(sk)) {
137 auto scope = CT::scoped_poison(*m_private);
138 m_public = std::make_shared<HSS_LMS_PublicKeyInternal>(HSS_LMS_PublicKeyInternal::create(*m_private));
140}
141
143
145 auto scope = CT::scoped_poison(*m_private);
146 return CT::driveby_unpoison(m_private->to_bytes());
147}
148
152
153std::unique_ptr<Public_Key> HSS_LMS_PrivateKey::public_key() const {
154 return std::make_unique<HSS_LMS_PublicKey>(*this);
155}
156
157// We use a separate algorithm identifier for the private key since we use a Botan scoped OID for it.
158// This is necessary since the private key format is implementation specific, since it is not defined
159// in RFC 8554.
163
164std::optional<uint64_t> HSS_LMS_PrivateKey::remaining_operations() const {
165 return m_private->remaining_operations(m_private->hss_params().max_sig_count()).get();
166}
167
168std::unique_ptr<Private_Key> HSS_LMS_PrivateKey::generate_another(RandomNumberGenerator& rng) const {
169 // Cannot use std::make_unique because the utilized constructor is private.
170 return std::unique_ptr<HSS_LMS_PrivateKey>(
171 new HSS_LMS_PrivateKey(std::make_shared<HSS_LMS_PrivateKeyInternal>(m_private->hss_params(), rng)));
172}
173
174namespace {
175
176class HSS_LMS_Signature_Operation final : public PK_Ops::Signature {
177 public:
178 HSS_LMS_Signature_Operation(std::shared_ptr<HSS_LMS_PrivateKeyInternal> private_key,
179 std::shared_ptr<HSS_LMS_PublicKeyInternal> public_key) :
180 m_private(std::move(private_key)), m_public(std::move(public_key)) {}
181
182 void update(std::span<const uint8_t> msg) override {
183 m_msg_buffer.insert(m_msg_buffer.end(), msg.begin(), msg.end());
184 }
185
186 std::vector<uint8_t> sign(RandomNumberGenerator& /*rng*/) override {
187 std::vector<uint8_t> message_to_sign = std::exchange(m_msg_buffer, {});
188 auto scope = CT::scoped_poison(*m_private);
189 return CT::driveby_unpoison(m_private->sign(message_to_sign));
190 }
191
192 size_t signature_length() const override { return m_private->signature_size(); }
193
194 AlgorithmIdentifier algorithm_identifier() const override { return m_public->algorithm_identifier(); }
195
196 std::string hash_function() const override { return m_public->lms_pub_key().lms_params().hash_name(); }
197
198 private:
199 std::shared_ptr<HSS_LMS_PrivateKeyInternal> m_private;
200 std::shared_ptr<HSS_LMS_PublicKeyInternal> m_public;
201 std::vector<uint8_t> m_msg_buffer;
202};
203
204} // namespace
205
207 std::string_view params,
208 std::string_view provider) const {
209 BOTAN_UNUSED(rng);
210 BOTAN_ARG_CHECK(params.empty(), "Unexpected parameters for signing with HSS-LMS");
211
212 if(provider.empty() || provider == "base") {
213 return std::make_unique<HSS_LMS_Signature_Operation>(m_private, m_public);
214 }
215 throw Provider_Not_Found(algo_name(), provider);
216}
217
218} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:144
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
The HSS-LMS parameters.
Definition hss.h:42
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:146
std::unique_ptr< Public_Key > public_key() const override
Definition hss_lms.cpp:153
AlgorithmIdentifier pkcs8_algorithm_identifier() const override
Definition hss_lms.cpp:160
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const override
Definition hss_lms.cpp:168
secure_vector< uint8_t > raw_private_key_bits() const override
Definition hss_lms.cpp:149
std::optional< uint64_t > remaining_operations() const override
Definition hss_lms.cpp:164
BOTAN_FUTURE_EXPLICIT HSS_LMS_PrivateKey(std::span< const uint8_t > private_key_bytes)
Load an existing LMS private key using its bytes.
Definition hss_lms.cpp:121
secure_vector< uint8_t > private_key_bits() const override
Definition hss_lms.cpp:144
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:206
The internal HSS-LMS public key.
Definition hss.h:247
static HSS_LMS_PublicKeyInternal create(const HSS_LMS_PrivateKeyInternal &hss_sk)
Create the public HSS-LMS key from its private key.
Definition hss.cpp:317
std::unique_ptr< PK_Ops::Verification > create_verification_op(std::string_view params, std::string_view provider) const override
Definition hss_lms.cpp:92
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const override
Definition hss_lms.cpp:115
size_t key_length() const override
Definition hss_lms.cpp:22
bool supports_operation(PublicKeyOperation op) const override
Definition hss_lms.cpp:111
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:100
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:74
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:392
static OID from_string(std::string_view str)
Definition asn1_oid.cpp:86
decltype(auto) driveby_unpoison(T &&v)
Definition ct_utils.h:243
constexpr auto scoped_poison(const Ts &... xs)
Definition ct_utils.h:222
constexpr void unpoison(const T *p, size_t n)
Definition ct_utils.h:67
PublicKeyOperation
Definition pk_keys.h:46
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:68