Botan 3.9.0
Crypto and TLS for C&
p11_rsa.cpp
Go to the documentation of this file.
1/*
2* PKCS#11 RSA
3* (C) 2016 Daniel Neus, Sirrix AG
4* (C) 2016 Philipp Weber, Sirrix AG
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/p11_rsa.h>
10
11#include <botan/pk_keys.h>
12
13#if defined(BOTAN_HAS_RSA)
14
15 #include <botan/numthry.h>
16 #include <botan/p11_mechanism.h>
17 #include <botan/pubkey.h>
18 #include <botan/rng.h>
19 #include <botan/internal/blinding.h>
20 #include <botan/internal/mod_inv.h>
21 #include <botan/internal/monty.h>
22 #include <botan/internal/monty_exp.h>
23 #include <botan/internal/pk_ops_impl.h>
24
25namespace Botan::PKCS11 {
26
27RSA_PublicKeyImportProperties::RSA_PublicKeyImportProperties(const BigInt& modulus, const BigInt& pub_exponent) :
28 PublicKeyProperties(KeyType::Rsa), m_modulus(modulus), m_pub_exponent(pub_exponent) {
29 add_binary(AttributeType::Modulus, m_modulus.serialize());
30 add_binary(AttributeType::PublicExponent, m_pub_exponent.serialize());
31}
32
33RSA_PublicKeyGenerationProperties::RSA_PublicKeyGenerationProperties(Ulong bits) : PublicKeyProperties(KeyType::Rsa) {
34 add_numeric(AttributeType::ModulusBits, bits);
35}
36
37PKCS11_RSA_PublicKey::PKCS11_RSA_PublicKey(Session& session, ObjectHandle handle) :
38 Object(session, handle),
39 RSA_PublicKey(BigInt::from_bytes(get_attribute_value(AttributeType::Modulus)),
40 BigInt::from_bytes(get_attribute_value(AttributeType::PublicExponent))) {}
41
42PKCS11_RSA_PublicKey::PKCS11_RSA_PublicKey(Session& session, const RSA_PublicKeyImportProperties& pubkey_props) :
43 Object(session, pubkey_props), RSA_PublicKey(pubkey_props.modulus(), pubkey_props.pub_exponent()) {}
44
45RSA_PrivateKeyImportProperties::RSA_PrivateKeyImportProperties(const BigInt& modulus, const BigInt& priv_exponent) :
46 PrivateKeyProperties(KeyType::Rsa), m_modulus(modulus), m_priv_exponent(priv_exponent) {
47 add_binary(AttributeType::Modulus, m_modulus.serialize());
48 add_binary(AttributeType::PrivateExponent, m_priv_exponent.serialize());
49}
50
51PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session, ObjectHandle handle) :
52 Object(session, handle),
53 RSA_PublicKey(BigInt::from_bytes(get_attribute_value(AttributeType::Modulus)),
54 BigInt::from_bytes(get_attribute_value(AttributeType::PublicExponent))) {}
55
56PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session, const RSA_PrivateKeyImportProperties& priv_key_props) :
57 Object(session, priv_key_props),
58 RSA_PublicKey(priv_key_props.modulus(), BigInt::from_bytes(get_attribute_value(AttributeType::PublicExponent))) {}
59
60PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session,
61 uint32_t bits,
62 const RSA_PrivateKeyGenerationProperties& priv_key_props) :
63 Object(session) {
64 RSA_PublicKeyGenerationProperties pub_key_props(bits);
65 pub_key_props.set_encrypt(true);
66 pub_key_props.set_verify(true);
67 pub_key_props.set_token(false); // don't create a persistent public key object
68
69 ObjectHandle pub_key_handle = CK_INVALID_HANDLE;
70 ObjectHandle priv_key_handle = CK_INVALID_HANDLE;
71 Mechanism mechanism = {static_cast<CK_MECHANISM_TYPE>(MechanismType::RsaPkcsKeyPairGen), nullptr, 0};
72 session.module()->C_GenerateKeyPair(session.handle(),
73 &mechanism,
74 pub_key_props.data(),
75 static_cast<Ulong>(pub_key_props.count()),
76 priv_key_props.data(),
77 static_cast<Ulong>(priv_key_props.count()),
78 &pub_key_handle,
79 &priv_key_handle);
80
81 this->reset_handle(priv_key_handle);
82
83 BigInt n = BigInt::from_bytes(get_attribute_value(AttributeType::Modulus));
84 BigInt e = BigInt::from_bytes(get_attribute_value(AttributeType::PublicExponent));
85 RSA_PublicKey::init(std::move(n), std::move(e));
86}
87
88RSA_PrivateKey PKCS11_RSA_PrivateKey::export_key() const {
89 auto p = get_attribute_value(AttributeType::Prime1);
90 auto q = get_attribute_value(AttributeType::Prime2);
91 auto e = get_attribute_value(AttributeType::PublicExponent);
92 auto d = get_attribute_value(AttributeType::PrivateExponent);
93 auto n = get_attribute_value(AttributeType::Modulus);
94
95 return RSA_PrivateKey(BigInt::from_bytes(p),
96 BigInt::from_bytes(q),
97 BigInt::from_bytes(e),
98 BigInt::from_bytes(d),
99 BigInt::from_bytes(n));
100}
101
102std::unique_ptr<Public_Key> PKCS11_RSA_PrivateKey::public_key() const {
103 return std::make_unique<RSA_PublicKey>(BigInt::from_bytes(get_attribute_value(AttributeType::Modulus)),
104 BigInt::from_bytes(get_attribute_value(AttributeType::PublicExponent)));
105}
106
107secure_vector<uint8_t> PKCS11_RSA_PrivateKey::private_key_bits() const {
108 return export_key().private_key_bits();
109}
110
111namespace {
112// note: multiple-part decryption operations (with C_DecryptUpdate/C_DecryptFinal)
113// are not supported (PK_Ops::Decryption does not provide an `update` method)
114class PKCS11_RSA_Decryption_Operation final : public PK_Ops::Decryption {
115 public:
116 PKCS11_RSA_Decryption_Operation(const PKCS11_RSA_PrivateKey& key,
117 std::string_view padding,
118 RandomNumberGenerator& rng) :
119 m_key(key),
120 m_mechanism(MechanismWrapper::create_rsa_crypt_mechanism(padding)),
121 m_mod_n(Barrett_Reduction::for_public_modulus(m_key.get_n())),
122 m_monty_n(m_key.get_n(), m_mod_n),
123 m_bits(m_key.get_n().bits() - 1),
124 m_blinder(
125 m_mod_n,
126 rng,
127 [this](const BigInt& k) {
128 const size_t powm_window = 1;
129 auto powm_m_n = monty_precompute(m_monty_n, k, powm_window, false);
130 return monty_execute_vartime(*powm_m_n, m_key.get_e()).value();
131 },
132 [this](const BigInt& k) { return inverse_mod_rsa_public_modulus(k, m_key.get_n()); }) {}
133
134 size_t plaintext_length(size_t /*ctext_len*/) const override { return m_key.get_n().bytes(); }
135
136 secure_vector<uint8_t> decrypt(uint8_t& valid_mask, std::span<const uint8_t> ctext) override {
137 valid_mask = 0;
138 m_key.module()->C_DecryptInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
139
140 std::vector<uint8_t> encrypted_data(ctext.begin(), ctext.end());
141
142 const size_t modulus_bytes = (m_key.get_n().bits() + 7) / 8;
143
144 // blind for RSA/RAW decryption
145 const bool use_blinding = m_mechanism.padding_size() == 0;
146
147 if(use_blinding) {
148 const BigInt blinded = m_blinder.blind(BigInt::from_bytes(encrypted_data));
149 // SoftHSM at least requires raw RSA inputs be == the modulus size
150 encrypted_data = blinded.serialize(modulus_bytes);
151 }
152
153 secure_vector<uint8_t> decrypted_data;
154 m_key.module()->C_Decrypt(m_key.session().handle(), encrypted_data, decrypted_data);
155
156 // Unblind for RSA/RAW decryption
157 if(use_blinding) {
158 const BigInt unblinded = m_blinder.unblind(BigInt::from_bytes(decrypted_data));
159 decrypted_data.resize(modulus_bytes);
160 unblinded.serialize_to(decrypted_data);
161 }
162
163 valid_mask = 0xFF;
164 return decrypted_data;
165 }
166
167 private:
168 const PKCS11_RSA_PrivateKey& m_key;
169 MechanismWrapper m_mechanism;
170 Barrett_Reduction m_mod_n;
171 const Montgomery_Params m_monty_n;
172 size_t m_bits;
173 Blinder m_blinder;
174};
175
176// note: multiple-part decryption operations (with C_DecryptUpdate/C_DecryptFinal)
177// are not supported (PK_Ops::Decryption does not provide an `update` method)
178class PKCS11_RSA_Decryption_Operation_Software_EME final : public PK_Ops::Decryption_with_EME {
179 public:
180 PKCS11_RSA_Decryption_Operation_Software_EME(const PKCS11_RSA_PrivateKey& key,
181 std::string_view padding,
182 RandomNumberGenerator& rng) :
183 PK_Ops::Decryption_with_EME(padding), m_raw_decryptor(key, rng, "Raw") {}
184
185 size_t plaintext_length(size_t ctext_len) const override { return m_raw_decryptor.plaintext_length(ctext_len); }
186
187 secure_vector<uint8_t> raw_decrypt(std::span<const uint8_t> input) override {
188 return m_raw_decryptor.decrypt(input);
189 }
190
191 private:
192 PK_Decryptor_EME m_raw_decryptor;
193};
194
195// note: multiple-part encryption operations (with C_EncryptUpdate/C_EncryptFinal)
196// are not supported (PK_Ops::Encryption does not provide an `update` method)
197class PKCS11_RSA_Encryption_Operation final : public PK_Ops::Encryption {
198 public:
199 PKCS11_RSA_Encryption_Operation(const PKCS11_RSA_PublicKey& key, std::string_view padding) :
200 m_key(key),
201 m_mechanism(MechanismWrapper::create_rsa_crypt_mechanism(padding)),
202 m_bits(8 * (key.get_n().bytes() - m_mechanism.padding_size()) - 1) {}
203
204 size_t ciphertext_length(size_t /*ptext_len*/) const override { return m_key.get_n().bytes(); }
205
206 size_t max_input_bits() const override { return m_bits; }
207
208 std::vector<uint8_t> encrypt(std::span<const uint8_t> input, RandomNumberGenerator& /*rng*/) override {
209 m_key.module()->C_EncryptInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
210
211 std::vector<uint8_t> encrypted_data;
212 m_key.module()->C_Encrypt(
213 m_key.session().handle(), secure_vector<uint8_t>(input.begin(), input.end()), encrypted_data);
214 return encrypted_data;
215 }
216
217 private:
218 const PKCS11_RSA_PublicKey& m_key;
219 MechanismWrapper m_mechanism;
220 size_t m_bits;
221};
222
223class PKCS11_RSA_Signature_Operation final : public PK_Ops::Signature {
224 public:
225 PKCS11_RSA_Signature_Operation(const PKCS11_RSA_PrivateKey& key, std::string_view padding) :
226 m_key(key), m_mechanism(MechanismWrapper::create_rsa_sign_mechanism(padding)) {}
227
228 size_t signature_length() const override { return m_key.get_n().bytes(); }
229
230 void update(std::span<const uint8_t> input) override {
231 if(!m_initialized) {
232 // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
233 m_key.module()->C_SignInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
234 m_initialized = true;
235 m_first_message.assign(input.begin(), input.end());
236 return;
237 }
238
239 if(!m_first_message.empty()) {
240 // second call to update: start multiple-part operation
241 m_key.module()->C_SignUpdate(m_key.session().handle(), m_first_message);
242 m_first_message.clear();
243 }
244
245 m_key.module()->C_SignUpdate(m_key.session().handle(), input.data(), static_cast<Ulong>(input.size()));
246 }
247
248 std::vector<uint8_t> sign(RandomNumberGenerator& /*rng*/) override {
249 std::vector<uint8_t> signature;
250 if(!m_first_message.empty()) {
251 // single call to update: perform single-part operation
252 m_key.module()->C_Sign(m_key.session().handle(), m_first_message, signature);
253 m_first_message.clear();
254 } else {
255 // multiple calls to update (or none): finish multiple-part operation
256 m_key.module()->C_SignFinal(m_key.session().handle(), signature);
257 }
258 m_initialized = false;
259 return signature;
260 }
261
262 std::string hash_function() const override;
263
264 AlgorithmIdentifier algorithm_identifier() const override;
265
266 private:
267 PKCS11_RSA_PrivateKey m_key;
268 bool m_initialized = false;
269 secure_vector<uint8_t> m_first_message;
270 MechanismWrapper m_mechanism;
271};
272
273namespace {
274
275std::string hash_function_name_from_pkcs11_rsa_mechanism_type(MechanismType type) {
276 switch(type) {
277 case MechanismType::Sha1RsaPkcs:
278 case MechanismType::Sha1RsaPkcsPss:
279 case MechanismType::Sha1RsaX931:
280 return "SHA-1";
281
282 case MechanismType::Sha224RsaPkcs:
283 case MechanismType::Sha224RsaPkcsPss:
284 return "SHA-224";
285
286 case MechanismType::Sha256RsaPkcs:
287 case MechanismType::Sha256RsaPkcsPss:
288 return "SHA-256";
289
290 case MechanismType::Sha384RsaPkcs:
291 case MechanismType::Sha384RsaPkcsPss:
292 return "SHA-384";
293
294 case MechanismType::Sha512RsaPkcs:
295 case MechanismType::Sha512RsaPkcsPss:
296 return "SHA-512";
297
298 case MechanismType::RsaX509:
299 case MechanismType::RsaX931:
300 case MechanismType::RsaPkcs:
301 case MechanismType::RsaPkcsPss:
302 return "Raw";
303
304 default:
305 throw Internal_Error("Unable to determine associated hash function of PKCS11 RSA signature operation");
306 }
307}
308
309} // namespace
310
311std::string PKCS11_RSA_Signature_Operation::hash_function() const {
312 return hash_function_name_from_pkcs11_rsa_mechanism_type(m_mechanism.mechanism_type());
313}
314
315AlgorithmIdentifier PKCS11_RSA_Signature_Operation::algorithm_identifier() const {
316 const std::string hash = this->hash_function();
317
318 switch(m_mechanism.mechanism_type()) {
319 case MechanismType::Sha1RsaPkcs:
320 case MechanismType::Sha224RsaPkcs:
321 case MechanismType::Sha256RsaPkcs:
322 case MechanismType::Sha384RsaPkcs:
323 case MechanismType::Sha512RsaPkcs: {
324 const OID oid = OID::from_string("RSA/EMSA3(" + hash + ")");
325 return AlgorithmIdentifier(oid, AlgorithmIdentifier::USE_NULL_PARAM);
326 }
327
328 case MechanismType::Sha1RsaPkcsPss:
329 case MechanismType::Sha224RsaPkcsPss:
330 case MechanismType::Sha256RsaPkcsPss:
331 case MechanismType::Sha384RsaPkcsPss:
332 case MechanismType::Sha512RsaPkcsPss:
333 throw Not_Implemented("RSA-PSS identifier encoding missing for PKCS11");
334
335 default:
336 throw Not_Implemented("No algorithm identifier defined for RSA with this PKCS11 mechanism");
337 }
338}
339
340class PKCS11_RSA_Verification_Operation final : public PK_Ops::Verification {
341 public:
342 PKCS11_RSA_Verification_Operation(const PKCS11_RSA_PublicKey& key, std::string_view padding) :
343 m_key(key), m_mechanism(MechanismWrapper::create_rsa_sign_mechanism(padding)) {}
344
345 void update(std::span<const uint8_t> input) override {
346 if(!m_initialized) {
347 // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
348 m_key.module()->C_VerifyInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
349 m_initialized = true;
350 m_first_message.assign(input.begin(), input.end());
351 return;
352 }
353
354 if(!m_first_message.empty()) {
355 // second call to update: start multiple-part operation
356 m_key.module()->C_VerifyUpdate(m_key.session().handle(), m_first_message);
357 m_first_message.clear();
358 }
359
360 m_key.module()->C_VerifyUpdate(m_key.session().handle(), input.data(), static_cast<Ulong>(input.size()));
361 }
362
363 bool is_valid_signature(std::span<const uint8_t> sig) override {
364 ReturnValue return_value = ReturnValue::SignatureInvalid;
365 if(!m_first_message.empty()) {
366 // single call to update: perform single-part operation
367 m_key.module()->C_Verify(m_key.session().handle(),
368 m_first_message.data(),
369 static_cast<Ulong>(m_first_message.size()),
370 sig.data(),
371 static_cast<Ulong>(sig.size()),
372 &return_value);
373 m_first_message.clear();
374 } else {
375 // multiple calls to update (or none): finish multiple-part operation
376 m_key.module()->C_VerifyFinal(
377 m_key.session().handle(), sig.data(), static_cast<Ulong>(sig.size()), &return_value);
378 }
379 m_initialized = false;
380 if(return_value != ReturnValue::OK && return_value != ReturnValue::SignatureInvalid) {
381 throw PKCS11_ReturnError(return_value);
382 }
383 return return_value == ReturnValue::OK;
384 }
385
386 std::string hash_function() const override;
387
388 private:
389 const PKCS11_RSA_PublicKey m_key;
390 bool m_initialized = false;
391 secure_vector<uint8_t> m_first_message;
392 MechanismWrapper m_mechanism;
393};
394
395std::string PKCS11_RSA_Verification_Operation::hash_function() const {
396 return hash_function_name_from_pkcs11_rsa_mechanism_type(m_mechanism.mechanism_type());
397}
398
399} // namespace
400
401std::unique_ptr<PK_Ops::Encryption> PKCS11_RSA_PublicKey::create_encryption_op(RandomNumberGenerator& /*rng*/,
402 std::string_view params,
403 std::string_view /*provider*/) const {
404 return std::make_unique<PKCS11_RSA_Encryption_Operation>(*this, params);
405}
406
407std::unique_ptr<PK_Ops::Verification> PKCS11_RSA_PublicKey::create_verification_op(
408 std::string_view params, std::string_view /*provider*/) const {
409 return std::make_unique<PKCS11_RSA_Verification_Operation>(*this, params);
410}
411
412std::unique_ptr<PK_Ops::Decryption> PKCS11_RSA_PrivateKey::create_decryption_op(RandomNumberGenerator& rng,
413 std::string_view params,
414 std::string_view /*provider*/) const {
415 if(params != "Raw" && m_use_software_padding) {
416 return std::make_unique<PKCS11_RSA_Decryption_Operation_Software_EME>(*this, params, rng);
417 } else {
418 return std::make_unique<PKCS11_RSA_Decryption_Operation>(*this, params, rng);
419 }
420}
421
422std::unique_ptr<PK_Ops::Signature> PKCS11_RSA_PrivateKey::create_signature_op(RandomNumberGenerator& /*rng*/,
423 std::string_view params,
424 std::string_view /*provider*/) const {
425 return std::make_unique<PKCS11_RSA_Signature_Operation>(*this, params);
426}
427
428PKCS11_RSA_KeyPair generate_rsa_keypair(Session& session,
429 const RSA_PublicKeyGenerationProperties& pub_props,
430 const RSA_PrivateKeyGenerationProperties& priv_props) {
431 ObjectHandle pub_key_handle = 0;
432 ObjectHandle priv_key_handle = 0;
433
434 Mechanism mechanism = {static_cast<CK_MECHANISM_TYPE>(MechanismType::RsaPkcsKeyPairGen), nullptr, 0};
435
436 session.module()->C_GenerateKeyPair(session.handle(),
437 &mechanism,
438 pub_props.data(),
439 static_cast<Ulong>(pub_props.count()),
440 priv_props.data(),
441 static_cast<Ulong>(priv_props.count()),
442 &pub_key_handle,
443 &priv_key_handle);
444
445 return std::make_pair(PKCS11_RSA_PublicKey(session, pub_key_handle),
446 PKCS11_RSA_PrivateKey(session, priv_key_handle));
447}
448
449} // namespace Botan::PKCS11
450
451#endif
BigInt value() const
Definition monty.cpp:245
Common attributes of all public key objects.
Definition p11_object.h:295
std::string decrypt(std::span< const uint8_t > input, std::string_view passphrase)
std::string encrypt(const uint8_t input[], size_t input_len, std::string_view passphrase, RandomNumberGenerator &rng)
Definition cryptobox.cpp:42
AttributeType
Definition p11.h:68
CK_MECHANISM Mechanism
Definition p11.h:828
CK_OBJECT_HANDLE ObjectHandle
Definition p11.h:835
CK_ULONG Ulong
Definition p11.h:825
Montgomery_Int monty_execute_vartime(const Montgomery_Exponentation_State &precomputed_state, const BigInt &k)
BigInt inverse_mod_rsa_public_modulus(const BigInt &x, const BigInt &n)
Definition mod_inv.cpp:295
std::shared_ptr< const Montgomery_Exponentation_State > monty_precompute(const Montgomery_Int &g, size_t window_bits, bool const_time)
#define CK_INVALID_HANDLE
Definition pkcs11t.h:75
CK_ULONG CK_MECHANISM_TYPE
Definition pkcs11t.h:583