Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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