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

Botan 1.10.12

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

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*
274 OpenSSL_Engine::get_key_agreement_op(const Private_Key& key) const
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
284 PK_Ops::Signature*
285 OpenSSL_Engine::get_signature_op(const Private_Key& key) const
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
300 PK_Ops::Verification*
301 OpenSSL_Engine::get_verify_op(const Public_Key& key) const
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
316 PK_Ops::Encryption*
317 OpenSSL_Engine::get_encryption_op(const Public_Key& key) const
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
327 PK_Ops::Decryption*
328 OpenSSL_Engine::get_decryption_op(const Private_Key& key) const
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 }
Botan::OpenSSL_Engine::get_key_agreement_op
PK_Ops::Key_Agreement * get_key_agreement_op(const Private_Key &key) const
Definition: ossl_pk.cpp:274
Botan::Private_Key
Definition: pk_keys.h:86
Botan::OpenSSL_Engine::get_decryption_op
PK_Ops::Decryption * get_decryption_op(const Private_Key &key) const
Definition: ossl_pk.cpp:328
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_encryption_op
PK_Ops::Encryption * get_encryption_op(const Public_Key &key) const
Definition: ossl_pk.cpp:317
Botan::byte
unsigned char byte
Definition: types.h:22
m
endian little unaligned ok family x86< aliases > ia32 x86 ix86 i86pc x86pc bepc</aliases >< submodels > i386 i486 i586 i686 pentium2 pentium3 pentium4 pentium m prescott k6 athlon atom32</submodels >< submodel_aliases > pentium i586 pentiumpro i686 pentium_pro i686 pentium2 pentium2 pentiumii pentium2 pentium3 pentium3 pentiumiii pentium3 x86family5 i586 x86family6 i686 pentiumm pentium m intelpentiumm pentium m intelpentium4 pentium4 duron athlon athlon xp athlon k7 athlon p2 i686 p3 i686 p4 pentium4 intelcput2250 prescott intelcput2300 prescott intelcput2400 prescott intelcput2500 prescott intelcput2600 prescott intelcput2700 prescott</submodel_aliases >< isa_extn > pentium m
Definition: x86_32.txt:65
Botan::OpenSSL_Engine::get_signature_op
PK_Ops::Signature * get_signature_op(const Private_Key &key) const
Definition: ossl_pk.cpp:285
h
macro_name HP_ACC binary_name aCC compile_option c output_to_option o add_include_dir_option I add_lib_dir_option L add_lib_option l lib_opt_flags O2 check_opt_flags O2 debug_flags g no_debug_flags lang_flags AA ext eh z warning_flags shared_flags Z makefile_style unix< mach_abi_linking > hppa1 DAportable hppa1 DA1 hppa2 DA2</mach_abi_linking >< so_link_flags > h
Definition: hpcc.txt:28
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::PK_Ops::Decryption
Definition: pk_ops.h:35
Botan::DH_PrivateKey
Definition: dh.h:48
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::OpenSSL_Engine::get_verify_op
PK_Ops::Verification * get_verify_op(const Public_Key &key) const
Definition: ossl_pk.cpp:301
Botan::PK_Ops::Verification
Definition: pk_ops.h:85
Botan::RSA_PublicKey
Definition: rsa.h:21