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