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