Botan  1.10.16
ossl_pk.cpp
Go to the documentation of this file.
1 /*
2 * OpenSSL PK operations
3 * (C) 1999-2010 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/internal/openssl_engine.h>
9 #include <botan/internal/bn_wrap.h>
10 
11 #if defined(BOTAN_HAS_RSA)
12  #include <botan/rsa.h>
13 #endif
14 
15 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
16  #include <botan/dh.h>
17 #endif
18 
19 #if defined(BOTAN_HAS_DSA)
20  #include <botan/dsa.h>
21 #endif
22 
23 #if defined(BOTAN_HAS_ECDSA)
24  #include <botan/ecdsa.h>
25 
26  #include <openssl/evp.h>
27 
28 #if !defined(OPENSSL_NO_ECDSA)
29  #include <openssl/ecdsa.h>
30 #endif
31 
32 #endif
33 
34 namespace Botan {
35 
36 namespace {
37 
38 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
39 class OSSL_DH_KA_Operation : public PK_Ops::Key_Agreement
40  {
41  public:
42  OSSL_DH_KA_Operation(const DH_PrivateKey& dh) :
43  x(dh.get_x()), p(dh.group_p()) {}
44 
45  SecureVector<byte> agree(const byte w[], size_t w_len)
46  {
47  OSSL_BN i(w, w_len), r;
48  BN_mod_exp(r.value, i.value, x.value, p.value, ctx.value);
49  return r.to_bytes();
50  }
51 
52  private:
53  const OSSL_BN x, p;
54  OSSL_BN_CTX ctx;
55  };
56 #endif
57 
58 #if defined(BOTAN_HAS_DSA)
59 
60 class OSSL_DSA_Signature_Operation : public PK_Ops::Signature
61  {
62  public:
63  OSSL_DSA_Signature_Operation(const DSA_PrivateKey& dsa) :
64  x(dsa.get_x()),
65  p(dsa.group_p()),
66  q(dsa.group_q()),
67  g(dsa.group_g()),
68  q_bits(dsa.group_q().bits()) {}
69 
70  size_t message_parts() const { return 2; }
71  size_t message_part_size() const { return (q_bits + 7) / 8; }
72  size_t max_input_bits() const { return q_bits; }
73 
74  SecureVector<byte> sign(const byte msg[], size_t msg_len,
75  RandomNumberGenerator& rng);
76  private:
77  const OSSL_BN x, p, q, g;
78  const OSSL_BN_CTX ctx;
79  size_t q_bits;
80  };
81 
82 SecureVector<byte>
83 OSSL_DSA_Signature_Operation::sign(const byte msg[], size_t msg_len,
84  RandomNumberGenerator& rng)
85  {
86  const size_t q_bytes = (q_bits + 7) / 8;
87 
88  rng.add_entropy(msg, msg_len);
89 
90  BigInt k_bn;
91  do
92  k_bn.randomize(rng, q_bits);
93  while(k_bn >= q.to_bigint());
94 
95  OSSL_BN i(msg, msg_len);
96  OSSL_BN k(k_bn);
97 
98  OSSL_BN r;
99  BN_mod_exp(r.value, g.value, k.value, p.value, ctx.value);
100  BN_nnmod(r.value, r.value, q.value, ctx.value);
101 
102  BN_mod_inverse(k.value, k.value, q.value, ctx.value);
103 
104  OSSL_BN s;
105  BN_mul(s.value, x.value, r.value, ctx.value);
106  BN_add(s.value, s.value, i.value);
107  BN_mod_mul(s.value, s.value, k.value, q.value, ctx.value);
108 
109  if(BN_is_zero(r.value) || BN_is_zero(s.value))
110  throw Internal_Error("OpenSSL_DSA_Op::sign: r or s was zero");
111 
112  SecureVector<byte> output(2*q_bytes);
113  r.encode(output, q_bytes);
114  s.encode(output + q_bytes, q_bytes);
115  return output;
116  }
117 
118 class OSSL_DSA_Verification_Operation : public PK_Ops::Verification
119  {
120  public:
121  OSSL_DSA_Verification_Operation(const DSA_PublicKey& dsa) :
122  y(dsa.get_y()),
123  p(dsa.group_p()),
124  q(dsa.group_q()),
125  g(dsa.group_g()),
126  q_bits(dsa.group_q().bits()) {}
127 
128  size_t message_parts() const { return 2; }
129  size_t message_part_size() const { return (q_bits + 7) / 8; }
130  size_t max_input_bits() const { return q_bits; }
131 
132  bool with_recovery() const { return false; }
133 
134  bool verify(const byte msg[], size_t msg_len,
135  const byte sig[], size_t sig_len);
136  private:
137  const OSSL_BN y, p, q, g;
138  const OSSL_BN_CTX ctx;
139  size_t q_bits;
140  };
141 
142 bool OSSL_DSA_Verification_Operation::verify(const byte msg[], size_t msg_len,
143  const byte sig[], size_t sig_len)
144  {
145  const size_t q_bytes = q.bytes();
146 
147  if(sig_len != 2*q_bytes || msg_len > q_bytes)
148  return false;
149 
150  OSSL_BN r(sig, q_bytes);
151  OSSL_BN s(sig + q_bytes, q_bytes);
152  OSSL_BN i(msg, msg_len);
153 
154  if(BN_is_zero(r.value) || BN_cmp(r.value, q.value) >= 0)
155  return false;
156  if(BN_is_zero(s.value) || BN_cmp(s.value, q.value) >= 0)
157  return false;
158 
159  if(BN_mod_inverse(s.value, s.value, q.value, ctx.value) == 0)
160  return false;
161 
162  OSSL_BN si;
163  BN_mod_mul(si.value, s.value, i.value, q.value, ctx.value);
164  BN_mod_exp(si.value, g.value, si.value, p.value, ctx.value);
165 
166  OSSL_BN sr;
167  BN_mod_mul(sr.value, s.value, r.value, q.value, ctx.value);
168  BN_mod_exp(sr.value, y.value, sr.value, p.value, ctx.value);
169 
170  BN_mod_mul(si.value, si.value, sr.value, p.value, ctx.value);
171  BN_nnmod(si.value, si.value, q.value, ctx.value);
172 
173  if(BN_cmp(si.value, r.value) == 0)
174  return true;
175  return false;
176 
177  return false;
178  }
179 
180 #endif
181 
182 #if defined(BOTAN_HAS_RSA)
183 
184 class OSSL_RSA_Private_Operation : public PK_Ops::Signature,
185  public PK_Ops::Decryption
186  {
187  public:
188  OSSL_RSA_Private_Operation(const RSA_PrivateKey& rsa) :
189  mod(rsa.get_n()),
190  p(rsa.get_p()),
191  q(rsa.get_q()),
192  d1(rsa.get_d1()),
193  d2(rsa.get_d2()),
194  c(rsa.get_c()),
195  n_bits(rsa.get_n().bits())
196  {}
197 
198  size_t max_input_bits() const { return (n_bits - 1); }
199 
200  SecureVector<byte> sign(const byte msg[], size_t msg_len,
201  RandomNumberGenerator&)
202  {
203  BigInt m(msg, msg_len);
204  BigInt x = private_op(m);
205  return BigInt::encode_1363(x, (n_bits + 7) / 8);
206  }
207 
208  SecureVector<byte> decrypt(const byte msg[], size_t msg_len)
209  {
210  BigInt m(msg, msg_len);
211  return BigInt::encode(private_op(m));
212  }
213 
214  private:
215  BigInt private_op(const BigInt& m) const;
216 
217  const OSSL_BN mod, p, q, d1, d2, c;
218  const OSSL_BN_CTX ctx;
219  size_t n_bits;
220  };
221 
222 BigInt OSSL_RSA_Private_Operation::private_op(const BigInt& m) const
223  {
224  OSSL_BN j1, j2, h(m);
225 
226  BN_mod_exp(j1.value, h.value, d1.value, p.value, ctx.value);
227  BN_mod_exp(j2.value, h.value, d2.value, q.value, ctx.value);
228  BN_sub(h.value, j1.value, j2.value);
229  BN_mod_mul(h.value, h.value, c.value, p.value, ctx.value);
230  BN_mul(h.value, h.value, q.value, ctx.value);
231  BN_add(h.value, h.value, j2.value);
232  return h.to_bigint();
233  }
234 
235 class OSSL_RSA_Public_Operation : public PK_Ops::Verification,
236  public PK_Ops::Encryption
237  {
238  public:
239  OSSL_RSA_Public_Operation(const RSA_PublicKey& rsa) :
240  n(rsa.get_n()), e(rsa.get_e()), mod(rsa.get_n())
241  {}
242 
243  size_t max_input_bits() const { return (n.bits() - 1); }
244  bool with_recovery() const { return true; }
245 
246  SecureVector<byte> encrypt(const byte msg[], size_t msg_len,
247  RandomNumberGenerator&)
248  {
249  BigInt m(msg, msg_len);
250  return BigInt::encode_1363(public_op(m), n.bytes());
251  }
252 
253  SecureVector<byte> verify_mr(const byte msg[], size_t msg_len)
254  {
255  BigInt m(msg, msg_len);
256  return BigInt::encode(public_op(m));
257  }
258 
259  private:
260  BigInt public_op(const BigInt& m) const
261  {
262  if(m >= n)
263  throw Invalid_Argument("RSA public op - input is too large");
264 
265  OSSL_BN m_bn(m), r;
266  BN_mod_exp(r.value, m_bn.value, e.value, mod.value, ctx.value);
267  return r.to_bigint();
268  }
269 
270  const BigInt& n;
271  const OSSL_BN e, mod;
272  const OSSL_BN_CTX ctx;
273  };
274 
275 #endif
276 
277 }
278 
279 PK_Ops::Key_Agreement*
281  {
282 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
283  if(const DH_PrivateKey* dh = dynamic_cast<const DH_PrivateKey*>(&key))
284  return new OSSL_DH_KA_Operation(*dh);
285 #endif
286 
287  return 0;
288  }
289 
292  {
293 #if defined(BOTAN_HAS_RSA)
294  if(const RSA_PrivateKey* s = dynamic_cast<const RSA_PrivateKey*>(&key))
295  return new OSSL_RSA_Private_Operation(*s);
296 #endif
297 
298 #if defined(BOTAN_HAS_DSA)
299  if(const DSA_PrivateKey* s = dynamic_cast<const DSA_PrivateKey*>(&key))
300  return new OSSL_DSA_Signature_Operation(*s);
301 #endif
302 
303  return 0;
304  }
305 
308  {
309 #if defined(BOTAN_HAS_RSA)
310  if(const RSA_PublicKey* s = dynamic_cast<const RSA_PublicKey*>(&key))
311  return new OSSL_RSA_Public_Operation(*s);
312 #endif
313 
314 #if defined(BOTAN_HAS_DSA)
315  if(const DSA_PublicKey* s = dynamic_cast<const DSA_PublicKey*>(&key))
316  return new OSSL_DSA_Verification_Operation(*s);
317 #endif
318 
319  return 0;
320  }
321 
324  {
325 #if defined(BOTAN_HAS_RSA)
326  if(const RSA_PublicKey* s = dynamic_cast<const RSA_PublicKey*>(&key))
327  return new OSSL_RSA_Public_Operation(*s);
328 #endif
329 
330  return 0;
331  }
332 
335  {
336 #if defined(BOTAN_HAS_RSA)
337  if(const RSA_PrivateKey* s = dynamic_cast<const RSA_PrivateKey*>(&key))
338  return new OSSL_RSA_Private_Operation(*s);
339 #endif
340 
341  return 0;
342  }
343 
344 }
PK_Ops::Encryption * get_encryption_op(const Public_Key &key) const
Definition: ossl_pk.cpp:323
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:64
PK_Ops::Signature * get_signature_op(const Private_Key &key) const
Definition: ossl_pk.cpp:291
unsigned char byte
Definition: types.h:22
PK_Ops::Verification * get_verify_op(const Public_Key &key) const
Definition: ossl_pk.cpp:307
PK_Ops::Decryption * get_decryption_op(const Private_Key &key) const
Definition: ossl_pk.cpp:334
PK_Ops::Key_Agreement * get_key_agreement_op(const Private_Key &key) const
Definition: ossl_pk.cpp:280
static SecureVector< byte > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:78