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