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