Botan  2.8.0
Crypto and TLS for C++11
openssl_rsa.cpp
Go to the documentation of this file.
1 /*
2 * RSA operations provided by OpenSSL
3 * (C) 2015 Jack Lloyd
4 * (C) 2017 Alexander Bluhm
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #include <botan/internal/openssl.h>
10 
11 #if defined(BOTAN_HAS_RSA)
12 
13 #include <botan/rsa.h>
14 #include <botan/rng.h>
15 #include <botan/internal/pk_ops_impl.h>
16 #include <botan/internal/ct_utils.h>
17 
18 #include <functional>
19 #include <memory>
20 #include <cstdlib>
21 
22 #include <openssl/rsa.h>
23 #include <openssl/x509.h>
24 #include <openssl/err.h>
25 #include <openssl/rand.h>
26 #include <limits.h>
27 
28 namespace Botan {
29 
30 namespace {
31 
32 std::pair<int, size_t> get_openssl_enc_pad(const std::string& eme)
33  {
34  if(eme == "Raw")
35  return std::make_pair(RSA_NO_PADDING, 0);
36  else if(eme == "EME-PKCS1-v1_5")
37  return std::make_pair(RSA_PKCS1_PADDING, 11);
38  else if(eme == "OAEP(SHA-1)" || eme == "EME1(SHA-1)")
39  return std::make_pair(RSA_PKCS1_OAEP_PADDING, 41);
40  else
41  throw Lookup_Error("OpenSSL RSA does not support EME " + eme);
42  }
43 
44 class OpenSSL_RSA_Encryption_Operation final : public PK_Ops::Encryption
45  {
46  public:
47 
48  OpenSSL_RSA_Encryption_Operation(const RSA_PublicKey& rsa, int pad, size_t pad_overhead) :
49  m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad)
50  {
51  const std::vector<uint8_t> der = rsa.public_key_bits();
52  const uint8_t* der_ptr = der.data();
53  m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size()));
54  if(!m_openssl_rsa)
55  throw OpenSSL_Error("d2i_RSAPublicKey");
56 
57  m_bits = 8 * (n_size() - pad_overhead) - 1;
58  }
59 
60  size_t ciphertext_length(size_t) const override { return ::RSA_size(m_openssl_rsa.get()); }
61 
62  size_t max_input_bits() const override { return m_bits; };
63 
64  secure_vector<uint8_t> encrypt(const uint8_t msg[], size_t msg_len,
65  RandomNumberGenerator&) override
66  {
67  const size_t mod_sz = n_size();
68 
69  if(msg_len > mod_sz)
70  throw Invalid_Argument("Input too large for RSA key");
71 
72  secure_vector<uint8_t> outbuf(mod_sz);
73 
74  secure_vector<uint8_t> inbuf;
75 
76  if(m_padding == RSA_NO_PADDING)
77  {
78  inbuf.resize(mod_sz);
79  copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
80  }
81  else
82  {
83  inbuf.assign(msg, msg + msg_len);
84  }
85 
86  int rc = ::RSA_public_encrypt(inbuf.size(), inbuf.data(), outbuf.data(),
87  m_openssl_rsa.get(), m_padding);
88  if(rc < 0)
89  throw OpenSSL_Error("RSA_public_encrypt");
90 
91  return outbuf;
92  }
93 
94  private:
95  size_t n_size() const { return ::RSA_size(m_openssl_rsa.get()); }
96  std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
97  size_t m_bits = 0;
98  int m_padding = 0;
99  };
100 
101 class OpenSSL_RSA_Decryption_Operation final : public PK_Ops::Decryption
102  {
103  public:
104 
105  OpenSSL_RSA_Decryption_Operation(const RSA_PrivateKey& rsa, int pad) :
106  m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad)
107  {
108  const secure_vector<uint8_t> der = rsa.private_key_bits();
109  const uint8_t* der_ptr = der.data();
110  m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
111  if(!m_openssl_rsa)
112  throw OpenSSL_Error("d2i_RSAPrivateKey");
113  }
114 
115  size_t plaintext_length(size_t) const override { return ::RSA_size(m_openssl_rsa.get()); }
116 
117  secure_vector<uint8_t> decrypt(uint8_t& valid_mask,
118  const uint8_t msg[], size_t msg_len) override
119  {
120  secure_vector<uint8_t> buf(::RSA_size(m_openssl_rsa.get()));
121  int rc = ::RSA_private_decrypt(msg_len, msg, buf.data(), m_openssl_rsa.get(), m_padding);
122  if(rc < 0 || static_cast<size_t>(rc) > buf.size())
123  {
124  valid_mask = 0;
125  buf.resize(0);
126  }
127  else
128  {
129  valid_mask = 0xFF;
130  buf.resize(rc);
131  }
132 
133  if(m_padding == RSA_NO_PADDING)
134  {
135  return CT::strip_leading_zeros(buf);
136  }
137 
138  return buf;
139  }
140 
141  private:
142  std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
143  int m_padding = 0;
144  };
145 
146 class OpenSSL_RSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA
147  {
148  public:
149 
150  OpenSSL_RSA_Verification_Operation(const RSA_PublicKey& rsa, const std::string& emsa) :
151  PK_Ops::Verification_with_EMSA(emsa),
152  m_openssl_rsa(nullptr, ::RSA_free)
153  {
154  const std::vector<uint8_t> der = rsa.public_key_bits();
155  const uint8_t* der_ptr = der.data();
156  m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size()));
157  if(!m_openssl_rsa)
158  throw OpenSSL_Error("d2i_RSAPublicKey");
159  }
160 
161  size_t max_input_bits() const override
162  {
163 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
164  return ::BN_num_bits(m_openssl_rsa->n) - 1;
165 #else
166  return ::RSA_bits(m_openssl_rsa.get()) - 1;
167 #endif
168  }
169 
170  bool with_recovery() const override { return true; }
171 
172  secure_vector<uint8_t> verify_mr(const uint8_t msg[], size_t msg_len) override
173  {
174  const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
175 
176  if(msg_len > mod_sz)
177  throw Invalid_Argument("OpenSSL RSA verify input too large");
178 
179  secure_vector<uint8_t> inbuf(mod_sz);
180 
181  if(msg_len > 0)
182  copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
183 
184  secure_vector<uint8_t> outbuf(mod_sz);
185 
186  int rc = ::RSA_public_decrypt(inbuf.size(), inbuf.data(), outbuf.data(),
187  m_openssl_rsa.get(), RSA_NO_PADDING);
188  if(rc < 0)
189  throw Invalid_Argument("RSA_public_decrypt");
190 
191  return CT::strip_leading_zeros(outbuf);
192  }
193  private:
194  std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
195  };
196 
197 class OpenSSL_RSA_Signing_Operation final : public PK_Ops::Signature_with_EMSA
198  {
199  public:
200 
201  OpenSSL_RSA_Signing_Operation(const RSA_PrivateKey& rsa, const std::string& emsa) :
202  PK_Ops::Signature_with_EMSA(emsa),
203  m_openssl_rsa(nullptr, ::RSA_free)
204  {
205  const secure_vector<uint8_t> der = rsa.private_key_bits();
206  const uint8_t* der_ptr = der.data();
207  m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
208  if(!m_openssl_rsa)
209  throw OpenSSL_Error("d2i_RSAPrivateKey");
210  }
211 
212  size_t signature_length() const override { return ::RSA_size(m_openssl_rsa.get()); }
213 
214  secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len,
215  RandomNumberGenerator&) override
216  {
217  const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
218 
219  if(msg_len > mod_sz)
220  throw Invalid_Argument("OpenSSL RSA sign input too large");
221 
222  secure_vector<uint8_t> inbuf(mod_sz);
223  copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
224 
225  secure_vector<uint8_t> outbuf(mod_sz);
226 
227  int rc = ::RSA_private_encrypt(inbuf.size(), inbuf.data(), outbuf.data(),
228  m_openssl_rsa.get(), RSA_NO_PADDING);
229  if(rc < 0)
230  throw OpenSSL_Error("RSA_private_encrypt");
231 
232  return outbuf;
233  }
234 
235  size_t max_input_bits() const override
236  {
237 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
238  return ::BN_num_bits(m_openssl_rsa->n) - 1;
239 #else
240  return ::RSA_bits(m_openssl_rsa.get()) - 1;
241 #endif
242  }
243 
244  private:
245  std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
246  };
247 
248 }
249 
250 std::unique_ptr<PK_Ops::Encryption>
251 make_openssl_rsa_enc_op(const RSA_PublicKey& key, const std::string& params)
252  {
253  auto pad_info = get_openssl_enc_pad(params);
254  return std::unique_ptr<PK_Ops::Encryption>(
255  new OpenSSL_RSA_Encryption_Operation(key, pad_info.first, pad_info.second));
256  }
257 
258 std::unique_ptr<PK_Ops::Decryption>
259 make_openssl_rsa_dec_op(const RSA_PrivateKey& key, const std::string& params)
260  {
261  auto pad_info = get_openssl_enc_pad(params);
262  return std::unique_ptr<PK_Ops::Decryption>(new OpenSSL_RSA_Decryption_Operation(key, pad_info.first));
263  }
264 
265 std::unique_ptr<PK_Ops::Verification>
266 make_openssl_rsa_ver_op(const RSA_PublicKey& key, const std::string& params)
267  {
268  return std::unique_ptr<PK_Ops::Verification>(new OpenSSL_RSA_Verification_Operation(key, params));
269  }
270 
271 std::unique_ptr<PK_Ops::Signature>
272 make_openssl_rsa_sig_op(const RSA_PrivateKey& key, const std::string& params)
273  {
274  return std::unique_ptr<PK_Ops::Signature>(new OpenSSL_RSA_Signing_Operation(key, params));
275  }
276 
277 std::unique_ptr<RSA_PrivateKey>
278 make_openssl_rsa_private_key(RandomNumberGenerator& rng, size_t rsa_bits)
279  {
280  if (rsa_bits > INT_MAX)
281  throw Internal_Error("rsa_bits overflow");
282 
283  secure_vector<uint8_t> seed(BOTAN_SYSTEM_RNG_POLL_REQUEST);
284  rng.randomize(seed.data(), seed.size());
285  RAND_seed(seed.data(), seed.size());
286 
287  std::unique_ptr<BIGNUM, std::function<void (BIGNUM*)>> bn(BN_new(), BN_free);
288  if(!bn)
289  throw OpenSSL_Error("BN_new");
290  if(!BN_set_word(bn.get(), RSA_F4))
291  throw OpenSSL_Error("BN_set_word");
292 
293  std::unique_ptr<RSA, std::function<void (RSA*)>> rsa(RSA_new(), RSA_free);
294  if(!rsa)
295  throw OpenSSL_Error("RSA_new");
296  if(!RSA_generate_key_ex(rsa.get(), rsa_bits, bn.get(), nullptr))
297  throw OpenSSL_Error("RSA_generate_key_ex");
298 
299  uint8_t* der = nullptr;
300  int bytes = i2d_RSAPrivateKey(rsa.get(), &der);
301  if(bytes < 0)
302  throw OpenSSL_Error("i2d_RSAPrivateKey");
303 
304  const secure_vector<uint8_t> keydata(der, der + bytes);
305  memset(der, 0, bytes);
306  std::free(der);
307  return std::unique_ptr<Botan::RSA_PrivateKey>
308  (new RSA_PrivateKey(AlgorithmIdentifier(), keydata));
309  }
310 }
311 
312 #endif // BOTAN_HAS_RSA
int(* final)(unsigned char *, CTX *)
std::string decrypt(const uint8_t input[], size_t input_len, const std::string &passphrase)
Definition: cryptobox.cpp:162
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:108
Definition: alg_id.cpp:13
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 > strip_leading_zeros(const uint8_t in[], size_t length)
Definition: ct_utils.h:191