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