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