• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.45
/src/lib/prov/pkcs11/p11_rsa.cpp
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.h>
20
   #include <botan/internal/pk_ops_impl.h>
21

22
namespace Botan::PKCS11 {
23

24
RSA_PublicKeyImportProperties::RSA_PublicKeyImportProperties(const BigInt& modulus, const BigInt& pub_exponent) :
1✔
25
      PublicKeyProperties(KeyType::Rsa), m_modulus(modulus), m_pub_exponent(pub_exponent) {
1✔
26
   add_binary(AttributeType::Modulus, BigInt::encode(m_modulus));
2✔
27
   add_binary(AttributeType::PublicExponent, BigInt::encode(m_pub_exponent));
2✔
28
}
1✔
29

30
RSA_PublicKeyGenerationProperties::RSA_PublicKeyGenerationProperties(Ulong bits) : PublicKeyProperties(KeyType::Rsa) {
4✔
31
   add_numeric(AttributeType::ModulusBits, bits);
4✔
32
}
4✔
33

34
PKCS11_RSA_PublicKey::PKCS11_RSA_PublicKey(Session& session, ObjectHandle handle) :
3✔
35
      Object(session, handle),
36
      RSA_PublicKey(BigInt::decode(get_attribute_value(AttributeType::Modulus)),
6✔
37
                    BigInt::decode(get_attribute_value(AttributeType::PublicExponent))) {}
15✔
38

39
PKCS11_RSA_PublicKey::PKCS11_RSA_PublicKey(Session& session, const RSA_PublicKeyImportProperties& pubkey_props) :
1✔
40
      Object(session, pubkey_props), RSA_PublicKey(pubkey_props.modulus(), pubkey_props.pub_exponent()) {}
1✔
41

42
RSA_PrivateKeyImportProperties::RSA_PrivateKeyImportProperties(const BigInt& modulus, const BigInt& priv_exponent) :
2✔
43
      PrivateKeyProperties(KeyType::Rsa), m_modulus(modulus), m_priv_exponent(priv_exponent) {
2✔
44
   add_binary(AttributeType::Modulus, BigInt::encode(m_modulus));
4✔
45
   add_binary(AttributeType::PrivateExponent, BigInt::encode(m_priv_exponent));
4✔
46
}
2✔
47

48
PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session, ObjectHandle handle) :
3✔
49
      Object(session, handle),
50
      RSA_PublicKey(BigInt::decode(get_attribute_value(AttributeType::Modulus)),
6✔
51
                    BigInt::decode(get_attribute_value(AttributeType::PublicExponent))) {}
15✔
52

53
PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session, const RSA_PrivateKeyImportProperties& priv_key_props) :
2✔
54
      Object(session, priv_key_props),
55
      RSA_PublicKey(priv_key_props.modulus(), BigInt::decode(get_attribute_value(AttributeType::PublicExponent))) {}
8✔
56

57
PKCS11_RSA_PrivateKey::PKCS11_RSA_PrivateKey(Session& session,
1✔
58
                                             uint32_t bits,
59
                                             const RSA_PrivateKeyGenerationProperties& priv_key_props) :
1✔
60
      Object(session), RSA_PublicKey() {
1✔
61
   RSA_PublicKeyGenerationProperties pub_key_props(bits);
1✔
62
   pub_key_props.set_encrypt(true);
1✔
63
   pub_key_props.set_verify(true);
1✔
64
   pub_key_props.set_token(false);  // don't create a persistent public key object
1✔
65

66
   ObjectHandle pub_key_handle = CK_INVALID_HANDLE;
1✔
67
   ObjectHandle priv_key_handle = CK_INVALID_HANDLE;
1✔
68
   Mechanism mechanism = {static_cast<CK_MECHANISM_TYPE>(MechanismType::RsaPkcsKeyPairGen), nullptr, 0};
1✔
69
   session.module()->C_GenerateKeyPair(session.handle(),
1✔
70
                                       &mechanism,
71
                                       pub_key_props.data(),
72
                                       static_cast<Ulong>(pub_key_props.count()),
1✔
73
                                       priv_key_props.data(),
74
                                       static_cast<Ulong>(priv_key_props.count()),
1✔
75
                                       &pub_key_handle,
76
                                       &priv_key_handle);
77

78
   this->reset_handle(priv_key_handle);
1✔
79

80
   BigInt n = BigInt::decode(get_attribute_value(AttributeType::Modulus));
2✔
81
   BigInt e = BigInt::decode(get_attribute_value(AttributeType::PublicExponent));
2✔
82
   RSA_PublicKey::init(std::move(n), std::move(e));
1✔
83
}
2✔
84

