1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 2002 Theo de Raadt
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 2002 Markus Friedl
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved.
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    documentation and/or other materials provided with the distribution.
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/objects.h>
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/engine.h>
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/evp.h>
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/bn.h>
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
3598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	(defined(OpenBSD) || defined(__FreeBSD__))
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <sys/param.h>
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#  define HAVE_CRYPTODEV
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# endif
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# if (OpenBSD >= 200110)
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#  define HAVE_SYSLOG_R
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project# endif
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef HAVE_CRYPTODEV
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectENGINE_load_cryptodev(void)
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* This is a NOP on platforms without /dev/crypto */
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return;
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <sys/types.h>
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <crypto/cryptodev.h>
58221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <crypto/dh/dh.h>
59221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <crypto/dsa/dsa.h>
60221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <crypto/err/err.h>
61221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <crypto/rsa/rsa.h>
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <sys/ioctl.h>
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <errno.h>
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <unistd.h>
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <fcntl.h>
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdarg.h>
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <syslog.h>
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <errno.h>
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h>
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstruct dev_crypto_state {
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct session_op d_sess;
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int d_fd;
75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef USE_CRYPTODEV_DIGESTS
77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	char dummy_mac_key[HASH_MAX_LEN];
78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
79221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned char digest_res[HASH_MAX_LEN];
80221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	char *mac_data;
81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int mac_len;
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic u_int32_t cryptodev_asymfeat = 0;
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int get_asym_dev_crypto(void);
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int open_dev_crypto(void);
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int get_dev_crypto(void);
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int get_cryptodev_ciphers(const int **cnids);
91221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef USE_CRYPTODEV_DIGESTS
92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int get_cryptodev_digests(const int **cnids);
93221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_usable_ciphers(const int **nids);
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_usable_digests(const int **nids);
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    const unsigned char *in, size_t inl);
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const unsigned char *iv, int enc);
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const int **nids, int nid);
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const int **nids, int nid);
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int bn2crparam(const BIGNUM *a, struct crparam *crp);
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int crparam2bn(struct crparam *crp, BIGNUM *a);
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void zapparams(struct crypt_kop *kop);
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int slen, BIGNUM *s);
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I,
11498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom    RSA *rsa, BN_CTX *ctx);
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a,
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    BN_CTX *ctx, BN_MONT_CTX *mont);
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst,
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int dlen, DSA *dsa);
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    DSA_SIG *sig, DSA *dsa);
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    BN_MONT_CTX *m_ctx);
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_dh_compute_key(unsigned char *key,
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const BIGNUM *pub_key, DH *dh);
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    void (*f)(void));
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ENGINE_load_cryptodev(void);
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic const ENGINE_CMD_DEFN cryptodev_defns[] = {
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ 0, NULL, NULL, 0 }
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic struct {
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	id;
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	nid;
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	ivmax;
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	keylen;
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} ciphers[] = {
144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ CRYPTO_ARC4,			NID_rc4,		0,	16, },
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ CRYPTO_DES_CBC,		NID_des_cbc,		8,	 8, },
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ CRYPTO_3DES_CBC,		NID_des_ede3_cbc,	8,	24, },
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ CRYPTO_AES_CBC,		NID_aes_128_cbc,	16,	16, },
148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ CRYPTO_AES_CBC,		NID_aes_192_cbc,	16,	24, },
149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ CRYPTO_AES_CBC,		NID_aes_256_cbc,	16,	32, },
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ CRYPTO_BLF_CBC,		NID_bf_cbc,		8,	16, },
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ CRYPTO_CAST_CBC,		NID_cast5_cbc,		8,	16, },
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ CRYPTO_SKIPJACK_CBC,		NID_undef,		0,	 0, },
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ 0,				NID_undef,		0,	 0, },
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef USE_CRYPTODEV_DIGESTS
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic struct {
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	id;
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	nid;
160221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int 	keylen;
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} digests[] = {
162221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ CRYPTO_MD5_HMAC,		NID_hmacWithMD5,	16},
163221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ CRYPTO_SHA1_HMAC,		NID_hmacWithSHA1,	20},
164221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		16/*?*/},
165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ CRYPTO_MD5_KPDK,		NID_undef,		0},
166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ CRYPTO_SHA1_KPDK,		NID_undef,		0},
167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ CRYPTO_MD5,			NID_md5,		16},
168221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ CRYPTO_SHA1,			NID_sha1,		20},
169221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{ 0,				NID_undef,		0},
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
17198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#endif
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Return a fd if /dev/crypto seems usable, 0 otherwise.
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectopen_dev_crypto(void)
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	static int fd = -1;
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (fd == -1) {
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return (-1);
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* close on exec */
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (fcntl(fd, F_SETFD, 1) == -1) {
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			close(fd);
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			fd = -1;
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return (-1);
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (fd);
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectget_dev_crypto(void)
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int fd, retfd;
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((fd = open_dev_crypto()) == -1)
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (-1);
20121c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom#ifndef CRIOGET_NOT_NEEDED
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ioctl(fd, CRIOGET, &retfd) == -1)
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (-1);
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* close on exec */
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (fcntl(retfd, F_SETFD, 1) == -1) {
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		close(retfd);
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (-1);
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
21021c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom#else
21121c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom        retfd = fd;
21221c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom#endif
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (retfd);
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
21621c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstromstatic void put_dev_crypto(int fd)
21721c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom{
21821c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom#ifndef CRIOGET_NOT_NEEDED
21921c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	close(fd);
22021c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom#endif
22121c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom}
22221c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Caching version for asym operations */
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectget_asym_dev_crypto(void)
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	static int fd = -1;
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (fd == -1)
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		fd = get_dev_crypto();
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return fd;
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Find out what ciphers /dev/crypto will let us have a session for.
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * XXX note, that some of these openssl doesn't deal with yet!
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * returning them here is harmless, as long as we return NULL
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * when asked for a handler in the cryptodev_engine_ciphers routine
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectget_cryptodev_ciphers(const int **cnids)
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	static int nids[CRYPTO_ALGORITHM_MAX];
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct session_op sess;
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int fd, i, count = 0;
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((fd = get_dev_crypto()) < 0) {
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cnids = NULL;
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (0);
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memset(&sess, 0, sizeof(sess));
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sess.key = (caddr_t)"123456789abcdefghijklmno";
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ciphers[i].nid == NID_undef)
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			continue;
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sess.cipher = ciphers[i].id;
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sess.keylen = ciphers[i].keylen;
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sess.mac = 0;
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			nids[count++] = ciphers[i].nid;
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
26421c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	put_dev_crypto(fd);
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (count > 0)
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cnids = nids;
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cnids = NULL;
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (count);
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
273221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef USE_CRYPTODEV_DIGESTS
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Find out what digests /dev/crypto will let us have a session for.
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * XXX note, that some of these openssl doesn't deal with yet!
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * returning them here is harmless, as long as we return NULL
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * when asked for a handler in the cryptodev_engine_digests routine
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectget_cryptodev_digests(const int **cnids)
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	static int nids[CRYPTO_ALGORITHM_MAX];
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct session_op sess;
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int fd, i, count = 0;
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((fd = get_dev_crypto()) < 0) {
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cnids = NULL;
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (0);
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memset(&sess, 0, sizeof(sess));
292221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sess.mackey = (caddr_t)"123456789abcdefghijklmno";
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (digests[i].nid == NID_undef)
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			continue;
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sess.mac = digests[i].id;
297221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		sess.mackeylen = digests[i].keylen;
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sess.cipher = 0;
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			nids[count++] = digests[i].nid;
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
30321c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	put_dev_crypto(fd);
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (count > 0)
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cnids = nids;
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cnids = NULL;
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (count);
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
311221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif  /* 0 */
31298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Find the useable ciphers|digests from dev/crypto - this is the first
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * thing called by the engine init crud which determines what it
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * can use for ciphers from this engine. We want to return
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * only what we can do, anythine else is handled by software.
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If we can't initialize the device to do anything useful for
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * any reason, we want to return a NULL array, and 0 length,
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * which forces everything to be done is software. By putting
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the initalization of the device in here, we ensure we can
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * use this engine as the default, and if for whatever reason
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * /dev/crypto won't do what we want it will just be done in
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * software
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can (should) be greatly expanded to perhaps take into
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * account speed of the device, and what we want to do.
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (although the disabling of particular alg's could be controlled
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by the device driver with sysctl's.) - this is where we
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * want most of the decisions made about what we actually want
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * to use from /dev/crypto.
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_usable_ciphers(const int **nids)
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (get_cryptodev_ciphers(nids));
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_usable_digests(const int **nids)
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef USE_CRYPTODEV_DIGESTS
344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return (get_cryptodev_digests(nids));
345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#else
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * XXXX just disable all digests for now, because it sucks.
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * we need a better way to decide this - i.e. I may not
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * want digests on slow cards like hifn on fast machines,
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * but might want them on slow or loaded machines, etc.
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * will also want them when using crypto cards that don't
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * suck moose gonads - would be nice to be able to decide something
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * as reasonable default without having hackery that's card dependent.
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * of course, the default should probably be just do everything,
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * with perhaps a sysctl to turn algoritms off (or have them off
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * by default) on cards that generally suck like the hifn.
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 */
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*nids = NULL;
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (0);
360221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
365221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    const unsigned char *in, size_t inl)
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct crypt_op cryp;
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct dev_crypto_state *state = ctx->cipher_data;
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct session_op *sess = &state->d_sess;
37098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	const void *iiv;
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char save_iv[EVP_MAX_IV_LENGTH];
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (state->d_fd < 0)
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (0);
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!inl)
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (1);
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((inl % ctx->cipher->block_size) != 0)
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (0);
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memset(&cryp, 0, sizeof(cryp));
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryp.ses = sess->ses;
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryp.flags = 0;
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryp.len = inl;
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryp.src = (caddr_t) in;
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryp.dst = (caddr_t) out;
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryp.mac = 0;
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ctx->cipher->iv_len) {
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cryp.iv = (caddr_t) ctx->iv;
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!ctx->encrypt) {
39498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			iiv = in + inl - ctx->cipher->iv_len;
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memcpy(save_iv, iiv, ctx->cipher->iv_len);
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cryp.iv = NULL;
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* XXX need better errror handling
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * this can fail for a number of different reasons.
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 */
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (0);
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ctx->cipher->iv_len) {
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx->encrypt)
40998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			iiv = out + inl - ctx->cipher->iv_len;
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			iiv = save_iv;
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (1);
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const unsigned char *iv, int enc)
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct dev_crypto_state *state = ctx->cipher_data;
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct session_op *sess = &state->d_sess;
423221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int cipher = -1, i;
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i = 0; ciphers[i].id; i++)
426221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (ctx->cipher->nid == ciphers[i].nid &&
427221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		    ctx->cipher->iv_len <= ciphers[i].ivmax &&
428221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		    ctx->key_len == ciphers[i].keylen) {
429221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			cipher = ciphers[i].id;
430221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			break;
431221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
433221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ciphers[i].id) {
434221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		state->d_fd = -1;
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (0);
436221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memset(sess, 0, sizeof(struct session_op));
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((state->d_fd = get_dev_crypto()) < 0)
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (0);
442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
443221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sess->key = (caddr_t)key;
444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sess->keylen = ctx->key_len;
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sess->cipher = cipher;
446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
44821c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom		put_dev_crypto(state->d_fd);
449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		state->d_fd = -1;
450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (0);
451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (1);
453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * free anything we allocated earlier when initting a
457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * session, and close the session.
458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_cleanup(EVP_CIPHER_CTX *ctx)
461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret = 0;
463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct dev_crypto_state *state = ctx->cipher_data;
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct session_op *sess = &state->d_sess;
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (state->d_fd < 0)
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (0);
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* XXX if this ioctl fails, someting's wrong. the invoker
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * may have called us with a bogus ctx, or we could
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * have a device that for whatever reason just doesn't
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * want to play ball - it's not clear what's right
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * here - should this be an error? should it just
474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * increase a counter, hmm. For right now, we return
475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * 0 - I don't believe that to be "right". we could
476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * call the gorpy openssl lib error handlers that
477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * print messages to users of the library. hmm..
478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 */
479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 0;
482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else {
483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 1;
484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
48521c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	put_dev_crypto(state->d_fd);
486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	state->d_fd = -1;
487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (ret);
489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * libcrypto EVP stuff - this is how we get wired to EVP so the engine
493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * gets called when libcrypto requests a cipher NID.
494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
496221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* RC4 */
497221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromconst EVP_CIPHER cryptodev_rc4 = {
498221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NID_rc4,
499221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	1, 16, 0,
500221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_CIPH_VARIABLE_LENGTH,
501221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_init_key,
502221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_cipher,
503221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_cleanup,
504221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sizeof(struct dev_crypto_state),
505221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NULL,
506221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NULL,
507221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NULL
508221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom};
509221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* DES CBC EVP */
511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst EVP_CIPHER cryptodev_des_cbc = {
512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NID_des_cbc,
513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	8, 8, 8,
514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPH_CBC_MODE,
515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_init_key,
516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_cipher,
517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_cleanup,
518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sizeof(struct dev_crypto_state),
519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_set_asn1_iv,
520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_get_asn1_iv,
521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL
522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* 3DES CBC EVP */
525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst EVP_CIPHER cryptodev_3des_cbc = {
526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NID_des_ede3_cbc,
527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	8, 24, 8,
528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPH_CBC_MODE,
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_init_key,
530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_cipher,
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_cleanup,
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sizeof(struct dev_crypto_state),
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_set_asn1_iv,
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_get_asn1_iv,
535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL
536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst EVP_CIPHER cryptodev_bf_cbc = {
539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NID_bf_cbc,
540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	8, 16, 8,
541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPH_CBC_MODE,
542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_init_key,
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_cipher,
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_cleanup,
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sizeof(struct dev_crypto_state),
546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_set_asn1_iv,
547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_get_asn1_iv,
548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL
549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst EVP_CIPHER cryptodev_cast_cbc = {
552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NID_cast5_cbc,
553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	8, 16, 8,
554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPH_CBC_MODE,
555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_init_key,
556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_cipher,
557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_cleanup,
558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sizeof(struct dev_crypto_state),
559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_set_asn1_iv,
560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_get_asn1_iv,
561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL
562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst EVP_CIPHER cryptodev_aes_cbc = {
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NID_aes_128_cbc,
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	16, 16, 16,
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPH_CBC_MODE,
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_init_key,
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_cipher,
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cryptodev_cleanup,
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sizeof(struct dev_crypto_state),
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_set_asn1_iv,
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_get_asn1_iv,
574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL
575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
577221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromconst EVP_CIPHER cryptodev_aes_192_cbc = {
578221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NID_aes_192_cbc,
579221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	16, 24, 16,
580221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_CIPH_CBC_MODE,
581221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_init_key,
582221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_cipher,
583221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_cleanup,
584221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sizeof(struct dev_crypto_state),
585221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_CIPHER_set_asn1_iv,
586221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_CIPHER_get_asn1_iv,
587221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NULL
588221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom};
589221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
590221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromconst EVP_CIPHER cryptodev_aes_256_cbc = {
591221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NID_aes_256_cbc,
592221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	16, 32, 16,
593221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_CIPH_CBC_MODE,
594221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_init_key,
595221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_cipher,
596221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_cleanup,
597221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sizeof(struct dev_crypto_state),
598221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_CIPHER_set_asn1_iv,
599221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_CIPHER_get_asn1_iv,
600221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NULL
601221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom};
602221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Registered by the ENGINE when used to find out how to deal with
605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * a particular NID in the ENGINE. this says what we'll do at the
606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * top level - note, that list is restricted by what we answer with
607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const int **nids, int nid)
611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!cipher)
613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (cryptodev_usable_ciphers(nids));
614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (nid) {
616221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	case NID_rc4:
617221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		*cipher = &cryptodev_rc4;
618221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		break;
619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case NID_des_ede3_cbc:
620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cipher = &cryptodev_3des_cbc;
621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case NID_des_cbc:
623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cipher = &cryptodev_des_cbc;
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case NID_bf_cbc:
626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cipher = &cryptodev_bf_cbc;
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case NID_cast5_cbc:
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cipher = &cryptodev_cast_cbc;
630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case NID_aes_128_cbc:
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cipher = &cryptodev_aes_cbc;
633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
634221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	case NID_aes_192_cbc:
635221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		*cipher = &cryptodev_aes_192_cbc;
636221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		break;
637221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	case NID_aes_256_cbc:
638221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		*cipher = &cryptodev_aes_256_cbc;
639221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		break;
640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*cipher = NULL;
642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (*cipher != NULL);
645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
647221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
648221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef USE_CRYPTODEV_DIGESTS
649221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
650221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* convert digest type to cryptodev */
651221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int
652221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromdigest_nid_to_cryptodev(int nid)
653221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{
654221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i;
655221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
656221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i = 0; digests[i].id; i++)
657221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (digests[i].nid == nid)
658221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return (digests[i].id);
659221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return (0);
660221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
661221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
662221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
663221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int
664221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromdigest_key_length(int nid)
665221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{
666221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i;
667221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
668221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i = 0; digests[i].id; i++)
669221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (digests[i].nid == nid)
670221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return digests[i].keylen;
671221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return (0);
672221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
673221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
674221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
675221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int cryptodev_digest_init(EVP_MD_CTX *ctx)
676221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{
677221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct dev_crypto_state *state = ctx->md_data;
678221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct session_op *sess = &state->d_sess;
679221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int digest;
680221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
681221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){
682221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("cryptodev_digest_init: Can't get digest \n");
683221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return (0);
684221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
685221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
686221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	memset(state, 0, sizeof(struct dev_crypto_state));
687221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
688221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if ((state->d_fd = get_dev_crypto()) < 0) {
689221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("cryptodev_digest_init: Can't get Dev \n");
690221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return (0);
691221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
692221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
693221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sess->mackey = state->dummy_mac_key;
694221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sess->mackeylen = digest_key_length(ctx->digest->type);
695221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sess->mac = digest;
696221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
697221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
69821c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom		put_dev_crypto(state->d_fd);
699221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		state->d_fd = -1;
700221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("cryptodev_digest_init: Open session failed\n");
701221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return (0);
702221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
703221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
704221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return (1);
705221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
706221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
707221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
708221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		size_t count)
709221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{
710221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct crypt_op cryp;
711221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct dev_crypto_state *state = ctx->md_data;
712221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct session_op *sess = &state->d_sess;
713221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
714221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!data || state->d_fd < 0) {
715221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("cryptodev_digest_update: illegal inputs \n");
716221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return (0);
717221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
718221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
719221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!count) {
720221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return (0);
721221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
722221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
723221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
724221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* if application doesn't support one buffer */
725221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		state->mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count);
726221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
727221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!state->mac_data) {
728221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			printf("cryptodev_digest_update: realloc failed\n");
729221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return (0);
730221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
731221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
732221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		memcpy(state->mac_data + state->mac_len, data, count);
733221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom   		state->mac_len += count;
734221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
735221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return (1);
736221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
737221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
738221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	memset(&cryp, 0, sizeof(cryp));
739221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
740221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryp.ses = sess->ses;
741221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryp.flags = 0;
742221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryp.len = count;
743221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryp.src = (caddr_t) data;
744221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryp.dst = NULL;
745221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryp.mac = (caddr_t) state->digest_res;
746221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
747221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("cryptodev_digest_update: digest failed\n");
748221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return (0);
749221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
750221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return (1);
751221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
752221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
753221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
754221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
755221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{
756221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct crypt_op cryp;
757221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct dev_crypto_state *state = ctx->md_data;
758221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct session_op *sess = &state->d_sess;
759221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
760221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret = 1;
761221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
762221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!md || state->d_fd < 0) {
763221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("cryptodev_digest_final: illegal input\n");
764221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return(0);
765221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
766221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
767221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
768221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		/* if application doesn't support one buffer */
769221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		memset(&cryp, 0, sizeof(cryp));
770221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		cryp.ses = sess->ses;
771221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		cryp.flags = 0;
772221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		cryp.len = state->mac_len;
773221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		cryp.src = state->mac_data;
774221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		cryp.dst = NULL;
775221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		cryp.mac = (caddr_t)md;
776221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
777221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			printf("cryptodev_digest_final: digest failed\n");
778221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return (0);
779221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
780221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
781221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
782221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
783221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
784221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	memcpy(md, state->digest_res, ctx->digest->md_size);
785221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
786221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return (ret);
787221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
788221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
789221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
790221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
791221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{
792221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ret = 1;
793221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct dev_crypto_state *state = ctx->md_data;
794221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct session_op *sess = &state->d_sess;
795221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
79621c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	if (state == NULL)
79721c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	  return 0;
79821c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom
799221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (state->d_fd < 0) {
800221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("cryptodev_digest_cleanup: illegal input\n");
801221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return (0);
802221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
803221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
804221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (state->mac_data) {
805221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		OPENSSL_free(state->mac_data);
806221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		state->mac_data = NULL;
807221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		state->mac_len = 0;
808221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
809221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
810221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
811221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("cryptodev_digest_cleanup: failed to close session\n");
812221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = 0;
813221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	} else {
814221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = 1;
815221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
81621c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	put_dev_crypto(state->d_fd);
817221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	state->d_fd = -1;
818221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
819221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return (ret);
820221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
821221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
822221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int cryptodev_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
823221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{
824221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct dev_crypto_state *fstate = from->md_data;
825221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct dev_crypto_state *dstate = to->md_data;
82621c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	struct session_op *sess;
82721c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	int digest;
828221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
82921c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	if (dstate == NULL || fstate == NULL)
83021c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	  return 1;
831221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
83221c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom       	memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
83321c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom
83421c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	sess = &dstate->d_sess;
83521c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom
83621c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	digest = digest_nid_to_cryptodev(to->digest->type);
83721c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom
83821c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	sess->mackey = dstate->dummy_mac_key;
83921c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	sess->mackeylen = digest_key_length(to->digest->type);
84021c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	sess->mac = digest;
84121c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom
84221c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	dstate->d_fd = get_dev_crypto();
84321c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom
84421c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) {
84521c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom		put_dev_crypto(dstate->d_fd);
84621c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom		dstate->d_fd = -1;
84721c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom		printf("cryptodev_digest_init: Open session failed\n");
84821c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom		return (0);
849221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
850221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
85121c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	if (fstate->mac_len != 0) {
85221c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	        if (fstate->mac_data != NULL)
85321c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	                {
85421c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom        		dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
85521c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	        	memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
85621c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom           		dstate->mac_len = fstate->mac_len;
85721c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	        	}
85821c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	}
859221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
860221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
861221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
862221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
863221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
864221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromconst EVP_MD cryptodev_sha1 = {
865221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NID_sha1,
866221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NID_undef,
867221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	SHA_DIGEST_LENGTH,
868221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_MD_FLAG_ONESHOT,
869221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_digest_init,
870221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_digest_update,
871221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_digest_final,
872221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_digest_copy,
873221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_digest_cleanup,
874221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY_NULL_method,
875221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	SHA_CBLOCK,
876221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sizeof(struct dev_crypto_state),
877221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom};
878221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
879221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromconst EVP_MD cryptodev_md5 = {
880221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NID_md5,
881221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NID_undef,
882221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	16 /* MD5_DIGEST_LENGTH */,
883221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_MD_FLAG_ONESHOT,
884221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_digest_init,
885221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_digest_update,
886221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_digest_final,
887221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_digest_copy,
888221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	cryptodev_digest_cleanup,
889221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY_NULL_method,
890221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	64 /* MD5_CBLOCK */,
891221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	sizeof(struct dev_crypto_state),
892221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom};
893221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
894221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif /* USE_CRYPTODEV_DIGESTS */
895221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
896221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
897656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
898656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
899656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const int **nids, int nid)
900656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
901656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!digest)
902656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (cryptodev_usable_digests(nids));
903656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
904656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (nid) {
905221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef USE_CRYPTODEV_DIGESTS
906656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case NID_md5:
907221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		*digest = &cryptodev_md5;
908656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
909221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	case NID_sha1:
910221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		*digest = &cryptodev_sha1;
911221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 		break;
912656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
913221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif /* USE_CRYPTODEV_DIGESTS */
914656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*digest = NULL;
915656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
916656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
917656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (*digest != NULL);
918656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
919656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
920656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
921656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Convert a BIGNUM to the representation that /dev/crypto needs.
922656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Upon completion of use, the caller is responsible for freeing
923656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * crp->crp_p.
924656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
925656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
926656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectbn2crparam(const BIGNUM *a, struct crparam *crp)
927656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
928656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i, j, k;
92998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	ssize_t bytes, bits;
930656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	u_char *b;
931656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
932656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	crp->crp_p = NULL;
933656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	crp->crp_nbits = 0;
934656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
935656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bits = BN_num_bits(a);
936656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bytes = (bits + 7) / 8;
937656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
938656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	b = malloc(bytes);
939656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (b == NULL)
940656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (1);
941221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	memset(b, 0, bytes);
942656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
943221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	crp->crp_p = (caddr_t) b;
944656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	crp->crp_nbits = bits;
945656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
946656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0, j = 0; i < a->top; i++) {
947656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for (k = 0; k < BN_BITS2 / 8; k++) {
948656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if ((j + k) >= bytes)
949656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return (0);
950656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			b[j + k] = a->d[i] >> (k * 8);
951656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
952656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		j += BN_BITS2 / 8;
953656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
954656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (0);
955656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
956656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
957656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Convert a /dev/crypto parameter to a BIGNUM */
958656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
959656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcrparam2bn(struct crparam *crp, BIGNUM *a)
960656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
961656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	u_int8_t *pd;
962656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i, bytes;
963656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
964656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bytes = (crp->crp_nbits + 7) / 8;
965656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
966656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bytes == 0)
967656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (-1);
968656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
969656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((pd = (u_int8_t *) malloc(bytes)) == NULL)
970656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (-1);
971656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
972656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (i = 0; i < bytes; i++)
973656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		pd[i] = crp->crp_p[bytes - i - 1];
974656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
975656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_bin2bn(pd, bytes, a);
976656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	free(pd);
977656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
978656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (0);
979656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
980656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
981656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void
982656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectzapparams(struct crypt_kop *kop)
983656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
984656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
985656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
986221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
987656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (kop->crk_param[i].crp_p)
988656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			free(kop->crk_param[i].crp_p);
989656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		kop->crk_param[i].crp_p = NULL;
990656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		kop->crk_param[i].crp_nbits = 0;
991656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
992656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
993656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
994656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
995656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, BIGNUM *s)
996656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
997656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int fd, ret = -1;
998656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
999656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((fd = get_asym_dev_crypto()) < 0)
1000656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (ret);
1001656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1002656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (r) {
1003656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
1004656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
1005656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		kop->crk_oparams++;
1006656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1007656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (s) {
1008656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		kop->crk_param[kop->crk_iparams+1].crp_p = calloc(slen, sizeof(char));
1009656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		kop->crk_param[kop->crk_iparams+1].crp_nbits = slen * 8;
1010656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		kop->crk_oparams++;
1011656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1012656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1013656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ioctl(fd, CIOCKEY, kop) == 0) {
1014656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (r)
1015656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			crparam2bn(&kop->crk_param[kop->crk_iparams], r);
1016656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (s)
1017656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			crparam2bn(&kop->crk_param[kop->crk_iparams+1], s);
1018656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = 0;
1019656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1020656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1021656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (ret);
1022656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1023656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1024656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
1025656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
1026656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
1027656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
1028656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct crypt_kop kop;
1029656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret = 1;
1030656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1031656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Currently, we know we can do mod exp iff we can do any
1032656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * asymmetric operations at all.
1033656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 */
1034656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (cryptodev_asymfeat == 0) {
1035656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = BN_mod_exp(r, a, p, m, ctx);
1036656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (ret);
1037656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1038656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1039656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memset(&kop, 0, sizeof kop);
1040656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_op = CRK_MOD_EXP;
1041656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1042656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* inputs: a^p % m */
1043656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(a, &kop.crk_param[0]))
1044656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1045656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(p, &kop.crk_param[1]))
1046656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1047656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(m, &kop.crk_param[2]))
1048656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1049656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_iparams = 3;
1050656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1051221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
1052221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1053221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("OCF asym process failed, Running in software\n");
1054221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
1055221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1056221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	} else if (ECANCELED == kop.crk_status) {
1057656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1058221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("OCF hardware operation cancelled. Running in Software\n");
1059656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont);
1060656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1061221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* else cryptodev operation worked ok ==> ret = 1*/
1062221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1063656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
1064656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zapparams(&kop);
1065656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (ret);
1066656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1067656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1068656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
106998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstromcryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
1070656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
1071656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int r;
1072221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ctx = BN_CTX_new();
1073656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL);
1074221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BN_CTX_free(ctx);
1075656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (r);
1076656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1077656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1078656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
1079656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
1080656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
1081656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct crypt_kop kop;
1082656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret = 1;
1083656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1084656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) {
1085656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* XXX 0 means failure?? */
1086656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (0);
1087656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1088656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1089656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memset(&kop, 0, sizeof kop);
1090656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_op = CRK_MOD_EXP_CRT;
1091656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
1092656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(rsa->p, &kop.crk_param[0]))
1093656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1094656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(rsa->q, &kop.crk_param[1]))
1095656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1096656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(I, &kop.crk_param[2]))
1097656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1098656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(rsa->dmp1, &kop.crk_param[3]))
1099656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(rsa->dmq1, &kop.crk_param[4]))
1101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(rsa->iqmp, &kop.crk_param[5]))
1103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_iparams = 6;
1105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) {
1107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("OCF asym process failed, running in Software\n");
1109221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
1110221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	} else if (ECANCELED == kop.crk_status) {
1112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		const RSA_METHOD *meth = RSA_PKCS1_SSLeay();
1113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("OCF hardware operation cancelled. Running in Software\n");
1114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = (*meth->rsa_mod_exp)(r0, I, rsa, ctx);
1115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* else cryptodev operation worked ok ==> ret = 1*/
1117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
1119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zapparams(&kop);
1120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (ret);
1121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic RSA_METHOD cryptodev_rsa = {
1124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	"cryptodev RSA method",
1125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* rsa_pub_enc */
1126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* rsa_pub_dec */
1127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* rsa_priv_enc */
1128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* rsa_priv_dec */
1129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
1130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
1131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* init */
1132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* finish */
1133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	0,				/* flags */
1134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* app_data */
1135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* rsa_sign */
1136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL				/* rsa_verify */
1137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
1138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
1140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
1141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
1142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
1143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
1147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g,
1148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p,
1149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    BN_CTX *ctx, BN_MONT_CTX *mont)
1150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
1151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIGNUM t2;
1152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret = 0;
1153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_init(&t2);
1155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* v = ( g^u1 * y^u2 mod p ) mod q */
1157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* let t1 = g ^ u1 mod p */
1158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = 0;
1159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!dsa->meth->bn_mod_exp(dsa,t1,dsa->g,u1,dsa->p,ctx,mont))
1161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* let t2 = y ^ u2 mod p */
1164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!dsa->meth->bn_mod_exp(dsa,&t2,dsa->pub_key,u2,dsa->p,ctx,mont))
1165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* let u1 = t1 * t2 mod p */
1167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!BN_mod_mul(u1,t1,&t2,dsa->p,ctx))
1168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_copy(t1,u1);
1171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = 1;
1173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
1174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_free(&t2);
1175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(ret);
1176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic DSA_SIG *
1179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
1180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
1181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct crypt_kop kop;
1182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIGNUM *r = NULL, *s = NULL;
1183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	DSA_SIG *dsaret = NULL;
1184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((r = BN_new()) == NULL)
1186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((s = BN_new()) == NULL) {
1188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(r);
1189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memset(&kop, 0, sizeof kop);
1193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_op = CRK_DSA_SIGN;
1194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
1196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_param[0].crp_p = (caddr_t)dgst;
1197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_param[0].crp_nbits = dlen * 8;
1198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(dsa->p, &kop.crk_param[1]))
1199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(dsa->q, &kop.crk_param[2]))
1201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(dsa->g, &kop.crk_param[3]))
1203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(dsa->priv_key, &kop.crk_param[4]))
1205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_iparams = 5;
1207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r,
1209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    BN_num_bytes(dsa->q), s) == 0) {
1210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dsaret = DSA_SIG_new();
1211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dsaret->r = r;
1212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dsaret->s = s;
1213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else {
1214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		const DSA_METHOD *meth = DSA_OpenSSL();
1215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(r);
1216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(s);
1217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dsaret = (meth->dsa_do_sign)(dgst, dlen, dsa);
1218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
1220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_param[0].crp_p = NULL;
1221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zapparams(&kop);
1222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (dsaret);
1223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
1226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_dsa_verify(const unsigned char *dgst, int dlen,
1227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    DSA_SIG *sig, DSA *dsa)
1228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
1229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct crypt_kop kop;
1230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int dsaret = 1;
1231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memset(&kop, 0, sizeof kop);
1233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_op = CRK_DSA_VERIFY;
1234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
1236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_param[0].crp_p = (caddr_t)dgst;
1237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_param[0].crp_nbits = dlen * 8;
1238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(dsa->p, &kop.crk_param[1]))
1239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(dsa->q, &kop.crk_param[2]))
1241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(dsa->g, &kop.crk_param[3]))
1243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(dsa->pub_key, &kop.crk_param[4]))
1245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(sig->r, &kop.crk_param[5]))
1247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(sig->s, &kop.crk_param[6]))
1249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_iparams = 7;
1251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
1253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/*OCF success value is 0, if not zero, change dsaret to fail*/
1254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if(0 != kop.crk_status) dsaret  = 0;
1255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else {
1256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		const DSA_METHOD *meth = DSA_OpenSSL();
1257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dsaret = (meth->dsa_do_verify)(dgst, dlen, sig, dsa);
1259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
1261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_param[0].crp_p = NULL;
1262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zapparams(&kop);
1263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (dsaret);
1264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic DSA_METHOD cryptodev_dsa = {
1267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	"cryptodev DSA method",
1268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
1269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* dsa_sign_setup */
1270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
1271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* dsa_mod_exp */
1272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
1273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* init */
1274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* finish */
1275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	0,	/* flags */
1276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL	/* app_data */
1277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
1278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
1280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
1281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
1282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    BN_MONT_CTX *m_ctx)
1283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
1284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
1285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
1288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectcryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
1289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
1290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct crypt_kop kop;
1291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int dhret = 1;
1292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int fd, keylen;
1293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((fd = get_asym_dev_crypto()) < 0) {
1295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		const DH_METHOD *meth = DH_OpenSSL();
1296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return ((meth->compute_key)(key, pub_key, dh));
1298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	keylen = BN_num_bits(dh->p);
1301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memset(&kop, 0, sizeof kop);
1303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_op = CRK_DH_COMPUTE_KEY;
1304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* inputs: dh->priv_key pub_key dh->p key */
1306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(dh->priv_key, &kop.crk_param[0]))
1307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(pub_key, &kop.crk_param[1]))
1309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (bn2crparam(dh->p, &kop.crk_param[2]))
1311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
1312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_iparams = 3;
1313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	kop.crk_param[3].crp_p = (caddr_t) key;
1315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_param[3].crp_nbits = keylen * 8;
1316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_oparams = 1;
1317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ioctl(fd, CIOCKEY, &kop) == -1) {
1319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		const DH_METHOD *meth = DH_OpenSSL();
1320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dhret = (meth->compute_key)(key, pub_key, dh);
1322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
1324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	kop.crk_param[3].crp_p = NULL;
1325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	zapparams(&kop);
1326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (dhret);
1327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic DH_METHOD cryptodev_dh = {
1330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	"cryptodev DH method",
1331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,				/* cryptodev_dh_generate_key */
1332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
1333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
1334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
1335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL,
1336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	0,	/* flags */
1337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL	/* app_data */
1338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project};
1339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
1341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ctrl right now is just a wrapper that doesn't do much
1342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * but I expect we'll want some options soon.
1343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
1344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int
1345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromcryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
1346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
1347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef HAVE_SYSLOG_R
1348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	struct syslog_data sd = SYSLOG_DATA_INIT;
1349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (cmd) {
1352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:
1353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef HAVE_SYSLOG_R
1354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		syslog_r(LOG_ERR, &sd,
1355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    "cryptodev_ctrl: unknown command %d", cmd);
1356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
1357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
1358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
1360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return (1);
1362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid
1365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectENGINE_load_cryptodev(void)
1366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
1367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *engine = ENGINE_new();
1368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int fd;
1369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (engine == NULL)
1371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return;
1372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((fd = get_dev_crypto()) < 0) {
1373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINE_free(engine);
1374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return;
1375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*
1378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * find out what asymmetric crypto algorithms we support
1379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 */
1380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
138121c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom		put_dev_crypto(fd);
1382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINE_free(engine);
1383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return;
1384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
138521c841450af61d0a9119cdc863e93d019127bfe1Brian Carlstrom	put_dev_crypto(fd);
1386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!ENGINE_set_id(engine, "cryptodev") ||
1388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    !ENGINE_set_name(engine, "BSD cryptodev engine") ||
1389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
1390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
1391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
1392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	    !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
1393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINE_free(engine);
1394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return;
1395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ENGINE_set_RSA(engine, &cryptodev_rsa)) {
1398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay();
1399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp;
1401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp;
1402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc;
1403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec;
1404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc;
1405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec;
1406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (cryptodev_asymfeat & CRF_MOD_EXP) {
1407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp;
1408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
1409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				cryptodev_rsa.rsa_mod_exp =
1410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				    cryptodev_rsa_mod_exp;
1411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
1412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				cryptodev_rsa.rsa_mod_exp =
1413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				    cryptodev_rsa_nocrt_mod_exp;
1414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ENGINE_set_DSA(engine, &cryptodev_dsa)) {
1418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		const DSA_METHOD *meth = DSA_OpenSSL();
1419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD));
1421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (cryptodev_asymfeat & CRF_DSA_SIGN)
1422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign;
1423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (cryptodev_asymfeat & CRF_MOD_EXP) {
1424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp;
1425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp;
1426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (cryptodev_asymfeat & CRF_DSA_VERIFY)
1428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify;
1429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ENGINE_set_DH(engine, &cryptodev_dh)){
1432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		const DH_METHOD *dh_meth = DH_OpenSSL();
1433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cryptodev_dh.generate_key = dh_meth->generate_key;
1435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cryptodev_dh.compute_key = dh_meth->compute_key;
1436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp;
1437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (cryptodev_asymfeat & CRF_MOD_EXP) {
1438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh;
1439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
1440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				cryptodev_dh.compute_key =
1441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				    cryptodev_dh_compute_key;
1442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE_add(engine);
1446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE_free(engine);
1447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_clear_error();
1448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
1449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif /* HAVE_CRYPTODEV */
1451