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	{
653f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	union { double align; AES_KEY ks; } 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	{
753f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	union { double align; AES_KEY ks; } 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	{
893f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	union { double align; AES_KEY ks; } 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	{
993f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	union { double align; AES_KEY ks; } 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
1633f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootextern unsigned int OPENSSL_ia32cap_P[];
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
169c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root#define BSAES_CAPABLE	(OPENSSL_ia32cap_P[1]&(1<<(41-32)))
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		{
3133f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.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			{
3583f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
359392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->xts.block1 = (block128_f)aesni_encrypt;
360392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->stream = aesni_xts_encrypt;
361392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
362392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
363392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
3643f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
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,
3703f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root						ctx->key_len * 4, &xctx->ks2.ks);
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		{
3973f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.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; }
485d55031a5e797d10e7106668121d18ef5608aaed9Kenny Root#endif
486d55031a5e797d10e7106668121d18ef5608aaed9Kenny Root
4873f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__))
488d55031a5e797d10e7106668121d18ef5608aaed9Kenny Root#include "arm_arch.h"
489d55031a5e797d10e7106668121d18ef5608aaed9Kenny Root#if __ARM_ARCH__>=7
4903f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# if defined(BSAES_ASM)
4913f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#  define BSAES_CAPABLE	(OPENSSL_armcap_P & ARMV7_NEON)
4923f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# endif
4933f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
4943f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWAES_set_encrypt_key aes_v8_set_encrypt_key
4953f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWAES_set_decrypt_key aes_v8_set_decrypt_key
4963f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWAES_encrypt aes_v8_encrypt
4973f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWAES_decrypt aes_v8_decrypt
4983f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWAES_cbc_encrypt aes_v8_cbc_encrypt
4993f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
5003f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#endif
501d55031a5e797d10e7106668121d18ef5608aaed9Kenny Root#endif
5023f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root
5033f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#if defined(HWAES_CAPABLE)
5043f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootint HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
5053f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	AES_KEY *key);
5063f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootint HWAES_set_decrypt_key(const unsigned char *userKey, const int bits,
5073f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	AES_KEY *key);
5083f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootvoid HWAES_encrypt(const unsigned char *in, unsigned char *out,
5093f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	const AES_KEY *key);
5103f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootvoid HWAES_decrypt(const unsigned char *in, unsigned char *out,
5113f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	const AES_KEY *key);
5123f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootvoid HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
5133f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	size_t length, const AES_KEY *key,
5143f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	unsigned char *ivec, const int enc);
5153f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Rootvoid HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
5163f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	size_t len, const AES_KEY *key, const unsigned char ivec[16]);
517392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
518392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
519392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define BLOCK_CIPHER_generic_pack(nid,keylen,flags)		\
520392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
521392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
522392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
523392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)	\
524392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags)	\
525392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)	\
526392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   const unsigned char *iv, int enc)
530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
531392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int ret, mode;
532392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
534392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	mode = ctx->cipher->flags & EVP_CIPH_MODE;
535392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
536392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    && !enc)
5373f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#ifdef HWAES_CAPABLE
5383f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	    if (HWAES_CAPABLE)
5393f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		{
5403f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		ret = HWAES_set_decrypt_key(key,ctx->key_len*8,&dat->ks.ks);
5413f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		dat->block      = (block128_f)HWAES_decrypt;
5423f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		dat->stream.cbc = NULL;
5433f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#ifdef HWAES_cbc_encrypt
5443f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		if (mode==EVP_CIPH_CBC_MODE)
5453f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		    dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
5463f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#endif
5473f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		}
5483f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	    else
5493f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#endif
550392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef BSAES_CAPABLE
551392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    if (BSAES_CAPABLE && mode==EVP_CIPH_CBC_MODE)
552392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
5533f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks.ks);
554392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)AES_decrypt;
555392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.cbc	= (cbc128_f)bsaes_cbc_encrypt;
556392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
557392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    else
558392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
559392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_CAPABLE
560392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    if (VPAES_CAPABLE)
561392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
5623f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		ret = vpaes_set_decrypt_key(key,ctx->key_len*8,&dat->ks.ks);
563392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)vpaes_decrypt;
564392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
565392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(cbc128_f)vpaes_cbc_encrypt :
566392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					NULL;
567392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
568392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    else
569392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
570392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
5713f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks.ks);
572392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)AES_decrypt;
573392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
574392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(cbc128_f)AES_cbc_encrypt :
575392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					NULL;
576392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
5783f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#ifdef HWAES_CAPABLE
5793f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	    if (HWAES_CAPABLE)
5803f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		{
5813f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		ret = HWAES_set_encrypt_key(key,ctx->key_len*8,&dat->ks.ks);
5823f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		dat->block      = (block128_f)HWAES_encrypt;
5833f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		dat->stream.cbc = NULL;
5843f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#ifdef HWAES_cbc_encrypt
5853f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		if (mode==EVP_CIPH_CBC_MODE)
5863f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		    dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
5873f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		else
5883f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#endif
5893f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#ifdef HWAES_ctr32_encrypt_blocks
5903f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		if (mode==EVP_CIPH_CTR_MODE)
5913f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		    dat->stream.ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks;
5923f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		else
5933f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#endif
5943f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		(void)0;	/* terminate potentially open 'else' */
5953f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		}
5963f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root	    else
5973f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#endif
598392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef BSAES_CAPABLE
599392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    if (BSAES_CAPABLE && mode==EVP_CIPH_CTR_MODE)
600392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
6013f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks.ks);
602392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)AES_encrypt;
603392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.ctr	= (ctr128_f)bsaes_ctr32_encrypt_blocks;
604392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
605392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    else
606392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
607392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_CAPABLE
608392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    if (VPAES_CAPABLE)
609392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
6103f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		ret = vpaes_set_encrypt_key(key,ctx->key_len*8,&dat->ks.ks);
611392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)vpaes_encrypt;
612392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
613392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(cbc128_f)vpaes_cbc_encrypt :
614392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					NULL;
615392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
616392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	    else
617392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
618392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
6193f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks.ks);
620392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->block	= (block128_f)AES_encrypt;
621392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		dat->stream.cbc	= mode==EVP_CIPH_CBC_MODE ?
622392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(cbc128_f)AES_cbc_encrypt :
623392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					NULL;
624392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef AES_CTR_ASM
625392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (mode==EVP_CIPH_CTR_MODE)
626392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt;
627392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
628392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ret < 0)
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVPerr(EVP_F_AES_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
639392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
640392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in, size_t len)
641392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
642392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
643392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
644392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (dat->stream.cbc)
645392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		(*dat->stream.cbc)(in,out,len,&dat->ks,ctx->iv,ctx->encrypt);
646392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else if (ctx->encrypt)
647392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
648392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
649392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block);
650392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
651392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
652392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
653392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
654392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
655392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in, size_t len)
656392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
657392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	size_t	bl = ctx->cipher->block_size;
658392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	size_t	i;
659392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
660392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
661392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (len<bl)	return 1;
662392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
663392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	for (i=0,len-=bl;i<=len;i+=bl)
664392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		(*dat->block)(in+i,out+i,&dat->ks);
665392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
666392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
667392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
668392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
669392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
670392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len)
671392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
672392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
673392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
674392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	CRYPTO_ofb128_encrypt(in,out,len,&dat->ks,
675392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,dat->block);
676392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
677392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
678392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
679392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
680392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len)
681392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
682392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
683392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
684392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	CRYPTO_cfb128_encrypt(in,out,len,&dat->ks,
685392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
686392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
687392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
688392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
689392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
690392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len)
691392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
692392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
693392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
694392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	CRYPTO_cfb128_8_encrypt(in,out,len,&dat->ks,
695392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
696392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
697392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
698392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
699392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
700392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	const unsigned char *in,size_t len)
701392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
702392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
703392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
704392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (ctx->flags&EVP_CIPH_FLAG_LENGTH_BITS) {
705392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_cfb128_1_encrypt(in,out,len,&dat->ks,
706392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
707392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
708392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
709392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
710392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	while (len>=MAXBITCHUNK) {
711392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_cfb128_1_encrypt(in,out,MAXBITCHUNK*8,&dat->ks,
712392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
713392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		len-=MAXBITCHUNK;
714392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
715392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (len)
716392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_cfb128_1_encrypt(in,out,len*8,&dat->ks,
717392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,&ctx->num,ctx->encrypt,dat->block);
718392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
719392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
720392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
721392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
722392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ctr_cipher (EVP_CIPHER_CTX *ctx, unsigned char *out,
723392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len)
724392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom{
725392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	unsigned int num = ctx->num;
726392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
727392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
728392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (dat->stream.ctr)
729392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_ctr128_encrypt_ctr32(in,out,len,&dat->ks,
730392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,ctx->buf,&num,dat->stream.ctr);
731392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
732392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_ctr128_encrypt(in,out,len,&dat->ks,
733392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			ctx->iv,ctx->buf,&num,dat->block);
734392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	ctx->num = (size_t)num;
735392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
736392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
737392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
738392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_generic_pack(NID_aes,128,EVP_CIPH_FLAG_FIPS)
739392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_generic_pack(NID_aes,192,EVP_CIPH_FLAG_FIPS)
740392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_generic_pack(NID_aes,256,EVP_CIPH_FLAG_FIPS)
741392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
742392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
743392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
744392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_GCM_CTX *gctx = c->cipher_data;
745392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
746392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (gctx->iv != c->iv)
747392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		OPENSSL_free(gctx->iv);
748392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
749392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
750392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
751392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* increment counter (64-bit int) by 1 */
752392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic void ctr64_inc(unsigned char *counter) {
753392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int n=8;
754392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	unsigned char  c;
755392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
756392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	do {
757392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		--n;
758392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		c = counter[n];
759392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		++c;
760392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		counter[n] = c;
761392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (c) return;
762392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	} while (n);
763392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom}
764392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
765392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
766392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
767392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_GCM_CTX *gctx = c->cipher_data;
768392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	switch (type)
769392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
770392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_INIT:
771392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->key_set = 0;
772392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_set = 0;
773392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->ivlen = c->cipher->iv_len;
774392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv = c->iv;
775392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->taglen = -1;
776392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_gen = 0;
777392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->tls_aad_len = -1;
778392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
779392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
780392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_SET_IVLEN:
781392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg <= 0)
782392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
783392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
784392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)
785392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						 && arg < 12)
786392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
787392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
788392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Allocate memory for IV if needed */
789392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen))
790392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
791392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (gctx->iv != c->iv)
792392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				OPENSSL_free(gctx->iv);
793392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->iv = OPENSSL_malloc(arg);
794392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (!gctx->iv)
795392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				return 0;
796392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
797392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->ivlen = arg;
798392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
799392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
800392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_SET_TAG:
801392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg <= 0 || arg > 16 || c->encrypt)
802392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
803392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(c->buf, ptr, arg);
804392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->taglen = arg;
805392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
806392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
807392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_GET_TAG:
808392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0)
809392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
810392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(ptr, c->buf, arg);
811392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
812392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
813392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_SET_IV_FIXED:
814392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Special case: -1 length restores whole IV */
815392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg == -1)
816392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
817392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			memcpy(gctx->iv, ptr, gctx->ivlen);
818392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->iv_gen = 1;
819392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 1;
820392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
821392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Fixed field must be at least 4 bytes and invocation field
822392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 * at least 8.
823392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 */
824392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if ((arg < 4) || (gctx->ivlen - arg) < 8)
825392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
826392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg)
827392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			memcpy(gctx->iv, ptr, arg);
828392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (c->encrypt &&
829392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
830392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
831392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_gen = 1;
832392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
833392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
834392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_IV_GEN:
835392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (gctx->iv_gen == 0 || gctx->key_set == 0)
836392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
837392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
838392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg <= 0 || arg > gctx->ivlen)
839392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			arg = gctx->ivlen;
840392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
841392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Invocation field will be at least 8 bytes in size and
842392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 * so no need to check wrap around or increment more than
843392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 * last 8 bytes.
844392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 */
845392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		ctr64_inc(gctx->iv + gctx->ivlen - 8);
846392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_set = 1;
847392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
848392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
849392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_GCM_SET_IV_INV:
850392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt)
851392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
852392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
853392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
854392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_set = 1;
855392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
856392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
857392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_AEAD_TLS1_AAD:
858392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Save the AAD for later use */
859392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg != 13)
860392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
861392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(c->buf, ptr, arg);
862392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->tls_aad_len = arg;
863392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
864392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned int len=c->buf[arg-2]<<8|c->buf[arg-1];
865392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			/* Correct length for explicit IV */
866392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
867392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			/* If decrypting correct for tag too */
868392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (!c->encrypt)
869392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				len -= EVP_GCM_TLS_TAG_LEN;
870392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        c->buf[arg-2] = len>>8;
871392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        c->buf[arg-1] = len & 0xff;
872392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
873392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Extra padding: tag appended to record */
874392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return EVP_GCM_TLS_TAG_LEN;
875392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
876c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root	case EVP_CTRL_COPY:
877c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		{
878c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			EVP_CIPHER_CTX *out = ptr;
879c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			EVP_AES_GCM_CTX *gctx_out = out->cipher_data;
880c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			if (gctx->gcm.key)
881c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				{
882c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				if (gctx->gcm.key != &gctx->ks)
883c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root					return 0;
884c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				gctx_out->gcm.key = &gctx_out->ks;
885c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				}
886c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			if (gctx->iv == c->iv)
887c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				gctx_out->iv = out->iv;
888c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			else
889c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			{
890c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				gctx_out->iv = OPENSSL_malloc(gctx->ivlen);
891c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				if (!gctx_out->iv)
892c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root					return 0;
893c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
894c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			}
895c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			return 1;
896c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		}
897c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root
898392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	default:
899392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
900392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
901392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
902392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
903392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
904392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
905392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        const unsigned char *iv, int enc)
906392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
907392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
908392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!iv && !key)
909392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
910392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (key)
911392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{ do {
9123f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#ifdef HWAES_CAPABLE
9133f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		if (HWAES_CAPABLE)
9143f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			{
9153f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			HWAES_set_encrypt_key(key,ctx->key_len*8,&gctx->ks.ks);
9163f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
9173f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root					(block128_f)HWAES_encrypt);
9183f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#ifdef HWAES_ctr32_encrypt_blocks
9193f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			gctx->ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks;
9203f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#else
9213f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			gctx->ctr = NULL;
9223f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#endif
9233f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			break;
9243f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			}
9253f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		else
9263f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#endif
927392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef BSAES_CAPABLE
928392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (BSAES_CAPABLE)
929392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
9303f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			AES_set_encrypt_key(key,ctx->key_len*8,&gctx->ks.ks);
931392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
932392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(block128_f)AES_encrypt);
933392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
934392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			break;
935392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
936392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
937392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
938392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_CAPABLE
939392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (VPAES_CAPABLE)
940392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
9413f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			vpaes_set_encrypt_key(key,ctx->key_len*8,&gctx->ks.ks);
942392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
943392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					(block128_f)vpaes_encrypt);
944392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->ctr = NULL;
945392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			break;
946392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
947ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		else
948392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
949ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		(void)0;	/* terminate potentially open 'else' */
950ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root
9513f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
952392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)AES_encrypt);
953392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef AES_CTR_ASM
954392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->ctr = (ctr128_f)AES_ctr32_encrypt;
955392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else
956392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->ctr = NULL;
957392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
958392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		} while (0);
959392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
960392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* If we have an iv can set it directly, otherwise use
961392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 * saved IV.
962392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 */
963392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (iv == NULL && gctx->iv_set)
964392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			iv = gctx->iv;
965392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (iv)
966392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
967392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
968392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->iv_set = 1;
969392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
970392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->key_set = 1;
971392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
972392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
973392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
974392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* If key set use IV, otherwise copy */
975392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (gctx->key_set)
976392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
977392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
978392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			memcpy(gctx->iv, iv, gctx->ivlen);
979392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_set = 1;
980392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_gen = 0;
981392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
982392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
983392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
984392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
985392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* Handle TLS GCM packet format. This consists of the last portion of the IV
986392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * followed by the payload and finally the tag. On encrypt generate IV,
987392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * encrypt payload and write the tag. On verify retrieve IV, decrypt payload
988392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * and verify tag.
989392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */
990392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
991392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
992392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len)
993392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
994392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
995392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int rv = -1;
996392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Encrypt/decrypt must be performed in place */
997392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN+EVP_GCM_TLS_TAG_LEN))
998392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
999392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Set IV from start of buffer or generate IV and write to start
1000392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * of buffer.
1001392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 */
1002392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ?
1003392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
1004392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0)
1005392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		goto err;
1006392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Use saved AAD */
1007392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len))
1008392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		goto err;
1009392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Fix buffer and length to point to payload */
1010392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
1011392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
1012392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
1013392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (ctx->encrypt)
1014392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1015392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Encrypt payload */
1016392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (gctx->ctr)
1017392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1018392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
1019392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							in, out, len,
1020392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							gctx->ctr))
1021392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				goto err;
1022392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1023392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else	{
1024392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
1025392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				goto err;
1026392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1027392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		out += len;
1028392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Finally write tag */
1029392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
1030392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
1031392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1032392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
1033392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1034392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Decrypt */
1035392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (gctx->ctr)
1036392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1037392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
1038392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							in, out, len,
1039392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							gctx->ctr))
1040392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				goto err;
1041392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1042392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else	{
1043392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
1044392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				goto err;
1045392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1046392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Retrieve tag */
1047392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf,
1048392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					EVP_GCM_TLS_TAG_LEN);
1049392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* If tag mismatch wipe buffer */
1050392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN))
1051392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1052392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			OPENSSL_cleanse(out, len);
1053392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			goto err;
1054392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1055392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		rv = len;
1056392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1057392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1058392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	err:
1059392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	gctx->iv_set = 0;
1060392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	gctx->tls_aad_len = -1;
1061392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return rv;
1062392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1063392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1064392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1065392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len)
1066392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1067392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
1068392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* If not set up, return error */
1069392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!gctx->key_set)
1070392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
1071392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1072392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (gctx->tls_aad_len >= 0)
1073392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return aes_gcm_tls_cipher(ctx, out, in, len);
1074392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1075392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!gctx->iv_set)
1076392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
1077392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (in)
1078392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1079392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (out == NULL)
1080392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1081392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
1082392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				return -1;
1083392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1084392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else if (ctx->encrypt)
1085392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1086392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (gctx->ctr)
1087392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
1088392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
1089392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							in, out, len,
1090392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							gctx->ctr))
1091392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					return -1;
1092392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
1093392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			else	{
1094392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len))
1095392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					return -1;
1096392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
1097392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1098392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
1099392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1100392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (gctx->ctr)
1101392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
1102392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
1103392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							in, out, len,
1104392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom							gctx->ctr))
1105392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					return -1;
1106392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
1107392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			else	{
1108392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len))
1109392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					return -1;
1110392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
1111392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1112392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return len;
1113392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1114392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
1115392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1116392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!ctx->encrypt)
1117392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
111804ef91b390dfcc6125913e2f2af502d23d7a5112Brian Carlstrom			if (gctx->taglen < 0)
111904ef91b390dfcc6125913e2f2af502d23d7a5112Brian Carlstrom				return -1;
1120392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_gcm128_finish(&gctx->gcm,
1121392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					ctx->buf, gctx->taglen) != 0)
1122392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				return -1;
1123392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			gctx->iv_set = 0;
1124392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1125392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1126392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
1127392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->taglen = 16;
1128392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Don't reuse the IV */
1129392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		gctx->iv_set = 0;
1130392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1131392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1132392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1133392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1134392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1135392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define CUSTOM_FLAGS	(EVP_CIPH_FLAG_DEFAULT_ASN1 \
1136392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
1137c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
1138c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		| EVP_CIPH_CUSTOM_COPY)
1139392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1140392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,128,1,12,gcm,GCM,
1141392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
1142392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,192,1,12,gcm,GCM,
1143392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
1144392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,256,1,12,gcm,GCM,
1145392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS)
1146392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1147392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
1148392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1149392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_XTS_CTX *xctx = c->cipher_data;
1150c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root	if (type == EVP_CTRL_COPY)
1151c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		{
1152c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		EVP_CIPHER_CTX *out = ptr;
1153c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		EVP_AES_XTS_CTX *xctx_out = out->cipher_data;
1154c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		if (xctx->xts.key1)
1155c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			{
1156c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			if (xctx->xts.key1 != &xctx->ks1)
1157c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				return 0;
1158c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			xctx_out->xts.key1 = &xctx_out->ks1;
1159c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			}
1160c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		if (xctx->xts.key2)
1161c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			{
1162c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			if (xctx->xts.key2 != &xctx->ks2)
1163c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				return 0;
1164c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			xctx_out->xts.key2 = &xctx_out->ks2;
1165c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			}
1166c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		return 1;
1167c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		}
1168c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root	else if (type != EVP_CTRL_INIT)
1169392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
1170392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* key1 and key2 are used as an indicator both key and IV are set */
1171392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	xctx->xts.key1 = NULL;
1172392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	xctx->xts.key2 = NULL;
1173392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
1174392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1175392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1176392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1177392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        const unsigned char *iv, int enc)
1178392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1179392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
1180392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!iv && !key)
1181392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1182392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1183392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (key) do
1184392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef AES_XTS_ASM
1186392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;
1187392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else
1188392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->stream = NULL;
1189392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1190392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* key_len is two AES keys */
11913f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#ifdef HWAES_CAPABLE
11923f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		if (HWAES_CAPABLE)
11933f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			{
11943f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			if (enc)
11953f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			    {
11963f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			    HWAES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
11973f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			    xctx->xts.block1 = (block128_f)HWAES_encrypt;
11983f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			    }
11993f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			else
12003f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			    {
12013f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			    HWAES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
12023f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			    xctx->xts.block1 = (block128_f)HWAES_decrypt;
12033f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			    }
12043f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root
12053f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			HWAES_set_encrypt_key(key + ctx->key_len/2,
12063f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root						    ctx->key_len * 4, &xctx->ks2.ks);
12073f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			xctx->xts.block2 = (block128_f)HWAES_encrypt;
12083f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root
12093f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			xctx->xts.key1 = &xctx->ks1;
12103f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			break;
12113f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			}
12123f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		else
12133f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#endif
1214392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef BSAES_CAPABLE
1215392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (BSAES_CAPABLE)
1216392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt;
1217392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
1218392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1219392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_CAPABLE
1220392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (VPAES_CAPABLE)
1221392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		    {
1222392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		    if (enc)
1223392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
12243f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			vpaes_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
1225392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->xts.block1 = (block128_f)vpaes_encrypt;
1226392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1227392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		    else
1228392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
12293f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			vpaes_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
1230392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->xts.block1 = (block128_f)vpaes_decrypt;
1231392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1232392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1233ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		    vpaes_set_encrypt_key(key + ctx->key_len/2,
12343f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root						ctx->key_len * 4, &xctx->ks2.ks);
1235ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		    xctx->xts.block2 = (block128_f)vpaes_encrypt;
1236392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1237ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		    xctx->xts.key1 = &xctx->ks1;
1238ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		    break;
1239ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		    }
1240ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		else
1241392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1242ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		(void)0;	/* terminate potentially open 'else' */
1243ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root
1244392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (enc)
1245392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
12463f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
1247392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->xts.block1 = (block128_f)AES_encrypt;
1248392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1249392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
1250392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
12513f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
1252392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			xctx->xts.block1 = (block128_f)AES_decrypt;
1253392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1254392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1255392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		AES_set_encrypt_key(key + ctx->key_len/2,
12563f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root						ctx->key_len * 4, &xctx->ks2.ks);
1257392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->xts.block2 = (block128_f)AES_encrypt;
1258392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1259392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->xts.key1 = &xctx->ks1;
1260392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		} while (0);
1261392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1262392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (iv)
1263392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1264392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		xctx->xts.key2 = &xctx->ks2;
1265392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(ctx->iv, iv, 16);
1266392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1267392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1268392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
1269392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1270392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1271392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1272392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len)
1273392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1274392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
1275392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!xctx->xts.key1 || !xctx->xts.key2)
1276392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1277392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!out || !in || len<AES_BLOCK_SIZE)
1278392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1279392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
1280392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Requirement of SP800-38E */
1281392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) &&
1282392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			(len > (1UL<<20)*16))
1283392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1284392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE);
1285392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1286392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1287392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1288392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (xctx->stream)
1289392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		(*xctx->stream)(in, out, len,
1290392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				xctx->xts.key1, xctx->xts.key2, ctx->iv);
1291392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len,
1292392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom								ctx->encrypt))
1293392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1294392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
1295392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1296392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1297392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aes_xts_cleanup NULL
1298392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1299392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define XTS_FLAGS	(EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \
1300c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			 | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
1301c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			 | EVP_CIPH_CUSTOM_COPY)
1302392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1303392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,128,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
1304392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,256,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS)
1305392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1306392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
1307392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1308392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_CCM_CTX *cctx = c->cipher_data;
1309392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	switch (type)
1310392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1311392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_INIT:
1312392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->key_set = 0;
1313392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->iv_set = 0;
1314392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->L = 8;
1315392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->M = 12;
1316392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->tag_set = 0;
1317392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->len_set = 0;
1318392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1319392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1320392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_CCM_SET_IVLEN:
1321392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		arg = 15 - arg;
1322392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_CCM_SET_L:
1323392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (arg < 2 || arg > 8)
1324392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1325392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->L = arg;
1326392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1327392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1328392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_CCM_SET_TAG:
1329392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if ((arg & 1) || arg < 4 || arg > 16)
1330392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1331392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if ((c->encrypt && ptr) || (!c->encrypt && !ptr))
1332392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1333392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (ptr)
1334392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1335392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			cctx->tag_set = 1;
1336392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			memcpy(c->buf, ptr, arg);
1337392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1338392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->M = arg;
1339392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1340392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1341392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	case EVP_CTRL_CCM_GET_TAG:
1342392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!c->encrypt || !cctx->tag_set)
1343392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1344392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if(!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
1345392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return 0;
1346392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->tag_set = 0;
1347392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->iv_set = 0;
1348392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->len_set = 0;
1349392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1350392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1351c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root	case EVP_CTRL_COPY:
1352c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		{
1353c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			EVP_CIPHER_CTX *out = ptr;
1354c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			EVP_AES_CCM_CTX *cctx_out = out->cipher_data;
1355c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			if (cctx->ccm.key)
1356c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				{
1357c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				if (cctx->ccm.key != &cctx->ks)
1358c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root					return 0;
1359c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				cctx_out->ccm.key = &cctx_out->ks;
1360c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root				}
1361c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root			return 1;
1362c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root		}
1363c64f6fe2be99cb3fa8e491b5bede9a217de87a4cKenny Root
1364392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	default:
1365392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
1366392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1367392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1368392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1369392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1370392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1371392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                        const unsigned char *iv, int enc)
1372392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1373392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
1374392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!iv && !key)
1375392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 1;
1376392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (key) do
1377392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
13783f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#ifdef HWAES_CAPABLE
13793f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		if (HWAES_CAPABLE)
13803f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			{
13813f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			HWAES_set_encrypt_key(key,ctx->key_len*8,&cctx->ks.ks);
13823f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root
13833f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
13843f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root					&cctx->ks, (block128_f)HWAES_encrypt);
13853f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			cctx->str = NULL;
13863f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			cctx->key_set = 1;
13873f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			break;
13883f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			}
13893f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		else
13903f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root#endif
1391392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef VPAES_CAPABLE
1392392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (VPAES_CAPABLE)
1393392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
13943f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root			vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks.ks);
1395392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
1396392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					&cctx->ks, (block128_f)vpaes_encrypt);
139704ef91b390dfcc6125913e2f2af502d23d7a5112Brian Carlstrom			cctx->str = NULL;
1398392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			cctx->key_set = 1;
1399392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			break;
1400392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1401392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
14023f9e6ada2c9f7183a41081263585e6a70bbd9f59Kenny Root		AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks);
1403392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
1404392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					&cctx->ks, (block128_f)AES_encrypt);
1405392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->str = NULL;
1406392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->key_set = 1;
1407392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		} while (0);
1408392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (iv)
1409392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1410392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		memcpy(ctx->iv, iv, 15 - cctx->L);
1411392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->iv_set = 1;
1412392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1413392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
1414392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1415392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1416392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1417392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		const unsigned char *in, size_t len)
1418392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1419392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_AES_CCM_CTX *cctx = ctx->cipher_data;
1420392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	CCM128_CONTEXT *ccm = &cctx->ccm;
1421392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* If not set up, return error */
1422392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!cctx->iv_set && !cctx->key_set)
1423392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
1424392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!ctx->encrypt && !cctx->tag_set)
1425392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return -1;
1426392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!out)
1427392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1428392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!in)
1429392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1430392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L,len))
1431392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				return -1;
1432392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			cctx->len_set = 1;
1433392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return len;
1434392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1435392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* If have AAD need message length */
1436392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!cctx->len_set && len)
1437392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return -1;
1438392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		CRYPTO_ccm128_aad(ccm, in, len);
1439392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return len;
1440392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1441392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* EVP_*Final() doesn't return any data */
1442392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!in)
1443392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
1444392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* If not set length yet do it */
1445392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!cctx->len_set)
1446392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1447392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len))
1448392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return -1;
1449392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->len_set = 1;
1450392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1451392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (ctx->encrypt)
1452392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1453392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
1454392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						cctx->str) :
1455392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				CRYPTO_ccm128_encrypt(ccm, in, out, len))
1456392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return -1;
1457392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->tag_set = 1;
1458392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return len;
1459392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1460392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
1461392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1462392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		int rv = -1;
1463392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
1464392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						cctx->str) :
1465392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				!CRYPTO_ccm128_decrypt(ccm, in, out, len))
1466392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1467392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char tag[16];
1468392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (CRYPTO_ccm128_tag(ccm, tag, cctx->M))
1469392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
1470392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (!memcmp(tag, ctx->buf, cctx->M))
1471392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					rv = len;
1472392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
1473392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1474392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (rv == -1)
1475392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			OPENSSL_cleanse(out, len);
1476392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->iv_set = 0;
1477392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->tag_set = 0;
1478392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		cctx->len_set = 0;
1479392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return rv;
1480392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1481392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1482392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1483392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1484392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define aes_ccm_cleanup NULL
1485392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1486392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,128,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
1487392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,192,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
1488392aa7cc7d2b122614c5393c3e357da07fd07af3Brian CarlstromBLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
1489392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1490392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1492