85
RSA_PrivateKey PKCS11_RSA_PrivateKey::export_key() const {
1✔
86
   auto p = get_attribute_value(AttributeType::Prime1);
1✔
87
   auto q = get_attribute_value(AttributeType::Prime2);
1✔
88
   auto e = get_attribute_value(AttributeType::PublicExponent);
1✔
89
   auto d = get_attribute_value(AttributeType::PrivateExponent);
1✔
90
   auto n = get_attribute_value(AttributeType::Modulus);
1✔
91

92
   return RSA_PrivateKey(BigInt::decode(p), BigInt::decode(q), BigInt::decode(e), BigInt::decode(d), BigInt::decode(n));
11✔
93
}
5✔
94

95
std::unique_ptr<Public_Key> PKCS11_RSA_PrivateKey::public_key() const {
×
96
   return std::make_unique<RSA_PublicKey>(BigInt::decode(get_attribute_value(AttributeType::Modulus)),
×
97
                                          BigInt::decode(get_attribute_value(AttributeType::PublicExponent)));
×
98
}
99

100
secure_vector<uint8_t> PKCS11_RSA_PrivateKey::private_key_bits() const { return export_key().private_key_bits(); }
×
101

102
namespace {
103
// note: multiple-part decryption operations (with C_DecryptUpdate/C_DecryptFinal)
104
// are not supported (PK_Ops::Decryption does not provide an `update` method)
105
class PKCS11_RSA_Decryption_Operation final : public PK_Ops::Decryption {
×
106
   public:
107
      PKCS11_RSA_Decryption_Operation(const PKCS11_RSA_PrivateKey& key,
5✔
108
                                      std::string_view padding,
109
                                      RandomNumberGenerator& rng) :
5✔
110
            m_key(key),
5✔
111
            m_mechanism(MechanismWrapper::create_rsa_crypt_mechanism(padding)),
5✔
112
            m_blinder(
10✔
113
               m_key.get_n(),
5✔
114
               rng,
115
               [this](const BigInt& k) { return power_mod(k, m_key.get_e(), m_key.get_n()); },
5✔
116
               [this](const BigInt& k) { return inverse_mod(k, m_key.get_n()); }) {
10✔
117
         m_bits = m_key.get_n().bits() - 1;
5✔
118
      }
5✔
119

120
      size_t plaintext_length(size_t /*ctext_len*/) const override { return m_key.get_n().bytes(); }
×
121

122
      secure_vector<uint8_t> decrypt(uint8_t& valid_mask, const uint8_t ciphertext[], size_t ciphertext_len) override {
5✔
123
         valid_mask = 0;
5✔
124
         m_key.module()->C_DecryptInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
5✔
125

126
         std::vector<uint8_t> encrypted_data(ciphertext, ciphertext + ciphertext_len);
5✔
127

128
         const size_t modulus_bytes = (m_key.get_n().bits() + 7) / 8;
5✔
129

130
         // blind for RSA/RAW decryption
131
         const bool use_blinding = !m_mechanism.padding_size();
5✔
132

133
         if(use_blinding) {
5✔
134
            const BigInt blinded = m_blinder.blind(BigInt::decode(encrypted_data));
6✔
135
            // SoftHSM at least requires raw RSA inputs be == the modulus size
136
            encrypted_data = unlock(BigInt::encode_1363(blinded, modulus_bytes));
9✔
137
         }
3✔
138

139
         secure_vector<uint8_t> decrypted_data;
5✔
140
         m_key.module()->C_Decrypt(m_key.session().handle(), encrypted_data, decrypted_data);
5✔
141

142
         // Unblind for RSA/RAW decryption
143
         if(use_blinding) {
5✔
144
            const BigInt unblinded = m_blinder.unblind(BigInt::decode(decrypted_data));
6✔
145
            decrypted_data = BigInt::encode_1363(unblinded, modulus_bytes);
6✔
146
         }
3✔
147

148
         valid_mask = 0xFF;
5✔
149
         return decrypted_data;
5✔
150
      }
5✔
151

152
   private:
153
      const PKCS11_RSA_PrivateKey& m_key;
154
      MechanismWrapper m_mechanism;
155
      size_t m_bits = 0;
156
      Blinder m_blinder;
157
};
158

159
// note: multiple-part decryption operations (with C_DecryptUpdate/C_DecryptFinal)
160
// are not supported (PK_Ops::Decryption does not provide an `update` method)
161
class PKCS11_RSA_Decryption_Operation_Software_EME final : public PK_Ops::Decryption_with_EME {
×
162
   public:
163
      PKCS11_RSA_Decryption_Operation_Software_EME(const PKCS11_RSA_PrivateKey& key,
2✔
164
                                                   std::string_view padding,
165
                                                   RandomNumberGenerator& rng) :
2✔
166
            PK_Ops::Decryption_with_EME(padding), m_raw_decryptor(key, rng, "Raw") {}
2✔
167

168
      size_t plaintext_length(size_t ctext_len) const override { return m_raw_decryptor.plaintext_length(ctext_len); }
×
169

170
      secure_vector<uint8_t> raw_decrypt(const uint8_t input[], size_t input_len) override {
2✔
171
         return m_raw_decryptor.decrypt(input, input_len);
2✔
172
      }
173

174
   private:
175
      PK_Decryptor_EME m_raw_decryptor;
176
};
177

178
// note: multiple-part encryption operations (with C_EncryptUpdate/C_EncryptFinal)
179
// are not supported (PK_Ops::Encryption does not provide an `update` method)
180
class PKCS11_RSA_Encryption_Operation final : public PK_Ops::Encryption {
181
   public:
182
      PKCS11_RSA_Encryption_Operation(const PKCS11_RSA_PublicKey& key, std::string_view padding) :
5✔
183
            m_key(key), m_mechanism(MechanismWrapper::create_rsa_crypt_mechanism(padding)) {
5✔
184
         m_bits = 8 * (key.get_n().bytes() - m_mechanism.padding_size()) - 1;
5✔
185
      }
5✔
186

187
      size_t ciphertext_length(size_t /*ptext_len*/) const override { return m_key.get_n().bytes(); }
×
188

189
      size_t max_input_bits() const override { return m_bits; }
×
190

191
      secure_vector<uint8_t> encrypt(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& /*rng*/) override {
5✔
192
         m_key.module()->C_EncryptInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
5✔
193

194
         secure_vector<uint8_t> encrytped_data;
5✔
195
         m_key.module()->C_Encrypt(
5✔
196
            m_key.session().handle(), secure_vector<uint8_t>(msg, msg + msg_len), encrytped_data);
5✔
197
         return encrytped_data;
5✔
198
      }
×
199

200
   private:
201
      const PKCS11_RSA_PublicKey& m_key;
202
      MechanismWrapper m_mechanism;
203
      size_t m_bits = 0;
204
};
205

206
class PKCS11_RSA_Signature_Operation final : public PK_Ops::Signature {
×
207
   public:
208
      PKCS11_RSA_Signature_Operation(const PKCS11_RSA_PrivateKey& key, std::string_view padding) :
5✔
209
            m_key(key), m_mechanism(MechanismWrapper::create_rsa_sign_mechanism(padding)) {}
5✔
210

211
      size_t signature_length() const override { return m_key.get_n().bytes(); }
×
212

213
      void update(const uint8_t msg[], size_t msg_len) override {
7✔
214
         if(!m_initialized) {
7✔
215
            // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
216
            m_key.module()->C_SignInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
5✔
217
            m_initialized = true;
5✔
218
            m_first_message = secure_vector<uint8_t>(msg, msg + msg_len);
5✔
219
            return;
5✔
220
         }
221

222
         if(!m_first_message.empty()) {
2✔
223
            // second call to update: start multiple-part operation
224
            m_key.module()->C_SignUpdate(m_key.session().handle(), m_first_message);
2✔
225
            m_first_message.clear();
2✔
226
         }
227

228
         m_key.module()->C_SignUpdate(m_key.session().handle(), msg, static_cast<Ulong>(msg_len));
2✔
229
      }
230

231
      secure_vector<uint8_t> sign(RandomNumberGenerator& /*rng*/) override {
5✔
232
         secure_vector<uint8_t> signature;
5✔
233
         if(!m_first_message.empty()) {
5✔
234
            // single call to update: perform single-part operation
235
            m_key.module()->C_Sign(m_key.session().handle(), m_first_message, signature);
3✔
236
            m_first_message.clear();
3✔
237
         } else {
238
            // multiple calls to update (or none): finish multiple-part operation
239
            m_key.module()->C_SignFinal(m_key.session().handle(), signature);
2✔
240
         }
241
         m_initialized = false;
5✔
242
         return signature;
5✔
243
      }
×
244

245
      std::string hash_function() const override;
246

247
      AlgorithmIdentifier algorithm_identifier() const override;
248

249
   private:
250
      const PKCS11_RSA_PrivateKey& m_key;
251
      bool m_initialized = false;
252
      secure_vector<uint8_t> m_first_message;
253
      MechanismWrapper m_mechanism;
254
};
255

256
namespace {
257

258
std::string hash_function_name_from_pkcs11_rsa_mechanism_type(MechanismType type) {
×
259
   switch(type) {
×
260
      case MechanismType::Sha1RsaPkcs:
×
261
      case MechanismType::Sha1RsaPkcsPss:
×
262
      case MechanismType::Sha1RsaX931:
×
263
         return "SHA-1";
×
264

265
      case MechanismType::Sha224RsaPkcs:
×
266
      case MechanismType::Sha224RsaPkcsPss:
×
267
         return "SHA-224";
×
268

269
      case MechanismType::Sha256RsaPkcs:
×
270
      case MechanismType::Sha256RsaPkcsPss:
×
271
         return "SHA-256";
×
272

273
      case MechanismType::Sha384RsaPkcs:
×
274
      case MechanismType::Sha384RsaPkcsPss:
×
275
         return "SHA-348";
×
276

277
      case MechanismType::Sha512RsaPkcs:
×
278
      case MechanismType::Sha512RsaPkcsPss:
×
279
         return "SHA-512";
×
280

281
      case MechanismType::RsaX509:
×
282
      case MechanismType::RsaX931:
×
283
      case MechanismType::RsaPkcs:
×
284
      case MechanismType::RsaPkcsPss:
×
285
         return "Raw";
×
286

287
      default:
×
288
         throw Internal_Error("Unable to determine associated hash function of PKCS11 RSA signature operation");
×
289
   }
290
}
291

292
}
293

294
std::string PKCS11_RSA_Signature_Operation::hash_function() const {
×
295
   return hash_function_name_from_pkcs11_rsa_mechanism_type(m_mechanism.mechanism_type());
×
296
}
297

298
AlgorithmIdentifier PKCS11_RSA_Signature_Operation::algorithm_identifier() const {
×
299
   const std::string hash = this->hash_function();
×
300

301
   switch(m_mechanism.mechanism_type()) {
×
302
      case MechanismType::Sha1RsaPkcs:
×
303
      case MechanismType::Sha224RsaPkcs:
×
304
      case MechanismType::Sha256RsaPkcs:
×
305
      case MechanismType::Sha384RsaPkcs:
×
306
      case MechanismType::Sha512RsaPkcs: {
×
307
         const OID oid = OID::from_string("RSA/EMSA3(" + hash + ")");
×
308
         return AlgorithmIdentifier(oid, AlgorithmIdentifier::USE_NULL_PARAM);
×
309
      }
×
310

311
      case MechanismType::Sha1RsaPkcsPss:
×
312
      case MechanismType::Sha224RsaPkcsPss:
×
313
      case MechanismType::Sha256RsaPkcsPss:
×
314
      case MechanismType::Sha384RsaPkcsPss:
×
315
      case MechanismType::Sha512RsaPkcsPss:
×
316
         throw Not_Implemented("RSA-PSS identifier encoding missing for PKCS11");
×
317

318
      default:
×
319
         throw Not_Implemented("No algorithm identifier defined for RSA with this PKCS11 mechanism");
×
320
   }
321
}
×
322

323
class PKCS11_RSA_Verification_Operation final : public PK_Ops::Verification {
×
324
   public:
325
      PKCS11_RSA_Verification_Operation(const PKCS11_RSA_PublicKey& key, std::string_view padding) :
5✔
326
            m_key(key), m_mechanism(MechanismWrapper::create_rsa_sign_mechanism(padding)) {}
5✔
327

328
      void update(const uint8_t msg[], size_t msg_len) override {
7✔
329
         if(!m_initialized) {
7✔
330
            // first call to update: initialize and cache message because we can not determine yet whether a single- or multiple-part operation will be performed
331
            m_key.module()->C_VerifyInit(m_key.session().handle(), m_mechanism.data(), m_key.handle());
5✔
332
            m_initialized = true;
5✔
333
            m_first_message = secure_vector<uint8_t>(msg, msg + msg_len);
5✔
334
            return;
5✔
335
         }
336

337
         if(!m_first_message.empty()) {
2✔
338
            // second call to update: start multiple-part operation
339
            m_key.module()->C_VerifyUpdate(m_key.session().handle(), m_first_message);
2✔
340
            m_first_message.clear();
2✔
341
         }
342

343
         m_key.module()->C_VerifyUpdate(m_key.session().handle(), msg, static_cast<Ulong>(msg_len));
2✔
344
      }
345

346
      bool is_valid_signature(const uint8_t sig[], size_t sig_len) override {
5✔
347
         ReturnValue return_value = ReturnValue::SignatureInvalid;
5✔
348
         if(!m_first_message.empty()) {
5✔
349
            // single call to update: perform single-part operation
350
            m_key.module()->C_Verify(m_key.session().handle(),
3✔
351
                                     m_first_message.data(),
3✔
352
                                     static_cast<Ulong>(m_first_message.size()),
3✔
353
                                     sig,
354
                                     static_cast<Ulong>(sig_len),
355
                                     &return_value);
356
            m_first_message.clear();
3✔
357
         } else {
358
            // multiple calls to update (or none): finish multiple-part operation
359
            m_key.module()->C_VerifyFinal(m_key.session().handle(), sig, static_cast<Ulong>(sig_len), &return_value);
2✔
360
         }
361
         m_initialized = false;
5✔
362
         if(return_value != ReturnValue::OK && return_value != ReturnValue::SignatureInvalid) {
5✔
363
            throw PKCS11_ReturnError(return_value);
×
364
         }
365
         return return_value == ReturnValue::OK;
5✔
366
      }
367

368
      std::string hash_function() const override;
369

370
   private:
371
      const PKCS11_RSA_PublicKey& m_key;
372
      bool m_initialized = false;
373
      secure_vector<uint8_t> m_first_message;
374
      MechanismWrapper m_mechanism;
375
};
376

377
std::string PKCS11_RSA_Verification_Operation::hash_function() const {
×
378
   return hash_function_name_from_pkcs11_rsa_mechanism_type(m_mechanism.mechanism_type());
×
379
}
380

381
}
382

