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