1109998Smarkm/* ==================================================================== 2238405Sjkim * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. 3109998Smarkm * 4109998Smarkm * Redistribution and use in source and binary forms, with or without 5109998Smarkm * modification, are permitted provided that the following conditions 6109998Smarkm * are met: 7109998Smarkm * 8109998Smarkm * 1. Redistributions of source code must retain the above copyright 9296341Sdelphij * notice, this list of conditions and the following disclaimer. 10109998Smarkm * 11109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 12109998Smarkm * notice, this list of conditions and the following disclaimer in 13109998Smarkm * the documentation and/or other materials provided with the 14109998Smarkm * distribution. 15109998Smarkm * 16109998Smarkm * 3. All advertising materials mentioning features or use of this 17109998Smarkm * software must display the following acknowledgment: 18109998Smarkm * "This product includes software developed by the OpenSSL Project 19109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20109998Smarkm * 21109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22109998Smarkm * endorse or promote products derived from this software without 23109998Smarkm * prior written permission. For written permission, please contact 24109998Smarkm * openssl-core@openssl.org. 25109998Smarkm * 26109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 27109998Smarkm * nor may "OpenSSL" appear in their names without prior written 28109998Smarkm * permission of the OpenSSL Project. 29109998Smarkm * 30109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 31109998Smarkm * acknowledgment: 32109998Smarkm * "This product includes software developed by the OpenSSL Project 33109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34109998Smarkm * 35109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 47109998Smarkm * ==================================================================== 48109998Smarkm * 49109998Smarkm */ 50109998Smarkm 51160814Ssimon#include <openssl/opensslconf.h> 52109998Smarkm#ifndef OPENSSL_NO_AES 53284295Sdelphij#include <openssl/crypto.h> 54296341Sdelphij# include <openssl/evp.h> 55296341Sdelphij# include <openssl/err.h> 56296341Sdelphij# include <string.h> 57296341Sdelphij# include <assert.h> 58296341Sdelphij# include <openssl/aes.h> 59296341Sdelphij# include "evp_locl.h" 60296341Sdelphij# ifndef OPENSSL_FIPS 61296341Sdelphij# include "modes_lcl.h" 62296341Sdelphij# include <openssl/rand.h> 63109998Smarkm 64296341Sdelphijtypedef struct { 65296341Sdelphij AES_KEY ks; 66296341Sdelphij block128_f block; 67296341Sdelphij union { 68296341Sdelphij cbc128_f cbc; 69296341Sdelphij ctr128_f ctr; 70296341Sdelphij } stream; 71296341Sdelphij} EVP_AES_KEY; 72109998Smarkm 73296341Sdelphijtypedef struct { 74296341Sdelphij AES_KEY ks; /* AES key schedule to use */ 75296341Sdelphij int key_set; /* Set if key initialised */ 76296341Sdelphij int iv_set; /* Set if an iv is set */ 77296341Sdelphij GCM128_CONTEXT gcm; 78296341Sdelphij unsigned char *iv; /* Temporary IV store */ 79296341Sdelphij int ivlen; /* IV length */ 80296341Sdelphij int taglen; 81296341Sdelphij int iv_gen; /* It is OK to generate IVs */ 82296341Sdelphij int tls_aad_len; /* TLS AAD length */ 83296341Sdelphij ctr128_f ctr; 84296341Sdelphij} EVP_AES_GCM_CTX; 85109998Smarkm 86296341Sdelphijtypedef struct { 87296341Sdelphij AES_KEY ks1, ks2; /* AES key schedules to use */ 88296341Sdelphij XTS128_CONTEXT xts; 89296341Sdelphij void (*stream) (const unsigned char *in, 90296341Sdelphij unsigned char *out, size_t length, 91296341Sdelphij const AES_KEY *key1, const AES_KEY *key2, 92296341Sdelphij const unsigned char iv[16]); 93296341Sdelphij} EVP_AES_XTS_CTX; 94109998Smarkm 95296341Sdelphijtypedef struct { 96296341Sdelphij AES_KEY ks; /* AES key schedule to use */ 97296341Sdelphij int key_set; /* Set if key initialised */ 98296341Sdelphij int iv_set; /* Set if an iv is set */ 99296341Sdelphij int tag_set; /* Set if tag is valid */ 100296341Sdelphij int len_set; /* Set if message length set */ 101296341Sdelphij int L, M; /* L and M parameters from RFC3610 */ 102296341Sdelphij CCM128_CONTEXT ccm; 103296341Sdelphij ccm128_f str; 104296341Sdelphij} EVP_AES_CCM_CTX; 105142425Snectar 106296341Sdelphij# define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) 107142425Snectar 108296341Sdelphij# ifdef VPAES_ASM 109238405Sjkimint vpaes_set_encrypt_key(const unsigned char *userKey, int bits, 110296341Sdelphij AES_KEY *key); 111238405Sjkimint vpaes_set_decrypt_key(const unsigned char *userKey, int bits, 112296341Sdelphij AES_KEY *key); 113142425Snectar 114238405Sjkimvoid vpaes_encrypt(const unsigned char *in, unsigned char *out, 115296341Sdelphij const AES_KEY *key); 116238405Sjkimvoid vpaes_decrypt(const unsigned char *in, unsigned char *out, 117296341Sdelphij const AES_KEY *key); 118238405Sjkim 119238405Sjkimvoid vpaes_cbc_encrypt(const unsigned char *in, 120296341Sdelphij unsigned char *out, 121296341Sdelphij size_t length, 122296341Sdelphij const AES_KEY *key, unsigned char *ivec, int enc); 123296341Sdelphij# endif 124296341Sdelphij# ifdef BSAES_ASM 125238405Sjkimvoid bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out, 126296341Sdelphij size_t length, const AES_KEY *key, 127296341Sdelphij unsigned char ivec[16], int enc); 128238405Sjkimvoid bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, 129296341Sdelphij size_t len, const AES_KEY *key, 130296341Sdelphij const unsigned char ivec[16]); 131238405Sjkimvoid bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out, 132296341Sdelphij size_t len, const AES_KEY *key1, 133296341Sdelphij const AES_KEY *key2, const unsigned char iv[16]); 134238405Sjkimvoid bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, 135296341Sdelphij size_t len, const AES_KEY *key1, 136296341Sdelphij const AES_KEY *key2, const unsigned char iv[16]); 137296341Sdelphij# endif 138296341Sdelphij# ifdef AES_CTR_ASM 139238405Sjkimvoid AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, 140296341Sdelphij size_t blocks, const AES_KEY *key, 141296341Sdelphij const unsigned char ivec[AES_BLOCK_SIZE]); 142296341Sdelphij# endif 143296341Sdelphij# ifdef AES_XTS_ASM 144296341Sdelphijvoid AES_xts_encrypt(const char *inp, char *out, size_t len, 145296341Sdelphij const AES_KEY *key1, const AES_KEY *key2, 146296341Sdelphij const unsigned char iv[16]); 147296341Sdelphijvoid AES_xts_decrypt(const char *inp, char *out, size_t len, 148296341Sdelphij const AES_KEY *key1, const AES_KEY *key2, 149296341Sdelphij const unsigned char iv[16]); 150296341Sdelphij# endif 151238405Sjkim 152296341Sdelphij# if defined(AES_ASM) && !defined(I386_ONLY) && ( \ 153296341Sdelphij ((defined(__i386) || defined(__i386__) || \ 154296341Sdelphij defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \ 155296341Sdelphij defined(__x86_64) || defined(__x86_64__) || \ 156296341Sdelphij defined(_M_AMD64) || defined(_M_X64) || \ 157296341Sdelphij defined(__INTEL__) ) 158238405Sjkim 159238405Sjkimextern unsigned int OPENSSL_ia32cap_P[2]; 160238405Sjkim 161296341Sdelphij# ifdef VPAES_ASM 162296341Sdelphij# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) 163296341Sdelphij# endif 164296341Sdelphij# ifdef BSAES_ASM 165296341Sdelphij# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) 166296341Sdelphij# endif 167238405Sjkim/* 168238405Sjkim * AES-NI section 169238405Sjkim */ 170296341Sdelphij# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32))) 171238405Sjkim 172238405Sjkimint aesni_set_encrypt_key(const unsigned char *userKey, int bits, 173296341Sdelphij AES_KEY *key); 174238405Sjkimint aesni_set_decrypt_key(const unsigned char *userKey, int bits, 175296341Sdelphij AES_KEY *key); 176238405Sjkim 177238405Sjkimvoid aesni_encrypt(const unsigned char *in, unsigned char *out, 178296341Sdelphij const AES_KEY *key); 179238405Sjkimvoid aesni_decrypt(const unsigned char *in, unsigned char *out, 180296341Sdelphij const AES_KEY *key); 181238405Sjkim 182238405Sjkimvoid aesni_ecb_encrypt(const unsigned char *in, 183296341Sdelphij unsigned char *out, 184296341Sdelphij size_t length, const AES_KEY *key, int enc); 185238405Sjkimvoid aesni_cbc_encrypt(const unsigned char *in, 186296341Sdelphij unsigned char *out, 187296341Sdelphij size_t length, 188296341Sdelphij const AES_KEY *key, unsigned char *ivec, int enc); 189238405Sjkim 190238405Sjkimvoid aesni_ctr32_encrypt_blocks(const unsigned char *in, 191296341Sdelphij unsigned char *out, 192296341Sdelphij size_t blocks, 193296341Sdelphij const void *key, const unsigned char *ivec); 194238405Sjkim 195238405Sjkimvoid aesni_xts_encrypt(const unsigned char *in, 196296341Sdelphij unsigned char *out, 197296341Sdelphij size_t length, 198296341Sdelphij const AES_KEY *key1, const AES_KEY *key2, 199296341Sdelphij const unsigned char iv[16]); 200238405Sjkim 201238405Sjkimvoid aesni_xts_decrypt(const unsigned char *in, 202296341Sdelphij unsigned char *out, 203296341Sdelphij size_t length, 204296341Sdelphij const AES_KEY *key1, const AES_KEY *key2, 205296341Sdelphij const unsigned char iv[16]); 206238405Sjkim 207296341Sdelphijvoid aesni_ccm64_encrypt_blocks(const unsigned char *in, 208296341Sdelphij unsigned char *out, 209296341Sdelphij size_t blocks, 210296341Sdelphij const void *key, 211296341Sdelphij const unsigned char ivec[16], 212296341Sdelphij unsigned char cmac[16]); 213238405Sjkim 214296341Sdelphijvoid aesni_ccm64_decrypt_blocks(const unsigned char *in, 215296341Sdelphij unsigned char *out, 216296341Sdelphij size_t blocks, 217296341Sdelphij const void *key, 218296341Sdelphij const unsigned char ivec[16], 219296341Sdelphij unsigned char cmac[16]); 220238405Sjkim 221238405Sjkimstatic int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 222296341Sdelphij const unsigned char *iv, int enc) 223296341Sdelphij{ 224296341Sdelphij int ret, mode; 225296341Sdelphij EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; 226238405Sjkim 227296341Sdelphij mode = ctx->cipher->flags & EVP_CIPH_MODE; 228296341Sdelphij if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) 229296341Sdelphij && !enc) { 230296341Sdelphij ret = aesni_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data); 231296341Sdelphij dat->block = (block128_f) aesni_decrypt; 232296341Sdelphij dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? 233296341Sdelphij (cbc128_f) aesni_cbc_encrypt : NULL; 234296341Sdelphij } else { 235296341Sdelphij ret = aesni_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data); 236296341Sdelphij dat->block = (block128_f) aesni_encrypt; 237296341Sdelphij if (mode == EVP_CIPH_CBC_MODE) 238296341Sdelphij dat->stream.cbc = (cbc128_f) aesni_cbc_encrypt; 239296341Sdelphij else if (mode == EVP_CIPH_CTR_MODE) 240296341Sdelphij dat->stream.ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; 241296341Sdelphij else 242296341Sdelphij dat->stream.cbc = NULL; 243296341Sdelphij } 244238405Sjkim 245296341Sdelphij if (ret < 0) { 246296341Sdelphij EVPerr(EVP_F_AESNI_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); 247296341Sdelphij return 0; 248296341Sdelphij } 249238405Sjkim 250296341Sdelphij return 1; 251296341Sdelphij} 252238405Sjkim 253296341Sdelphijstatic int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 254296341Sdelphij const unsigned char *in, size_t len) 255238405Sjkim{ 256296341Sdelphij aesni_cbc_encrypt(in, out, len, ctx->cipher_data, ctx->iv, ctx->encrypt); 257238405Sjkim 258296341Sdelphij return 1; 259238405Sjkim} 260238405Sjkim 261296341Sdelphijstatic int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 262296341Sdelphij const unsigned char *in, size_t len) 263238405Sjkim{ 264296341Sdelphij size_t bl = ctx->cipher->block_size; 265238405Sjkim 266296341Sdelphij if (len < bl) 267296341Sdelphij return 1; 268238405Sjkim 269296341Sdelphij aesni_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt); 270238405Sjkim 271296341Sdelphij return 1; 272238405Sjkim} 273238405Sjkim 274296341Sdelphij# define aesni_ofb_cipher aes_ofb_cipher 275296341Sdelphijstatic int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 276296341Sdelphij const unsigned char *in, size_t len); 277238405Sjkim 278296341Sdelphij# define aesni_cfb_cipher aes_cfb_cipher 279296341Sdelphijstatic int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 280296341Sdelphij const unsigned char *in, size_t len); 281238405Sjkim 282296341Sdelphij# define aesni_cfb8_cipher aes_cfb8_cipher 283296341Sdelphijstatic int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 284296341Sdelphij const unsigned char *in, size_t len); 285238405Sjkim 286296341Sdelphij# define aesni_cfb1_cipher aes_cfb1_cipher 287296341Sdelphijstatic int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 288296341Sdelphij const unsigned char *in, size_t len); 289238405Sjkim 290296341Sdelphij# define aesni_ctr_cipher aes_ctr_cipher 291238405Sjkimstatic int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 292296341Sdelphij const unsigned char *in, size_t len); 293238405Sjkim 294238405Sjkimstatic int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 295296341Sdelphij const unsigned char *iv, int enc) 296296341Sdelphij{ 297296341Sdelphij EVP_AES_GCM_CTX *gctx = ctx->cipher_data; 298296341Sdelphij if (!iv && !key) 299296341Sdelphij return 1; 300296341Sdelphij if (key) { 301296341Sdelphij aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); 302296341Sdelphij CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) aesni_encrypt); 303296341Sdelphij gctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; 304296341Sdelphij /* 305296341Sdelphij * If we have an iv can set it directly, otherwise use saved IV. 306296341Sdelphij */ 307296341Sdelphij if (iv == NULL && gctx->iv_set) 308296341Sdelphij iv = gctx->iv; 309296341Sdelphij if (iv) { 310296341Sdelphij CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); 311296341Sdelphij gctx->iv_set = 1; 312296341Sdelphij } 313296341Sdelphij gctx->key_set = 1; 314296341Sdelphij } else { 315296341Sdelphij /* If key set use IV, otherwise copy */ 316296341Sdelphij if (gctx->key_set) 317296341Sdelphij CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); 318296341Sdelphij else 319296341Sdelphij memcpy(gctx->iv, iv, gctx->ivlen); 320296341Sdelphij gctx->iv_set = 1; 321296341Sdelphij gctx->iv_gen = 0; 322296341Sdelphij } 323296341Sdelphij return 1; 324296341Sdelphij} 325238405Sjkim 326296341Sdelphij# define aesni_gcm_cipher aes_gcm_cipher 327238405Sjkimstatic int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 328296341Sdelphij const unsigned char *in, size_t len); 329238405Sjkim 330238405Sjkimstatic int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 331296341Sdelphij const unsigned char *iv, int enc) 332296341Sdelphij{ 333296341Sdelphij EVP_AES_XTS_CTX *xctx = ctx->cipher_data; 334296341Sdelphij if (!iv && !key) 335296341Sdelphij return 1; 336238405Sjkim 337296341Sdelphij if (key) { 338296341Sdelphij /* key_len is two AES keys */ 339296341Sdelphij if (enc) { 340296341Sdelphij aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1); 341296341Sdelphij xctx->xts.block1 = (block128_f) aesni_encrypt; 342296341Sdelphij xctx->stream = aesni_xts_encrypt; 343296341Sdelphij } else { 344296341Sdelphij aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1); 345296341Sdelphij xctx->xts.block1 = (block128_f) aesni_decrypt; 346296341Sdelphij xctx->stream = aesni_xts_decrypt; 347296341Sdelphij } 348238405Sjkim 349296341Sdelphij aesni_set_encrypt_key(key + ctx->key_len / 2, 350296341Sdelphij ctx->key_len * 4, &xctx->ks2); 351296341Sdelphij xctx->xts.block2 = (block128_f) aesni_encrypt; 352238405Sjkim 353296341Sdelphij xctx->xts.key1 = &xctx->ks1; 354296341Sdelphij } 355238405Sjkim 356296341Sdelphij if (iv) { 357296341Sdelphij xctx->xts.key2 = &xctx->ks2; 358296341Sdelphij memcpy(ctx->iv, iv, 16); 359296341Sdelphij } 360238405Sjkim 361296341Sdelphij return 1; 362296341Sdelphij} 363238405Sjkim 364296341Sdelphij# define aesni_xts_cipher aes_xts_cipher 365238405Sjkimstatic int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 366296341Sdelphij const unsigned char *in, size_t len); 367238405Sjkim 368238405Sjkimstatic int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 369296341Sdelphij const unsigned char *iv, int enc) 370296341Sdelphij{ 371296341Sdelphij EVP_AES_CCM_CTX *cctx = ctx->cipher_data; 372296341Sdelphij if (!iv && !key) 373296341Sdelphij return 1; 374296341Sdelphij if (key) { 375296341Sdelphij aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks); 376296341Sdelphij CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, 377296341Sdelphij &cctx->ks, (block128_f) aesni_encrypt); 378296341Sdelphij cctx->str = enc ? (ccm128_f) aesni_ccm64_encrypt_blocks : 379296341Sdelphij (ccm128_f) aesni_ccm64_decrypt_blocks; 380296341Sdelphij cctx->key_set = 1; 381296341Sdelphij } 382296341Sdelphij if (iv) { 383296341Sdelphij memcpy(ctx->iv, iv, 15 - cctx->L); 384296341Sdelphij cctx->iv_set = 1; 385296341Sdelphij } 386296341Sdelphij return 1; 387296341Sdelphij} 388238405Sjkim 389296341Sdelphij# define aesni_ccm_cipher aes_ccm_cipher 390238405Sjkimstatic int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 391296341Sdelphij const unsigned char *in, size_t len); 392238405Sjkim 393296341Sdelphij# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ 394238405Sjkimstatic const EVP_CIPHER aesni_##keylen##_##mode = { \ 395296341Sdelphij nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ 396296341Sdelphij flags|EVP_CIPH_##MODE##_MODE, \ 397296341Sdelphij aesni_init_key, \ 398296341Sdelphij aesni_##mode##_cipher, \ 399296341Sdelphij NULL, \ 400296341Sdelphij sizeof(EVP_AES_KEY), \ 401296341Sdelphij NULL,NULL,NULL,NULL }; \ 402238405Sjkimstatic const EVP_CIPHER aes_##keylen##_##mode = { \ 403296341Sdelphij nid##_##keylen##_##nmode,blocksize, \ 404296341Sdelphij keylen/8,ivlen, \ 405296341Sdelphij flags|EVP_CIPH_##MODE##_MODE, \ 406296341Sdelphij aes_init_key, \ 407296341Sdelphij aes_##mode##_cipher, \ 408296341Sdelphij NULL, \ 409296341Sdelphij sizeof(EVP_AES_KEY), \ 410296341Sdelphij NULL,NULL,NULL,NULL }; \ 411238405Sjkimconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ 412238405Sjkim{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } 413238405Sjkim 414296341Sdelphij# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ 415238405Sjkimstatic const EVP_CIPHER aesni_##keylen##_##mode = { \ 416296341Sdelphij nid##_##keylen##_##mode,blocksize, \ 417296341Sdelphij (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ 418296341Sdelphij flags|EVP_CIPH_##MODE##_MODE, \ 419296341Sdelphij aesni_##mode##_init_key, \ 420296341Sdelphij aesni_##mode##_cipher, \ 421296341Sdelphij aes_##mode##_cleanup, \ 422296341Sdelphij sizeof(EVP_AES_##MODE##_CTX), \ 423296341Sdelphij NULL,NULL,aes_##mode##_ctrl,NULL }; \ 424238405Sjkimstatic const EVP_CIPHER aes_##keylen##_##mode = { \ 425296341Sdelphij nid##_##keylen##_##mode,blocksize, \ 426296341Sdelphij (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ 427296341Sdelphij flags|EVP_CIPH_##MODE##_MODE, \ 428296341Sdelphij aes_##mode##_init_key, \ 429296341Sdelphij aes_##mode##_cipher, \ 430296341Sdelphij aes_##mode##_cleanup, \ 431296341Sdelphij sizeof(EVP_AES_##MODE##_CTX), \ 432296341Sdelphij NULL,NULL,aes_##mode##_ctrl,NULL }; \ 433238405Sjkimconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ 434238405Sjkim{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } 435238405Sjkim 436296341Sdelphij# else 437238405Sjkim 438296341Sdelphij# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ 439238405Sjkimstatic const EVP_CIPHER aes_##keylen##_##mode = { \ 440296341Sdelphij nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ 441296341Sdelphij flags|EVP_CIPH_##MODE##_MODE, \ 442296341Sdelphij aes_init_key, \ 443296341Sdelphij aes_##mode##_cipher, \ 444296341Sdelphij NULL, \ 445296341Sdelphij sizeof(EVP_AES_KEY), \ 446296341Sdelphij NULL,NULL,NULL,NULL }; \ 447238405Sjkimconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ 448238405Sjkim{ return &aes_##keylen##_##mode; } 449238405Sjkim 450296341Sdelphij# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ 451238405Sjkimstatic const EVP_CIPHER aes_##keylen##_##mode = { \ 452296341Sdelphij nid##_##keylen##_##mode,blocksize, \ 453296341Sdelphij (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ 454296341Sdelphij flags|EVP_CIPH_##MODE##_MODE, \ 455296341Sdelphij aes_##mode##_init_key, \ 456296341Sdelphij aes_##mode##_cipher, \ 457296341Sdelphij aes_##mode##_cleanup, \ 458296341Sdelphij sizeof(EVP_AES_##MODE##_CTX), \ 459296341Sdelphij NULL,NULL,aes_##mode##_ctrl,NULL }; \ 460238405Sjkimconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ 461238405Sjkim{ return &aes_##keylen##_##mode; } 462296341Sdelphij# endif 463238405Sjkim 464296341Sdelphij# define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ 465296341Sdelphij BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ 466296341Sdelphij BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ 467296341Sdelphij BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ 468296341Sdelphij BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ 469296341Sdelphij BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \ 470296341Sdelphij BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) \ 471296341Sdelphij BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags) 472238405Sjkim 473109998Smarkmstatic int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 474296341Sdelphij const unsigned char *iv, int enc) 475296341Sdelphij{ 476296341Sdelphij int ret, mode; 477296341Sdelphij EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; 478109998Smarkm 479296341Sdelphij mode = ctx->cipher->flags & EVP_CIPH_MODE; 480296341Sdelphij if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) 481296341Sdelphij && !enc) 482296341Sdelphij# ifdef BSAES_CAPABLE 483296341Sdelphij if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) { 484296341Sdelphij ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks); 485296341Sdelphij dat->block = (block128_f) AES_decrypt; 486296341Sdelphij dat->stream.cbc = (cbc128_f) bsaes_cbc_encrypt; 487296341Sdelphij } else 488296341Sdelphij# endif 489296341Sdelphij# ifdef VPAES_CAPABLE 490296341Sdelphij if (VPAES_CAPABLE) { 491296341Sdelphij ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks); 492296341Sdelphij dat->block = (block128_f) vpaes_decrypt; 493296341Sdelphij dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? 494296341Sdelphij (cbc128_f) vpaes_cbc_encrypt : NULL; 495296341Sdelphij } else 496296341Sdelphij# endif 497296341Sdelphij { 498296341Sdelphij ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks); 499296341Sdelphij dat->block = (block128_f) AES_decrypt; 500296341Sdelphij dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? 501296341Sdelphij (cbc128_f) AES_cbc_encrypt : NULL; 502296341Sdelphij } else 503296341Sdelphij# ifdef BSAES_CAPABLE 504296341Sdelphij if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) { 505296341Sdelphij ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks); 506296341Sdelphij dat->block = (block128_f) AES_encrypt; 507296341Sdelphij dat->stream.ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks; 508296341Sdelphij } else 509296341Sdelphij# endif 510296341Sdelphij# ifdef VPAES_CAPABLE 511296341Sdelphij if (VPAES_CAPABLE) { 512296341Sdelphij ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, &dat->ks); 513296341Sdelphij dat->block = (block128_f) vpaes_encrypt; 514296341Sdelphij dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? 515296341Sdelphij (cbc128_f) vpaes_cbc_encrypt : NULL; 516296341Sdelphij } else 517296341Sdelphij# endif 518296341Sdelphij { 519296341Sdelphij ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks); 520296341Sdelphij dat->block = (block128_f) AES_encrypt; 521296341Sdelphij dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? 522296341Sdelphij (cbc128_f) AES_cbc_encrypt : NULL; 523296341Sdelphij# ifdef AES_CTR_ASM 524296341Sdelphij if (mode == EVP_CIPH_CTR_MODE) 525296341Sdelphij dat->stream.ctr = (ctr128_f) AES_ctr32_encrypt; 526296341Sdelphij# endif 527296341Sdelphij } 528109998Smarkm 529296341Sdelphij if (ret < 0) { 530296341Sdelphij EVPerr(EVP_F_AES_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); 531296341Sdelphij return 0; 532296341Sdelphij } 533142425Snectar 534296341Sdelphij return 1; 535296341Sdelphij} 536109998Smarkm 537296341Sdelphijstatic int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 538296341Sdelphij const unsigned char *in, size_t len) 539238405Sjkim{ 540296341Sdelphij EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; 541238405Sjkim 542296341Sdelphij if (dat->stream.cbc) 543296341Sdelphij (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt); 544296341Sdelphij else if (ctx->encrypt) 545296341Sdelphij CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block); 546296341Sdelphij else 547296341Sdelphij CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block); 548238405Sjkim 549296341Sdelphij return 1; 550238405Sjkim} 551238405Sjkim 552296341Sdelphijstatic int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 553296341Sdelphij const unsigned char *in, size_t len) 554238405Sjkim{ 555296341Sdelphij size_t bl = ctx->cipher->block_size; 556296341Sdelphij size_t i; 557296341Sdelphij EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; 558238405Sjkim 559296341Sdelphij if (len < bl) 560296341Sdelphij return 1; 561238405Sjkim 562296341Sdelphij for (i = 0, len -= bl; i <= len; i += bl) 563296341Sdelphij (*dat->block) (in + i, out + i, &dat->ks); 564238405Sjkim 565296341Sdelphij return 1; 566238405Sjkim} 567238405Sjkim 568296341Sdelphijstatic int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 569296341Sdelphij const unsigned char *in, size_t len) 570238405Sjkim{ 571296341Sdelphij EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; 572238405Sjkim 573296341Sdelphij CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, 574296341Sdelphij ctx->iv, &ctx->num, dat->block); 575296341Sdelphij return 1; 576238405Sjkim} 577238405Sjkim 578296341Sdelphijstatic int aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 579296341Sdelphij const unsigned char *in, size_t len) 580238405Sjkim{ 581296341Sdelphij EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; 582238405Sjkim 583296341Sdelphij CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, 584296341Sdelphij ctx->iv, &ctx->num, ctx->encrypt, dat->block); 585296341Sdelphij return 1; 586238405Sjkim} 587238405Sjkim 588296341Sdelphijstatic int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 589296341Sdelphij const unsigned char *in, size_t len) 590238405Sjkim{ 591296341Sdelphij EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; 592238405Sjkim 593296341Sdelphij CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, 594296341Sdelphij ctx->iv, &ctx->num, ctx->encrypt, dat->block); 595296341Sdelphij return 1; 596238405Sjkim} 597238405Sjkim 598296341Sdelphijstatic int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 599296341Sdelphij const unsigned char *in, size_t len) 600238405Sjkim{ 601296341Sdelphij EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; 602238405Sjkim 603296341Sdelphij if (ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) { 604296341Sdelphij CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, 605296341Sdelphij ctx->iv, &ctx->num, ctx->encrypt, dat->block); 606296341Sdelphij return 1; 607296341Sdelphij } 608238405Sjkim 609296341Sdelphij while (len >= MAXBITCHUNK) { 610296341Sdelphij CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks, 611296341Sdelphij ctx->iv, &ctx->num, ctx->encrypt, dat->block); 612296341Sdelphij len -= MAXBITCHUNK; 613296341Sdelphij } 614296341Sdelphij if (len) 615296341Sdelphij CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks, 616296341Sdelphij ctx->iv, &ctx->num, ctx->encrypt, dat->block); 617296341Sdelphij 618296341Sdelphij return 1; 619238405Sjkim} 620238405Sjkim 621296341Sdelphijstatic int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 622296341Sdelphij const unsigned char *in, size_t len) 623238405Sjkim{ 624296341Sdelphij unsigned int num = ctx->num; 625296341Sdelphij EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; 626238405Sjkim 627296341Sdelphij if (dat->stream.ctr) 628296341Sdelphij CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, 629296341Sdelphij ctx->iv, ctx->buf, &num, dat->stream.ctr); 630296341Sdelphij else 631296341Sdelphij CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, 632296341Sdelphij ctx->iv, ctx->buf, &num, dat->block); 633296341Sdelphij ctx->num = (size_t)num; 634296341Sdelphij return 1; 635238405Sjkim} 636238405Sjkim 637296341SdelphijBLOCK_CIPHER_generic_pack(NID_aes, 128, EVP_CIPH_FLAG_FIPS) 638296341Sdelphij BLOCK_CIPHER_generic_pack(NID_aes, 192, EVP_CIPH_FLAG_FIPS) 639296341Sdelphij BLOCK_CIPHER_generic_pack(NID_aes, 256, EVP_CIPH_FLAG_FIPS) 640238405Sjkim 641238405Sjkimstatic int aes_gcm_cleanup(EVP_CIPHER_CTX *c) 642296341Sdelphij{ 643296341Sdelphij EVP_AES_GCM_CTX *gctx = c->cipher_data; 644296341Sdelphij OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); 645296341Sdelphij if (gctx->iv != c->iv) 646296341Sdelphij OPENSSL_free(gctx->iv); 647296341Sdelphij return 1; 648296341Sdelphij} 649238405Sjkim 650238405Sjkim/* increment counter (64-bit int) by 1 */ 651296341Sdelphijstatic void ctr64_inc(unsigned char *counter) 652296341Sdelphij{ 653296341Sdelphij int n = 8; 654296341Sdelphij unsigned char c; 655238405Sjkim 656296341Sdelphij do { 657296341Sdelphij --n; 658296341Sdelphij c = counter[n]; 659296341Sdelphij ++c; 660296341Sdelphij counter[n] = c; 661296341Sdelphij if (c) 662296341Sdelphij return; 663296341Sdelphij } while (n); 664238405Sjkim} 665238405Sjkim 666238405Sjkimstatic int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 667296341Sdelphij{ 668296341Sdelphij EVP_AES_GCM_CTX *gctx = c->cipher_data; 669296341Sdelphij switch (type) { 670296341Sdelphij case EVP_CTRL_INIT: 671296341Sdelphij gctx->key_set = 0; 672296341Sdelphij gctx->iv_set = 0; 673296341Sdelphij gctx->ivlen = c->cipher->iv_len; 674296341Sdelphij gctx->iv = c->iv; 675296341Sdelphij gctx->taglen = -1; 676296341Sdelphij gctx->iv_gen = 0; 677296341Sdelphij gctx->tls_aad_len = -1; 678296341Sdelphij return 1; 679238405Sjkim 680296341Sdelphij case EVP_CTRL_GCM_SET_IVLEN: 681296341Sdelphij if (arg <= 0) 682296341Sdelphij return 0; 683296341Sdelphij# ifdef OPENSSL_FIPS 684296341Sdelphij if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) 685296341Sdelphij && arg < 12) 686296341Sdelphij return 0; 687296341Sdelphij# endif 688296341Sdelphij /* Allocate memory for IV if needed */ 689296341Sdelphij if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { 690296341Sdelphij if (gctx->iv != c->iv) 691296341Sdelphij OPENSSL_free(gctx->iv); 692296341Sdelphij gctx->iv = OPENSSL_malloc(arg); 693296341Sdelphij if (!gctx->iv) 694296341Sdelphij return 0; 695296341Sdelphij } 696296341Sdelphij gctx->ivlen = arg; 697296341Sdelphij return 1; 698238405Sjkim 699296341Sdelphij case EVP_CTRL_GCM_SET_TAG: 700296341Sdelphij if (arg <= 0 || arg > 16 || c->encrypt) 701296341Sdelphij return 0; 702296341Sdelphij memcpy(c->buf, ptr, arg); 703296341Sdelphij gctx->taglen = arg; 704296341Sdelphij return 1; 705238405Sjkim 706296341Sdelphij case EVP_CTRL_GCM_GET_TAG: 707296341Sdelphij if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) 708296341Sdelphij return 0; 709296341Sdelphij memcpy(ptr, c->buf, arg); 710296341Sdelphij return 1; 711238405Sjkim 712296341Sdelphij case EVP_CTRL_GCM_SET_IV_FIXED: 713296341Sdelphij /* Special case: -1 length restores whole IV */ 714296341Sdelphij if (arg == -1) { 715296341Sdelphij memcpy(gctx->iv, ptr, gctx->ivlen); 716296341Sdelphij gctx->iv_gen = 1; 717296341Sdelphij return 1; 718296341Sdelphij } 719296341Sdelphij /* 720296341Sdelphij * Fixed field must be at least 4 bytes and invocation field at least 721296341Sdelphij * 8. 722296341Sdelphij */ 723296341Sdelphij if ((arg < 4) || (gctx->ivlen - arg) < 8) 724296341Sdelphij return 0; 725296341Sdelphij if (arg) 726296341Sdelphij memcpy(gctx->iv, ptr, arg); 727296341Sdelphij if (c->encrypt && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) 728296341Sdelphij return 0; 729296341Sdelphij gctx->iv_gen = 1; 730296341Sdelphij return 1; 731238405Sjkim 732296341Sdelphij case EVP_CTRL_GCM_IV_GEN: 733296341Sdelphij if (gctx->iv_gen == 0 || gctx->key_set == 0) 734296341Sdelphij return 0; 735296341Sdelphij CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); 736296341Sdelphij if (arg <= 0 || arg > gctx->ivlen) 737296341Sdelphij arg = gctx->ivlen; 738296341Sdelphij memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); 739296341Sdelphij /* 740296341Sdelphij * Invocation field will be at least 8 bytes in size and so no need 741296341Sdelphij * to check wrap around or increment more than last 8 bytes. 742296341Sdelphij */ 743296341Sdelphij ctr64_inc(gctx->iv + gctx->ivlen - 8); 744296341Sdelphij gctx->iv_set = 1; 745296341Sdelphij return 1; 746238405Sjkim 747296341Sdelphij case EVP_CTRL_GCM_SET_IV_INV: 748296341Sdelphij if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) 749296341Sdelphij return 0; 750296341Sdelphij memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); 751296341Sdelphij CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); 752296341Sdelphij gctx->iv_set = 1; 753296341Sdelphij return 1; 754238405Sjkim 755296341Sdelphij case EVP_CTRL_AEAD_TLS1_AAD: 756296341Sdelphij /* Save the AAD for later use */ 757296341Sdelphij if (arg != EVP_AEAD_TLS1_AAD_LEN) 758296341Sdelphij return 0; 759296341Sdelphij memcpy(c->buf, ptr, arg); 760296341Sdelphij gctx->tls_aad_len = arg; 761296341Sdelphij { 762296341Sdelphij unsigned int len = c->buf[arg - 2] << 8 | c->buf[arg - 1]; 763296341Sdelphij /* Correct length for explicit IV */ 764296341Sdelphij len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; 765296341Sdelphij /* If decrypting correct for tag too */ 766296341Sdelphij if (!c->encrypt) 767296341Sdelphij len -= EVP_GCM_TLS_TAG_LEN; 768296341Sdelphij c->buf[arg - 2] = len >> 8; 769296341Sdelphij c->buf[arg - 1] = len & 0xff; 770296341Sdelphij } 771296341Sdelphij /* Extra padding: tag appended to record */ 772296341Sdelphij return EVP_GCM_TLS_TAG_LEN; 773238405Sjkim 774296341Sdelphij case EVP_CTRL_COPY: 775296341Sdelphij { 776296341Sdelphij EVP_CIPHER_CTX *out = ptr; 777296341Sdelphij EVP_AES_GCM_CTX *gctx_out = out->cipher_data; 778296341Sdelphij if (gctx->gcm.key) { 779296341Sdelphij if (gctx->gcm.key != &gctx->ks) 780296341Sdelphij return 0; 781296341Sdelphij gctx_out->gcm.key = &gctx_out->ks; 782296341Sdelphij } 783296341Sdelphij if (gctx->iv == c->iv) 784296341Sdelphij gctx_out->iv = out->iv; 785296341Sdelphij else { 786296341Sdelphij gctx_out->iv = OPENSSL_malloc(gctx->ivlen); 787296341Sdelphij if (!gctx_out->iv) 788296341Sdelphij return 0; 789296341Sdelphij memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); 790296341Sdelphij } 791296341Sdelphij return 1; 792296341Sdelphij } 793269686Sjkim 794296341Sdelphij default: 795296341Sdelphij return -1; 796238405Sjkim 797296341Sdelphij } 798296341Sdelphij} 799238405Sjkim 800238405Sjkimstatic int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 801296341Sdelphij const unsigned char *iv, int enc) 802296341Sdelphij{ 803296341Sdelphij EVP_AES_GCM_CTX *gctx = ctx->cipher_data; 804296341Sdelphij if (!iv && !key) 805296341Sdelphij return 1; 806296341Sdelphij if (key) { 807296341Sdelphij do { 808296341Sdelphij# ifdef BSAES_CAPABLE 809296341Sdelphij if (BSAES_CAPABLE) { 810296341Sdelphij AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); 811296341Sdelphij CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, 812296341Sdelphij (block128_f) AES_encrypt); 813296341Sdelphij gctx->ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks; 814296341Sdelphij break; 815296341Sdelphij } else 816296341Sdelphij# endif 817296341Sdelphij# ifdef VPAES_CAPABLE 818296341Sdelphij if (VPAES_CAPABLE) { 819296341Sdelphij vpaes_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); 820296341Sdelphij CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, 821296341Sdelphij (block128_f) vpaes_encrypt); 822296341Sdelphij gctx->ctr = NULL; 823296341Sdelphij break; 824296341Sdelphij } else 825296341Sdelphij# endif 826296341Sdelphij (void)0; /* terminate potentially open 'else' */ 827264331Sjkim 828296341Sdelphij AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); 829296341Sdelphij CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, 830296341Sdelphij (block128_f) AES_encrypt); 831296341Sdelphij# ifdef AES_CTR_ASM 832296341Sdelphij gctx->ctr = (ctr128_f) AES_ctr32_encrypt; 833296341Sdelphij# else 834296341Sdelphij gctx->ctr = NULL; 835296341Sdelphij# endif 836296341Sdelphij } while (0); 837238405Sjkim 838296341Sdelphij /* 839296341Sdelphij * If we have an iv can set it directly, otherwise use saved IV. 840296341Sdelphij */ 841296341Sdelphij if (iv == NULL && gctx->iv_set) 842296341Sdelphij iv = gctx->iv; 843296341Sdelphij if (iv) { 844296341Sdelphij CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); 845296341Sdelphij gctx->iv_set = 1; 846296341Sdelphij } 847296341Sdelphij gctx->key_set = 1; 848296341Sdelphij } else { 849296341Sdelphij /* If key set use IV, otherwise copy */ 850296341Sdelphij if (gctx->key_set) 851296341Sdelphij CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); 852296341Sdelphij else 853296341Sdelphij memcpy(gctx->iv, iv, gctx->ivlen); 854296341Sdelphij gctx->iv_set = 1; 855296341Sdelphij gctx->iv_gen = 0; 856296341Sdelphij } 857296341Sdelphij return 1; 858296341Sdelphij} 859238405Sjkim 860296341Sdelphij/* 861296341Sdelphij * Handle TLS GCM packet format. This consists of the last portion of the IV 862238405Sjkim * followed by the payload and finally the tag. On encrypt generate IV, 863238405Sjkim * encrypt payload and write the tag. On verify retrieve IV, decrypt payload 864238405Sjkim * and verify tag. 865238405Sjkim */ 866238405Sjkim 867238405Sjkimstatic int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 868296341Sdelphij const unsigned char *in, size_t len) 869296341Sdelphij{ 870296341Sdelphij EVP_AES_GCM_CTX *gctx = ctx->cipher_data; 871296341Sdelphij int rv = -1; 872296341Sdelphij /* Encrypt/decrypt must be performed in place */ 873296341Sdelphij if (out != in 874296341Sdelphij || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) 875296341Sdelphij return -1; 876296341Sdelphij /* 877296341Sdelphij * Set IV from start of buffer or generate IV and write to start of 878296341Sdelphij * buffer. 879296341Sdelphij */ 880296341Sdelphij if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ? 881296341Sdelphij EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, 882296341Sdelphij EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) 883296341Sdelphij goto err; 884296341Sdelphij /* Use saved AAD */ 885296341Sdelphij if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len)) 886296341Sdelphij goto err; 887296341Sdelphij /* Fix buffer and length to point to payload */ 888296341Sdelphij in += EVP_GCM_TLS_EXPLICIT_IV_LEN; 889296341Sdelphij out += EVP_GCM_TLS_EXPLICIT_IV_LEN; 890296341Sdelphij len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; 891296341Sdelphij if (ctx->encrypt) { 892296341Sdelphij /* Encrypt payload */ 893296341Sdelphij if (gctx->ctr) { 894296341Sdelphij if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, 895296341Sdelphij in, out, len, gctx->ctr)) 896296341Sdelphij goto err; 897296341Sdelphij } else { 898296341Sdelphij if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) 899296341Sdelphij goto err; 900296341Sdelphij } 901296341Sdelphij out += len; 902296341Sdelphij /* Finally write tag */ 903296341Sdelphij CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); 904296341Sdelphij rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; 905296341Sdelphij } else { 906296341Sdelphij /* Decrypt */ 907296341Sdelphij if (gctx->ctr) { 908296341Sdelphij if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, 909296341Sdelphij in, out, len, gctx->ctr)) 910296341Sdelphij goto err; 911296341Sdelphij } else { 912296341Sdelphij if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) 913296341Sdelphij goto err; 914296341Sdelphij } 915296341Sdelphij /* Retrieve tag */ 916296341Sdelphij CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN); 917296341Sdelphij /* If tag mismatch wipe buffer */ 918296341Sdelphij if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) { 919296341Sdelphij OPENSSL_cleanse(out, len); 920296341Sdelphij goto err; 921296341Sdelphij } 922296341Sdelphij rv = len; 923296341Sdelphij } 924238405Sjkim 925296341Sdelphij err: 926296341Sdelphij gctx->iv_set = 0; 927296341Sdelphij gctx->tls_aad_len = -1; 928296341Sdelphij return rv; 929296341Sdelphij} 930238405Sjkim 931238405Sjkimstatic int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 932296341Sdelphij const unsigned char *in, size_t len) 933296341Sdelphij{ 934296341Sdelphij EVP_AES_GCM_CTX *gctx = ctx->cipher_data; 935296341Sdelphij /* If not set up, return error */ 936296341Sdelphij if (!gctx->key_set) 937296341Sdelphij return -1; 938238405Sjkim 939296341Sdelphij if (gctx->tls_aad_len >= 0) 940296341Sdelphij return aes_gcm_tls_cipher(ctx, out, in, len); 941238405Sjkim 942296341Sdelphij if (!gctx->iv_set) 943296341Sdelphij return -1; 944296341Sdelphij if (in) { 945296341Sdelphij if (out == NULL) { 946296341Sdelphij if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) 947296341Sdelphij return -1; 948296341Sdelphij } else if (ctx->encrypt) { 949296341Sdelphij if (gctx->ctr) { 950296341Sdelphij if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, 951296341Sdelphij in, out, len, gctx->ctr)) 952296341Sdelphij return -1; 953296341Sdelphij } else { 954296341Sdelphij if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) 955296341Sdelphij return -1; 956296341Sdelphij } 957296341Sdelphij } else { 958296341Sdelphij if (gctx->ctr) { 959296341Sdelphij if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, 960296341Sdelphij in, out, len, gctx->ctr)) 961296341Sdelphij return -1; 962296341Sdelphij } else { 963296341Sdelphij if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) 964296341Sdelphij return -1; 965296341Sdelphij } 966296341Sdelphij } 967296341Sdelphij return len; 968296341Sdelphij } else { 969296341Sdelphij if (!ctx->encrypt) { 970296341Sdelphij if (gctx->taglen < 0) 971296341Sdelphij return -1; 972296341Sdelphij if (CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0) 973296341Sdelphij return -1; 974296341Sdelphij gctx->iv_set = 0; 975296341Sdelphij return 0; 976296341Sdelphij } 977296341Sdelphij CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16); 978296341Sdelphij gctx->taglen = 16; 979296341Sdelphij /* Don't reuse the IV */ 980296341Sdelphij gctx->iv_set = 0; 981296341Sdelphij return 0; 982296341Sdelphij } 983238405Sjkim 984296341Sdelphij} 985238405Sjkim 986296341Sdelphij# define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \ 987296341Sdelphij | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ 988296341Sdelphij | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ 989296341Sdelphij | EVP_CIPH_CUSTOM_COPY) 990238405Sjkim 991296341SdelphijBLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM, 992296341Sdelphij EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | 993296341Sdelphij CUSTOM_FLAGS) 994296341Sdelphij BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, gcm, GCM, 995296341Sdelphij EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | 996296341Sdelphij CUSTOM_FLAGS) 997296341Sdelphij BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, gcm, GCM, 998296341Sdelphij EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | 999296341Sdelphij CUSTOM_FLAGS) 1000238405Sjkim 1001238405Sjkimstatic int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 1002296341Sdelphij{ 1003296341Sdelphij EVP_AES_XTS_CTX *xctx = c->cipher_data; 1004296341Sdelphij if (type == EVP_CTRL_COPY) { 1005296341Sdelphij EVP_CIPHER_CTX *out = ptr; 1006296341Sdelphij EVP_AES_XTS_CTX *xctx_out = out->cipher_data; 1007296341Sdelphij if (xctx->xts.key1) { 1008296341Sdelphij if (xctx->xts.key1 != &xctx->ks1) 1009296341Sdelphij return 0; 1010296341Sdelphij xctx_out->xts.key1 = &xctx_out->ks1; 1011296341Sdelphij } 1012296341Sdelphij if (xctx->xts.key2) { 1013296341Sdelphij if (xctx->xts.key2 != &xctx->ks2) 1014296341Sdelphij return 0; 1015296341Sdelphij xctx_out->xts.key2 = &xctx_out->ks2; 1016296341Sdelphij } 1017296341Sdelphij return 1; 1018296341Sdelphij } else if (type != EVP_CTRL_INIT) 1019296341Sdelphij return -1; 1020296341Sdelphij /* key1 and key2 are used as an indicator both key and IV are set */ 1021296341Sdelphij xctx->xts.key1 = NULL; 1022296341Sdelphij xctx->xts.key2 = NULL; 1023296341Sdelphij return 1; 1024296341Sdelphij} 1025238405Sjkim 1026238405Sjkimstatic int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 1027296341Sdelphij const unsigned char *iv, int enc) 1028296341Sdelphij{ 1029296341Sdelphij EVP_AES_XTS_CTX *xctx = ctx->cipher_data; 1030296341Sdelphij if (!iv && !key) 1031296341Sdelphij return 1; 1032238405Sjkim 1033296341Sdelphij if (key) 1034296341Sdelphij do { 1035296341Sdelphij# ifdef AES_XTS_ASM 1036296341Sdelphij xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt; 1037296341Sdelphij# else 1038296341Sdelphij xctx->stream = NULL; 1039296341Sdelphij# endif 1040296341Sdelphij /* key_len is two AES keys */ 1041296341Sdelphij# ifdef BSAES_CAPABLE 1042296341Sdelphij if (BSAES_CAPABLE) 1043296341Sdelphij xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt; 1044296341Sdelphij else 1045296341Sdelphij# endif 1046296341Sdelphij# ifdef VPAES_CAPABLE 1047296341Sdelphij if (VPAES_CAPABLE) { 1048296341Sdelphij if (enc) { 1049296341Sdelphij vpaes_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1); 1050296341Sdelphij xctx->xts.block1 = (block128_f) vpaes_encrypt; 1051296341Sdelphij } else { 1052296341Sdelphij vpaes_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1); 1053296341Sdelphij xctx->xts.block1 = (block128_f) vpaes_decrypt; 1054296341Sdelphij } 1055238405Sjkim 1056296341Sdelphij vpaes_set_encrypt_key(key + ctx->key_len / 2, 1057296341Sdelphij ctx->key_len * 4, &xctx->ks2); 1058296341Sdelphij xctx->xts.block2 = (block128_f) vpaes_encrypt; 1059238405Sjkim 1060296341Sdelphij xctx->xts.key1 = &xctx->ks1; 1061296341Sdelphij break; 1062296341Sdelphij } else 1063296341Sdelphij# endif 1064296341Sdelphij (void)0; /* terminate potentially open 'else' */ 1065264331Sjkim 1066296341Sdelphij if (enc) { 1067296341Sdelphij AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1); 1068296341Sdelphij xctx->xts.block1 = (block128_f) AES_encrypt; 1069296341Sdelphij } else { 1070296341Sdelphij AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1); 1071296341Sdelphij xctx->xts.block1 = (block128_f) AES_decrypt; 1072296341Sdelphij } 1073238405Sjkim 1074296341Sdelphij AES_set_encrypt_key(key + ctx->key_len / 2, 1075296341Sdelphij ctx->key_len * 4, &xctx->ks2); 1076296341Sdelphij xctx->xts.block2 = (block128_f) AES_encrypt; 1077238405Sjkim 1078296341Sdelphij xctx->xts.key1 = &xctx->ks1; 1079296341Sdelphij } while (0); 1080238405Sjkim 1081296341Sdelphij if (iv) { 1082296341Sdelphij xctx->xts.key2 = &xctx->ks2; 1083296341Sdelphij memcpy(ctx->iv, iv, 16); 1084296341Sdelphij } 1085238405Sjkim 1086296341Sdelphij return 1; 1087296341Sdelphij} 1088238405Sjkim 1089238405Sjkimstatic int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 1090296341Sdelphij const unsigned char *in, size_t len) 1091296341Sdelphij{ 1092296341Sdelphij EVP_AES_XTS_CTX *xctx = ctx->cipher_data; 1093296341Sdelphij if (!xctx->xts.key1 || !xctx->xts.key2) 1094296341Sdelphij return 0; 1095296341Sdelphij if (!out || !in || len < AES_BLOCK_SIZE) 1096296341Sdelphij return 0; 1097296341Sdelphij# ifdef OPENSSL_FIPS 1098296341Sdelphij /* Requirement of SP800-38E */ 1099296341Sdelphij if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && 1100296341Sdelphij (len > (1UL << 20) * 16)) { 1101296341Sdelphij EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE); 1102296341Sdelphij return 0; 1103296341Sdelphij } 1104296341Sdelphij# endif 1105296341Sdelphij if (xctx->stream) 1106296341Sdelphij (*xctx->stream) (in, out, len, 1107296341Sdelphij xctx->xts.key1, xctx->xts.key2, ctx->iv); 1108296341Sdelphij else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, 1109296341Sdelphij ctx->encrypt)) 1110296341Sdelphij return 0; 1111296341Sdelphij return 1; 1112296341Sdelphij} 1113238405Sjkim 1114296341Sdelphij# define aes_xts_cleanup NULL 1115238405Sjkim 1116296341Sdelphij# define XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \ 1117296341Sdelphij | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ 1118296341Sdelphij | EVP_CIPH_CUSTOM_COPY) 1119238405Sjkim 1120296341SdelphijBLOCK_CIPHER_custom(NID_aes, 128, 1, 16, xts, XTS, 1121296341Sdelphij EVP_CIPH_FLAG_FIPS | XTS_FLAGS) 1122296341Sdelphij BLOCK_CIPHER_custom(NID_aes, 256, 1, 16, xts, XTS, 1123296341Sdelphij EVP_CIPH_FLAG_FIPS | XTS_FLAGS) 1124238405Sjkim 1125238405Sjkimstatic int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 1126296341Sdelphij{ 1127296341Sdelphij EVP_AES_CCM_CTX *cctx = c->cipher_data; 1128296341Sdelphij switch (type) { 1129296341Sdelphij case EVP_CTRL_INIT: 1130296341Sdelphij cctx->key_set = 0; 1131296341Sdelphij cctx->iv_set = 0; 1132296341Sdelphij cctx->L = 8; 1133296341Sdelphij cctx->M = 12; 1134296341Sdelphij cctx->tag_set = 0; 1135296341Sdelphij cctx->len_set = 0; 1136296341Sdelphij return 1; 1137238405Sjkim 1138296341Sdelphij case EVP_CTRL_CCM_SET_IVLEN: 1139296341Sdelphij arg = 15 - arg; 1140296341Sdelphij case EVP_CTRL_CCM_SET_L: 1141296341Sdelphij if (arg < 2 || arg > 8) 1142296341Sdelphij return 0; 1143296341Sdelphij cctx->L = arg; 1144296341Sdelphij return 1; 1145238405Sjkim 1146296341Sdelphij case EVP_CTRL_CCM_SET_TAG: 1147296341Sdelphij if ((arg & 1) || arg < 4 || arg > 16) 1148296341Sdelphij return 0; 1149296341Sdelphij if (c->encrypt && ptr) 1150296341Sdelphij return 0; 1151296341Sdelphij if (ptr) { 1152296341Sdelphij cctx->tag_set = 1; 1153296341Sdelphij memcpy(c->buf, ptr, arg); 1154296341Sdelphij } 1155296341Sdelphij cctx->M = arg; 1156296341Sdelphij return 1; 1157238405Sjkim 1158296341Sdelphij case EVP_CTRL_CCM_GET_TAG: 1159296341Sdelphij if (!c->encrypt || !cctx->tag_set) 1160296341Sdelphij return 0; 1161296341Sdelphij if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg)) 1162296341Sdelphij return 0; 1163296341Sdelphij cctx->tag_set = 0; 1164296341Sdelphij cctx->iv_set = 0; 1165296341Sdelphij cctx->len_set = 0; 1166296341Sdelphij return 1; 1167238405Sjkim 1168296341Sdelphij case EVP_CTRL_COPY: 1169296341Sdelphij { 1170296341Sdelphij EVP_CIPHER_CTX *out = ptr; 1171296341Sdelphij EVP_AES_CCM_CTX *cctx_out = out->cipher_data; 1172296341Sdelphij if (cctx->ccm.key) { 1173296341Sdelphij if (cctx->ccm.key != &cctx->ks) 1174296341Sdelphij return 0; 1175296341Sdelphij cctx_out->ccm.key = &cctx_out->ks; 1176296341Sdelphij } 1177296341Sdelphij return 1; 1178296341Sdelphij } 1179269686Sjkim 1180296341Sdelphij default: 1181296341Sdelphij return -1; 1182238405Sjkim 1183296341Sdelphij } 1184296341Sdelphij} 1185238405Sjkim 1186238405Sjkimstatic int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 1187296341Sdelphij const unsigned char *iv, int enc) 1188296341Sdelphij{ 1189296341Sdelphij EVP_AES_CCM_CTX *cctx = ctx->cipher_data; 1190296341Sdelphij if (!iv && !key) 1191296341Sdelphij return 1; 1192296341Sdelphij if (key) 1193296341Sdelphij do { 1194296341Sdelphij# ifdef VPAES_CAPABLE 1195296341Sdelphij if (VPAES_CAPABLE) { 1196296341Sdelphij vpaes_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks); 1197296341Sdelphij CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, 1198296341Sdelphij &cctx->ks, (block128_f) vpaes_encrypt); 1199296341Sdelphij cctx->str = NULL; 1200296341Sdelphij cctx->key_set = 1; 1201296341Sdelphij break; 1202296341Sdelphij } 1203296341Sdelphij# endif 1204296341Sdelphij AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks); 1205296341Sdelphij CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, 1206296341Sdelphij &cctx->ks, (block128_f) AES_encrypt); 1207296341Sdelphij cctx->str = NULL; 1208296341Sdelphij cctx->key_set = 1; 1209296341Sdelphij } while (0); 1210296341Sdelphij if (iv) { 1211296341Sdelphij memcpy(ctx->iv, iv, 15 - cctx->L); 1212296341Sdelphij cctx->iv_set = 1; 1213296341Sdelphij } 1214296341Sdelphij return 1; 1215296341Sdelphij} 1216238405Sjkim 1217238405Sjkimstatic int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 1218296341Sdelphij const unsigned char *in, size_t len) 1219296341Sdelphij{ 1220296341Sdelphij EVP_AES_CCM_CTX *cctx = ctx->cipher_data; 1221296341Sdelphij CCM128_CONTEXT *ccm = &cctx->ccm; 1222296341Sdelphij /* If not set up, return error */ 1223296341Sdelphij if (!cctx->iv_set && !cctx->key_set) 1224296341Sdelphij return -1; 1225296341Sdelphij if (!ctx->encrypt && !cctx->tag_set) 1226296341Sdelphij return -1; 1227296341Sdelphij if (!out) { 1228296341Sdelphij if (!in) { 1229296341Sdelphij if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) 1230296341Sdelphij return -1; 1231296341Sdelphij cctx->len_set = 1; 1232296341Sdelphij return len; 1233296341Sdelphij } 1234296341Sdelphij /* If have AAD need message length */ 1235296341Sdelphij if (!cctx->len_set && len) 1236296341Sdelphij return -1; 1237296341Sdelphij CRYPTO_ccm128_aad(ccm, in, len); 1238296341Sdelphij return len; 1239296341Sdelphij } 1240296341Sdelphij /* EVP_*Final() doesn't return any data */ 1241296341Sdelphij if (!in) 1242296341Sdelphij return 0; 1243296341Sdelphij /* If not set length yet do it */ 1244296341Sdelphij if (!cctx->len_set) { 1245296341Sdelphij if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) 1246296341Sdelphij return -1; 1247296341Sdelphij cctx->len_set = 1; 1248296341Sdelphij } 1249296341Sdelphij if (ctx->encrypt) { 1250296341Sdelphij if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, 1251296341Sdelphij cctx->str) : 1252296341Sdelphij CRYPTO_ccm128_encrypt(ccm, in, out, len)) 1253296341Sdelphij return -1; 1254296341Sdelphij cctx->tag_set = 1; 1255296341Sdelphij return len; 1256296341Sdelphij } else { 1257296341Sdelphij int rv = -1; 1258296341Sdelphij if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, 1259296341Sdelphij cctx->str) : 1260296341Sdelphij !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { 1261296341Sdelphij unsigned char tag[16]; 1262296341Sdelphij if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { 1263296341Sdelphij if (!CRYPTO_memcmp(tag, ctx->buf, cctx->M)) 1264296341Sdelphij rv = len; 1265296341Sdelphij } 1266296341Sdelphij } 1267296341Sdelphij if (rv == -1) 1268296341Sdelphij OPENSSL_cleanse(out, len); 1269296341Sdelphij cctx->iv_set = 0; 1270296341Sdelphij cctx->tag_set = 0; 1271296341Sdelphij cctx->len_set = 0; 1272296341Sdelphij return rv; 1273296341Sdelphij } 1274238405Sjkim 1275296341Sdelphij} 1276238405Sjkim 1277296341Sdelphij# define aes_ccm_cleanup NULL 1278238405Sjkim 1279296341SdelphijBLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM, 1280296341Sdelphij EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) 1281296341Sdelphij BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM, 1282296341Sdelphij EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) 1283296341Sdelphij BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM, 1284296341Sdelphij EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) 1285296341Sdelphij# endif 1286238405Sjkim#endif 1287