383
std::unique_ptr<PK_Ops::Encryption> PKCS11_RSA_PublicKey::create_encryption_op(RandomNumberGenerator& /*rng*/,
5✔
384
                                                                               std::string_view params,
385
                                                                               std::string_view /*provider*/) const {
386
   return std::make_unique<PKCS11_RSA_Encryption_Operation>(*this, params);
5✔
387
}
388

389
std::unique_ptr<PK_Ops::Verification> PKCS11_RSA_PublicKey::create_verification_op(
5✔
390
   std::string_view params, std::string_view /*provider*/) const {
391
   return std::make_unique<PKCS11_RSA_Verification_Operation>(*this, params);
5✔
392
}
393

394
std::unique_ptr<PK_Ops::Decryption> PKCS11_RSA_PrivateKey::create_decryption_op(RandomNumberGenerator& rng,
7✔
395
                                                                                std::string_view params,
396
                                                                                std::string_view /*provider*/) const {
397
   if(params != "Raw" && m_use_software_padding) {
10✔
398
      return std::make_unique<PKCS11_RSA_Decryption_Operation_Software_EME>(*this, params, rng);
2✔
399
   } else {
400
      return std::make_unique<PKCS11_RSA_Decryption_Operation>(*this, params, rng);
5✔
401
   }
402
}
403

