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