Botan: src/engine/openssl/ossl_pk.cpp Source File

Botan 1.10.17

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*
280 OpenSSL_Engine::get_key_agreement_op(const Private_Key& key) const
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
290 PK_Ops::Signature*
291 OpenSSL_Engine::get_signature_op(const Private_Key& key) const
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
306 PK_Ops::Verification*
307 OpenSSL_Engine::get_verify_op(const Public_Key& key) const
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
322 PK_Ops::Encryption*
323 OpenSSL_Engine::get_encryption_op(const Public_Key& key) const
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
333 PK_Ops::Decryption*
334 OpenSSL_Engine::get_decryption_op(const Private_Key& key) const
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 }
Botan::OpenSSL_Engine::get_encryption_op
PK_Ops::Encryption * get_encryption_op(const Public_Key &key) const
Definition: ossl_pk.cpp:323
Botan::RandomNumberGenerator::add_entropy
virtual void add_entropy(const byte in[], size_t length)=0
Botan::Private_Key
Definition: pk_keys.h:86
Botan::PK_Ops::Signature
Definition: pk_ops.h:49
Botan::Invalid_Argument
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
Botan::BigInt::encode
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
Definition: big_code.cpp:64
Botan::OpenSSL_Engine::get_signature_op
PK_Ops::Signature * get_signature_op(const Private_Key &key) const
Definition: ossl_pk.cpp:291
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::OpenSSL_Engine::get_verify_op
PK_Ops::Verification * get_verify_op(const Public_Key &key) const
Definition: ossl_pk.cpp:307
Botan::OpenSSL_Engine::get_decryption_op
PK_Ops::Decryption * get_decryption_op(const Private_Key &key) const
Definition: ossl_pk.cpp:334
Botan::DSA_PrivateKey
Definition: dsa.h:45
Botan::RSA_PrivateKey
Definition: rsa.h:47
Botan
Definition: algo_base.h:14
Botan::Public_Key
Definition: pk_keys.h:21
Botan::DSA_PublicKey
Definition: dsa.h:21
Botan::OpenSSL_Engine::get_key_agreement_op
PK_Ops::Key_Agreement * get_key_agreement_op(const Private_Key &key) const
Definition: ossl_pk.cpp:280
Botan::PK_Ops::Decryption
Definition: pk_ops.h:35
Botan::DH_PrivateKey
Definition: dh.h:48
Botan::OSSL_BN_CTX::value
BN_CTX * value
Definition: bn_wrap.h:45
Botan::PK_Ops::Encryption
Definition: pk_ops.h:21
Botan::BigInt::encode_1363
static SecureVector< byte > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:78
Botan::PK_Ops::Verification
Definition: pk_ops.h:85
Botan::RSA_PublicKey
Definition: rsa.h:21