Botan 2.19.3
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#include <botan/pk_keys.h>
11
12#if defined(BOTAN_HAS_RSA)
13
14#include <botan/internal/p11_mechanism.h>
15#include <botan/pk_ops.h>
16#include <botan/rng.h>
17#include <botan/blinding.h>
18
19namespace Botan {
20
21namespace 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 {
26 add_binary(AttributeType::Modulus, BigInt::encode(m_modulus));
27 add_binary(AttributeType::PublicExponent, BigInt::encode(m_pub_exponent));
28 }
29
30RSA_PublicKeyGenerationProperties::RSA_PublicKeyGenerationProperties(Ulong bits)
31 : PublicKeyProperties(KeyType::Rsa)
32 {
33 add_numeric(AttributeType::ModulusBits, bits);
34 }
35
36PKCS11_RSA_PublicKey::PKCS11_RSA_PublicKey(Session& session, ObjectHandle handle)
37 : Object(session, handle),
38 RSA_PublicKey(BigInt::decode(get_attribute_value(AttributeType::Modulus)),
39 BigInt::decode(get_attribute_value(AttributeType::PublicExponent)))
40 {
41 }
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 {}
46
47
48RSA_PrivateKeyImportProperties::RSA_PrivateKeyImportProperties(const BigInt& modulus, const BigInt& priv_exponent)
49 : PrivateKeyProperties(KeyType::Rsa), m_modulus(modulus), m_priv_exponent(priv_exponent)
50 {
51 add_binary(AttributeType::Modulus, BigInt::encode(m_modulus));
52 add_binary(AttributeType::PrivateExponent, BigInt::encode(m_priv_exponent));
53 }
54
55
56PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session, ObjectHandle handle)
57 : Object(session, handle),
58 RSA_PublicKey(BigInt::decode(get_attribute_value(AttributeType::Modulus)),
59 BigInt::decode(get_attribute_value(AttributeType::PublicExponent)))
60 {
61 }
62
63PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session, const RSA_PrivateKeyImportProperties& priv_key_props)
64 : Object(session, priv_key_props),
65 RSA_PublicKey(priv_key_props.modulus(),
66 BigInt::decode(get_attribute_value(AttributeType::PublicExponent)))
67 {
68 }
69
70PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session, uint32_t bits,
71 const RSA_PrivateKeyGenerationProperties& priv_key_props)
72 : Object(session), RSA_PublicKey()
73 {
74 RSA_PublicKeyGenerationProperties pub_key_props(bits);
75 pub_key_props.set_encrypt(true);
76 pub_key_props.set_verify(true);
77 pub_key_props.set_token(false); // don't create a persistent public key object
78
79 ObjectHandle pub_key_handle = CK_INVALID_HANDLE;
80 ObjectHandle priv_key_handle = CK_INVALID_HANDLE;
81 Mechanism mechanism = { static_cast< CK_MECHANISM_TYPE >(MechanismType::RsaPkcsKeyPairGen), nullptr, 0 };
82 session.module()->C_GenerateKeyPair(session.handle(), &mechanism,
83 pub_key_props.data(), static_cast<Ulong>(pub_key_props.count()),
84 priv_key_props.data(), static_cast<Ulong>(priv_key_props.count()),
85 &pub_key_handle, &priv_key_handle);
86
87 this->reset_handle(priv_key_handle);
88
89 BigInt n = BigInt::decode(get_attribute_value(AttributeType::Modulus));
90 BigInt e = BigInt::decode(get_attribute_value(AttributeType::PublicExponent));
91 RSA_PublicKey::init(std::move(n), std::move(e));
92 }
93
94RSA_PrivateKey PKCS11_RSA_PrivateKey::export_key() const
95 {
96 auto p = get_attribute_value(AttributeType::Prime1);
97 auto q = get_attribute_value(AttributeType::Prime2);
98 auto e = get_attribute_value(AttributeType::PublicExponent);
99 auto d = get_attribute_value(AttributeType::PrivateExponent);
100 auto n = get_attribute_value(AttributeType::Modulus);
101
102 return RSA_PrivateKey( BigInt::decode(p)
103 , BigInt::decode(q)
104 , BigInt::decode(e)
105 , BigInt::decode(d)
106 , BigInt::decode(n));
107 }
108
109secure_vector<uint8_t> PKCS11_RSA_PrivateKey::private_key_bits() const
110 {
111 return export_key().private_key_bits();
112 }
113
114
115namespace {
116// note: multiple-part decryption operations (with C_DecryptUpdate/C_DecryptFinal)
117// are not supported (PK_Ops::Decryption does not provide an `update` method)
118class PKCS11_RSA_Decryption_Operation final : public PK_Ops::Decryption
119 {
120 public:
121
122 PKCS11_RSA_Decryption_Operation(const PKCS11_RSA_PrivateKey& key,
123 const std::string& padding,
124 RandomNumberGenerator& rng)
125 : m_key(key),
126 m_mechanism(MechanismWrapper::create_rsa_crypt_mechanism(padding)),
127 m_blinder(m_key.get_n(), rng,
128 [ this ](const BigInt& k) { return power_mod(k, m_key.get_e(), m_key.get_n()); },
129 [ this ](const BigInt& k) { return inverse_mod(k, m_key.get_n()); })
130 {
131 m_bits = m_key.get_n().bits() - 1;
132 }
133
134 size_t plaintext_length(size_t) const override { return m_key.get_n().bytes(); }
135
136 secure_vector<uint8_t> decrypt(uint8_t& valid_mask, const uint8_t ciphertext[], size_t ciphertext_len) override
137 {
138 valid_mask = 0;
139 m_key.module()->C_DecryptInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
140
141 std::vector<uint8_t> encrypted_data(ciphertext, ciphertext + ciphertext_len);
142
143 // blind for RSA/RAW decryption
144 if(! m_mechanism.padding_size())
145 {
146 encrypted_data = BigInt::encode(m_blinder.blind(BigInt::decode(encrypted_data)));
147 }
148
149 secure_vector<uint8_t> decrypted_data;
150 m_key.module()->C_Decrypt(m_key.session().handle(), encrypted_data, decrypted_data);
151
152 // Unblind for RSA/RAW decryption
153 if(!m_mechanism.padding_size())
154 {
155 decrypted_data = BigInt::encode_1363(m_blinder.unblind(BigInt::decode(decrypted_data)), m_key.get_n().bits() / 8 );
156 }
157
158 valid_mask = 0xFF;
159 return decrypted_data;
160 }
161
162 private:
163 const PKCS11_RSA_PrivateKey& m_key;
164 MechanismWrapper m_mechanism;
165 size_t m_bits = 0;
166 Blinder m_blinder;
167 };
168
169// note: multiple-part encryption operations (with C_EncryptUpdate/C_EncryptFinal)
170// are not supported (PK_Ops::Encryption does not provide an `update` method)
171class PKCS11_RSA_Encryption_Operation final : public PK_Ops::Encryption
172 {
173 public:
174
175 PKCS11_RSA_Encryption_Operation(const PKCS11_RSA_PublicKey& key, const std::string& padding)
176 : m_key(key), m_mechanism(MechanismWrapper::create_rsa_crypt_mechanism(padding))
177 {
178 m_bits = 8 * (key.get_n().bytes() - m_mechanism.padding_size()) - 1;
179 }
180
181 size_t ciphertext_length(size_t) const override { return m_key.get_n().bytes(); }
182
183 size_t max_input_bits() const override
184 {
185 return m_bits;
186 }
187
188 secure_vector<uint8_t> encrypt(const uint8_t msg[], size_t msg_len, RandomNumberGenerator&) override
189 {
190 m_key.module()->C_EncryptInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
191
192 secure_vector<uint8_t> encrytped_data;
193 m_key.module()->C_Encrypt(m_key.session().handle(), secure_vector<uint8_t>(msg, msg + msg_len), encrytped_data);
194 return encrytped_data;
195 }
196
197 private:
198 const PKCS11_RSA_PublicKey& m_key;
199 MechanismWrapper m_mechanism;
200 size_t m_bits = 0;
201 };
202
203
204class PKCS11_RSA_Signature_Operation final : public PK_Ops::Signature
205 {
206 public:
207
208 PKCS11_RSA_Signature_Operation(const PKCS11_RSA_PrivateKey& key, const std::string& padding)
209 : m_key(key), m_mechanism(MechanismWrapper::create_rsa_sign_mechanism(padding))
210 {}
211
212 size_t signature_length() const override { return m_key.get_n().bytes(); }
213
214 void update(const uint8_t msg[], size_t msg_len) override
215 {
216 if(!m_initialized)
217 {
218 // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
219 m_key.module()->C_SignInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
220 m_initialized = true;
221 m_first_message = secure_vector<uint8_t>(msg, msg + msg_len);
222 return;
223 }
224
225 if(!m_first_message.empty())
226 {
227 // second call to update: start multiple-part operation
228 m_key.module()->C_SignUpdate(m_key.session().handle(), m_first_message);
229 m_first_message.clear();
230 }
231
232 m_key.module()->C_SignUpdate(m_key.session().handle(), const_cast< Byte* >(msg), static_cast<Ulong>(msg_len));
233 }
234
235 secure_vector<uint8_t> sign(RandomNumberGenerator&) override
236 {
237 secure_vector<uint8_t> signature;
238 if(!m_first_message.empty())
239 {
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 }
244 else
245 {
246 // multiple calls to update (or none): finish multiple-part operation
247 m_key.module()->C_SignFinal(m_key.session().handle(), signature);
248 }
249 m_initialized = false;
250 return signature;
251 }
252
253 private:
254 const PKCS11_RSA_PrivateKey& m_key;
255 bool m_initialized = false;
256 secure_vector<uint8_t> m_first_message;
257 MechanismWrapper m_mechanism;
258 };
259
260
261class PKCS11_RSA_Verification_Operation final : public PK_Ops::Verification
262 {
263 public:
264
265 PKCS11_RSA_Verification_Operation(const PKCS11_RSA_PublicKey& key, const std::string& padding)
266 : m_key(key), m_mechanism(MechanismWrapper::create_rsa_sign_mechanism(padding))
267 {}
268
269 void update(const uint8_t msg[], size_t msg_len) override
270 {
271 if(!m_initialized)
272 {
273 // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
274 m_key.module()->C_VerifyInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
275 m_initialized = true;
276 m_first_message = secure_vector<uint8_t>(msg, msg + msg_len);
277 return;
278 }
279
280 if(!m_first_message.empty())
281 {
282 // second call to update: start multiple-part operation
283 m_key.module()->C_VerifyUpdate(m_key.session().handle(), m_first_message);
284 m_first_message.clear();
285 }
286
287 m_key.module()->C_VerifyUpdate(m_key.session().handle(), const_cast< Byte* >(msg), static_cast<Ulong>(msg_len));
288 }
289
290 bool is_valid_signature(const uint8_t sig[], size_t sig_len) override
291 {
292 ReturnValue return_value = ReturnValue::SignatureInvalid;
293 if(!m_first_message.empty())
294 {
295 // single call to update: perform single-part operation
296 m_key.module()->C_Verify(m_key.session().handle(),
297 m_first_message.data(), static_cast<Ulong>(m_first_message.size()),
298 const_cast< Byte* >(sig), static_cast<Ulong>(sig_len), &return_value);
299 m_first_message.clear();
300 }
301 else
302 {
303 // multiple calls to update (or none): finish multiple-part operation
304 m_key.module()->C_VerifyFinal(m_key.session().handle(), const_cast< Byte* >(sig), static_cast<Ulong>(sig_len), &return_value);
305 }
306 m_initialized = false;
307 if(return_value != ReturnValue::OK && return_value != ReturnValue::SignatureInvalid)
308 {
309 throw PKCS11_ReturnError(return_value);
310 }
311 return return_value == ReturnValue::OK;
312 }
313
314 private:
315 const PKCS11_RSA_PublicKey& m_key;
316 bool m_initialized = false;
317 secure_vector<uint8_t> m_first_message;
318 MechanismWrapper m_mechanism;
319 };
320
321}
322
323std::unique_ptr<PK_Ops::Encryption>
324PKCS11_RSA_PublicKey::create_encryption_op(RandomNumberGenerator& /*rng*/,
325 const std::string& params,
326 const std::string& /*provider*/) const
327 {
328 return std::unique_ptr<PK_Ops::Encryption>(new PKCS11_RSA_Encryption_Operation(*this, params));
329 }
330
331std::unique_ptr<PK_Ops::Verification>
332PKCS11_RSA_PublicKey::create_verification_op(const std::string& params,
333 const std::string& /*provider*/) const
334 {
335 return std::unique_ptr<PK_Ops::Verification>(new PKCS11_RSA_Verification_Operation(*this, params));
336 }
337
338std::unique_ptr<PK_Ops::Decryption>
339PKCS11_RSA_PrivateKey::create_decryption_op(RandomNumberGenerator& rng,
340 const std::string& params,
341 const std::string& /*provider*/) const
342 {
343 return std::unique_ptr<PK_Ops::Decryption>(new PKCS11_RSA_Decryption_Operation(*this, params, rng));
344 }
345
346std::unique_ptr<PK_Ops::Signature>
347PKCS11_RSA_PrivateKey::create_signature_op(RandomNumberGenerator& /*rng*/,
348 const std::string& params,
349 const std::string& /*provider*/) const
350 {
351 return std::unique_ptr<PK_Ops::Signature>(new PKCS11_RSA_Signature_Operation(*this, params));
352 }
353
354PKCS11_RSA_KeyPair generate_rsa_keypair(Session& session, const RSA_PublicKeyGenerationProperties& pub_props,
355 const RSA_PrivateKeyGenerationProperties& priv_props)
356 {
357 ObjectHandle pub_key_handle = 0;
358 ObjectHandle priv_key_handle = 0;
359
360 Mechanism mechanism = { static_cast< CK_MECHANISM_TYPE >(MechanismType::RsaPkcsKeyPairGen), nullptr, 0 };
361
362 session.module()->C_GenerateKeyPair(session.handle(), &mechanism,
363 pub_props.data(), static_cast<Ulong>(pub_props.count()),
364 priv_props.data(), static_cast<Ulong>(priv_props.count()),
365 &pub_key_handle, &priv_key_handle);
366
367 return std::make_pair(PKCS11_RSA_PublicKey(session, pub_key_handle), PKCS11_RSA_PrivateKey(session, priv_key_handle));
368 }
369
370}
371}
372
373#endif
int(* update)(CTX *, const void *, CC_LONG len)
int(* final)(unsigned char *, CTX *)
std::string decrypt(const uint8_t input[], size_t input_len, const std::string &passphrase)
std::string encrypt(const uint8_t input[], size_t input_len, const std::string &passphrase, RandomNumberGenerator &rng)
Definition cryptobox.cpp:43
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition pem.cpp:68
AttributeType
Definition p11.h:66
CK_ULONG Ulong
Definition p11.h:838
CK_MECHANISM Mechanism
Definition p11.h:841
CK_OBJECT_HANDLE ObjectHandle
Definition p11.h:848
CK_BYTE Byte
Definition p11.h:849
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition numthry.cpp:151
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition mod_inv.cpp:250
#define CK_INVALID_HANDLE
Definition pkcs11t.h:75
CK_ULONG CK_MECHANISM_TYPE
Definition pkcs11t.h:583