404
std::unique_ptr<PK_Ops::Signature> PKCS11_RSA_PrivateKey::create_signature_op(RandomNumberGenerator& /*rng*/,
5✔
405
                                                                              std::string_view params,
406
                                                                              std::string_view /*provider*/) const {
407
   return std::make_unique<PKCS11_RSA_Signature_Operation>(*this, params);
5✔
408
}
409

410
PKCS11_RSA_KeyPair generate_rsa_keypair(Session& session,
3✔
411
                                        const RSA_PublicKeyGenerationProperties& pub_props,
412
                                        const RSA_PrivateKeyGenerationProperties& priv_props) {
413
   ObjectHandle pub_key_handle = 0;
3✔
414
   ObjectHandle priv_key_handle = 0;
3✔
415

416
   Mechanism mechanism = {static_cast<CK_MECHANISM_TYPE>(MechanismType::RsaPkcsKeyPairGen), nullptr, 0};
3✔
417

418
   session.module()->C_GenerateKeyPair(session.handle(),
3✔
419
                                       &mechanism,
420
                                       pub_props.data(),
421
                                       static_cast<Ulong>(pub_props.count()),
3✔
422
                                       priv_props.data(),
423
                                       static_cast<Ulong>(priv_props.count()),
3✔
424
                                       &pub_key_handle,
425
                                       &priv_key_handle);
426

427
   return std::make_pair(PKCS11_RSA_PublicKey(session, pub_key_handle),
6✔
428
                         PKCS11_RSA_PrivateKey(session, priv_key_handle));
9✔
429
}
430

431
}
432

433
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc