1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
2392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * Copyright (c) 2001-2011 The OpenSSL Project.  All rights reserved.
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    openssl-core@openssl.org.
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/opensslconf.h>
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_AES
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/evp.h>
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h>
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h>
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <assert.h>
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/aes.h>
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "evp_locl.h"
59392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_FIPS
60392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include "modes_lcl.h"
61392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/rand.h>
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef struct
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	AES_KEY ks;
66392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	block128_f block;
67392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	union {
68392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cbc128_f cbc;
69392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ctr128_f ctr;
70392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	} stream;
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} EVP_AES_KEY;
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
73392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef struct
74392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
75392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	AES_KEY ks;		/* AES key schedule to use */
76392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int key_set;		/* Set if key initialised */
77392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int iv_set;		/* Set if an iv is set */
78392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	GCM128_CONTEXT gcm;
79392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	unsigned char *iv;	/* Temporary IV store */
80392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int ivlen;		/* IV length */
81392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int taglen;
82392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int iv_gen;		/* It is OK to generate IVs */
83392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int tls_aad_len;	/* TLS AAD length */
84392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	ctr128_f ctr;
85392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	} EVP_AES_GCM_CTX;
86392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
87392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef struct
88392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
89392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	AES_KEY ks1, ks2;	/* AES key schedules to use */
90392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	XTS128_CONTEXT xts;
91392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	void     (*stream)(const unsigned char *in,
92392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char *out, size_t length,
93392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key1, const AES_KEY *key2,
94392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const unsigned char iv[16]);
95392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	} EVP_AES_XTS_CTX;
96392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
97392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromtypedef struct
98392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
99392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	AES_KEY ks;		/* AES key schedule to use */
100392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int key_set;		/* Set if key initialised */
101392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int iv_set;		/* Set if an iv is set */
102392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int tag_set;		/* Set if tag is valid */
103392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int len_set;		/* Set if message length set */
104392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int L, M;		/* L and M parameters from RFC3610 */
105392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	CCM128_CONTEXT ccm;
106392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	ccm128_f str;
107392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	} EVP_AES_CCM_CTX;
108392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
109392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define MAXBITCHUNK	((size_t)1<<(sizeof(size_t)*8-4))
110392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
111392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_ASM
112392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint vpaes_set_encrypt_key(const unsigned char *userKey, int bits,
113392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			AES_KEY *key);
114392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint vpaes_set_decrypt_key(const unsigned char *userKey, int bits,
115392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			AES_KEY *key);
116392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
117392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid vpaes_encrypt(const unsigned char *in, unsigned char *out,
118392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key);
119392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid vpaes_decrypt(const unsigned char *in, unsigned char *out,
120392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key);
121392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
122392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid vpaes_cbc_encrypt(const unsigned char *in,
123392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char *out,
124392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t length,
125392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key,
126392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char *ivec, int enc);
127392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
128392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef BSAES_ASM
129392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
130392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t length, const AES_KEY *key,
131392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char ivec[16], int enc);
132392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
133392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t len, const AES_KEY *key,
134392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const unsigned char ivec[16]);
135392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out,
136392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t len, const AES_KEY *key1,
137392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key2, const unsigned char iv[16]);
138392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out,
139392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t len, const AES_KEY *key1,
140392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key2, const unsigned char iv[16]);
141392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
142392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef AES_CTR_ASM
143392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
144392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t blocks, const AES_KEY *key,
145392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const unsigned char ivec[AES_BLOCK_SIZE]);
146392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
147392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef AES_XTS_ASM
148392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid AES_xts_encrypt(const char *inp,char *out,size_t len,
149392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key1, const AES_KEY *key2,
150392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const unsigned char iv[16]);
151392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid AES_xts_decrypt(const char *inp,char *out,size_t len,
152392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key1, const AES_KEY *key2,
153392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const unsigned char iv[16]);
154392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
155392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
156392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#if	defined(AES_ASM) && !defined(I386_ONLY) &&	(  \
157392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	((defined(__i386)	|| defined(__i386__)	|| \
158392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	  defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
159392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	defined(__x86_64)	|| defined(__x86_64__)	|| \
160392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	defined(_M_AMD64)	|| defined(_M_X64)	|| \
161392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	defined(__INTEL__)				)
162392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
163392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromextern unsigned int OPENSSL_ia32cap_P[2];
164392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
165392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_ASM
166392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define VPAES_CAPABLE	(OPENSSL_ia32cap_P[1]&(1<<(41-32)))
167392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
168392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef BSAES_ASM
169392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define BSAES_CAPABLE	VPAES_CAPABLE
170392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
171392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/*
172392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * AES-NI section
173392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */
174392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define	AESNI_CAPABLE	(OPENSSL_ia32cap_P[1]&(1<<(57-32)))
175392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
176392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint aesni_set_encrypt_key(const unsigned char *userKey, int bits,
177392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			AES_KEY *key);
178392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint aesni_set_decrypt_key(const unsigned char *userKey, int bits,
179392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			AES_KEY *key);
180392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
181392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid aesni_encrypt(const unsigned char *in, unsigned char *out,
182392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key);
183392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid aesni_decrypt(const unsigned char *in, unsigned char *out,
184392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key);
185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
186392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid aesni_ecb_encrypt(const unsigned char *in,
187392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char *out,
188392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t length,
189392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key,
190392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			int enc);
191392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid aesni_cbc_encrypt(const unsigned char *in,
192392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char *out,
193392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t length,
194392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key,
195392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char *ivec, int enc);
196392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
197392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid aesni_ctr32_encrypt_blocks(const unsigned char *in,
198392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char *out,
199392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t blocks,
200392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const void *key,
201392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const unsigned char *ivec);
202392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
203392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid aesni_xts_encrypt(const unsigned char *in,
204392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char *out,
205392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t length,
206392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key1, const AES_KEY *key2,
207392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const unsigned char iv[16]);
208392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
209392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid aesni_xts_decrypt(const unsigned char *in,
210392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char *out,
211392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t length,
212392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const AES_KEY *key1, const AES_KEY *key2,
213392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const unsigned char iv[16]);
214392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
215392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid aesni_ccm64_encrypt_blocks (const unsigned char *in,
216392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char *out,
217392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t blocks,
218392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const void *key,
219392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const unsigned char ivec[16],
220392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char cmac[16]);
221392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
222392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid aesni_ccm64_decrypt_blocks (const unsigned char *in,
223392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char *out,
224392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			size_t blocks,
225392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const void *key,
226392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			const unsigned char ivec[16],
227392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char cmac[16]);
228392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
229392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
230392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		   const unsigned char *iv, int enc)
231392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
232392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int ret, mode;
233392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
234392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
235392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	mode = ctx->cipher->flags & EVP_CIPH_MODE;
236392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
237392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    && !enc)
238392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
239392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ret = aesni_set_decrypt_key(key, ctx->key_len*8, ctx->cipher_data);
240392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)aesni_decrypt;
241392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
242392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(cbc128_f)aesni_cbc_encrypt :
243392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					NULL;
244392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
245392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else	{
246392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ret = aesni_set_encrypt_key(key, ctx->key_len*8, ctx->cipher_data);
247392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)aesni_encrypt;
248392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (mode==EVP_CIPH_CBC_MODE)
249392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			dat->stream.cbc	= (cbc128_f)aesni_cbc_encrypt;
250392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else if (mode==EVP_CIPH_CTR_MODE)
251392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			dat->stream.ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
252392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
253392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			dat->stream.cbc = NULL;
254392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
255392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
256392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if(ret < 0)
257392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
258392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVPerr(EVP_F_AESNI_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
259392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
260392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
261392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
262392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
263392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
264392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
265392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
266392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in, size_t len)
267392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
268392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aesni_cbc_encrypt(in,out,len,ctx->cipher_data,ctx->iv,ctx->encrypt);
269392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
270392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
271392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
272392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
273392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
274392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in, size_t len)
275392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
276392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	size_t	bl = ctx->cipher->block_size;
277392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
278392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (len<bl)	return 1;
279392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
280392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aesni_ecb_encrypt(in,out,len,ctx->cipher_data,ctx->encrypt);
281392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
282392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
283392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
284392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
285392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aesni_ofb_cipher aes_ofb_cipher
286392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
287392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len);
288392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
289392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aesni_cfb_cipher aes_cfb_cipher
290392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
291392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len);
292392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
293392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aesni_cfb8_cipher aes_cfb8_cipher
294392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
295392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len);
296392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
297392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aesni_cfb1_cipher aes_cfb1_cipher
298392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
299392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len);
300392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
301392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aesni_ctr_cipher aes_ctr_cipher
302392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
303392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len);
304392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
305392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
306392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        const unsigned char *iv, int enc)
307392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
308392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
309392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!iv && !key)
310392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
311392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (key)
312392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
313392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
314392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
315392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				(block128_f)aesni_encrypt);
316392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
317392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* If we have an iv can set it directly, otherwise use
318392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 * saved IV.
319392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 */
320392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (iv == NULL && gctx->iv_set)
321392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			iv = gctx->iv;
322392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (iv)
323392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
324392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
325392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->iv_set = 1;
326392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
327392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->key_set = 1;
328392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
329392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
330392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
331392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* If key set use IV, otherwise copy */
332392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (gctx->key_set)
333392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
334392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
335392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			memcpy(gctx->iv, iv, gctx->ivlen);
336392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_set = 1;
337392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_gen = 0;
338392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
339392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
340392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
341392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
342392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aesni_gcm_cipher aes_gcm_cipher
343392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
344392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len);
345392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
346392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
347392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        const unsigned char *iv, int enc)
348392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
349392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
350392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!iv && !key)
351392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
352392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
353392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (key)
354392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
355392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* key_len is two AES keys */
356392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (enc)
357392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
358392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
359392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->xts.block1 = (block128_f)aesni_encrypt;
360392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->stream = aesni_xts_encrypt;
361392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
362392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
363392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
364392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
365392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->xts.block1 = (block128_f)aesni_decrypt;
366392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->stream = aesni_xts_decrypt;
367392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
368392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
369392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		aesni_set_encrypt_key(key + ctx->key_len/2,
370392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						ctx->key_len * 4, &xctx->ks2);
371392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->xts.block2 = (block128_f)aesni_encrypt;
372392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
373392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->xts.key1 = &xctx->ks1;
374392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
375392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
376392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (iv)
377392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
378392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->xts.key2 = &xctx->ks2;
379392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(ctx->iv, iv, 16);
380392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
381392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
382392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
383392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
384392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
385392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aesni_xts_cipher aes_xts_cipher
386392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
387392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len);
388392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
389392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
390392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        const unsigned char *iv, int enc)
391392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
392392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
393392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!iv && !key)
394392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
395392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (key)
396392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
397392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
398392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
399392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					&cctx->ks, (block128_f)aesni_encrypt);
400392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->str = enc?(ccm128_f)aesni_ccm64_encrypt_blocks :
401392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				(ccm128_f)aesni_ccm64_decrypt_blocks;
402392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->key_set = 1;
403392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
404392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (iv)
405392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
406392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(ctx->iv, iv, 15 - cctx->L);
407392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->iv_set = 1;
408392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
409392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
410392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
411392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
412392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aesni_ccm_cipher aes_ccm_cipher
413392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
414392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len);
415392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
416392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
417392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic const EVP_CIPHER aesni_##keylen##_##mode = { \
418392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
419392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	flags|EVP_CIPH_##MODE##_MODE,	\
420392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aesni_init_key,			\
421392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aesni_##mode##_cipher,		\
422392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	NULL,				\
423392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	sizeof(EVP_AES_KEY),		\
424392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	NULL,NULL,NULL,NULL }; \
425392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic const EVP_CIPHER aes_##keylen##_##mode = { \
426392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	nid##_##keylen##_##nmode,blocksize,	\
427392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	keylen/8,ivlen, \
428392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	flags|EVP_CIPH_##MODE##_MODE,	\
429392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aes_init_key,			\
430392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aes_##mode##_cipher,		\
431392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	NULL,				\
432392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	sizeof(EVP_AES_KEY),		\
433392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	NULL,NULL,NULL,NULL }; \
434392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
435392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
436392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
437392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
438392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic const EVP_CIPHER aesni_##keylen##_##mode = { \
439392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	nid##_##keylen##_##mode,blocksize, \
440392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
441392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	flags|EVP_CIPH_##MODE##_MODE,	\
442392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aesni_##mode##_init_key,	\
443392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aesni_##mode##_cipher,		\
444392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aes_##mode##_cleanup,		\
445392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	sizeof(EVP_AES_##MODE##_CTX),	\
446392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	NULL,NULL,aes_##mode##_ctrl,NULL }; \
447392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic const EVP_CIPHER aes_##keylen##_##mode = { \
448392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	nid##_##keylen##_##mode,blocksize, \
449392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
450392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	flags|EVP_CIPH_##MODE##_MODE,	\
451392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aes_##mode##_init_key,		\
452392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aes_##mode##_cipher,		\
453392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aes_##mode##_cleanup,		\
454392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	sizeof(EVP_AES_##MODE##_CTX),	\
455392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	NULL,NULL,aes_##mode##_ctrl,NULL }; \
456392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
457392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
458392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
459392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else
460392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
461392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
462392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic const EVP_CIPHER aes_##keylen##_##mode = { \
463392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
464392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	flags|EVP_CIPH_##MODE##_MODE,	\
465392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aes_init_key,			\
466392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aes_##mode##_cipher,		\
467392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	NULL,				\
468392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	sizeof(EVP_AES_KEY),		\
469392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	NULL,NULL,NULL,NULL }; \
470392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
471392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ return &aes_##keylen##_##mode; }
472392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
473392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
474392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic const EVP_CIPHER aes_##keylen##_##mode = { \
475392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	nid##_##keylen##_##mode,blocksize, \
476392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	(EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
477392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	flags|EVP_CIPH_##MODE##_MODE,	\
478392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aes_##mode##_init_key,		\
479392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aes_##mode##_cipher,		\
480392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	aes_##mode##_cleanup,		\
481392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	sizeof(EVP_AES_##MODE##_CTX),	\
482392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	NULL,NULL,aes_##mode##_ctrl,NULL }; \
483392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
484392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{ return &aes_##keylen##_##mode; }
485392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
486392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
487392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define BLOCK_CIPHER_generic_pack(nid,keylen,flags)		\
488392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
489392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
490392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
491392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
492392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags)	\
493392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)	\
494392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   const unsigned char *iv, int enc)
498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
499392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int ret, mode;
500392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
502392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	mode = ctx->cipher->flags & EVP_CIPH_MODE;
503392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
504392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    && !enc)
505392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef BSAES_CAPABLE
506392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    if (BSAES_CAPABLE && mode==EVP_CIPH_CBC_MODE)
507392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
508392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
509392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)AES_decrypt;
510392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.cbc	= (cbc128_f)bsaes_cbc_encrypt;
511392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
512392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    else
513392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
514392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_CAPABLE
515392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    if (VPAES_CAPABLE)
516392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
517392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ret = vpaes_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
518392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)vpaes_decrypt;
519392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
520392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(cbc128_f)vpaes_cbc_encrypt :
521392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					NULL;
522392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
523392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    else
524392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
525392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
526392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks);
527392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)AES_decrypt;
528392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
529392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(cbc128_f)AES_cbc_encrypt :
530392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					NULL;
531392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
533392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef BSAES_CAPABLE
534392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    if (BSAES_CAPABLE && mode==EVP_CIPH_CTR_MODE)
535392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
536392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
537392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)AES_encrypt;
538392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.ctr	= (ctr128_f)bsaes_ctr32_encrypt_blocks;
539392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
540392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    else
541392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
542392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_CAPABLE
543392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    if (VPAES_CAPABLE)
544392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
545392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ret = vpaes_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
546392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)vpaes_encrypt;
547392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
548392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(cbc128_f)vpaes_cbc_encrypt :
549392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					NULL;
550392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
551392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    else
552392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
553392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
554392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks);
555392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)AES_encrypt;
556392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
557392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(cbc128_f)AES_cbc_encrypt :
558392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					NULL;
559392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef AES_CTR_ASM
560392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (mode==EVP_CIPH_CTR_MODE)
561392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt;
562392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
563392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ret < 0)
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVPerr(EVP_F_AES_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
574392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
575392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in, size_t len)
576392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
577392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
578392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
579392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (dat->stream.cbc)
580392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		(*dat->stream.cbc)(in,out,len,&dat->ks,ctx->iv,ctx->encrypt);
581392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else if (ctx->encrypt)
582392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
583392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
584392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
585392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
586392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
587392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
588392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
589392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
590392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in, size_t len)
591392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
592392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	size_t	bl = ctx->cipher->block_size;
593392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	size_t	i;
594392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
595392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
596392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (len<bl)	return 1;
597392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
598392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	for (i=0,len-=bl;i<=len;i+=bl)
599392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		(*dat->block)(in+i,out+i,&dat->ks);
600392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
601392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
602392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
603392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
604392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
605392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len)
606392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
607392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
608392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
609392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	CRYPTO_ofb128_encrypt(in,out,len,&dat->ks,
610392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,dat->block);
611392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
612392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
613392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
614392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
615392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len)
616392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
617392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
618392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
619392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	CRYPTO_cfb128_encrypt(in,out,len,&dat->ks,
620392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
621392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
622392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
623392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
624392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
625392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len)
626392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
627392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
628392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
629392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	CRYPTO_cfb128_8_encrypt(in,out,len,&dat->ks,
630392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
631392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
632392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
633392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
634392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
635392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len)
636392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
637392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
638392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
639392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (ctx->flags&EVP_CIPH_FLAG_LENGTH_BITS) {
640392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_cfb128_1_encrypt(in,out,len,&dat->ks,
641392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
642392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
643392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
644392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
645392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	while (len>=MAXBITCHUNK) {
646392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_cfb128_1_encrypt(in,out,MAXBITCHUNK*8,&dat->ks,
647392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
648392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		len-=MAXBITCHUNK;
649392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
650392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (len)
651392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_cfb128_1_encrypt(in,out,len*8,&dat->ks,
652392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
653392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
654392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
655392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
656392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
657392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ctr_cipher (EVP_CIPHER_CTX *ctx, unsigned char *out,
658392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len)
659392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
660392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	unsigned int num = ctx->num;
661392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
662392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
663392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (dat->stream.ctr)
664392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_ctr128_encrypt_ctr32(in,out,len,&dat->ks,
665392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,ctx->buf,&num,dat->stream.ctr);
666392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
667392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_ctr128_encrypt(in,out,len,&dat->ks,
668392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,ctx->buf,&num,dat->block);
669392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	ctx->num = (size_t)num;
670392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
671392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
672392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
673392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_generic_pack(NID_aes,128,EVP_CIPH_FLAG_FIPS)
674392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_generic_pack(NID_aes,192,EVP_CIPH_FLAG_FIPS)
675392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_generic_pack(NID_aes,256,EVP_CIPH_FLAG_FIPS)
676392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
677392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
678392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
679392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_GCM_CTX *gctx = c->cipher_data;
680392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
681392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (gctx->iv != c->iv)
682392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		OPENSSL_free(gctx->iv);
683392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
684392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
685392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
686392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* increment counter (64-bit int) by 1 */
687392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic void ctr64_inc(unsigned char *counter) {
688392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int n=8;
689392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	unsigned char  c;
690392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
691392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	do {
692392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		--n;
693392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		c = counter[n];
694392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		++c;
695392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		counter[n] = c;
696392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (c) return;
697392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	} while (n);
698392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
699392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
700392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
701392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
702392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_GCM_CTX *gctx = c->cipher_data;
703392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	switch (type)
704392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
705392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_INIT:
706392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->key_set = 0;
707392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_set = 0;
708392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->ivlen = c->cipher->iv_len;
709392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv = c->iv;
710392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->taglen = -1;
711392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_gen = 0;
712392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->tls_aad_len = -1;
713392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
714392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
715392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_SET_IVLEN:
716392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg <= 0)
717392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
718392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
719392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)
720392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						 && arg < 12)
721392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
722392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
723392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Allocate memory for IV if needed */
724392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen))
725392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
726392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (gctx->iv != c->iv)
727392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				OPENSSL_free(gctx->iv);
728392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->iv = OPENSSL_malloc(arg);
729392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (!gctx->iv)
730392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				return 0;
731392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
732392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->ivlen = arg;
733392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
734392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
735392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_SET_TAG:
736392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg <= 0 || arg > 16 || c->encrypt)
737392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
738392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(c->buf, ptr, arg);
739392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->taglen = arg;
740392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
741392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
742392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_GET_TAG:
743392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0)
744392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
745392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(ptr, c->buf, arg);
746392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
747392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
748392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_SET_IV_FIXED:
749392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Special case: -1 length restores whole IV */
750392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg == -1)
751392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
752392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			memcpy(gctx->iv, ptr, gctx->ivlen);
753392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->iv_gen = 1;
754392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 1;
755392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
756392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Fixed field must be at least 4 bytes and invocation field
757392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 * at least 8.
758392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 */
759392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if ((arg < 4) || (gctx->ivlen - arg) < 8)
760392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
761392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg)
762392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			memcpy(gctx->iv, ptr, arg);
763392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (c->encrypt &&
764392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
765392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
766392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_gen = 1;
767392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
768392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
769392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_IV_GEN:
770392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (gctx->iv_gen == 0 || gctx->key_set == 0)
771392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
772392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
773392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg <= 0 || arg > gctx->ivlen)
774392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			arg = gctx->ivlen;
775392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
776392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Invocation field will be at least 8 bytes in size and
777392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 * so no need to check wrap around or increment more than
778392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 * last 8 bytes.
779392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 */
780392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ctr64_inc(gctx->iv + gctx->ivlen - 8);
781392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_set = 1;
782392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
783392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
784392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_SET_IV_INV:
785392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt)
786392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
787392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
788392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
789392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_set = 1;
790392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
791392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
792392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_AEAD_TLS1_AAD:
793392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Save the AAD for later use */
794392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg != 13)
795392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
796392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(c->buf, ptr, arg);
797392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->tls_aad_len = arg;
798392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
799392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned int len=c->buf[arg-2]<<8|c->buf[arg-1];
800392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			/* Correct length for explicit IV */
801392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
802392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			/* If decrypting correct for tag too */
803392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (!c->encrypt)
804392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				len -= EVP_GCM_TLS_TAG_LEN;
805392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        c->buf[arg-2] = len>>8;
806392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        c->buf[arg-1] = len & 0xff;
807392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
808392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Extra padding: tag appended to record */
809392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return EVP_GCM_TLS_TAG_LEN;
810392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
811392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	default:
812392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
813392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
814392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
815392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
816392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
817392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
818392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        const unsigned char *iv, int enc)
819392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
820392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
821392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!iv && !key)
822392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
823392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (key)
824392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{ do {
825392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef BSAES_CAPABLE
826392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (BSAES_CAPABLE)
827392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
828392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			AES_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
829392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
830392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(block128_f)AES_encrypt);
831392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
832392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			break;
833392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
834392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
835392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
836392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_CAPABLE
837392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (VPAES_CAPABLE)
838392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
839392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			vpaes_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
840392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
841392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(block128_f)vpaes_encrypt);
842392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->ctr = NULL;
843392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			break;
844392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
845392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
846392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
847392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)AES_encrypt);
848392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef AES_CTR_ASM
849392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->ctr = (ctr128_f)AES_ctr32_encrypt;
850392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else
851392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->ctr = NULL;
852392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
853392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		} while (0);
854392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
855392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* If we have an iv can set it directly, otherwise use
856392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 * saved IV.
857392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 */
858392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (iv == NULL && gctx->iv_set)
859392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			iv = gctx->iv;
860392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (iv)
861392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
862392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
863392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->iv_set = 1;
864392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
865392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->key_set = 1;
866392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
867392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
868392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
869392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* If key set use IV, otherwise copy */
870392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (gctx->key_set)
871392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
872392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
873392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			memcpy(gctx->iv, iv, gctx->ivlen);
874392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_set = 1;
875392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_gen = 0;
876392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
877392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
878392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
879392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
880392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* Handle TLS GCM packet format. This consists of the last portion of the IV
881392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * followed by the payload and finally the tag. On encrypt generate IV,
882392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * encrypt payload and write the tag. On verify retrieve IV, decrypt payload
883392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * and verify tag.
884392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */
885392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
886392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
887392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len)
888392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
889392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
890392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int rv = -1;
891392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Encrypt/decrypt must be performed in place */
892392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN+EVP_GCM_TLS_TAG_LEN))
893392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
894392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Set IV from start of buffer or generate IV and write to start
895392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * of buffer.
896392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 */
897392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ?
898392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
899392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0)
900392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		goto err;
901392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Use saved AAD */
902392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len))
903392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		goto err;
904392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Fix buffer and length to point to payload */
905392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
906392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
907392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
908392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (ctx->encrypt)
909392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
910392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Encrypt payload */
911392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (gctx->ctr)
912392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
913392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
914392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							in, out, len,
915392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							gctx->ctr))
916392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				goto err;
917392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
918392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else	{
919392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
920392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				goto err;
921392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
922392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		out += len;
923392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Finally write tag */
924392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
925392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
926392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
927392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
928392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
929392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Decrypt */
930392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (gctx->ctr)
931392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
932392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
933392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							in, out, len,
934392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							gctx->ctr))
935392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				goto err;
936392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
937392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else	{
938392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
939392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				goto err;
940392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
941392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Retrieve tag */
942392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf,
943392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					EVP_GCM_TLS_TAG_LEN);
944392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* If tag mismatch wipe buffer */
945392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN))
946392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
947392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			OPENSSL_cleanse(out, len);
948392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			goto err;
949392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
950392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		rv = len;
951392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
952392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
953392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	err:
954392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	gctx->iv_set = 0;
955392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	gctx->tls_aad_len = -1;
956392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return rv;
957392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
958392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
959392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
960392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len)
961392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
962392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
963392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* If not set up, return error */
964392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!gctx->key_set)
965392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
966392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
967392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (gctx->tls_aad_len >= 0)
968392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return aes_gcm_tls_cipher(ctx, out, in, len);
969392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
970392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!gctx->iv_set)
971392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
972392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!ctx->encrypt && gctx->taglen < 0)
973392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
974392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (in)
975392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
976392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (out == NULL)
977392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
978392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
979392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				return -1;
980392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
981392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else if (ctx->encrypt)
982392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
983392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (gctx->ctr)
984392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
985392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
986392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							in, out, len,
987392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							gctx->ctr))
988392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					return -1;
989392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
990392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			else	{
991392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
992392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					return -1;
993392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
994392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
995392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
996392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
997392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (gctx->ctr)
998392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
999392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
1000392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							in, out, len,
1001392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							gctx->ctr))
1002392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					return -1;
1003392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
1004392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			else	{
1005392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
1006392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					return -1;
1007392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
1008392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1009392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return len;
1010392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1011392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
1012392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1013392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!ctx->encrypt)
1014392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1015392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_finish(&gctx->gcm,
1016392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					ctx->buf, gctx->taglen) != 0)
1017392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				return -1;
1018392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->iv_set = 0;
1019392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1020392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1021392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
1022392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->taglen = 16;
1023392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Don't reuse the IV */
1024392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_set = 0;
1025392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1026392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1027392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1028392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1029392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1030392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define CUSTOM_FLAGS	(EVP_CIPH_FLAG_DEFAULT_ASN1 \
1031392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
1032392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT)
1033392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1034392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,128,1,12,gcm,GCM,
1035392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
1036392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,192,1,12,gcm,GCM,
1037392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
1038392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,256,1,12,gcm,GCM,
1039392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
1040392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1041392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
1042392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1043392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_XTS_CTX *xctx = c->cipher_data;
1044392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (type != EVP_CTRL_INIT)
1045392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
1046392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* key1 and key2 are used as an indicator both key and IV are set */
1047392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	xctx->xts.key1 = NULL;
1048392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	xctx->xts.key2 = NULL;
1049392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
1050392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1051392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1052392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1053392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        const unsigned char *iv, int enc)
1054392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1055392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
1056392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!iv && !key)
1057392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1058392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1059392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (key) do
1060392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1061392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef AES_XTS_ASM
1062392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;
1063392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else
1064392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->stream = NULL;
1065392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1066392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* key_len is two AES keys */
1067392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef BSAES_CAPABLE
1068392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (BSAES_CAPABLE)
1069392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt;
1070392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
1071392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1072392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_CAPABLE
1073392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (VPAES_CAPABLE)
1074392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		    {
1075392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		    if (enc)
1076392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1077392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			vpaes_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
1078392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->xts.block1 = (block128_f)vpaes_encrypt;
1079392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1080392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		    else
1081392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1082392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			vpaes_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
1083392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->xts.block1 = (block128_f)vpaes_decrypt;
1084392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1085392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1086392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		vpaes_set_encrypt_key(key + ctx->key_len/2,
1087392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						ctx->key_len * 4, &xctx->ks2);
1088392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->xts.block2 = (block128_f)vpaes_encrypt;
1089392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1090392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->xts.key1 = &xctx->ks1;
1091392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		break;
1092392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1093392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1094392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (enc)
1095392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1096392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
1097392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->xts.block1 = (block128_f)AES_encrypt;
1098392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1099392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
1100392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1101392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
1102392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->xts.block1 = (block128_f)AES_decrypt;
1103392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1104392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1105392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		AES_set_encrypt_key(key + ctx->key_len/2,
1106392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						ctx->key_len * 4, &xctx->ks2);
1107392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->xts.block2 = (block128_f)AES_encrypt;
1108392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1109392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->xts.key1 = &xctx->ks1;
1110392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		} while (0);
1111392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1112392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (iv)
1113392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1114392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->xts.key2 = &xctx->ks2;
1115392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(ctx->iv, iv, 16);
1116392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1117392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1118392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
1119392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1120392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1121392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1122392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len)
1123392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1124392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
1125392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!xctx->xts.key1 || !xctx->xts.key2)
1126392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1127392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!out || !in || len<AES_BLOCK_SIZE)
1128392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1129392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
1130392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Requirement of SP800-38E */
1131392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) &&
1132392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			(len > (1UL<<20)*16))
1133392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1134392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE);
1135392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1136392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1137392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1138392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (xctx->stream)
1139392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		(*xctx->stream)(in, out, len,
1140392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				xctx->xts.key1, xctx->xts.key2, ctx->iv);
1141392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len,
1142392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom								ctx->encrypt))
1143392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1144392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
1145392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1146392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1147392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aes_xts_cleanup NULL
1148392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1149392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define XTS_FLAGS	(EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \
1150392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			 | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT)
1151392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1152392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,128,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
1153392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,256,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
1154392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1155392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
1156392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1157392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_CCM_CTX *cctx = c->cipher_data;
1158392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	switch (type)
1159392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1160392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_INIT:
1161392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->key_set = 0;
1162392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->iv_set = 0;
1163392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->L = 8;
1164392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->M = 12;
1165392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->tag_set = 0;
1166392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->len_set = 0;
1167392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1168392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1169392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_CCM_SET_IVLEN:
1170392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		arg = 15 - arg;
1171392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_CCM_SET_L:
1172392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg < 2 || arg > 8)
1173392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1174392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->L = arg;
1175392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1176392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1177392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_CCM_SET_TAG:
1178392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if ((arg & 1) || arg < 4 || arg > 16)
1179392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1180392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if ((c->encrypt && ptr) || (!c->encrypt && !ptr))
1181392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1182392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (ptr)
1183392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1184392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			cctx->tag_set = 1;
1185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			memcpy(c->buf, ptr, arg);
1186392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1187392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->M = arg;
1188392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1189392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1190392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_CCM_GET_TAG:
1191392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!c->encrypt || !cctx->tag_set)
1192392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1193392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if(!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
1194392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1195392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->tag_set = 0;
1196392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->iv_set = 0;
1197392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->len_set = 0;
1198392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1199392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1200392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	default:
1201392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
1202392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1203392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1204392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1205392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1206392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1207392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        const unsigned char *iv, int enc)
1208392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1209392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
1210392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!iv && !key)
1211392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1212392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (key) do
1213392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1214392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_CAPABLE
1215392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (VPAES_CAPABLE)
1216392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1217392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks);
1218392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
1219392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					&cctx->ks, (block128_f)vpaes_encrypt);
1220392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			cctx->key_set = 1;
1221392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			break;
1222392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1223392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1224392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
1225392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
1226392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					&cctx->ks, (block128_f)AES_encrypt);
1227392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->str = NULL;
1228392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->key_set = 1;
1229392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		} while (0);
1230392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (iv)
1231392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1232392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(ctx->iv, iv, 15 - cctx->L);
1233392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->iv_set = 1;
1234392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1235392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
1236392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1237392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1238392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1239392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len)
1240392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1241392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
1242392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	CCM128_CONTEXT *ccm = &cctx->ccm;
1243392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* If not set up, return error */
1244392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!cctx->iv_set && !cctx->key_set)
1245392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
1246392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!ctx->encrypt && !cctx->tag_set)
1247392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
1248392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!out)
1249392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1250392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!in)
1251392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1252392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L,len))
1253392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				return -1;
1254392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			cctx->len_set = 1;
1255392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return len;
1256392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1257392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* If have AAD need message length */
1258392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!cctx->len_set && len)
1259392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return -1;
1260392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_ccm128_aad(ccm, in, len);
1261392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return len;
1262392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1263392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* EVP_*Final() doesn't return any data */
1264392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!in)
1265392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1266392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* If not set length yet do it */
1267392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!cctx->len_set)
1268392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1269392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
1270392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return -1;
1271392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->len_set = 1;
1272392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1273392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (ctx->encrypt)
1274392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1275392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
1276392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						cctx->str) :
1277392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				CRYPTO_ccm128_encrypt(ccm, in, out, len))
1278392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return -1;
1279392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->tag_set = 1;
1280392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return len;
1281392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1282392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
1283392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1284392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		int rv = -1;
1285392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
1286392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						cctx->str) :
1287392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				!CRYPTO_ccm128_decrypt(ccm, in, out, len))
1288392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1289392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char tag[16];
1290392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_ccm128_tag(ccm, tag, cctx->M))
1291392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
1292392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (!memcmp(tag, ctx->buf, cctx->M))
1293392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					rv = len;
1294392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
1295392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1296392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (rv == -1)
1297392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			OPENSSL_cleanse(out, len);
1298392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->iv_set = 0;
1299392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->tag_set = 0;
1300392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->len_set = 0;
1301392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return rv;
1302392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1303392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1304392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1305392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1306392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aes_ccm_cleanup NULL
1307392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1308392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,128,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
1309392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,192,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
1310392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
1311392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1312392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1314