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