]>
Commit | Line | Data |
---|---|---|
76dfca87 RL |
1 | /* |
2 | * Copyright (c) 2002 Bob Beck <beck@openbsd.org> | |
3 | * Copyright (c) 2002 Theo de Raadt | |
4 | * Copyright (c) 2002 Markus Friedl | |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | |
76dfca87 RL |
15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY | |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
19 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY | |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 | * | |
27 | */ | |
28 | ||
29 | #include <openssl/objects.h> | |
30 | #include <openssl/engine.h> | |
31 | #include <openssl/evp.h> | |
ac0d0a5e | 32 | #include <openssl/bn.h> |
76dfca87 | 33 | |
6145b0b1 | 34 | #if (defined(__unix__) || defined(unix)) && !defined(USG) && \ |
0f113f3e MC |
35 | (defined(OpenBSD) || defined(__FreeBSD__)) |
36 | # include <sys/param.h> | |
0c3426da | 37 | # if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) |
c00cee00 RL |
38 | # define HAVE_CRYPTODEV |
39 | # endif | |
40 | # if (OpenBSD >= 200110) | |
41 | # define HAVE_SYSLOG_R | |
42 | # endif | |
43 | #endif | |
b84d5b72 | 44 | |
84cf97af BL |
45 | #include <sys/types.h> |
46 | #ifdef HAVE_CRYPTODEV | |
47 | # include <crypto/cryptodev.h> | |
d2c3d5d4 BL |
48 | # include <sys/ioctl.h> |
49 | # include <errno.h> | |
50 | # include <stdio.h> | |
51 | # include <unistd.h> | |
52 | # include <fcntl.h> | |
53 | # include <stdarg.h> | |
54 | # include <syslog.h> | |
55 | # include <errno.h> | |
56 | # include <string.h> | |
84cf97af BL |
57 | #endif |
58 | #include <openssl/dh.h> | |
59 | #include <openssl/dsa.h> | |
60 | #include <openssl/err.h> | |
61 | #include <openssl/rsa.h> | |
84cf97af | 62 | |
c00cee00 | 63 | #ifndef HAVE_CRYPTODEV |
b84d5b72 | 64 | |
0f113f3e | 65 | void ENGINE_load_cryptodev(void) |
b84d5b72 | 66 | { |
0f113f3e MC |
67 | /* This is a NOP on platforms without /dev/crypto */ |
68 | return; | |
b84d5b72 RL |
69 | } |
70 | ||
0f113f3e | 71 | #else |
8b968750 | 72 | |
0f113f3e MC |
73 | struct dev_crypto_state { |
74 | struct session_op d_sess; | |
75 | int d_fd; | |
76 | # ifdef USE_CRYPTODEV_DIGESTS | |
77 | char dummy_mac_key[HASH_MAX_LEN]; | |
78 | unsigned char digest_res[HASH_MAX_LEN]; | |
79 | char *mac_data; | |
80 | int mac_len; | |
81 | # endif | |
76dfca87 RL |
82 | }; |
83 | ||
84 | static u_int32_t cryptodev_asymfeat = 0; | |
85 | ||
86 | static int get_asym_dev_crypto(void); | |
87 | static int open_dev_crypto(void); | |
88 | static int get_dev_crypto(void); | |
76dfca87 | 89 | static int get_cryptodev_ciphers(const int **cnids); |
0f113f3e | 90 | # ifdef USE_CRYPTODEV_DIGESTS |
5e28ccb7 | 91 | static int get_cryptodev_digests(const int **cnids); |
0f113f3e | 92 | # endif |
76dfca87 RL |
93 | static int cryptodev_usable_ciphers(const int **nids); |
94 | static int cryptodev_usable_digests(const int **nids); | |
95 | static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |
0f113f3e | 96 | const unsigned char *in, size_t inl); |
76dfca87 | 97 | static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
0f113f3e | 98 | const unsigned char *iv, int enc); |
76dfca87 RL |
99 | static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); |
100 | static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |
0f113f3e | 101 | const int **nids, int nid); |
76dfca87 | 102 | static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, |
0f113f3e | 103 | const int **nids, int nid); |
76dfca87 RL |
104 | static int bn2crparam(const BIGNUM *a, struct crparam *crp); |
105 | static int crparam2bn(struct crparam *crp, BIGNUM *a); | |
106 | static void zapparams(struct crypt_kop *kop); | |
107 | static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, | |
0f113f3e | 108 | int slen, BIGNUM *s); |
76dfca87 RL |
109 | |
110 | static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, | |
0f113f3e MC |
111 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, |
112 | BN_MONT_CTX *m_ctx); | |
113 | static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, | |
114 | BN_CTX *ctx); | |
115 | static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, | |
116 | BN_CTX *ctx); | |
76dfca87 | 117 | static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, |
0f113f3e MC |
118 | const BIGNUM *p, const BIGNUM *m, |
119 | BN_CTX *ctx, BN_MONT_CTX *m_ctx); | |
76dfca87 | 120 | static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, |
0f113f3e MC |
121 | BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, |
122 | BIGNUM *p, BN_CTX *ctx, | |
123 | BN_MONT_CTX *mont); | |
124 | static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, | |
125 | DSA *dsa); | |
76dfca87 | 126 | static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, |
0f113f3e | 127 | DSA_SIG *sig, DSA *dsa); |
76dfca87 | 128 | static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, |
0f113f3e MC |
129 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, |
130 | BN_MONT_CTX *m_ctx); | |
131 | static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, | |
132 | DH *dh); | |
76dfca87 | 133 | static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, |
0f113f3e | 134 | void (*f) (void)); |
76dfca87 RL |
135 | void ENGINE_load_cryptodev(void); |
136 | ||
137 | static const ENGINE_CMD_DEFN cryptodev_defns[] = { | |
0f113f3e | 138 | {0, NULL, NULL, 0} |
76dfca87 RL |
139 | }; |
140 | ||
141 | static struct { | |
0f113f3e MC |
142 | int id; |
143 | int nid; | |
144 | int ivmax; | |
145 | int keylen; | |
76dfca87 | 146 | } ciphers[] = { |
0f113f3e MC |
147 | { |
148 | CRYPTO_ARC4, NID_rc4, 0, 16, | |
149 | }, | |
150 | { | |
151 | CRYPTO_DES_CBC, NID_des_cbc, 8, 8, | |
152 | }, | |
153 | { | |
154 | CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, | |
155 | }, | |
156 | { | |
157 | CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, | |
158 | }, | |
159 | { | |
160 | CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, | |
161 | }, | |
162 | { | |
163 | CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, | |
164 | }, | |
165 | # ifdef CRYPTO_AES_CTR | |
166 | { | |
167 | CRYPTO_AES_CTR, NID_aes_128_ctr, 14, 16, | |
168 | }, | |
169 | { | |
170 | CRYPTO_AES_CTR, NID_aes_192_ctr, 14, 24, | |
171 | }, | |
172 | { | |
173 | CRYPTO_AES_CTR, NID_aes_256_ctr, 14, 32, | |
174 | }, | |
175 | # endif | |
176 | { | |
177 | CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, | |
178 | }, | |
179 | { | |
180 | CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, | |
181 | }, | |
182 | { | |
183 | CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, | |
184 | }, | |
185 | { | |
186 | 0, NID_undef, 0, 0, | |
187 | }, | |
76dfca87 RL |
188 | }; |
189 | ||
0f113f3e | 190 | # ifdef USE_CRYPTODEV_DIGESTS |
76dfca87 | 191 | static struct { |
0f113f3e MC |
192 | int id; |
193 | int nid; | |
194 | int keylen; | |
76dfca87 | 195 | } digests[] = { |
0f113f3e MC |
196 | { |
197 | CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16 | |
198 | }, | |
199 | { | |
200 | CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20 | |
201 | }, | |
202 | { | |
203 | CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16 | |
204 | /* ? */ | |
205 | }, | |
206 | { | |
207 | CRYPTO_MD5_KPDK, NID_undef, 0 | |
208 | }, | |
209 | { | |
210 | CRYPTO_SHA1_KPDK, NID_undef, 0 | |
211 | }, | |
212 | { | |
213 | CRYPTO_MD5, NID_md5, 16 | |
214 | }, | |
215 | { | |
216 | CRYPTO_SHA1, NID_sha1, 20 | |
217 | }, | |
218 | { | |
219 | 0, NID_undef, 0 | |
220 | }, | |
76dfca87 | 221 | }; |
0f113f3e | 222 | # endif |
76dfca87 RL |
223 | |
224 | /* | |
225 | * Return a fd if /dev/crypto seems usable, 0 otherwise. | |
226 | */ | |
0f113f3e | 227 | static int open_dev_crypto(void) |
76dfca87 | 228 | { |
0f113f3e MC |
229 | static int fd = -1; |
230 | ||
231 | if (fd == -1) { | |
232 | if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) | |
233 | return (-1); | |
234 | /* close on exec */ | |
235 | if (fcntl(fd, F_SETFD, 1) == -1) { | |
236 | close(fd); | |
237 | fd = -1; | |
238 | return (-1); | |
239 | } | |
240 | } | |
241 | return (fd); | |
76dfca87 RL |
242 | } |
243 | ||
0f113f3e | 244 | static int get_dev_crypto(void) |
76dfca87 | 245 | { |
0f113f3e MC |
246 | int fd, retfd; |
247 | ||
248 | if ((fd = open_dev_crypto()) == -1) | |
249 | return (-1); | |
250 | # ifndef CRIOGET_NOT_NEEDED | |
251 | if (ioctl(fd, CRIOGET, &retfd) == -1) | |
252 | return (-1); | |
253 | ||
254 | /* close on exec */ | |
255 | if (fcntl(retfd, F_SETFD, 1) == -1) { | |
256 | close(retfd); | |
257 | return (-1); | |
258 | } | |
259 | # else | |
260 | retfd = fd; | |
261 | # endif | |
262 | return (retfd); | |
76dfca87 RL |
263 | } |
264 | ||
d441e6d8 DSH |
265 | static void put_dev_crypto(int fd) |
266 | { | |
0f113f3e MC |
267 | # ifndef CRIOGET_NOT_NEEDED |
268 | close(fd); | |
269 | # endif | |
d441e6d8 DSH |
270 | } |
271 | ||
76dfca87 | 272 | /* Caching version for asym operations */ |
0f113f3e | 273 | static int get_asym_dev_crypto(void) |
76dfca87 | 274 | { |
0f113f3e | 275 | static int fd = -1; |
76dfca87 | 276 | |
0f113f3e MC |
277 | if (fd == -1) |
278 | fd = get_dev_crypto(); | |
279 | return fd; | |
76dfca87 RL |
280 | } |
281 | ||
76dfca87 RL |
282 | /* |
283 | * Find out what ciphers /dev/crypto will let us have a session for. | |
284 | * XXX note, that some of these openssl doesn't deal with yet! | |
285 | * returning them here is harmless, as long as we return NULL | |
286 | * when asked for a handler in the cryptodev_engine_ciphers routine | |
287 | */ | |
0f113f3e | 288 | static int get_cryptodev_ciphers(const int **cnids) |
76dfca87 | 289 | { |
0f113f3e MC |
290 | static int nids[CRYPTO_ALGORITHM_MAX]; |
291 | struct session_op sess; | |
292 | int fd, i, count = 0; | |
293 | ||
294 | if ((fd = get_dev_crypto()) < 0) { | |
295 | *cnids = NULL; | |
296 | return (0); | |
297 | } | |
298 | memset(&sess, 0, sizeof(sess)); | |
299 | sess.key = (caddr_t) "123456789abcdefghijklmno"; | |
300 | ||
301 | for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { | |
302 | if (ciphers[i].nid == NID_undef) | |
303 | continue; | |
304 | sess.cipher = ciphers[i].id; | |
305 | sess.keylen = ciphers[i].keylen; | |
306 | sess.mac = 0; | |
307 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && | |
308 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) | |
309 | nids[count++] = ciphers[i].nid; | |
310 | } | |
311 | put_dev_crypto(fd); | |
312 | ||
313 | if (count > 0) | |
314 | *cnids = nids; | |
315 | else | |
316 | *cnids = NULL; | |
317 | return (count); | |
76dfca87 RL |
318 | } |
319 | ||
0f113f3e | 320 | # ifdef USE_CRYPTODEV_DIGESTS |
76dfca87 RL |
321 | /* |
322 | * Find out what digests /dev/crypto will let us have a session for. | |
323 | * XXX note, that some of these openssl doesn't deal with yet! | |
324 | * returning them here is harmless, as long as we return NULL | |
325 | * when asked for a handler in the cryptodev_engine_digests routine | |
326 | */ | |
0f113f3e | 327 | static int get_cryptodev_digests(const int **cnids) |
76dfca87 | 328 | { |
0f113f3e MC |
329 | static int nids[CRYPTO_ALGORITHM_MAX]; |
330 | struct session_op sess; | |
331 | int fd, i, count = 0; | |
332 | ||
333 | if ((fd = get_dev_crypto()) < 0) { | |
334 | *cnids = NULL; | |
335 | return (0); | |
336 | } | |
337 | memset(&sess, 0, sizeof(sess)); | |
338 | sess.mackey = (caddr_t) "123456789abcdefghijklmno"; | |
339 | for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { | |
340 | if (digests[i].nid == NID_undef) | |
341 | continue; | |
342 | sess.mac = digests[i].id; | |
343 | sess.mackeylen = digests[i].keylen; | |
344 | sess.cipher = 0; | |
345 | if (ioctl(fd, CIOCGSESSION, &sess) != -1 && | |
346 | ioctl(fd, CIOCFSESSION, &sess.ses) != -1) | |
347 | nids[count++] = digests[i].nid; | |
348 | } | |
349 | put_dev_crypto(fd); | |
350 | ||
351 | if (count > 0) | |
352 | *cnids = nids; | |
353 | else | |
354 | *cnids = NULL; | |
355 | return (count); | |
76dfca87 | 356 | } |
0f113f3e | 357 | # endif /* 0 */ |
76dfca87 RL |
358 | |
359 | /* | |
360 | * Find the useable ciphers|digests from dev/crypto - this is the first | |
361 | * thing called by the engine init crud which determines what it | |
362 | * can use for ciphers from this engine. We want to return | |
363 | * only what we can do, anythine else is handled by software. | |
364 | * | |
365 | * If we can't initialize the device to do anything useful for | |
366 | * any reason, we want to return a NULL array, and 0 length, | |
367 | * which forces everything to be done is software. By putting | |
368 | * the initalization of the device in here, we ensure we can | |
369 | * use this engine as the default, and if for whatever reason | |
370 | * /dev/crypto won't do what we want it will just be done in | |
371 | * software | |
372 | * | |
373 | * This can (should) be greatly expanded to perhaps take into | |
374 | * account speed of the device, and what we want to do. | |
375 | * (although the disabling of particular alg's could be controlled | |
376 | * by the device driver with sysctl's.) - this is where we | |
377 | * want most of the decisions made about what we actually want | |
378 | * to use from /dev/crypto. | |
379 | */ | |
0f113f3e | 380 | static int cryptodev_usable_ciphers(const int **nids) |
76dfca87 | 381 | { |
0f113f3e | 382 | return (get_cryptodev_ciphers(nids)); |
76dfca87 RL |
383 | } |
384 | ||
0f113f3e | 385 | static int cryptodev_usable_digests(const int **nids) |
76dfca87 | 386 | { |
0f113f3e MC |
387 | # ifdef USE_CRYPTODEV_DIGESTS |
388 | return (get_cryptodev_digests(nids)); | |
389 | # else | |
390 | /* | |
391 | * XXXX just disable all digests for now, because it sucks. | |
392 | * we need a better way to decide this - i.e. I may not | |
393 | * want digests on slow cards like hifn on fast machines, | |
394 | * but might want them on slow or loaded machines, etc. | |
395 | * will also want them when using crypto cards that don't | |
396 | * suck moose gonads - would be nice to be able to decide something | |
397 | * as reasonable default without having hackery that's card dependent. | |
398 | * of course, the default should probably be just do everything, | |
399 | * with perhaps a sysctl to turn algoritms off (or have them off | |
400 | * by default) on cards that generally suck like the hifn. | |
401 | */ | |
402 | *nids = NULL; | |
403 | return (0); | |
404 | # endif | |
76dfca87 RL |
405 | } |
406 | ||
407 | static int | |
408 | cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | |
0f113f3e | 409 | const unsigned char *in, size_t inl) |
76dfca87 | 410 | { |
0f113f3e MC |
411 | struct crypt_op cryp; |
412 | struct dev_crypto_state *state = ctx->cipher_data; | |
413 | struct session_op *sess = &state->d_sess; | |
414 | const void *iiv; | |
415 | unsigned char save_iv[EVP_MAX_IV_LENGTH]; | |
416 | ||
417 | if (state->d_fd < 0) | |
418 | return (0); | |
419 | if (!inl) | |
420 | return (1); | |
421 | if ((inl % ctx->cipher->block_size) != 0) | |
422 | return (0); | |
423 | ||
424 | memset(&cryp, 0, sizeof(cryp)); | |
425 | ||
426 | cryp.ses = sess->ses; | |
427 | cryp.flags = 0; | |
428 | cryp.len = inl; | |
429 | cryp.src = (caddr_t) in; | |
430 | cryp.dst = (caddr_t) out; | |
431 | cryp.mac = 0; | |
432 | ||
433 | cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; | |
434 | ||
435 | if (ctx->cipher->iv_len) { | |
436 | cryp.iv = (caddr_t) ctx->iv; | |
437 | if (!ctx->encrypt) { | |
438 | iiv = in + inl - ctx->cipher->iv_len; | |
439 | memcpy(save_iv, iiv, ctx->cipher->iv_len); | |
440 | } | |
441 | } else | |
442 | cryp.iv = NULL; | |
443 | ||
444 | if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) { | |
445 | /* | |
446 | * XXX need better errror handling this can fail for a number of | |
447 | * different reasons. | |
448 | */ | |
449 | return (0); | |
450 | } | |
451 | ||
452 | if (ctx->cipher->iv_len) { | |
453 | if (ctx->encrypt) | |
454 | iiv = out + inl - ctx->cipher->iv_len; | |
455 | else | |
456 | iiv = save_iv; | |
457 | memcpy(ctx->iv, iiv, ctx->cipher->iv_len); | |
458 | } | |
459 | return (1); | |
76dfca87 RL |
460 | } |
461 | ||
462 | static int | |
463 | cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, | |
0f113f3e | 464 | const unsigned char *iv, int enc) |
76dfca87 | 465 | { |
0f113f3e MC |
466 | struct dev_crypto_state *state = ctx->cipher_data; |
467 | struct session_op *sess = &state->d_sess; | |
468 | int cipher = -1, i; | |
469 | ||
470 | for (i = 0; ciphers[i].id; i++) | |
471 | if (ctx->cipher->nid == ciphers[i].nid && | |
472 | ctx->cipher->iv_len <= ciphers[i].ivmax && | |
473 | ctx->key_len == ciphers[i].keylen) { | |
474 | cipher = ciphers[i].id; | |
475 | break; | |
476 | } | |
477 | ||
478 | if (!ciphers[i].id) { | |
479 | state->d_fd = -1; | |
480 | return (0); | |
481 | } | |
482 | ||
16f8d4eb | 483 | memset(sess, 0, sizeof(*sess)); |
0f113f3e MC |
484 | |
485 | if ((state->d_fd = get_dev_crypto()) < 0) | |
486 | return (0); | |
487 | ||
488 | sess->key = (caddr_t) key; | |
489 | sess->keylen = ctx->key_len; | |
490 | sess->cipher = cipher; | |
491 | ||
492 | if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { | |
493 | put_dev_crypto(state->d_fd); | |
494 | state->d_fd = -1; | |
495 | return (0); | |
496 | } | |
497 | return (1); | |
76dfca87 RL |
498 | } |
499 | ||
500 | /* | |
501 | * free anything we allocated earlier when initting a | |
502 | * session, and close the session. | |
503 | */ | |
0f113f3e | 504 | static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx) |
76dfca87 | 505 | { |
0f113f3e MC |
506 | int ret = 0; |
507 | struct dev_crypto_state *state = ctx->cipher_data; | |
508 | struct session_op *sess = &state->d_sess; | |
509 | ||
510 | if (state->d_fd < 0) | |
511 | return (0); | |
512 | ||
513 | /* | |
514 | * XXX if this ioctl fails, someting's wrong. the invoker may have called | |
515 | * us with a bogus ctx, or we could have a device that for whatever | |
516 | * reason just doesn't want to play ball - it's not clear what's right | |
517 | * here - should this be an error? should it just increase a counter, | |
518 | * hmm. For right now, we return 0 - I don't believe that to be "right". | |
519 | * we could call the gorpy openssl lib error handlers that print messages | |
520 | * to users of the library. hmm.. | |
521 | */ | |
522 | ||
523 | if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) { | |
524 | ret = 0; | |
525 | } else { | |
526 | ret = 1; | |
527 | } | |
528 | put_dev_crypto(state->d_fd); | |
529 | state->d_fd = -1; | |
530 | ||
531 | return (ret); | |
76dfca87 RL |
532 | } |
533 | ||
534 | /* | |
535 | * libcrypto EVP stuff - this is how we get wired to EVP so the engine | |
536 | * gets called when libcrypto requests a cipher NID. | |
537 | */ | |
538 | ||
b53e0769 | 539 | /* RC4 */ |
df2ee0e2 | 540 | static const EVP_CIPHER cryptodev_rc4 = { |
0f113f3e MC |
541 | NID_rc4, |
542 | 1, 16, 0, | |
543 | EVP_CIPH_VARIABLE_LENGTH, | |
544 | cryptodev_init_key, | |
545 | cryptodev_cipher, | |
546 | cryptodev_cleanup, | |
547 | sizeof(struct dev_crypto_state), | |
548 | NULL, | |
549 | NULL, | |
550 | NULL | |
b53e0769 DSH |
551 | }; |
552 | ||
76dfca87 | 553 | /* DES CBC EVP */ |
df2ee0e2 | 554 | static const EVP_CIPHER cryptodev_des_cbc = { |
0f113f3e MC |
555 | NID_des_cbc, |
556 | 8, 8, 8, | |
557 | EVP_CIPH_CBC_MODE, | |
558 | cryptodev_init_key, | |
559 | cryptodev_cipher, | |
560 | cryptodev_cleanup, | |
561 | sizeof(struct dev_crypto_state), | |
562 | EVP_CIPHER_set_asn1_iv, | |
563 | EVP_CIPHER_get_asn1_iv, | |
564 | NULL | |
76dfca87 RL |
565 | }; |
566 | ||
567 | /* 3DES CBC EVP */ | |
df2ee0e2 | 568 | static const EVP_CIPHER cryptodev_3des_cbc = { |
0f113f3e MC |
569 | NID_des_ede3_cbc, |
570 | 8, 24, 8, | |
571 | EVP_CIPH_CBC_MODE, | |
572 | cryptodev_init_key, | |
573 | cryptodev_cipher, | |
574 | cryptodev_cleanup, | |
575 | sizeof(struct dev_crypto_state), | |
576 | EVP_CIPHER_set_asn1_iv, | |
577 | EVP_CIPHER_get_asn1_iv, | |
578 | NULL | |
76dfca87 RL |
579 | }; |
580 | ||
df2ee0e2 | 581 | static const EVP_CIPHER cryptodev_bf_cbc = { |
0f113f3e MC |
582 | NID_bf_cbc, |
583 | 8, 16, 8, | |
584 | EVP_CIPH_CBC_MODE, | |
585 | cryptodev_init_key, | |
586 | cryptodev_cipher, | |
587 | cryptodev_cleanup, | |
588 | sizeof(struct dev_crypto_state), | |
589 | EVP_CIPHER_set_asn1_iv, | |
590 | EVP_CIPHER_get_asn1_iv, | |
591 | NULL | |
76dfca87 RL |
592 | }; |
593 | ||
df2ee0e2 | 594 | static const EVP_CIPHER cryptodev_cast_cbc = { |
0f113f3e MC |
595 | NID_cast5_cbc, |
596 | 8, 16, 8, | |
597 | EVP_CIPH_CBC_MODE, | |
598 | cryptodev_init_key, | |
599 | cryptodev_cipher, | |
600 | cryptodev_cleanup, | |
601 | sizeof(struct dev_crypto_state), | |
602 | EVP_CIPHER_set_asn1_iv, | |
603 | EVP_CIPHER_get_asn1_iv, | |
604 | NULL | |
76dfca87 RL |
605 | }; |
606 | ||
df2ee0e2 | 607 | static const EVP_CIPHER cryptodev_aes_cbc = { |
0f113f3e MC |
608 | NID_aes_128_cbc, |
609 | 16, 16, 16, | |
610 | EVP_CIPH_CBC_MODE, | |
611 | cryptodev_init_key, | |
612 | cryptodev_cipher, | |
613 | cryptodev_cleanup, | |
614 | sizeof(struct dev_crypto_state), | |
615 | EVP_CIPHER_set_asn1_iv, | |
616 | EVP_CIPHER_get_asn1_iv, | |
617 | NULL | |
76dfca87 RL |
618 | }; |
619 | ||
df2ee0e2 | 620 | static const EVP_CIPHER cryptodev_aes_192_cbc = { |
0f113f3e MC |
621 | NID_aes_192_cbc, |
622 | 16, 24, 16, | |
623 | EVP_CIPH_CBC_MODE, | |
624 | cryptodev_init_key, | |
625 | cryptodev_cipher, | |
626 | cryptodev_cleanup, | |
627 | sizeof(struct dev_crypto_state), | |
628 | EVP_CIPHER_set_asn1_iv, | |
629 | EVP_CIPHER_get_asn1_iv, | |
630 | NULL | |
b53e0769 DSH |
631 | }; |
632 | ||
df2ee0e2 | 633 | static const EVP_CIPHER cryptodev_aes_256_cbc = { |
0f113f3e MC |
634 | NID_aes_256_cbc, |
635 | 16, 32, 16, | |
636 | EVP_CIPH_CBC_MODE, | |
637 | cryptodev_init_key, | |
638 | cryptodev_cipher, | |
639 | cryptodev_cleanup, | |
640 | sizeof(struct dev_crypto_state), | |
641 | EVP_CIPHER_set_asn1_iv, | |
642 | EVP_CIPHER_get_asn1_iv, | |
643 | NULL | |
b53e0769 | 644 | }; |
0f113f3e MC |
645 | |
646 | # ifdef CRYPTO_AES_CTR | |
be2c4d9b | 647 | const EVP_CIPHER cryptodev_aes_ctr = { |
0f113f3e MC |
648 | NID_aes_128_ctr, |
649 | 16, 16, 14, | |
650 | EVP_CIPH_CTR_MODE, | |
651 | cryptodev_init_key, | |
652 | cryptodev_cipher, | |
653 | cryptodev_cleanup, | |
654 | sizeof(struct dev_crypto_state), | |
655 | EVP_CIPHER_set_asn1_iv, | |
656 | EVP_CIPHER_get_asn1_iv, | |
657 | NULL | |
be2c4d9b KPJ |
658 | }; |
659 | ||
660 | const EVP_CIPHER cryptodev_aes_ctr_192 = { | |
0f113f3e MC |
661 | NID_aes_192_ctr, |
662 | 16, 24, 14, | |
663 | EVP_CIPH_CTR_MODE, | |
664 | cryptodev_init_key, | |
665 | cryptodev_cipher, | |
666 | cryptodev_cleanup, | |
667 | sizeof(struct dev_crypto_state), | |
668 | EVP_CIPHER_set_asn1_iv, | |
669 | EVP_CIPHER_get_asn1_iv, | |
670 | NULL | |
be2c4d9b KPJ |
671 | }; |
672 | ||
673 | const EVP_CIPHER cryptodev_aes_ctr_256 = { | |
0f113f3e MC |
674 | NID_aes_256_ctr, |
675 | 16, 32, 14, | |
676 | EVP_CIPH_CTR_MODE, | |
677 | cryptodev_init_key, | |
678 | cryptodev_cipher, | |
679 | cryptodev_cleanup, | |
680 | sizeof(struct dev_crypto_state), | |
681 | EVP_CIPHER_set_asn1_iv, | |
682 | EVP_CIPHER_get_asn1_iv, | |
683 | NULL | |
be2c4d9b | 684 | }; |
0f113f3e | 685 | # endif |
76dfca87 RL |
686 | /* |
687 | * Registered by the ENGINE when used to find out how to deal with | |
688 | * a particular NID in the ENGINE. this says what we'll do at the | |
689 | * top level - note, that list is restricted by what we answer with | |
690 | */ | |
691 | static int | |
692 | cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, | |
0f113f3e | 693 | const int **nids, int nid) |
76dfca87 | 694 | { |
0f113f3e MC |
695 | if (!cipher) |
696 | return (cryptodev_usable_ciphers(nids)); | |
697 | ||
698 | switch (nid) { | |
699 | case NID_rc4: | |
700 | *cipher = &cryptodev_rc4; | |
701 | break; | |
702 | case NID_des_ede3_cbc: | |
703 | *cipher = &cryptodev_3des_cbc; | |
704 | break; | |
705 | case NID_des_cbc: | |
706 | *cipher = &cryptodev_des_cbc; | |
707 | break; | |
708 | case NID_bf_cbc: | |
709 | *cipher = &cryptodev_bf_cbc; | |
710 | break; | |
711 | case NID_cast5_cbc: | |
712 | *cipher = &cryptodev_cast_cbc; | |
713 | break; | |
714 | case NID_aes_128_cbc: | |
715 | *cipher = &cryptodev_aes_cbc; | |
716 | break; | |
717 | case NID_aes_192_cbc: | |
718 | *cipher = &cryptodev_aes_192_cbc; | |
719 | break; | |
720 | case NID_aes_256_cbc: | |
721 | *cipher = &cryptodev_aes_256_cbc; | |
722 | break; | |
723 | # ifdef CRYPTO_AES_CTR | |
724 | case NID_aes_128_ctr: | |
725 | *cipher = &cryptodev_aes_ctr; | |
726 | break; | |
727 | case NID_aes_192_ctr: | |
728 | *cipher = &cryptodev_aes_ctr_192; | |
729 | break; | |
730 | case NID_aes_256_ctr: | |
731 | *cipher = &cryptodev_aes_ctr_256; | |
732 | break; | |
733 | # endif | |
734 | default: | |
735 | *cipher = NULL; | |
736 | break; | |
737 | } | |
738 | return (*cipher != NULL); | |
76dfca87 RL |
739 | } |
740 | ||
0f113f3e | 741 | # ifdef USE_CRYPTODEV_DIGESTS |
8b968750 DSH |
742 | |
743 | /* convert digest type to cryptodev */ | |
0f113f3e | 744 | static int digest_nid_to_cryptodev(int nid) |
8b968750 | 745 | { |
0f113f3e | 746 | int i; |
8b968750 | 747 | |
0f113f3e MC |
748 | for (i = 0; digests[i].id; i++) |
749 | if (digests[i].nid == nid) | |
750 | return (digests[i].id); | |
751 | return (0); | |
8b968750 DSH |
752 | } |
753 | ||
0f113f3e | 754 | static int digest_key_length(int nid) |
8b968750 | 755 | { |
0f113f3e | 756 | int i; |
8b968750 | 757 | |
0f113f3e MC |
758 | for (i = 0; digests[i].id; i++) |
759 | if (digests[i].nid == nid) | |
760 | return digests[i].keylen; | |
761 | return (0); | |
8b968750 DSH |
762 | } |
763 | ||
8b968750 DSH |
764 | static int cryptodev_digest_init(EVP_MD_CTX *ctx) |
765 | { | |
0f113f3e MC |
766 | struct dev_crypto_state *state = ctx->md_data; |
767 | struct session_op *sess = &state->d_sess; | |
768 | int digest; | |
769 | ||
770 | if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef) { | |
771 | printf("cryptodev_digest_init: Can't get digest \n"); | |
772 | return (0); | |
773 | } | |
774 | ||
16f8d4eb | 775 | memset(state, 0, sizeof(*state)); |
0f113f3e MC |
776 | |
777 | if ((state->d_fd = get_dev_crypto()) < 0) { | |
778 | printf("cryptodev_digest_init: Can't get Dev \n"); | |
779 | return (0); | |
780 | } | |
781 | ||
782 | sess->mackey = state->dummy_mac_key; | |
783 | sess->mackeylen = digest_key_length(ctx->digest->type); | |
784 | sess->mac = digest; | |
785 | ||
786 | if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) { | |
787 | put_dev_crypto(state->d_fd); | |
788 | state->d_fd = -1; | |
789 | printf("cryptodev_digest_init: Open session failed\n"); | |
790 | return (0); | |
791 | } | |
792 | ||
793 | return (1); | |
8b968750 DSH |
794 | } |
795 | ||
796 | static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, | |
0f113f3e | 797 | size_t count) |
8b968750 | 798 | { |
0f113f3e MC |
799 | struct crypt_op cryp; |
800 | struct dev_crypto_state *state = ctx->md_data; | |
801 | struct session_op *sess = &state->d_sess; | |
802 | char *new_mac_data; | |
803 | ||
804 | if (!data || state->d_fd < 0) { | |
805 | printf("cryptodev_digest_update: illegal inputs \n"); | |
806 | return (0); | |
807 | } | |
808 | ||
809 | if (!count) { | |
810 | return (0); | |
811 | } | |
812 | ||
813 | if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { | |
814 | /* if application doesn't support one buffer */ | |
815 | new_mac_data = | |
816 | OPENSSL_realloc(state->mac_data, state->mac_len + count); | |
817 | ||
818 | if (!new_mac_data) { | |
819 | printf("cryptodev_digest_update: realloc failed\n"); | |
820 | return (0); | |
821 | } | |
822 | state->mac_data = new_mac_data; | |
823 | ||
824 | memcpy(state->mac_data + state->mac_len, data, count); | |
825 | state->mac_len += count; | |
826 | ||
827 | return (1); | |
828 | } | |
829 | ||
830 | memset(&cryp, 0, sizeof(cryp)); | |
831 | ||
832 | cryp.ses = sess->ses; | |
833 | cryp.flags = 0; | |
834 | cryp.len = count; | |
835 | cryp.src = (caddr_t) data; | |
836 | cryp.dst = NULL; | |
837 | cryp.mac = (caddr_t) state->digest_res; | |
838 | if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { | |
839 | printf("cryptodev_digest_update: digest failed\n"); | |
840 | return (0); | |
841 | } | |
842 | return (1); | |
8b968750 DSH |
843 | } |
844 | ||
8b968750 DSH |
845 | static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) |
846 | { | |
0f113f3e MC |
847 | struct crypt_op cryp; |
848 | struct dev_crypto_state *state = ctx->md_data; | |
849 | struct session_op *sess = &state->d_sess; | |
850 | ||
851 | int ret = 1; | |
852 | ||
853 | if (!md || state->d_fd < 0) { | |
854 | printf("cryptodev_digest_final: illegal input\n"); | |
855 | return (0); | |
856 | } | |
857 | ||
858 | if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { | |
859 | /* if application doesn't support one buffer */ | |
860 | memset(&cryp, 0, sizeof(cryp)); | |
861 | cryp.ses = sess->ses; | |
862 | cryp.flags = 0; | |
863 | cryp.len = state->mac_len; | |
864 | cryp.src = state->mac_data; | |
865 | cryp.dst = NULL; | |
866 | cryp.mac = (caddr_t) md; | |
867 | if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { | |
868 | printf("cryptodev_digest_final: digest failed\n"); | |
869 | return (0); | |
870 | } | |
871 | ||
872 | return 1; | |
873 | } | |
874 | ||
875 | memcpy(md, state->digest_res, ctx->digest->md_size); | |
876 | ||
877 | return (ret); | |
8b968750 DSH |
878 | } |
879 | ||
8b968750 DSH |
880 | static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx) |
881 | { | |
0f113f3e MC |
882 | int ret = 1; |
883 | struct dev_crypto_state *state = ctx->md_data; | |
884 | struct session_op *sess = &state->d_sess; | |
885 | ||
886 | if (state == NULL) | |
887 | return 0; | |
888 | ||
889 | if (state->d_fd < 0) { | |
890 | printf("cryptodev_digest_cleanup: illegal input\n"); | |
891 | return (0); | |
892 | } | |
893 | ||
b548a1f1 RS |
894 | OPENSSL_free(state->mac_data); |
895 | state->mac_data = NULL; | |
896 | state->mac_len = 0; | |
0f113f3e MC |
897 | |
898 | if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) { | |
899 | printf("cryptodev_digest_cleanup: failed to close session\n"); | |
900 | ret = 0; | |
901 | } else { | |
902 | ret = 1; | |
903 | } | |
904 | put_dev_crypto(state->d_fd); | |
905 | state->d_fd = -1; | |
906 | ||
907 | return (ret); | |
8b968750 DSH |
908 | } |
909 | ||
0f113f3e | 910 | static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) |
8b968750 | 911 | { |
0f113f3e MC |
912 | struct dev_crypto_state *fstate = from->md_data; |
913 | struct dev_crypto_state *dstate = to->md_data; | |
914 | struct session_op *sess; | |
915 | int digest; | |
916 | ||
917 | if (dstate == NULL || fstate == NULL) | |
918 | return 1; | |
919 | ||
920 | memcpy(dstate, fstate, sizeof(struct dev_crypto_state)); | |
921 | ||
922 | sess = &dstate->d_sess; | |
923 | ||
924 | digest = digest_nid_to_cryptodev(to->digest->type); | |
925 | ||
926 | sess->mackey = dstate->dummy_mac_key; | |
927 | sess->mackeylen = digest_key_length(to->digest->type); | |
928 | sess->mac = digest; | |
929 | ||
930 | dstate->d_fd = get_dev_crypto(); | |
931 | ||
932 | if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) { | |
933 | put_dev_crypto(dstate->d_fd); | |
934 | dstate->d_fd = -1; | |
935 | printf("cryptodev_digest_copy: Open session failed\n"); | |
936 | return (0); | |
937 | } | |
938 | ||
939 | if (fstate->mac_len != 0) { | |
940 | if (fstate->mac_data != NULL) { | |
941 | dstate->mac_data = OPENSSL_malloc(fstate->mac_len); | |
942 | if (dstate->mac_data == NULL) { | |
943 | printf("cryptodev_digest_copy: mac_data allocation failed\n"); | |
944 | return (0); | |
945 | } | |
946 | memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len); | |
947 | dstate->mac_len = fstate->mac_len; | |
948 | } | |
949 | } | |
950 | ||
951 | return 1; | |
8b968750 DSH |
952 | } |
953 | ||
8b968750 | 954 | const EVP_MD cryptodev_sha1 = { |
0f113f3e MC |
955 | NID_sha1, |
956 | NID_undef, | |
957 | SHA_DIGEST_LENGTH, | |
958 | EVP_MD_FLAG_ONESHOT, | |
959 | cryptodev_digest_init, | |
960 | cryptodev_digest_update, | |
961 | cryptodev_digest_final, | |
962 | cryptodev_digest_copy, | |
963 | cryptodev_digest_cleanup, | |
964 | EVP_PKEY_NULL_method, | |
965 | SHA_CBLOCK, | |
966 | sizeof(struct dev_crypto_state), | |
8b968750 DSH |
967 | }; |
968 | ||
969 | const EVP_MD cryptodev_md5 = { | |
0f113f3e MC |
970 | NID_md5, |
971 | NID_undef, | |
972 | 16 /* MD5_DIGEST_LENGTH */ , | |
973 | EVP_MD_FLAG_ONESHOT, | |
974 | cryptodev_digest_init, | |
975 | cryptodev_digest_update, | |
976 | cryptodev_digest_final, | |
977 | cryptodev_digest_copy, | |
978 | cryptodev_digest_cleanup, | |
979 | EVP_PKEY_NULL_method, | |
980 | 64 /* MD5_CBLOCK */ , | |
981 | sizeof(struct dev_crypto_state), | |
8b968750 DSH |
982 | }; |
983 | ||
0f113f3e | 984 | # endif /* USE_CRYPTODEV_DIGESTS */ |
8b968750 | 985 | |
76dfca87 RL |
986 | static int |
987 | cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, | |
0f113f3e | 988 | const int **nids, int nid) |
76dfca87 | 989 | { |
0f113f3e MC |
990 | if (!digest) |
991 | return (cryptodev_usable_digests(nids)); | |
992 | ||
993 | switch (nid) { | |
994 | # ifdef USE_CRYPTODEV_DIGESTS | |
995 | case NID_md5: | |
996 | *digest = &cryptodev_md5; | |
997 | break; | |
998 | case NID_sha1: | |
999 | *digest = &cryptodev_sha1; | |
1000 | break; | |
1001 | default: | |
1002 | # endif /* USE_CRYPTODEV_DIGESTS */ | |
1003 | *digest = NULL; | |
1004 | break; | |
1005 | } | |
1006 | return (*digest != NULL); | |
76dfca87 RL |
1007 | } |
1008 | ||
1009 | /* | |
1010 | * Convert a BIGNUM to the representation that /dev/crypto needs. | |
1011 | * Upon completion of use, the caller is responsible for freeing | |
1012 | * crp->crp_p. | |
1013 | */ | |
0f113f3e | 1014 | static int bn2crparam(const BIGNUM *a, struct crparam *crp) |
76dfca87 | 1015 | { |
0f113f3e MC |
1016 | ssize_t bytes, bits; |
1017 | u_char *b; | |
1018 | ||
1019 | crp->crp_p = NULL; | |
1020 | crp->crp_nbits = 0; | |
1021 | ||
1022 | bits = BN_num_bits(a); | |
912d7c75 | 1023 | bytes = BN_num_bytes(a); |
0f113f3e | 1024 | |
b51bce94 | 1025 | b = OPENSSL_zalloc(bytes); |
0f113f3e MC |
1026 | if (b == NULL) |
1027 | return (1); | |
0f113f3e MC |
1028 | |
1029 | crp->crp_p = (caddr_t) b; | |
1030 | crp->crp_nbits = bits; | |
1031 | ||
912d7c75 | 1032 | BN_bn2bin(a, b); |
0f113f3e | 1033 | return (0); |
76dfca87 RL |
1034 | } |
1035 | ||
1036 | /* Convert a /dev/crypto parameter to a BIGNUM */ | |
0f113f3e | 1037 | static int crparam2bn(struct crparam *crp, BIGNUM *a) |
76dfca87 | 1038 | { |
0f113f3e MC |
1039 | u_int8_t *pd; |
1040 | int i, bytes; | |
76dfca87 | 1041 | |
0f113f3e | 1042 | bytes = (crp->crp_nbits + 7) / 8; |
76dfca87 | 1043 | |
0f113f3e MC |
1044 | if (bytes == 0) |
1045 | return (-1); | |
76dfca87 | 1046 | |
b196e7d9 | 1047 | if ((pd = OPENSSL_malloc(bytes)) == NULL) |
0f113f3e | 1048 | return (-1); |
76dfca87 | 1049 | |
0f113f3e MC |
1050 | for (i = 0; i < bytes; i++) |
1051 | pd[i] = crp->crp_p[bytes - i - 1]; | |
76dfca87 | 1052 | |
0f113f3e MC |
1053 | BN_bin2bn(pd, bytes, a); |
1054 | free(pd); | |
76dfca87 | 1055 | |
0f113f3e | 1056 | return (0); |
76dfca87 RL |
1057 | } |
1058 | ||
0f113f3e | 1059 | static void zapparams(struct crypt_kop *kop) |
76dfca87 | 1060 | { |
0f113f3e MC |
1061 | int i; |
1062 | ||
1063 | for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { | |
1064 | if (kop->crk_param[i].crp_p) | |
1065 | free(kop->crk_param[i].crp_p); | |
1066 | kop->crk_param[i].crp_p = NULL; | |
1067 | kop->crk_param[i].crp_nbits = 0; | |
1068 | } | |
76dfca87 RL |
1069 | } |
1070 | ||
1071 | static int | |
0f113f3e MC |
1072 | cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, |
1073 | BIGNUM *s) | |
76dfca87 | 1074 | { |
0f113f3e MC |
1075 | int fd, ret = -1; |
1076 | ||
1077 | if ((fd = get_asym_dev_crypto()) < 0) | |
1078 | return (ret); | |
1079 | ||
1080 | if (r) { | |
1081 | kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); | |
1082 | kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; | |
1083 | kop->crk_oparams++; | |
1084 | } | |
1085 | if (s) { | |
1086 | kop->crk_param[kop->crk_iparams + 1].crp_p = | |
1087 | calloc(slen, sizeof(char)); | |
1088 | kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8; | |
1089 | kop->crk_oparams++; | |
1090 | } | |
1091 | ||
1092 | if (ioctl(fd, CIOCKEY, kop) == 0) { | |
1093 | if (r) | |
1094 | crparam2bn(&kop->crk_param[kop->crk_iparams], r); | |
1095 | if (s) | |
1096 | crparam2bn(&kop->crk_param[kop->crk_iparams + 1], s); | |
1097 | ret = 0; | |
1098 | } | |
1099 | ||
1100 | return (ret); | |
76dfca87 RL |
1101 | } |
1102 | ||
1103 | static int | |
1104 | cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | |
0f113f3e | 1105 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) |
76dfca87 | 1106 | { |
0f113f3e MC |
1107 | struct crypt_kop kop; |
1108 | int ret = 1; | |
1109 | ||
1110 | /* | |
1111 | * Currently, we know we can do mod exp iff we can do any asymmetric | |
1112 | * operations at all. | |
1113 | */ | |
1114 | if (cryptodev_asymfeat == 0) { | |
1115 | ret = BN_mod_exp(r, a, p, m, ctx); | |
1116 | return (ret); | |
1117 | } | |
1118 | ||
16f8d4eb | 1119 | memset(&kop, 0, sizeof(kop)); |
0f113f3e MC |
1120 | kop.crk_op = CRK_MOD_EXP; |
1121 | ||
1122 | /* inputs: a^p % m */ | |
1123 | if (bn2crparam(a, &kop.crk_param[0])) | |
1124 | goto err; | |
1125 | if (bn2crparam(p, &kop.crk_param[1])) | |
1126 | goto err; | |
1127 | if (bn2crparam(m, &kop.crk_param[2])) | |
1128 | goto err; | |
1129 | kop.crk_iparams = 3; | |
1130 | ||
1131 | if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) { | |
b0700d2c | 1132 | const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); |
0f113f3e MC |
1133 | printf("OCF asym process failed, Running in software\n"); |
1134 | ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); | |
1135 | ||
1136 | } else if (ECANCELED == kop.crk_status) { | |
b0700d2c | 1137 | const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); |
0f113f3e MC |
1138 | printf("OCF hardware operation cancelled. Running in Software\n"); |
1139 | ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); | |
1140 | } | |
1141 | /* else cryptodev operation worked ok ==> ret = 1 */ | |
1142 | ||
1143 | err: | |
1144 | zapparams(&kop); | |
1145 | return (ret); | |
76dfca87 RL |
1146 | } |
1147 | ||
1148 | static int | |
0f113f3e MC |
1149 | cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, |
1150 | BN_CTX *ctx) | |
76dfca87 | 1151 | { |
0f113f3e MC |
1152 | int r; |
1153 | ctx = BN_CTX_new(); | |
1154 | r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); | |
1155 | BN_CTX_free(ctx); | |
1156 | return (r); | |
76dfca87 RL |
1157 | } |
1158 | ||
1159 | static int | |
ea77fc33 | 1160 | cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) |
76dfca87 | 1161 | { |
0f113f3e MC |
1162 | struct crypt_kop kop; |
1163 | int ret = 1; | |
1164 | ||
1165 | if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { | |
1166 | /* XXX 0 means failure?? */ | |
1167 | return (0); | |
1168 | } | |
1169 | ||
16f8d4eb | 1170 | memset(&kop, 0, sizeof(kop)); |
0f113f3e MC |
1171 | kop.crk_op = CRK_MOD_EXP_CRT; |
1172 | /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ | |
1173 | if (bn2crparam(rsa->p, &kop.crk_param[0])) | |
1174 | goto err; | |
1175 | if (bn2crparam(rsa->q, &kop.crk_param[1])) | |
1176 | goto err; | |
1177 | if (bn2crparam(I, &kop.crk_param[2])) | |
1178 | goto err; | |
1179 | if (bn2crparam(rsa->dmp1, &kop.crk_param[3])) | |
1180 | goto err; | |
1181 | if (bn2crparam(rsa->dmq1, &kop.crk_param[4])) | |
1182 | goto err; | |
1183 | if (bn2crparam(rsa->iqmp, &kop.crk_param[5])) | |
1184 | goto err; | |
1185 | kop.crk_iparams = 6; | |
1186 | ||
1187 | if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) { | |
b0700d2c | 1188 | const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); |
0f113f3e MC |
1189 | printf("OCF asym process failed, running in Software\n"); |
1190 | ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); | |
1191 | ||
1192 | } else if (ECANCELED == kop.crk_status) { | |
b0700d2c | 1193 | const RSA_METHOD *meth = RSA_PKCS1_OpenSSL(); |
0f113f3e MC |
1194 | printf("OCF hardware operation cancelled. Running in Software\n"); |
1195 | ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); | |
1196 | } | |
1197 | /* else cryptodev operation worked ok ==> ret = 1 */ | |
1198 | ||
1199 | err: | |
1200 | zapparams(&kop); | |
1201 | return (ret); | |
76dfca87 RL |
1202 | } |
1203 | ||
1204 | static RSA_METHOD cryptodev_rsa = { | |
0f113f3e MC |
1205 | "cryptodev RSA method", |
1206 | NULL, /* rsa_pub_enc */ | |
1207 | NULL, /* rsa_pub_dec */ | |
1208 | NULL, /* rsa_priv_enc */ | |
1209 | NULL, /* rsa_priv_dec */ | |
1210 | NULL, | |
1211 | NULL, | |
1212 | NULL, /* init */ | |
1213 | NULL, /* finish */ | |
1214 | 0, /* flags */ | |
1215 | NULL, /* app_data */ | |
1216 | NULL, /* rsa_sign */ | |
1217 | NULL /* rsa_verify */ | |
76dfca87 RL |
1218 | }; |
1219 | ||
1220 | static int | |
1221 | cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, | |
0f113f3e | 1222 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) |
76dfca87 | 1223 | { |
0f113f3e | 1224 | return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); |
76dfca87 RL |
1225 | } |
1226 | ||
1227 | static int | |
1228 | cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, | |
0f113f3e MC |
1229 | BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, |
1230 | BN_CTX *ctx, BN_MONT_CTX *mont) | |
76dfca87 | 1231 | { |
912d7c75 | 1232 | BIGNUM *t2; |
0f113f3e | 1233 | int ret = 0; |
76dfca87 | 1234 | |
912d7c75 | 1235 | t2 = BN_new(); |
76dfca87 | 1236 | |
0f113f3e MC |
1237 | /* v = ( g^u1 * y^u2 mod p ) mod q */ |
1238 | /* let t1 = g ^ u1 mod p */ | |
1239 | ret = 0; | |
76dfca87 | 1240 | |
0f113f3e MC |
1241 | if (!dsa->meth->bn_mod_exp(dsa, t1, dsa->g, u1, dsa->p, ctx, mont)) |
1242 | goto err; | |
76dfca87 | 1243 | |
0f113f3e | 1244 | /* let t2 = y ^ u2 mod p */ |
912d7c75 | 1245 | if (!dsa->meth->bn_mod_exp(dsa, t2, dsa->pub_key, u2, dsa->p, ctx, mont)) |
0f113f3e MC |
1246 | goto err; |
1247 | /* let u1 = t1 * t2 mod p */ | |
912d7c75 | 1248 | if (!BN_mod_mul(u1, t1, t2, dsa->p, ctx)) |
0f113f3e | 1249 | goto err; |
76dfca87 | 1250 | |
0f113f3e | 1251 | BN_copy(t1, u1); |
76dfca87 | 1252 | |
0f113f3e MC |
1253 | ret = 1; |
1254 | err: | |
912d7c75 | 1255 | BN_free(t2); |
0f113f3e | 1256 | return (ret); |
76dfca87 RL |
1257 | } |
1258 | ||
0f113f3e MC |
1259 | static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, |
1260 | DSA *dsa) | |
76dfca87 | 1261 | { |
0f113f3e MC |
1262 | struct crypt_kop kop; |
1263 | BIGNUM *r = NULL, *s = NULL; | |
1264 | DSA_SIG *dsaret = NULL; | |
1265 | ||
1266 | if ((r = BN_new()) == NULL) | |
1267 | goto err; | |
1268 | if ((s = BN_new()) == NULL) { | |
1269 | BN_free(r); | |
1270 | goto err; | |
1271 | } | |
1272 | ||
16f8d4eb | 1273 | memset(&kop, 0, sizeof(kop)); |
0f113f3e MC |
1274 | kop.crk_op = CRK_DSA_SIGN; |
1275 | ||
1276 | /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ | |
1277 | kop.crk_param[0].crp_p = (caddr_t) dgst; | |
1278 | kop.crk_param[0].crp_nbits = dlen * 8; | |
1279 | if (bn2crparam(dsa->p, &kop.crk_param[1])) | |
1280 | goto err; | |
1281 | if (bn2crparam(dsa->q, &kop.crk_param[2])) | |
1282 | goto err; | |
1283 | if (bn2crparam(dsa->g, &kop.crk_param[3])) | |
1284 | goto err; | |
1285 | if (bn2crparam(dsa->priv_key, &kop.crk_param[4])) | |
1286 | goto err; | |
1287 | kop.crk_iparams = 5; | |
1288 | ||
1289 | if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, | |
1290 | BN_num_bytes(dsa->q), s) == 0) { | |
1291 | dsaret = DSA_SIG_new(); | |
1292 | dsaret->r = r; | |
1293 | dsaret->s = s; | |
1294 | } else { | |
1295 | const DSA_METHOD *meth = DSA_OpenSSL(); | |
1296 | BN_free(r); | |
1297 | BN_free(s); | |
1298 | dsaret = (meth->dsa_do_sign) (dgst, dlen, dsa); | |
1299 | } | |
1300 | err: | |
1301 | kop.crk_param[0].crp_p = NULL; | |
1302 | zapparams(&kop); | |
1303 | return (dsaret); | |
76dfca87 RL |
1304 | } |
1305 | ||
1306 | static int | |
1307 | cryptodev_dsa_verify(const unsigned char *dgst, int dlen, | |
0f113f3e | 1308 | DSA_SIG *sig, DSA *dsa) |
76dfca87 | 1309 | { |
0f113f3e MC |
1310 | struct crypt_kop kop; |
1311 | int dsaret = 1; | |
1312 | ||
16f8d4eb | 1313 | memset(&kop, 0, sizeof(kop)); |
0f113f3e MC |
1314 | kop.crk_op = CRK_DSA_VERIFY; |
1315 | ||
1316 | /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ | |
1317 | kop.crk_param[0].crp_p = (caddr_t) dgst; | |
1318 | kop.crk_param[0].crp_nbits = dlen * 8; | |
1319 | if (bn2crparam(dsa->p, &kop.crk_param[1])) | |
1320 | goto err; | |
1321 | if (bn2crparam(dsa->q, &kop.crk_param[2])) | |
1322 | goto err; | |
1323 | if (bn2crparam(dsa->g, &kop.crk_param[3])) | |
1324 | goto err; | |
1325 | if (bn2crparam(dsa->pub_key, &kop.crk_param[4])) | |
1326 | goto err; | |
1327 | if (bn2crparam(sig->r, &kop.crk_param[5])) | |
1328 | goto err; | |
1329 | if (bn2crparam(sig->s, &kop.crk_param[6])) | |
1330 | goto err; | |
1331 | kop.crk_iparams = 7; | |
1332 | ||
1333 | if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { | |
1334 | /* | |
1335 | * OCF success value is 0, if not zero, change dsaret to fail | |
1336 | */ | |
1337 | if (0 != kop.crk_status) | |
1338 | dsaret = 0; | |
1339 | } else { | |
1340 | const DSA_METHOD *meth = DSA_OpenSSL(); | |
1341 | ||
1342 | dsaret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa); | |
1343 | } | |
1344 | err: | |
1345 | kop.crk_param[0].crp_p = NULL; | |
1346 | zapparams(&kop); | |
1347 | return (dsaret); | |
76dfca87 RL |
1348 | } |
1349 | ||
1350 | static DSA_METHOD cryptodev_dsa = { | |
0f113f3e MC |
1351 | "cryptodev DSA method", |
1352 | NULL, | |
1353 | NULL, /* dsa_sign_setup */ | |
1354 | NULL, | |
1355 | NULL, /* dsa_mod_exp */ | |
1356 | NULL, | |
1357 | NULL, /* init */ | |
1358 | NULL, /* finish */ | |
1359 | 0, /* flags */ | |
1360 | NULL /* app_data */ | |
76dfca87 RL |
1361 | }; |
1362 | ||
1363 | static int | |
1364 | cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, | |
0f113f3e MC |
1365 | const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, |
1366 | BN_MONT_CTX *m_ctx) | |
76dfca87 | 1367 | { |
0f113f3e | 1368 | return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); |
76dfca87 RL |
1369 | } |
1370 | ||
1371 | static int | |
1372 | cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) | |
1373 | { | |
0f113f3e MC |
1374 | struct crypt_kop kop; |
1375 | int dhret = 1; | |
1376 | int fd, keylen; | |
1377 | ||
1378 | if ((fd = get_asym_dev_crypto()) < 0) { | |
1379 | const DH_METHOD *meth = DH_OpenSSL(); | |
1380 | ||
1381 | return ((meth->compute_key) (key, pub_key, dh)); | |
1382 | } | |
1383 | ||
1384 | keylen = BN_num_bits(dh->p); | |
1385 | ||
16f8d4eb | 1386 | memset(&kop, 0, sizeof(kop)); |
0f113f3e MC |
1387 | kop.crk_op = CRK_DH_COMPUTE_KEY; |
1388 | ||
1389 | /* inputs: dh->priv_key pub_key dh->p key */ | |
1390 | if (bn2crparam(dh->priv_key, &kop.crk_param[0])) | |
1391 | goto err; | |
1392 | if (bn2crparam(pub_key, &kop.crk_param[1])) | |
1393 | goto err; | |
1394 | if (bn2crparam(dh->p, &kop.crk_param[2])) | |
1395 | goto err; | |
1396 | kop.crk_iparams = 3; | |
1397 | ||
1398 | kop.crk_param[3].crp_p = (caddr_t) key; | |
1399 | kop.crk_param[3].crp_nbits = keylen * 8; | |
1400 | kop.crk_oparams = 1; | |
1401 | ||
1402 | if (ioctl(fd, CIOCKEY, &kop) == -1) { | |
1403 | const DH_METHOD *meth = DH_OpenSSL(); | |
1404 | ||
1405 | dhret = (meth->compute_key) (key, pub_key, dh); | |
1406 | } | |
1407 | err: | |
1408 | kop.crk_param[3].crp_p = NULL; | |
1409 | zapparams(&kop); | |
1410 | return (dhret); | |
76dfca87 RL |
1411 | } |
1412 | ||
1413 | static DH_METHOD cryptodev_dh = { | |
0f113f3e MC |
1414 | "cryptodev DH method", |
1415 | NULL, /* cryptodev_dh_generate_key */ | |
1416 | NULL, | |
1417 | NULL, | |
1418 | NULL, | |
1419 | NULL, | |
1420 | 0, /* flags */ | |
1421 | NULL /* app_data */ | |
76dfca87 RL |
1422 | }; |
1423 | ||
1424 | /* | |
1425 | * ctrl right now is just a wrapper that doesn't do much | |
1426 | * but I expect we'll want some options soon. | |
1427 | */ | |
1428 | static int | |
0f113f3e | 1429 | cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) |
76dfca87 | 1430 | { |
0f113f3e MC |
1431 | # ifdef HAVE_SYSLOG_R |
1432 | struct syslog_data sd = SYSLOG_DATA_INIT; | |
1433 | # endif | |
76dfca87 | 1434 | |
0f113f3e MC |
1435 | switch (cmd) { |
1436 | default: | |
1437 | # ifdef HAVE_SYSLOG_R | |
1438 | syslog_r(LOG_ERR, &sd, "cryptodev_ctrl: unknown command %d", cmd); | |
1439 | # else | |
1440 | syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd); | |
1441 | # endif | |
1442 | break; | |
1443 | } | |
1444 | return (1); | |
76dfca87 RL |
1445 | } |
1446 | ||
0f113f3e | 1447 | void ENGINE_load_cryptodev(void) |
76dfca87 | 1448 | { |
0f113f3e MC |
1449 | ENGINE *engine = ENGINE_new(); |
1450 | int fd; | |
1451 | ||
1452 | if (engine == NULL) | |
1453 | return; | |
1454 | if ((fd = get_dev_crypto()) < 0) { | |
1455 | ENGINE_free(engine); | |
1456 | return; | |
1457 | } | |
1458 | ||
1459 | /* | |
1460 | * find out what asymmetric crypto algorithms we support | |
1461 | */ | |
1462 | if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { | |
1463 | put_dev_crypto(fd); | |
1464 | ENGINE_free(engine); | |
1465 | return; | |
1466 | } | |
1467 | put_dev_crypto(fd); | |
1468 | ||
1469 | if (!ENGINE_set_id(engine, "cryptodev") || | |
1470 | !ENGINE_set_name(engine, "BSD cryptodev engine") || | |
1471 | !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || | |
1472 | !ENGINE_set_digests(engine, cryptodev_engine_digests) || | |
1473 | !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || | |
1474 | !ENGINE_set_cmd_defns(engine, cryptodev_defns)) { | |
1475 | ENGINE_free(engine); | |
1476 | return; | |
1477 | } | |
1478 | ||
1479 | if (ENGINE_set_RSA(engine, &cryptodev_rsa)) { | |
b0700d2c | 1480 | const RSA_METHOD *rsa_meth = RSA_PKCS1_OpenSSL(); |
0f113f3e MC |
1481 | |
1482 | cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp; | |
1483 | cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp; | |
1484 | cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; | |
1485 | cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; | |
1486 | cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc; | |
1487 | cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; | |
1488 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | |
1489 | cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; | |
1490 | if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) | |
1491 | cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_mod_exp; | |
1492 | else | |
1493 | cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_nocrt_mod_exp; | |
1494 | } | |
1495 | } | |
1496 | ||
1497 | if (ENGINE_set_DSA(engine, &cryptodev_dsa)) { | |
1498 | const DSA_METHOD *meth = DSA_OpenSSL(); | |
1499 | ||
1500 | memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); | |
1501 | if (cryptodev_asymfeat & CRF_DSA_SIGN) | |
1502 | cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; | |
1503 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | |
1504 | cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; | |
1505 | cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; | |
1506 | } | |
1507 | if (cryptodev_asymfeat & CRF_DSA_VERIFY) | |
1508 | cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; | |
1509 | } | |
1510 | ||
1511 | if (ENGINE_set_DH(engine, &cryptodev_dh)) { | |
1512 | const DH_METHOD *dh_meth = DH_OpenSSL(); | |
1513 | ||
1514 | cryptodev_dh.generate_key = dh_meth->generate_key; | |
1515 | cryptodev_dh.compute_key = dh_meth->compute_key; | |
1516 | cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; | |
1517 | if (cryptodev_asymfeat & CRF_MOD_EXP) { | |
1518 | cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; | |
1519 | if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) | |
1520 | cryptodev_dh.compute_key = cryptodev_dh_compute_key; | |
1521 | } | |
1522 | } | |
1523 | ||
1524 | ENGINE_add(engine); | |
1525 | ENGINE_free(engine); | |
1526 | ERR_clear_error(); | |
76dfca87 RL |
1527 | } |
1528 | ||
0f113f3e | 1529 | #endif /* HAVE_CRYPTODEV */ |