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 9109998Smarkm * 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 53109998Smarkm#include <openssl/evp.h> 54109998Smarkm#include <openssl/err.h> 55109998Smarkm#include <string.h> 56160814Ssimon#include <assert.h> 57109998Smarkm#include <openssl/aes.h> 58109998Smarkm#include "evp_locl.h" 59238405Sjkim#ifndef OPENSSL_FIPS 60238405Sjkim#include "modes_lcl.h" 61238405Sjkim#include <openssl/rand.h> 62109998Smarkm 63109998Smarkmtypedef struct 64109998Smarkm { 65109998Smarkm AES_KEY ks; 66238405Sjkim block128_f block; 67238405Sjkim union { 68238405Sjkim cbc128_f cbc; 69238405Sjkim ctr128_f ctr; 70238405Sjkim } stream; 71109998Smarkm } EVP_AES_KEY; 72109998Smarkm 73238405Sjkimtypedef struct 74238405Sjkim { 75238405Sjkim AES_KEY ks; /* AES key schedule to use */ 76238405Sjkim int key_set; /* Set if key initialised */ 77238405Sjkim int iv_set; /* Set if an iv is set */ 78238405Sjkim GCM128_CONTEXT gcm; 79238405Sjkim unsigned char *iv; /* Temporary IV store */ 80238405Sjkim int ivlen; /* IV length */ 81238405Sjkim int taglen; 82238405Sjkim int iv_gen; /* It is OK to generate IVs */ 83238405Sjkim int tls_aad_len; /* TLS AAD length */ 84238405Sjkim ctr128_f ctr; 85238405Sjkim } EVP_AES_GCM_CTX; 86109998Smarkm 87238405Sjkimtypedef struct 88238405Sjkim { 89238405Sjkim AES_KEY ks1, ks2; /* AES key schedules to use */ 90238405Sjkim XTS128_CONTEXT xts; 91238405Sjkim void (*stream)(const unsigned char *in, 92238405Sjkim unsigned char *out, size_t length, 93238405Sjkim const AES_KEY *key1, const AES_KEY *key2, 94238405Sjkim const unsigned char iv[16]); 95238405Sjkim } EVP_AES_XTS_CTX; 96109998Smarkm 97238405Sjkimtypedef struct 98238405Sjkim { 99238405Sjkim AES_KEY ks; /* AES key schedule to use */ 100238405Sjkim int key_set; /* Set if key initialised */ 101238405Sjkim int iv_set; /* Set if an iv is set */ 102238405Sjkim int tag_set; /* Set if tag is valid */ 103238405Sjkim int len_set; /* Set if message length set */ 104238405Sjkim int L, M; /* L and M parameters from RFC3610 */ 105238405Sjkim CCM128_CONTEXT ccm; 106238405Sjkim ccm128_f str; 107238405Sjkim } EVP_AES_CCM_CTX; 108142425Snectar 109238405Sjkim#define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) 110142425Snectar 111238405Sjkim#ifdef VPAES_ASM 112238405Sjkimint vpaes_set_encrypt_key(const unsigned char *userKey, int bits, 113238405Sjkim AES_KEY *key); 114238405Sjkimint vpaes_set_decrypt_key(const unsigned char *userKey, int bits, 115238405Sjkim AES_KEY *key); 116142425Snectar 117238405Sjkimvoid vpaes_encrypt(const unsigned char *in, unsigned char *out, 118238405Sjkim const AES_KEY *key); 119238405Sjkimvoid vpaes_decrypt(const unsigned char *in, unsigned char *out, 120238405Sjkim const AES_KEY *key); 121238405Sjkim 122238405Sjkimvoid vpaes_cbc_encrypt(const unsigned char *in, 123238405Sjkim unsigned char *out, 124238405Sjkim size_t length, 125238405Sjkim const AES_KEY *key, 126238405Sjkim unsigned char *ivec, int enc); 127238405Sjkim#endif 128238405Sjkim#ifdef BSAES_ASM 129238405Sjkimvoid bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out, 130238405Sjkim size_t length, const AES_KEY *key, 131238405Sjkim unsigned char ivec[16], int enc); 132238405Sjkimvoid bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, 133238405Sjkim size_t len, const AES_KEY *key, 134238405Sjkim const unsigned char ivec[16]); 135238405Sjkimvoid bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out, 136238405Sjkim size_t len, const AES_KEY *key1, 137238405Sjkim const AES_KEY *key2, const unsigned char iv[16]); 138238405Sjkimvoid bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, 139238405Sjkim size_t len, const AES_KEY *key1, 140238405Sjkim const AES_KEY *key2, const unsigned char iv[16]); 141238405Sjkim#endif 142238405Sjkim#ifdef AES_CTR_ASM 143238405Sjkimvoid AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, 144238405Sjkim size_t blocks, const AES_KEY *key, 145238405Sjkim const unsigned char ivec[AES_BLOCK_SIZE]); 146238405Sjkim#endif 147238405Sjkim#ifdef AES_XTS_ASM 148238405Sjkimvoid AES_xts_encrypt(const char *inp,char *out,size_t len, 149238405Sjkim const AES_KEY *key1, const AES_KEY *key2, 150238405Sjkim const unsigned char iv[16]); 151238405Sjkimvoid AES_xts_decrypt(const char *inp,char *out,size_t len, 152238405Sjkim const AES_KEY *key1, const AES_KEY *key2, 153238405Sjkim const unsigned char iv[16]); 154238405Sjkim#endif 155238405Sjkim 156238405Sjkim#if defined(AES_ASM) && !defined(I386_ONLY) && ( \ 157238405Sjkim ((defined(__i386) || defined(__i386__) || \ 158238405Sjkim defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \ 159238405Sjkim defined(__x86_64) || defined(__x86_64__) || \ 160238405Sjkim defined(_M_AMD64) || defined(_M_X64) || \ 161238405Sjkim defined(__INTEL__) ) 162238405Sjkim 163238405Sjkimextern unsigned int OPENSSL_ia32cap_P[2]; 164238405Sjkim 165238405Sjkim#ifdef VPAES_ASM 166238405Sjkim#define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) 167238405Sjkim#endif 168238405Sjkim#ifdef BSAES_ASM 169279264Sdelphij#define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) 170238405Sjkim#endif 171238405Sjkim/* 172238405Sjkim * AES-NI section 173238405Sjkim */ 174238405Sjkim#define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32))) 175238405Sjkim 176238405Sjkimint aesni_set_encrypt_key(const unsigned char *userKey, int bits, 177238405Sjkim AES_KEY *key); 178238405Sjkimint aesni_set_decrypt_key(const unsigned char *userKey, int bits, 179238405Sjkim AES_KEY *key); 180238405Sjkim 181238405Sjkimvoid aesni_encrypt(const unsigned char *in, unsigned char *out, 182238405Sjkim const AES_KEY *key); 183238405Sjkimvoid aesni_decrypt(const unsigned char *in, unsigned char *out, 184238405Sjkim const AES_KEY *key); 185238405Sjkim 186238405Sjkimvoid aesni_ecb_encrypt(const unsigned char *in, 187238405Sjkim unsigned char *out, 188238405Sjkim size_t length, 189238405Sjkim const AES_KEY *key, 190238405Sjkim int enc); 191238405Sjkimvoid aesni_cbc_encrypt(const unsigned char *in, 192238405Sjkim unsigned char *out, 193238405Sjkim size_t length, 194238405Sjkim const AES_KEY *key, 195238405Sjkim unsigned char *ivec, int enc); 196238405Sjkim 197238405Sjkimvoid aesni_ctr32_encrypt_blocks(const unsigned char *in, 198238405Sjkim unsigned char *out, 199238405Sjkim size_t blocks, 200238405Sjkim const void *key, 201238405Sjkim const unsigned char *ivec); 202238405Sjkim 203238405Sjkimvoid aesni_xts_encrypt(const unsigned char *in, 204238405Sjkim unsigned char *out, 205238405Sjkim size_t length, 206238405Sjkim const AES_KEY *key1, const AES_KEY *key2, 207238405Sjkim const unsigned char iv[16]); 208238405Sjkim 209238405Sjkimvoid aesni_xts_decrypt(const unsigned char *in, 210238405Sjkim unsigned char *out, 211238405Sjkim size_t length, 212238405Sjkim const AES_KEY *key1, const AES_KEY *key2, 213238405Sjkim const unsigned char iv[16]); 214238405Sjkim 215238405Sjkimvoid aesni_ccm64_encrypt_blocks (const unsigned char *in, 216238405Sjkim unsigned char *out, 217238405Sjkim size_t blocks, 218238405Sjkim const void *key, 219238405Sjkim const unsigned char ivec[16], 220238405Sjkim unsigned char cmac[16]); 221238405Sjkim 222238405Sjkimvoid aesni_ccm64_decrypt_blocks (const unsigned char *in, 223238405Sjkim unsigned char *out, 224238405Sjkim size_t blocks, 225238405Sjkim const void *key, 226238405Sjkim const unsigned char ivec[16], 227238405Sjkim unsigned char cmac[16]); 228238405Sjkim 229238405Sjkimstatic int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 230238405Sjkim const unsigned char *iv, int enc) 231238405Sjkim { 232238405Sjkim int ret, mode; 233238405Sjkim EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; 234238405Sjkim 235238405Sjkim mode = ctx->cipher->flags & EVP_CIPH_MODE; 236238405Sjkim if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) 237238405Sjkim && !enc) 238238405Sjkim { 239238405Sjkim ret = aesni_set_decrypt_key(key, ctx->key_len*8, ctx->cipher_data); 240238405Sjkim dat->block = (block128_f)aesni_decrypt; 241238405Sjkim dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ? 242238405Sjkim (cbc128_f)aesni_cbc_encrypt : 243238405Sjkim NULL; 244238405Sjkim } 245238405Sjkim else { 246238405Sjkim ret = aesni_set_encrypt_key(key, ctx->key_len*8, ctx->cipher_data); 247238405Sjkim dat->block = (block128_f)aesni_encrypt; 248238405Sjkim if (mode==EVP_CIPH_CBC_MODE) 249238405Sjkim dat->stream.cbc = (cbc128_f)aesni_cbc_encrypt; 250238405Sjkim else if (mode==EVP_CIPH_CTR_MODE) 251238405Sjkim dat->stream.ctr = (ctr128_f)aesni_ctr32_encrypt_blocks; 252238405Sjkim else 253238405Sjkim dat->stream.cbc = NULL; 254238405Sjkim } 255238405Sjkim 256238405Sjkim if(ret < 0) 257238405Sjkim { 258238405Sjkim EVPerr(EVP_F_AESNI_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED); 259238405Sjkim return 0; 260238405Sjkim } 261238405Sjkim 262238405Sjkim return 1; 263238405Sjkim } 264238405Sjkim 265238405Sjkimstatic int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 266238405Sjkim const unsigned char *in, size_t len) 267238405Sjkim{ 268238405Sjkim aesni_cbc_encrypt(in,out,len,ctx->cipher_data,ctx->iv,ctx->encrypt); 269238405Sjkim 270238405Sjkim return 1; 271238405Sjkim} 272238405Sjkim 273238405Sjkimstatic int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 274238405Sjkim const unsigned char *in, size_t len) 275238405Sjkim{ 276238405Sjkim size_t bl = ctx->cipher->block_size; 277238405Sjkim 278238405Sjkim if (len<bl) return 1; 279238405Sjkim 280238405Sjkim aesni_ecb_encrypt(in,out,len,ctx->cipher_data,ctx->encrypt); 281238405Sjkim 282238405Sjkim return 1; 283238405Sjkim} 284238405Sjkim 285238405Sjkim#define aesni_ofb_cipher aes_ofb_cipher 286238405Sjkimstatic int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 287238405Sjkim const unsigned char *in,size_t len); 288238405Sjkim 289238405Sjkim#define aesni_cfb_cipher aes_cfb_cipher 290238405Sjkimstatic int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 291238405Sjkim const unsigned char *in,size_t len); 292238405Sjkim 293238405Sjkim#define aesni_cfb8_cipher aes_cfb8_cipher 294238405Sjkimstatic int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 295238405Sjkim const unsigned char *in,size_t len); 296238405Sjkim 297238405Sjkim#define aesni_cfb1_cipher aes_cfb1_cipher 298238405Sjkimstatic int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 299238405Sjkim const unsigned char *in,size_t len); 300238405Sjkim 301238405Sjkim#define aesni_ctr_cipher aes_ctr_cipher 302238405Sjkimstatic int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 303238405Sjkim const unsigned char *in, size_t len); 304238405Sjkim 305238405Sjkimstatic int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 306238405Sjkim const unsigned char *iv, int enc) 307238405Sjkim { 308238405Sjkim EVP_AES_GCM_CTX *gctx = ctx->cipher_data; 309238405Sjkim if (!iv && !key) 310238405Sjkim return 1; 311238405Sjkim if (key) 312238405Sjkim { 313238405Sjkim aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); 314238405Sjkim CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, 315238405Sjkim (block128_f)aesni_encrypt); 316238405Sjkim gctx->ctr = (ctr128_f)aesni_ctr32_encrypt_blocks; 317238405Sjkim /* If we have an iv can set it directly, otherwise use 318238405Sjkim * saved IV. 319238405Sjkim */ 320238405Sjkim if (iv == NULL && gctx->iv_set) 321238405Sjkim iv = gctx->iv; 322238405Sjkim if (iv) 323238405Sjkim { 324238405Sjkim CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); 325238405Sjkim gctx->iv_set = 1; 326238405Sjkim } 327238405Sjkim gctx->key_set = 1; 328238405Sjkim } 329238405Sjkim else 330238405Sjkim { 331238405Sjkim /* If key set use IV, otherwise copy */ 332238405Sjkim if (gctx->key_set) 333238405Sjkim CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); 334238405Sjkim else 335238405Sjkim memcpy(gctx->iv, iv, gctx->ivlen); 336238405Sjkim gctx->iv_set = 1; 337238405Sjkim gctx->iv_gen = 0; 338238405Sjkim } 339238405Sjkim return 1; 340238405Sjkim } 341238405Sjkim 342238405Sjkim#define aesni_gcm_cipher aes_gcm_cipher 343238405Sjkimstatic int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 344238405Sjkim const unsigned char *in, size_t len); 345238405Sjkim 346238405Sjkimstatic int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 347238405Sjkim const unsigned char *iv, int enc) 348238405Sjkim { 349238405Sjkim EVP_AES_XTS_CTX *xctx = ctx->cipher_data; 350238405Sjkim if (!iv && !key) 351238405Sjkim return 1; 352238405Sjkim 353238405Sjkim if (key) 354238405Sjkim { 355238405Sjkim /* key_len is two AES keys */ 356238405Sjkim if (enc) 357238405Sjkim { 358238405Sjkim aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1); 359238405Sjkim xctx->xts.block1 = (block128_f)aesni_encrypt; 360238405Sjkim xctx->stream = aesni_xts_encrypt; 361238405Sjkim } 362238405Sjkim else 363238405Sjkim { 364238405Sjkim aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1); 365238405Sjkim xctx->xts.block1 = (block128_f)aesni_decrypt; 366238405Sjkim xctx->stream = aesni_xts_decrypt; 367238405Sjkim } 368238405Sjkim 369238405Sjkim aesni_set_encrypt_key(key + ctx->key_len/2, 370238405Sjkim ctx->key_len * 4, &xctx->ks2); 371238405Sjkim xctx->xts.block2 = (block128_f)aesni_encrypt; 372238405Sjkim 373238405Sjkim xctx->xts.key1 = &xctx->ks1; 374238405Sjkim } 375238405Sjkim 376238405Sjkim if (iv) 377238405Sjkim { 378238405Sjkim xctx->xts.key2 = &xctx->ks2; 379238405Sjkim memcpy(ctx->iv, iv, 16); 380238405Sjkim } 381238405Sjkim 382238405Sjkim return 1; 383238405Sjkim } 384238405Sjkim 385238405Sjkim#define aesni_xts_cipher aes_xts_cipher 386238405Sjkimstatic int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 387238405Sjkim const unsigned char *in, size_t len); 388238405Sjkim 389238405Sjkimstatic int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 390238405Sjkim const unsigned char *iv, int enc) 391238405Sjkim { 392238405Sjkim EVP_AES_CCM_CTX *cctx = ctx->cipher_data; 393238405Sjkim if (!iv && !key) 394238405Sjkim return 1; 395238405Sjkim if (key) 396238405Sjkim { 397238405Sjkim aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks); 398238405Sjkim CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, 399238405Sjkim &cctx->ks, (block128_f)aesni_encrypt); 400238405Sjkim cctx->str = enc?(ccm128_f)aesni_ccm64_encrypt_blocks : 401238405Sjkim (ccm128_f)aesni_ccm64_decrypt_blocks; 402238405Sjkim cctx->key_set = 1; 403238405Sjkim } 404238405Sjkim if (iv) 405238405Sjkim { 406238405Sjkim memcpy(ctx->iv, iv, 15 - cctx->L); 407238405Sjkim cctx->iv_set = 1; 408238405Sjkim } 409238405Sjkim return 1; 410238405Sjkim } 411238405Sjkim 412238405Sjkim#define aesni_ccm_cipher aes_ccm_cipher 413238405Sjkimstatic int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 414238405Sjkim const unsigned char *in, size_t len); 415238405Sjkim 416238405Sjkim#define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ 417238405Sjkimstatic const EVP_CIPHER aesni_##keylen##_##mode = { \ 418238405Sjkim nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ 419238405Sjkim flags|EVP_CIPH_##MODE##_MODE, \ 420238405Sjkim aesni_init_key, \ 421238405Sjkim aesni_##mode##_cipher, \ 422238405Sjkim NULL, \ 423238405Sjkim sizeof(EVP_AES_KEY), \ 424238405Sjkim NULL,NULL,NULL,NULL }; \ 425238405Sjkimstatic const EVP_CIPHER aes_##keylen##_##mode = { \ 426238405Sjkim nid##_##keylen##_##nmode,blocksize, \ 427238405Sjkim keylen/8,ivlen, \ 428238405Sjkim flags|EVP_CIPH_##MODE##_MODE, \ 429238405Sjkim aes_init_key, \ 430238405Sjkim aes_##mode##_cipher, \ 431238405Sjkim NULL, \ 432238405Sjkim sizeof(EVP_AES_KEY), \ 433238405Sjkim NULL,NULL,NULL,NULL }; \ 434238405Sjkimconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ 435238405Sjkim{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } 436238405Sjkim 437238405Sjkim#define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ 438238405Sjkimstatic const EVP_CIPHER aesni_##keylen##_##mode = { \ 439238405Sjkim nid##_##keylen##_##mode,blocksize, \ 440238405Sjkim (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ 441238405Sjkim flags|EVP_CIPH_##MODE##_MODE, \ 442238405Sjkim aesni_##mode##_init_key, \ 443238405Sjkim aesni_##mode##_cipher, \ 444238405Sjkim aes_##mode##_cleanup, \ 445238405Sjkim sizeof(EVP_AES_##MODE##_CTX), \ 446238405Sjkim NULL,NULL,aes_##mode##_ctrl,NULL }; \ 447238405Sjkimstatic const EVP_CIPHER aes_##keylen##_##mode = { \ 448238405Sjkim nid##_##keylen##_##mode,blocksize, \ 449238405Sjkim (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ 450238405Sjkim flags|EVP_CIPH_##MODE##_MODE, \ 451238405Sjkim aes_##mode##_init_key, \ 452238405Sjkim aes_##mode##_cipher, \ 453238405Sjkim aes_##mode##_cleanup, \ 454238405Sjkim sizeof(EVP_AES_##MODE##_CTX), \ 455238405Sjkim NULL,NULL,aes_##mode##_ctrl,NULL }; \ 456238405Sjkimconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ 457238405Sjkim{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } 458238405Sjkim 459238405Sjkim#else 460238405Sjkim 461238405Sjkim#define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ 462238405Sjkimstatic const EVP_CIPHER aes_##keylen##_##mode = { \ 463238405Sjkim nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ 464238405Sjkim flags|EVP_CIPH_##MODE##_MODE, \ 465238405Sjkim aes_init_key, \ 466238405Sjkim aes_##mode##_cipher, \ 467238405Sjkim NULL, \ 468238405Sjkim sizeof(EVP_AES_KEY), \ 469238405Sjkim NULL,NULL,NULL,NULL }; \ 470238405Sjkimconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ 471238405Sjkim{ return &aes_##keylen##_##mode; } 472238405Sjkim 473238405Sjkim#define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ 474238405Sjkimstatic const EVP_CIPHER aes_##keylen##_##mode = { \ 475238405Sjkim nid##_##keylen##_##mode,blocksize, \ 476238405Sjkim (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ 477238405Sjkim flags|EVP_CIPH_##MODE##_MODE, \ 478238405Sjkim aes_##mode##_init_key, \ 479238405Sjkim aes_##mode##_cipher, \ 480238405Sjkim aes_##mode##_cleanup, \ 481238405Sjkim sizeof(EVP_AES_##MODE##_CTX), \ 482238405Sjkim NULL,NULL,aes_##mode##_ctrl,NULL }; \ 483238405Sjkimconst EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ 484238405Sjkim{ return &aes_##keylen##_##mode; } 485238405Sjkim#endif 486238405Sjkim 487238405Sjkim#define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ 488238405Sjkim BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ 489238405Sjkim BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ 490238405Sjkim BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ 491238405Sjkim BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ 492238405Sjkim BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \ 493238405Sjkim BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) \ 494238405Sjkim BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags) 495238405Sjkim 496109998Smarkmstatic int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 497142425Snectar const unsigned char *iv, int enc) 498142425Snectar { 499238405Sjkim int ret, mode; 500238405Sjkim EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; 501109998Smarkm 502238405Sjkim mode = ctx->cipher->flags & EVP_CIPH_MODE; 503238405Sjkim if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) 504238405Sjkim && !enc) 505238405Sjkim#ifdef BSAES_CAPABLE 506238405Sjkim if (BSAES_CAPABLE && mode==EVP_CIPH_CBC_MODE) 507238405Sjkim { 508238405Sjkim ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks); 509238405Sjkim dat->block = (block128_f)AES_decrypt; 510238405Sjkim dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt; 511238405Sjkim } 512238405Sjkim else 513238405Sjkim#endif 514238405Sjkim#ifdef VPAES_CAPABLE 515238405Sjkim if (VPAES_CAPABLE) 516238405Sjkim { 517238405Sjkim ret = vpaes_set_decrypt_key(key,ctx->key_len*8,&dat->ks); 518238405Sjkim dat->block = (block128_f)vpaes_decrypt; 519238405Sjkim dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ? 520238405Sjkim (cbc128_f)vpaes_cbc_encrypt : 521238405Sjkim NULL; 522238405Sjkim } 523238405Sjkim else 524238405Sjkim#endif 525238405Sjkim { 526238405Sjkim ret = AES_set_decrypt_key(key,ctx->key_len*8,&dat->ks); 527238405Sjkim dat->block = (block128_f)AES_decrypt; 528238405Sjkim dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ? 529238405Sjkim (cbc128_f)AES_cbc_encrypt : 530238405Sjkim NULL; 531238405Sjkim } 532109998Smarkm else 533238405Sjkim#ifdef BSAES_CAPABLE 534238405Sjkim if (BSAES_CAPABLE && mode==EVP_CIPH_CTR_MODE) 535238405Sjkim { 536238405Sjkim ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks); 537238405Sjkim dat->block = (block128_f)AES_encrypt; 538238405Sjkim dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks; 539238405Sjkim } 540238405Sjkim else 541238405Sjkim#endif 542238405Sjkim#ifdef VPAES_CAPABLE 543238405Sjkim if (VPAES_CAPABLE) 544238405Sjkim { 545238405Sjkim ret = vpaes_set_encrypt_key(key,ctx->key_len*8,&dat->ks); 546238405Sjkim dat->block = (block128_f)vpaes_encrypt; 547238405Sjkim dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ? 548238405Sjkim (cbc128_f)vpaes_cbc_encrypt : 549238405Sjkim NULL; 550238405Sjkim } 551238405Sjkim else 552238405Sjkim#endif 553238405Sjkim { 554238405Sjkim ret = AES_set_encrypt_key(key,ctx->key_len*8,&dat->ks); 555238405Sjkim dat->block = (block128_f)AES_encrypt; 556238405Sjkim dat->stream.cbc = mode==EVP_CIPH_CBC_MODE ? 557238405Sjkim (cbc128_f)AES_cbc_encrypt : 558238405Sjkim NULL; 559238405Sjkim#ifdef AES_CTR_ASM 560238405Sjkim if (mode==EVP_CIPH_CTR_MODE) 561238405Sjkim dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt; 562238405Sjkim#endif 563238405Sjkim } 564109998Smarkm 565142425Snectar if(ret < 0) 566142425Snectar { 567142425Snectar EVPerr(EVP_F_AES_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED); 568142425Snectar return 0; 569142425Snectar } 570142425Snectar 571109998Smarkm return 1; 572142425Snectar } 573109998Smarkm 574238405Sjkimstatic int aes_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 575238405Sjkim const unsigned char *in, size_t len) 576238405Sjkim{ 577238405Sjkim EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; 578238405Sjkim 579238405Sjkim if (dat->stream.cbc) 580238405Sjkim (*dat->stream.cbc)(in,out,len,&dat->ks,ctx->iv,ctx->encrypt); 581238405Sjkim else if (ctx->encrypt) 582238405Sjkim CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block); 583238405Sjkim else 584238405Sjkim CRYPTO_cbc128_encrypt(in,out,len,&dat->ks,ctx->iv,dat->block); 585238405Sjkim 586238405Sjkim return 1; 587238405Sjkim} 588238405Sjkim 589238405Sjkimstatic int aes_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 590238405Sjkim const unsigned char *in, size_t len) 591238405Sjkim{ 592238405Sjkim size_t bl = ctx->cipher->block_size; 593238405Sjkim size_t i; 594238405Sjkim EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; 595238405Sjkim 596238405Sjkim if (len<bl) return 1; 597238405Sjkim 598238405Sjkim for (i=0,len-=bl;i<=len;i+=bl) 599238405Sjkim (*dat->block)(in+i,out+i,&dat->ks); 600238405Sjkim 601238405Sjkim return 1; 602238405Sjkim} 603238405Sjkim 604238405Sjkimstatic int aes_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 605238405Sjkim const unsigned char *in,size_t len) 606238405Sjkim{ 607238405Sjkim EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; 608238405Sjkim 609238405Sjkim CRYPTO_ofb128_encrypt(in,out,len,&dat->ks, 610238405Sjkim ctx->iv,&ctx->num,dat->block); 611238405Sjkim return 1; 612238405Sjkim} 613238405Sjkim 614238405Sjkimstatic int aes_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 615238405Sjkim const unsigned char *in,size_t len) 616238405Sjkim{ 617238405Sjkim EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; 618238405Sjkim 619238405Sjkim CRYPTO_cfb128_encrypt(in,out,len,&dat->ks, 620238405Sjkim ctx->iv,&ctx->num,ctx->encrypt,dat->block); 621238405Sjkim return 1; 622238405Sjkim} 623238405Sjkim 624238405Sjkimstatic int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 625238405Sjkim const unsigned char *in,size_t len) 626238405Sjkim{ 627238405Sjkim EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; 628238405Sjkim 629238405Sjkim CRYPTO_cfb128_8_encrypt(in,out,len,&dat->ks, 630238405Sjkim ctx->iv,&ctx->num,ctx->encrypt,dat->block); 631238405Sjkim return 1; 632238405Sjkim} 633238405Sjkim 634238405Sjkimstatic int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out, 635238405Sjkim const unsigned char *in,size_t len) 636238405Sjkim{ 637238405Sjkim EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; 638238405Sjkim 639238405Sjkim if (ctx->flags&EVP_CIPH_FLAG_LENGTH_BITS) { 640238405Sjkim CRYPTO_cfb128_1_encrypt(in,out,len,&dat->ks, 641238405Sjkim ctx->iv,&ctx->num,ctx->encrypt,dat->block); 642238405Sjkim return 1; 643238405Sjkim } 644238405Sjkim 645238405Sjkim while (len>=MAXBITCHUNK) { 646238405Sjkim CRYPTO_cfb128_1_encrypt(in,out,MAXBITCHUNK*8,&dat->ks, 647238405Sjkim ctx->iv,&ctx->num,ctx->encrypt,dat->block); 648238405Sjkim len-=MAXBITCHUNK; 649238405Sjkim } 650238405Sjkim if (len) 651238405Sjkim CRYPTO_cfb128_1_encrypt(in,out,len*8,&dat->ks, 652238405Sjkim ctx->iv,&ctx->num,ctx->encrypt,dat->block); 653238405Sjkim 654238405Sjkim return 1; 655238405Sjkim} 656238405Sjkim 657238405Sjkimstatic int aes_ctr_cipher (EVP_CIPHER_CTX *ctx, unsigned char *out, 658238405Sjkim const unsigned char *in, size_t len) 659238405Sjkim{ 660238405Sjkim unsigned int num = ctx->num; 661238405Sjkim EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; 662238405Sjkim 663238405Sjkim if (dat->stream.ctr) 664238405Sjkim CRYPTO_ctr128_encrypt_ctr32(in,out,len,&dat->ks, 665238405Sjkim ctx->iv,ctx->buf,&num,dat->stream.ctr); 666238405Sjkim else 667238405Sjkim CRYPTO_ctr128_encrypt(in,out,len,&dat->ks, 668238405Sjkim ctx->iv,ctx->buf,&num,dat->block); 669238405Sjkim ctx->num = (size_t)num; 670238405Sjkim return 1; 671238405Sjkim} 672238405Sjkim 673238405SjkimBLOCK_CIPHER_generic_pack(NID_aes,128,EVP_CIPH_FLAG_FIPS) 674238405SjkimBLOCK_CIPHER_generic_pack(NID_aes,192,EVP_CIPH_FLAG_FIPS) 675238405SjkimBLOCK_CIPHER_generic_pack(NID_aes,256,EVP_CIPH_FLAG_FIPS) 676238405Sjkim 677238405Sjkimstatic int aes_gcm_cleanup(EVP_CIPHER_CTX *c) 678238405Sjkim { 679238405Sjkim EVP_AES_GCM_CTX *gctx = c->cipher_data; 680238405Sjkim OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); 681238405Sjkim if (gctx->iv != c->iv) 682238405Sjkim OPENSSL_free(gctx->iv); 683238405Sjkim return 1; 684238405Sjkim } 685238405Sjkim 686238405Sjkim/* increment counter (64-bit int) by 1 */ 687238405Sjkimstatic void ctr64_inc(unsigned char *counter) { 688238405Sjkim int n=8; 689238405Sjkim unsigned char c; 690238405Sjkim 691238405Sjkim do { 692238405Sjkim --n; 693238405Sjkim c = counter[n]; 694238405Sjkim ++c; 695238405Sjkim counter[n] = c; 696238405Sjkim if (c) return; 697238405Sjkim } while (n); 698238405Sjkim} 699238405Sjkim 700238405Sjkimstatic int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 701238405Sjkim { 702238405Sjkim EVP_AES_GCM_CTX *gctx = c->cipher_data; 703238405Sjkim switch (type) 704238405Sjkim { 705238405Sjkim case EVP_CTRL_INIT: 706238405Sjkim gctx->key_set = 0; 707238405Sjkim gctx->iv_set = 0; 708238405Sjkim gctx->ivlen = c->cipher->iv_len; 709238405Sjkim gctx->iv = c->iv; 710238405Sjkim gctx->taglen = -1; 711238405Sjkim gctx->iv_gen = 0; 712238405Sjkim gctx->tls_aad_len = -1; 713238405Sjkim return 1; 714238405Sjkim 715238405Sjkim case EVP_CTRL_GCM_SET_IVLEN: 716238405Sjkim if (arg <= 0) 717238405Sjkim return 0; 718238405Sjkim#ifdef OPENSSL_FIPS 719238405Sjkim if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) 720238405Sjkim && arg < 12) 721238405Sjkim return 0; 722109998Smarkm#endif 723238405Sjkim /* Allocate memory for IV if needed */ 724238405Sjkim if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) 725238405Sjkim { 726238405Sjkim if (gctx->iv != c->iv) 727238405Sjkim OPENSSL_free(gctx->iv); 728238405Sjkim gctx->iv = OPENSSL_malloc(arg); 729238405Sjkim if (!gctx->iv) 730238405Sjkim return 0; 731238405Sjkim } 732238405Sjkim gctx->ivlen = arg; 733238405Sjkim return 1; 734238405Sjkim 735238405Sjkim case EVP_CTRL_GCM_SET_TAG: 736238405Sjkim if (arg <= 0 || arg > 16 || c->encrypt) 737238405Sjkim return 0; 738238405Sjkim memcpy(c->buf, ptr, arg); 739238405Sjkim gctx->taglen = arg; 740238405Sjkim return 1; 741238405Sjkim 742238405Sjkim case EVP_CTRL_GCM_GET_TAG: 743238405Sjkim if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) 744238405Sjkim return 0; 745238405Sjkim memcpy(ptr, c->buf, arg); 746238405Sjkim return 1; 747238405Sjkim 748238405Sjkim case EVP_CTRL_GCM_SET_IV_FIXED: 749238405Sjkim /* Special case: -1 length restores whole IV */ 750238405Sjkim if (arg == -1) 751238405Sjkim { 752238405Sjkim memcpy(gctx->iv, ptr, gctx->ivlen); 753238405Sjkim gctx->iv_gen = 1; 754238405Sjkim return 1; 755238405Sjkim } 756238405Sjkim /* Fixed field must be at least 4 bytes and invocation field 757238405Sjkim * at least 8. 758238405Sjkim */ 759238405Sjkim if ((arg < 4) || (gctx->ivlen - arg) < 8) 760238405Sjkim return 0; 761238405Sjkim if (arg) 762238405Sjkim memcpy(gctx->iv, ptr, arg); 763238405Sjkim if (c->encrypt && 764238405Sjkim RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) 765238405Sjkim return 0; 766238405Sjkim gctx->iv_gen = 1; 767238405Sjkim return 1; 768238405Sjkim 769238405Sjkim case EVP_CTRL_GCM_IV_GEN: 770238405Sjkim if (gctx->iv_gen == 0 || gctx->key_set == 0) 771238405Sjkim return 0; 772238405Sjkim CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); 773238405Sjkim if (arg <= 0 || arg > gctx->ivlen) 774238405Sjkim arg = gctx->ivlen; 775238405Sjkim memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); 776238405Sjkim /* Invocation field will be at least 8 bytes in size and 777238405Sjkim * so no need to check wrap around or increment more than 778238405Sjkim * last 8 bytes. 779238405Sjkim */ 780238405Sjkim ctr64_inc(gctx->iv + gctx->ivlen - 8); 781238405Sjkim gctx->iv_set = 1; 782238405Sjkim return 1; 783238405Sjkim 784238405Sjkim case EVP_CTRL_GCM_SET_IV_INV: 785238405Sjkim if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) 786238405Sjkim return 0; 787238405Sjkim memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); 788238405Sjkim CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); 789238405Sjkim gctx->iv_set = 1; 790238405Sjkim return 1; 791238405Sjkim 792238405Sjkim case EVP_CTRL_AEAD_TLS1_AAD: 793238405Sjkim /* Save the AAD for later use */ 794238405Sjkim if (arg != 13) 795238405Sjkim return 0; 796238405Sjkim memcpy(c->buf, ptr, arg); 797238405Sjkim gctx->tls_aad_len = arg; 798238405Sjkim { 799238405Sjkim unsigned int len=c->buf[arg-2]<<8|c->buf[arg-1]; 800238405Sjkim /* Correct length for explicit IV */ 801238405Sjkim len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; 802238405Sjkim /* If decrypting correct for tag too */ 803238405Sjkim if (!c->encrypt) 804238405Sjkim len -= EVP_GCM_TLS_TAG_LEN; 805238405Sjkim c->buf[arg-2] = len>>8; 806238405Sjkim c->buf[arg-1] = len & 0xff; 807238405Sjkim } 808238405Sjkim /* Extra padding: tag appended to record */ 809238405Sjkim return EVP_GCM_TLS_TAG_LEN; 810238405Sjkim 811279264Sdelphij case EVP_CTRL_COPY: 812279264Sdelphij { 813279264Sdelphij EVP_CIPHER_CTX *out = ptr; 814279264Sdelphij EVP_AES_GCM_CTX *gctx_out = out->cipher_data; 815279264Sdelphij if (gctx->gcm.key) 816279264Sdelphij { 817279264Sdelphij if (gctx->gcm.key != &gctx->ks) 818279264Sdelphij return 0; 819279264Sdelphij gctx_out->gcm.key = &gctx_out->ks; 820279264Sdelphij } 821279264Sdelphij if (gctx->iv == c->iv) 822279264Sdelphij gctx_out->iv = out->iv; 823279264Sdelphij else 824279264Sdelphij { 825279264Sdelphij gctx_out->iv = OPENSSL_malloc(gctx->ivlen); 826279264Sdelphij if (!gctx_out->iv) 827279264Sdelphij return 0; 828279264Sdelphij memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); 829279264Sdelphij } 830279264Sdelphij return 1; 831279264Sdelphij } 832279264Sdelphij 833238405Sjkim default: 834238405Sjkim return -1; 835238405Sjkim 836238405Sjkim } 837238405Sjkim } 838238405Sjkim 839238405Sjkimstatic int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 840238405Sjkim const unsigned char *iv, int enc) 841238405Sjkim { 842238405Sjkim EVP_AES_GCM_CTX *gctx = ctx->cipher_data; 843238405Sjkim if (!iv && !key) 844238405Sjkim return 1; 845238405Sjkim if (key) 846238405Sjkim { do { 847238405Sjkim#ifdef BSAES_CAPABLE 848238405Sjkim if (BSAES_CAPABLE) 849238405Sjkim { 850238405Sjkim AES_set_encrypt_key(key,ctx->key_len*8,&gctx->ks); 851238405Sjkim CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks, 852238405Sjkim (block128_f)AES_encrypt); 853238405Sjkim gctx->ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks; 854238405Sjkim break; 855238405Sjkim } 856238405Sjkim else 857238405Sjkim#endif 858238405Sjkim#ifdef VPAES_CAPABLE 859238405Sjkim if (VPAES_CAPABLE) 860238405Sjkim { 861238405Sjkim vpaes_set_encrypt_key(key,ctx->key_len*8,&gctx->ks); 862238405Sjkim CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks, 863238405Sjkim (block128_f)vpaes_encrypt); 864238405Sjkim gctx->ctr = NULL; 865238405Sjkim break; 866238405Sjkim } 867279264Sdelphij else 868238405Sjkim#endif 869279264Sdelphij (void)0; /* terminate potentially open 'else' */ 870279264Sdelphij 871238405Sjkim AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); 872238405Sjkim CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)AES_encrypt); 873238405Sjkim#ifdef AES_CTR_ASM 874238405Sjkim gctx->ctr = (ctr128_f)AES_ctr32_encrypt; 875238405Sjkim#else 876238405Sjkim gctx->ctr = NULL; 877238405Sjkim#endif 878238405Sjkim } while (0); 879238405Sjkim 880238405Sjkim /* If we have an iv can set it directly, otherwise use 881238405Sjkim * saved IV. 882238405Sjkim */ 883238405Sjkim if (iv == NULL && gctx->iv_set) 884238405Sjkim iv = gctx->iv; 885238405Sjkim if (iv) 886238405Sjkim { 887238405Sjkim CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); 888238405Sjkim gctx->iv_set = 1; 889238405Sjkim } 890238405Sjkim gctx->key_set = 1; 891238405Sjkim } 892238405Sjkim else 893238405Sjkim { 894238405Sjkim /* If key set use IV, otherwise copy */ 895238405Sjkim if (gctx->key_set) 896238405Sjkim CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); 897238405Sjkim else 898238405Sjkim memcpy(gctx->iv, iv, gctx->ivlen); 899238405Sjkim gctx->iv_set = 1; 900238405Sjkim gctx->iv_gen = 0; 901238405Sjkim } 902238405Sjkim return 1; 903238405Sjkim } 904238405Sjkim 905238405Sjkim/* Handle TLS GCM packet format. This consists of the last portion of the IV 906238405Sjkim * followed by the payload and finally the tag. On encrypt generate IV, 907238405Sjkim * encrypt payload and write the tag. On verify retrieve IV, decrypt payload 908238405Sjkim * and verify tag. 909238405Sjkim */ 910238405Sjkim 911238405Sjkimstatic int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 912238405Sjkim const unsigned char *in, size_t len) 913238405Sjkim { 914238405Sjkim EVP_AES_GCM_CTX *gctx = ctx->cipher_data; 915238405Sjkim int rv = -1; 916238405Sjkim /* Encrypt/decrypt must be performed in place */ 917238405Sjkim if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN+EVP_GCM_TLS_TAG_LEN)) 918238405Sjkim return -1; 919238405Sjkim /* Set IV from start of buffer or generate IV and write to start 920238405Sjkim * of buffer. 921238405Sjkim */ 922238405Sjkim if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ? 923238405Sjkim EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, 924238405Sjkim EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) 925238405Sjkim goto err; 926238405Sjkim /* Use saved AAD */ 927238405Sjkim if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len)) 928238405Sjkim goto err; 929238405Sjkim /* Fix buffer and length to point to payload */ 930238405Sjkim in += EVP_GCM_TLS_EXPLICIT_IV_LEN; 931238405Sjkim out += EVP_GCM_TLS_EXPLICIT_IV_LEN; 932238405Sjkim len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; 933238405Sjkim if (ctx->encrypt) 934238405Sjkim { 935238405Sjkim /* Encrypt payload */ 936238405Sjkim if (gctx->ctr) 937238405Sjkim { 938238405Sjkim if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, 939238405Sjkim in, out, len, 940238405Sjkim gctx->ctr)) 941238405Sjkim goto err; 942238405Sjkim } 943238405Sjkim else { 944238405Sjkim if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) 945238405Sjkim goto err; 946238405Sjkim } 947238405Sjkim out += len; 948238405Sjkim /* Finally write tag */ 949238405Sjkim CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); 950238405Sjkim rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; 951238405Sjkim } 952238405Sjkim else 953238405Sjkim { 954238405Sjkim /* Decrypt */ 955238405Sjkim if (gctx->ctr) 956238405Sjkim { 957238405Sjkim if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, 958238405Sjkim in, out, len, 959238405Sjkim gctx->ctr)) 960238405Sjkim goto err; 961238405Sjkim } 962238405Sjkim else { 963238405Sjkim if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) 964238405Sjkim goto err; 965238405Sjkim } 966238405Sjkim /* Retrieve tag */ 967238405Sjkim CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 968238405Sjkim EVP_GCM_TLS_TAG_LEN); 969238405Sjkim /* If tag mismatch wipe buffer */ 970238405Sjkim if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) 971238405Sjkim { 972238405Sjkim OPENSSL_cleanse(out, len); 973238405Sjkim goto err; 974238405Sjkim } 975238405Sjkim rv = len; 976238405Sjkim } 977238405Sjkim 978238405Sjkim err: 979238405Sjkim gctx->iv_set = 0; 980238405Sjkim gctx->tls_aad_len = -1; 981238405Sjkim return rv; 982238405Sjkim } 983238405Sjkim 984238405Sjkimstatic int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 985238405Sjkim const unsigned char *in, size_t len) 986238405Sjkim { 987238405Sjkim EVP_AES_GCM_CTX *gctx = ctx->cipher_data; 988238405Sjkim /* If not set up, return error */ 989238405Sjkim if (!gctx->key_set) 990238405Sjkim return -1; 991238405Sjkim 992238405Sjkim if (gctx->tls_aad_len >= 0) 993238405Sjkim return aes_gcm_tls_cipher(ctx, out, in, len); 994238405Sjkim 995238405Sjkim if (!gctx->iv_set) 996238405Sjkim return -1; 997238405Sjkim if (in) 998238405Sjkim { 999238405Sjkim if (out == NULL) 1000238405Sjkim { 1001238405Sjkim if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) 1002238405Sjkim return -1; 1003238405Sjkim } 1004238405Sjkim else if (ctx->encrypt) 1005238405Sjkim { 1006238405Sjkim if (gctx->ctr) 1007238405Sjkim { 1008238405Sjkim if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, 1009238405Sjkim in, out, len, 1010238405Sjkim gctx->ctr)) 1011238405Sjkim return -1; 1012238405Sjkim } 1013238405Sjkim else { 1014238405Sjkim if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) 1015238405Sjkim return -1; 1016238405Sjkim } 1017238405Sjkim } 1018238405Sjkim else 1019238405Sjkim { 1020238405Sjkim if (gctx->ctr) 1021238405Sjkim { 1022238405Sjkim if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, 1023238405Sjkim in, out, len, 1024238405Sjkim gctx->ctr)) 1025238405Sjkim return -1; 1026238405Sjkim } 1027238405Sjkim else { 1028238405Sjkim if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) 1029238405Sjkim return -1; 1030238405Sjkim } 1031238405Sjkim } 1032238405Sjkim return len; 1033238405Sjkim } 1034238405Sjkim else 1035238405Sjkim { 1036238405Sjkim if (!ctx->encrypt) 1037238405Sjkim { 1038246772Sjkim if (gctx->taglen < 0) 1039246772Sjkim return -1; 1040238405Sjkim if (CRYPTO_gcm128_finish(&gctx->gcm, 1041238405Sjkim ctx->buf, gctx->taglen) != 0) 1042238405Sjkim return -1; 1043238405Sjkim gctx->iv_set = 0; 1044238405Sjkim return 0; 1045238405Sjkim } 1046238405Sjkim CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16); 1047238405Sjkim gctx->taglen = 16; 1048238405Sjkim /* Don't reuse the IV */ 1049238405Sjkim gctx->iv_set = 0; 1050238405Sjkim return 0; 1051238405Sjkim } 1052238405Sjkim 1053238405Sjkim } 1054238405Sjkim 1055238405Sjkim#define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \ 1056238405Sjkim | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ 1057279264Sdelphij | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ 1058279264Sdelphij | EVP_CIPH_CUSTOM_COPY) 1059238405Sjkim 1060238405SjkimBLOCK_CIPHER_custom(NID_aes,128,1,12,gcm,GCM, 1061238405Sjkim EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS) 1062238405SjkimBLOCK_CIPHER_custom(NID_aes,192,1,12,gcm,GCM, 1063238405Sjkim EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS) 1064238405SjkimBLOCK_CIPHER_custom(NID_aes,256,1,12,gcm,GCM, 1065238405Sjkim EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS) 1066238405Sjkim 1067238405Sjkimstatic int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 1068238405Sjkim { 1069238405Sjkim EVP_AES_XTS_CTX *xctx = c->cipher_data; 1070279264Sdelphij if (type == EVP_CTRL_COPY) 1071279264Sdelphij { 1072279264Sdelphij EVP_CIPHER_CTX *out = ptr; 1073279264Sdelphij EVP_AES_XTS_CTX *xctx_out = out->cipher_data; 1074279264Sdelphij if (xctx->xts.key1) 1075279264Sdelphij { 1076279264Sdelphij if (xctx->xts.key1 != &xctx->ks1) 1077279264Sdelphij return 0; 1078279264Sdelphij xctx_out->xts.key1 = &xctx_out->ks1; 1079279264Sdelphij } 1080279264Sdelphij if (xctx->xts.key2) 1081279264Sdelphij { 1082279264Sdelphij if (xctx->xts.key2 != &xctx->ks2) 1083279264Sdelphij return 0; 1084279264Sdelphij xctx_out->xts.key2 = &xctx_out->ks2; 1085279264Sdelphij } 1086279264Sdelphij return 1; 1087279264Sdelphij } 1088279264Sdelphij else if (type != EVP_CTRL_INIT) 1089238405Sjkim return -1; 1090238405Sjkim /* key1 and key2 are used as an indicator both key and IV are set */ 1091238405Sjkim xctx->xts.key1 = NULL; 1092238405Sjkim xctx->xts.key2 = NULL; 1093238405Sjkim return 1; 1094238405Sjkim } 1095238405Sjkim 1096238405Sjkimstatic int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 1097238405Sjkim const unsigned char *iv, int enc) 1098238405Sjkim { 1099238405Sjkim EVP_AES_XTS_CTX *xctx = ctx->cipher_data; 1100238405Sjkim if (!iv && !key) 1101238405Sjkim return 1; 1102238405Sjkim 1103238405Sjkim if (key) do 1104238405Sjkim { 1105238405Sjkim#ifdef AES_XTS_ASM 1106238405Sjkim xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt; 1107238405Sjkim#else 1108238405Sjkim xctx->stream = NULL; 1109238405Sjkim#endif 1110238405Sjkim /* key_len is two AES keys */ 1111238405Sjkim#ifdef BSAES_CAPABLE 1112238405Sjkim if (BSAES_CAPABLE) 1113238405Sjkim xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt; 1114238405Sjkim else 1115238405Sjkim#endif 1116238405Sjkim#ifdef VPAES_CAPABLE 1117238405Sjkim if (VPAES_CAPABLE) 1118238405Sjkim { 1119238405Sjkim if (enc) 1120238405Sjkim { 1121238405Sjkim vpaes_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1); 1122238405Sjkim xctx->xts.block1 = (block128_f)vpaes_encrypt; 1123238405Sjkim } 1124238405Sjkim else 1125238405Sjkim { 1126238405Sjkim vpaes_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1); 1127238405Sjkim xctx->xts.block1 = (block128_f)vpaes_decrypt; 1128238405Sjkim } 1129238405Sjkim 1130279264Sdelphij vpaes_set_encrypt_key(key + ctx->key_len/2, 1131238405Sjkim ctx->key_len * 4, &xctx->ks2); 1132279264Sdelphij xctx->xts.block2 = (block128_f)vpaes_encrypt; 1133238405Sjkim 1134279264Sdelphij xctx->xts.key1 = &xctx->ks1; 1135279264Sdelphij break; 1136279264Sdelphij } 1137279264Sdelphij else 1138238405Sjkim#endif 1139279264Sdelphij (void)0; /* terminate potentially open 'else' */ 1140279264Sdelphij 1141238405Sjkim if (enc) 1142238405Sjkim { 1143238405Sjkim AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1); 1144238405Sjkim xctx->xts.block1 = (block128_f)AES_encrypt; 1145238405Sjkim } 1146238405Sjkim else 1147238405Sjkim { 1148238405Sjkim AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1); 1149238405Sjkim xctx->xts.block1 = (block128_f)AES_decrypt; 1150238405Sjkim } 1151238405Sjkim 1152238405Sjkim AES_set_encrypt_key(key + ctx->key_len/2, 1153238405Sjkim ctx->key_len * 4, &xctx->ks2); 1154238405Sjkim xctx->xts.block2 = (block128_f)AES_encrypt; 1155238405Sjkim 1156238405Sjkim xctx->xts.key1 = &xctx->ks1; 1157238405Sjkim } while (0); 1158238405Sjkim 1159238405Sjkim if (iv) 1160238405Sjkim { 1161238405Sjkim xctx->xts.key2 = &xctx->ks2; 1162238405Sjkim memcpy(ctx->iv, iv, 16); 1163238405Sjkim } 1164238405Sjkim 1165238405Sjkim return 1; 1166238405Sjkim } 1167238405Sjkim 1168238405Sjkimstatic int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 1169238405Sjkim const unsigned char *in, size_t len) 1170238405Sjkim { 1171238405Sjkim EVP_AES_XTS_CTX *xctx = ctx->cipher_data; 1172238405Sjkim if (!xctx->xts.key1 || !xctx->xts.key2) 1173238405Sjkim return 0; 1174238405Sjkim if (!out || !in || len<AES_BLOCK_SIZE) 1175238405Sjkim return 0; 1176238405Sjkim#ifdef OPENSSL_FIPS 1177238405Sjkim /* Requirement of SP800-38E */ 1178238405Sjkim if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && 1179238405Sjkim (len > (1UL<<20)*16)) 1180238405Sjkim { 1181238405Sjkim EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE); 1182238405Sjkim return 0; 1183238405Sjkim } 1184238405Sjkim#endif 1185238405Sjkim if (xctx->stream) 1186238405Sjkim (*xctx->stream)(in, out, len, 1187238405Sjkim xctx->xts.key1, xctx->xts.key2, ctx->iv); 1188238405Sjkim else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, 1189238405Sjkim ctx->encrypt)) 1190238405Sjkim return 0; 1191238405Sjkim return 1; 1192238405Sjkim } 1193238405Sjkim 1194238405Sjkim#define aes_xts_cleanup NULL 1195238405Sjkim 1196238405Sjkim#define XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \ 1197279264Sdelphij | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ 1198279264Sdelphij | EVP_CIPH_CUSTOM_COPY) 1199238405Sjkim 1200238405SjkimBLOCK_CIPHER_custom(NID_aes,128,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS) 1201238405SjkimBLOCK_CIPHER_custom(NID_aes,256,1,16,xts,XTS,EVP_CIPH_FLAG_FIPS|XTS_FLAGS) 1202238405Sjkim 1203238405Sjkimstatic int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 1204238405Sjkim { 1205238405Sjkim EVP_AES_CCM_CTX *cctx = c->cipher_data; 1206238405Sjkim switch (type) 1207238405Sjkim { 1208238405Sjkim case EVP_CTRL_INIT: 1209238405Sjkim cctx->key_set = 0; 1210238405Sjkim cctx->iv_set = 0; 1211238405Sjkim cctx->L = 8; 1212238405Sjkim cctx->M = 12; 1213238405Sjkim cctx->tag_set = 0; 1214238405Sjkim cctx->len_set = 0; 1215238405Sjkim return 1; 1216238405Sjkim 1217238405Sjkim case EVP_CTRL_CCM_SET_IVLEN: 1218238405Sjkim arg = 15 - arg; 1219238405Sjkim case EVP_CTRL_CCM_SET_L: 1220238405Sjkim if (arg < 2 || arg > 8) 1221238405Sjkim return 0; 1222238405Sjkim cctx->L = arg; 1223238405Sjkim return 1; 1224238405Sjkim 1225238405Sjkim case EVP_CTRL_CCM_SET_TAG: 1226238405Sjkim if ((arg & 1) || arg < 4 || arg > 16) 1227238405Sjkim return 0; 1228238405Sjkim if ((c->encrypt && ptr) || (!c->encrypt && !ptr)) 1229238405Sjkim return 0; 1230238405Sjkim if (ptr) 1231238405Sjkim { 1232238405Sjkim cctx->tag_set = 1; 1233238405Sjkim memcpy(c->buf, ptr, arg); 1234238405Sjkim } 1235238405Sjkim cctx->M = arg; 1236238405Sjkim return 1; 1237238405Sjkim 1238238405Sjkim case EVP_CTRL_CCM_GET_TAG: 1239238405Sjkim if (!c->encrypt || !cctx->tag_set) 1240238405Sjkim return 0; 1241238405Sjkim if(!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg)) 1242238405Sjkim return 0; 1243238405Sjkim cctx->tag_set = 0; 1244238405Sjkim cctx->iv_set = 0; 1245238405Sjkim cctx->len_set = 0; 1246238405Sjkim return 1; 1247238405Sjkim 1248279264Sdelphij case EVP_CTRL_COPY: 1249279264Sdelphij { 1250279264Sdelphij EVP_CIPHER_CTX *out = ptr; 1251279264Sdelphij EVP_AES_CCM_CTX *cctx_out = out->cipher_data; 1252279264Sdelphij if (cctx->ccm.key) 1253279264Sdelphij { 1254279264Sdelphij if (cctx->ccm.key != &cctx->ks) 1255279264Sdelphij return 0; 1256279264Sdelphij cctx_out->ccm.key = &cctx_out->ks; 1257279264Sdelphij } 1258279264Sdelphij return 1; 1259279264Sdelphij } 1260279264Sdelphij 1261238405Sjkim default: 1262238405Sjkim return -1; 1263238405Sjkim 1264238405Sjkim } 1265238405Sjkim } 1266238405Sjkim 1267238405Sjkimstatic int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 1268238405Sjkim const unsigned char *iv, int enc) 1269238405Sjkim { 1270238405Sjkim EVP_AES_CCM_CTX *cctx = ctx->cipher_data; 1271238405Sjkim if (!iv && !key) 1272238405Sjkim return 1; 1273238405Sjkim if (key) do 1274238405Sjkim { 1275238405Sjkim#ifdef VPAES_CAPABLE 1276238405Sjkim if (VPAES_CAPABLE) 1277238405Sjkim { 1278238405Sjkim vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks); 1279238405Sjkim CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, 1280238405Sjkim &cctx->ks, (block128_f)vpaes_encrypt); 1281246772Sjkim cctx->str = NULL; 1282238405Sjkim cctx->key_set = 1; 1283238405Sjkim break; 1284238405Sjkim } 1285238405Sjkim#endif 1286238405Sjkim AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks); 1287238405Sjkim CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, 1288238405Sjkim &cctx->ks, (block128_f)AES_encrypt); 1289238405Sjkim cctx->str = NULL; 1290238405Sjkim cctx->key_set = 1; 1291238405Sjkim } while (0); 1292238405Sjkim if (iv) 1293238405Sjkim { 1294238405Sjkim memcpy(ctx->iv, iv, 15 - cctx->L); 1295238405Sjkim cctx->iv_set = 1; 1296238405Sjkim } 1297238405Sjkim return 1; 1298238405Sjkim } 1299238405Sjkim 1300238405Sjkimstatic int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 1301238405Sjkim const unsigned char *in, size_t len) 1302238405Sjkim { 1303238405Sjkim EVP_AES_CCM_CTX *cctx = ctx->cipher_data; 1304238405Sjkim CCM128_CONTEXT *ccm = &cctx->ccm; 1305238405Sjkim /* If not set up, return error */ 1306238405Sjkim if (!cctx->iv_set && !cctx->key_set) 1307238405Sjkim return -1; 1308238405Sjkim if (!ctx->encrypt && !cctx->tag_set) 1309238405Sjkim return -1; 1310238405Sjkim if (!out) 1311238405Sjkim { 1312238405Sjkim if (!in) 1313238405Sjkim { 1314238405Sjkim if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L,len)) 1315238405Sjkim return -1; 1316238405Sjkim cctx->len_set = 1; 1317238405Sjkim return len; 1318238405Sjkim } 1319238405Sjkim /* If have AAD need message length */ 1320238405Sjkim if (!cctx->len_set && len) 1321238405Sjkim return -1; 1322238405Sjkim CRYPTO_ccm128_aad(ccm, in, len); 1323238405Sjkim return len; 1324238405Sjkim } 1325238405Sjkim /* EVP_*Final() doesn't return any data */ 1326238405Sjkim if (!in) 1327238405Sjkim return 0; 1328238405Sjkim /* If not set length yet do it */ 1329238405Sjkim if (!cctx->len_set) 1330238405Sjkim { 1331238405Sjkim if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) 1332238405Sjkim return -1; 1333238405Sjkim cctx->len_set = 1; 1334238405Sjkim } 1335238405Sjkim if (ctx->encrypt) 1336238405Sjkim { 1337238405Sjkim if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, 1338238405Sjkim cctx->str) : 1339238405Sjkim CRYPTO_ccm128_encrypt(ccm, in, out, len)) 1340238405Sjkim return -1; 1341238405Sjkim cctx->tag_set = 1; 1342238405Sjkim return len; 1343238405Sjkim } 1344238405Sjkim else 1345238405Sjkim { 1346238405Sjkim int rv = -1; 1347238405Sjkim if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, 1348238405Sjkim cctx->str) : 1349238405Sjkim !CRYPTO_ccm128_decrypt(ccm, in, out, len)) 1350238405Sjkim { 1351238405Sjkim unsigned char tag[16]; 1352238405Sjkim if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) 1353238405Sjkim { 1354238405Sjkim if (!memcmp(tag, ctx->buf, cctx->M)) 1355238405Sjkim rv = len; 1356238405Sjkim } 1357238405Sjkim } 1358238405Sjkim if (rv == -1) 1359238405Sjkim OPENSSL_cleanse(out, len); 1360238405Sjkim cctx->iv_set = 0; 1361238405Sjkim cctx->tag_set = 0; 1362238405Sjkim cctx->len_set = 0; 1363238405Sjkim return rv; 1364238405Sjkim } 1365238405Sjkim 1366238405Sjkim } 1367238405Sjkim 1368238405Sjkim#define aes_ccm_cleanup NULL 1369238405Sjkim 1370238405SjkimBLOCK_CIPHER_custom(NID_aes,128,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) 1371238405SjkimBLOCK_CIPHER_custom(NID_aes,192,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) 1372238405SjkimBLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) 1373238405Sjkim 1374238405Sjkim#endif 1375238405Sjkim#endif 1376