1238384Sjkim/* ==================================================================== 2246772Sjkim * Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved. 3238384Sjkim * 4238384Sjkim * Redistribution and use in source and binary forms, with or without 5238384Sjkim * modification, are permitted provided that the following conditions 6238384Sjkim * are met: 7238384Sjkim * 8238384Sjkim * 1. Redistributions of source code must retain the above copyright 9238384Sjkim * notice, this list of conditions and the following disclaimer. 10238384Sjkim * 11238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright 12238384Sjkim * notice, this list of conditions and the following disclaimer in 13238384Sjkim * the documentation and/or other materials provided with the 14238384Sjkim * distribution. 15238384Sjkim * 16238384Sjkim * 3. All advertising materials mentioning features or use of this 17238384Sjkim * software must display the following acknowledgment: 18238384Sjkim * "This product includes software developed by the OpenSSL Project 19238384Sjkim * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 20238384Sjkim * 21238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22238384Sjkim * endorse or promote products derived from this software without 23238384Sjkim * prior written permission. For written permission, please contact 24238384Sjkim * licensing@OpenSSL.org. 25238384Sjkim * 26238384Sjkim * 5. Products derived from this software may not be called "OpenSSL" 27238384Sjkim * nor may "OpenSSL" appear in their names without prior written 28238384Sjkim * permission of the OpenSSL Project. 29238384Sjkim * 30238384Sjkim * 6. Redistributions of any form whatsoever must retain the following 31238384Sjkim * acknowledgment: 32238384Sjkim * "This product includes software developed by the OpenSSL Project 33238384Sjkim * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 34238384Sjkim * 35238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38238384Sjkim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE. 47238384Sjkim * ==================================================================== 48238384Sjkim */ 49238384Sjkim 50238384Sjkim#include <openssl/opensslconf.h> 51238384Sjkim 52238384Sjkim#include <stdio.h> 53238384Sjkim#include <string.h> 54238384Sjkim 55238384Sjkim#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1) 56238384Sjkim 57280297Sjkim# include <openssl/evp.h> 58280297Sjkim# include <openssl/objects.h> 59280297Sjkim# include <openssl/aes.h> 60280297Sjkim# include <openssl/sha.h> 61290207Sjkim# include <openssl/rand.h> 62290207Sjkim# include "modes_lcl.h" 63298998Sjkim# include "constant_time_locl.h" 64238384Sjkim 65280297Sjkim# ifndef EVP_CIPH_FLAG_AEAD_CIPHER 66280297Sjkim# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 67280297Sjkim# define EVP_CTRL_AEAD_TLS1_AAD 0x16 68280297Sjkim# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 69280297Sjkim# endif 70238384Sjkim 71280297Sjkim# if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1) 72280297Sjkim# define EVP_CIPH_FLAG_DEFAULT_ASN1 0 73280297Sjkim# endif 74238384Sjkim 75290207Sjkim# if !defined(EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) 76290207Sjkim# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 77290207Sjkim# endif 78290207Sjkim 79280297Sjkim# define TLS1_1_VERSION 0x0302 80238384Sjkim 81280297Sjkimtypedef struct { 82280297Sjkim AES_KEY ks; 83280297Sjkim SHA_CTX head, tail, md; 84280297Sjkim size_t payload_length; /* AAD length in decrypt case */ 85238384Sjkim union { 86280297Sjkim unsigned int tls_ver; 87280297Sjkim unsigned char tls_aad[16]; /* 13 used */ 88238384Sjkim } aux; 89280297Sjkim} EVP_AES_HMAC_SHA1; 90238384Sjkim 91280297Sjkim# define NO_PAYLOAD_LENGTH ((size_t)-1) 92238384Sjkim 93280297Sjkim# if defined(AES_ASM) && ( \ 94280297Sjkim defined(__x86_64) || defined(__x86_64__) || \ 95280297Sjkim defined(_M_AMD64) || defined(_M_X64) || \ 96280297Sjkim defined(__INTEL__) ) 97238384Sjkim 98290207Sjkimextern unsigned int OPENSSL_ia32cap_P[]; 99280297Sjkim# define AESNI_CAPABLE (1<<(57-32)) 100238384Sjkim 101238384Sjkimint aesni_set_encrypt_key(const unsigned char *userKey, int bits, 102280297Sjkim AES_KEY *key); 103238384Sjkimint aesni_set_decrypt_key(const unsigned char *userKey, int bits, 104280297Sjkim AES_KEY *key); 105238384Sjkim 106238384Sjkimvoid aesni_cbc_encrypt(const unsigned char *in, 107280297Sjkim unsigned char *out, 108280297Sjkim size_t length, 109280297Sjkim const AES_KEY *key, unsigned char *ivec, int enc); 110238384Sjkim 111280297Sjkimvoid aesni_cbc_sha1_enc(const void *inp, void *out, size_t blocks, 112280297Sjkim const AES_KEY *key, unsigned char iv[16], 113280297Sjkim SHA_CTX *ctx, const void *in0); 114238384Sjkim 115290207Sjkimvoid aesni256_cbc_sha1_dec(const void *inp, void *out, size_t blocks, 116290207Sjkim const AES_KEY *key, unsigned char iv[16], 117290207Sjkim SHA_CTX *ctx, const void *in0); 118290207Sjkim 119280297Sjkim# define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data) 120238384Sjkim 121238384Sjkimstatic int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, 122280297Sjkim const unsigned char *inkey, 123280297Sjkim const unsigned char *iv, int enc) 124280297Sjkim{ 125280297Sjkim EVP_AES_HMAC_SHA1 *key = data(ctx); 126280297Sjkim int ret; 127238384Sjkim 128280297Sjkim if (enc) 129280297Sjkim ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks); 130280297Sjkim else 131280297Sjkim ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks); 132238384Sjkim 133280297Sjkim SHA1_Init(&key->head); /* handy when benchmarking */ 134280297Sjkim key->tail = key->head; 135280297Sjkim key->md = key->head; 136238384Sjkim 137280297Sjkim key->payload_length = NO_PAYLOAD_LENGTH; 138238384Sjkim 139280297Sjkim return ret < 0 ? 0 : 1; 140280297Sjkim} 141238384Sjkim 142280297Sjkim# define STITCHED_CALL 143290207Sjkim# undef STITCHED_DECRYPT_CALL 144238384Sjkim 145280297Sjkim# if !defined(STITCHED_CALL) 146280297Sjkim# define aes_off 0 147280297Sjkim# endif 148238384Sjkim 149280297Sjkimvoid sha1_block_data_order(void *c, const void *p, size_t len); 150238384Sjkim 151280297Sjkimstatic void sha1_update(SHA_CTX *c, const void *data, size_t len) 152280297Sjkim{ 153280297Sjkim const unsigned char *ptr = data; 154280297Sjkim size_t res; 155238384Sjkim 156280297Sjkim if ((res = c->num)) { 157280297Sjkim res = SHA_CBLOCK - res; 158280297Sjkim if (len < res) 159280297Sjkim res = len; 160280297Sjkim SHA1_Update(c, ptr, res); 161280297Sjkim ptr += res; 162280297Sjkim len -= res; 163280297Sjkim } 164238384Sjkim 165280297Sjkim res = len % SHA_CBLOCK; 166280297Sjkim len -= res; 167238384Sjkim 168280297Sjkim if (len) { 169280297Sjkim sha1_block_data_order(c, ptr, len / SHA_CBLOCK); 170238384Sjkim 171280297Sjkim ptr += len; 172280297Sjkim c->Nh += len >> 29; 173280297Sjkim c->Nl += len <<= 3; 174280297Sjkim if (c->Nl < (unsigned int)len) 175280297Sjkim c->Nh++; 176280297Sjkim } 177238384Sjkim 178280297Sjkim if (res) 179280297Sjkim SHA1_Update(c, ptr, res); 180238384Sjkim} 181238384Sjkim 182280297Sjkim# ifdef SHA1_Update 183280297Sjkim# undef SHA1_Update 184280297Sjkim# endif 185280297Sjkim# define SHA1_Update sha1_update 186238384Sjkim 187290207Sjkim# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 188290207Sjkim 189290207Sjkimtypedef struct { 190290207Sjkim unsigned int A[8], B[8], C[8], D[8], E[8]; 191290207Sjkim} SHA1_MB_CTX; 192290207Sjkimtypedef struct { 193290207Sjkim const unsigned char *ptr; 194290207Sjkim int blocks; 195290207Sjkim} HASH_DESC; 196290207Sjkim 197290207Sjkimvoid sha1_multi_block(SHA1_MB_CTX *, const HASH_DESC *, int); 198290207Sjkim 199290207Sjkimtypedef struct { 200290207Sjkim const unsigned char *inp; 201290207Sjkim unsigned char *out; 202290207Sjkim int blocks; 203290207Sjkim u64 iv[2]; 204290207Sjkim} CIPH_DESC; 205290207Sjkim 206290207Sjkimvoid aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int); 207290207Sjkim 208290207Sjkimstatic size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA1 *key, 209290207Sjkim unsigned char *out, 210290207Sjkim const unsigned char *inp, 211290207Sjkim size_t inp_len, int n4x) 212290207Sjkim{ /* n4x is 1 or 2 */ 213290207Sjkim HASH_DESC hash_d[8], edges[8]; 214290207Sjkim CIPH_DESC ciph_d[8]; 215290207Sjkim unsigned char storage[sizeof(SHA1_MB_CTX) + 32]; 216290207Sjkim union { 217290207Sjkim u64 q[16]; 218290207Sjkim u32 d[32]; 219290207Sjkim u8 c[128]; 220290207Sjkim } blocks[8]; 221290207Sjkim SHA1_MB_CTX *ctx; 222290207Sjkim unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed = 223290207Sjkim 0; 224290207Sjkim size_t ret = 0; 225290207Sjkim u8 *IVs; 226290207Sjkim# if defined(BSWAP8) 227290207Sjkim u64 seqnum; 228290207Sjkim# endif 229290207Sjkim 230290207Sjkim /* ask for IVs in bulk */ 231290207Sjkim if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0) 232290207Sjkim return 0; 233290207Sjkim 234290207Sjkim ctx = (SHA1_MB_CTX *) (storage + 32 - ((size_t)storage % 32)); /* align */ 235290207Sjkim 236290207Sjkim frag = (unsigned int)inp_len >> (1 + n4x); 237290207Sjkim last = (unsigned int)inp_len + frag - (frag << (1 + n4x)); 238290207Sjkim if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) { 239290207Sjkim frag++; 240290207Sjkim last -= x4 - 1; 241290207Sjkim } 242290207Sjkim 243290207Sjkim packlen = 5 + 16 + ((frag + 20 + 16) & -16); 244290207Sjkim 245290207Sjkim /* populate descriptors with pointers and IVs */ 246290207Sjkim hash_d[0].ptr = inp; 247290207Sjkim ciph_d[0].inp = inp; 248290207Sjkim /* 5+16 is place for header and explicit IV */ 249290207Sjkim ciph_d[0].out = out + 5 + 16; 250290207Sjkim memcpy(ciph_d[0].out - 16, IVs, 16); 251290207Sjkim memcpy(ciph_d[0].iv, IVs, 16); 252290207Sjkim IVs += 16; 253290207Sjkim 254290207Sjkim for (i = 1; i < x4; i++) { 255290207Sjkim ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag; 256290207Sjkim ciph_d[i].out = ciph_d[i - 1].out + packlen; 257290207Sjkim memcpy(ciph_d[i].out - 16, IVs, 16); 258290207Sjkim memcpy(ciph_d[i].iv, IVs, 16); 259290207Sjkim IVs += 16; 260290207Sjkim } 261290207Sjkim 262290207Sjkim# if defined(BSWAP8) 263290207Sjkim memcpy(blocks[0].c, key->md.data, 8); 264290207Sjkim seqnum = BSWAP8(blocks[0].q[0]); 265290207Sjkim# endif 266290207Sjkim for (i = 0; i < x4; i++) { 267290207Sjkim unsigned int len = (i == (x4 - 1) ? last : frag); 268290207Sjkim# if !defined(BSWAP8) 269290207Sjkim unsigned int carry, j; 270290207Sjkim# endif 271290207Sjkim 272290207Sjkim ctx->A[i] = key->md.h0; 273290207Sjkim ctx->B[i] = key->md.h1; 274290207Sjkim ctx->C[i] = key->md.h2; 275290207Sjkim ctx->D[i] = key->md.h3; 276290207Sjkim ctx->E[i] = key->md.h4; 277290207Sjkim 278290207Sjkim /* fix seqnum */ 279290207Sjkim# if defined(BSWAP8) 280290207Sjkim blocks[i].q[0] = BSWAP8(seqnum + i); 281290207Sjkim# else 282290207Sjkim for (carry = i, j = 8; j--;) { 283290207Sjkim blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry; 284290207Sjkim carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1); 285290207Sjkim } 286290207Sjkim# endif 287290207Sjkim blocks[i].c[8] = ((u8 *)key->md.data)[8]; 288290207Sjkim blocks[i].c[9] = ((u8 *)key->md.data)[9]; 289290207Sjkim blocks[i].c[10] = ((u8 *)key->md.data)[10]; 290290207Sjkim /* fix length */ 291290207Sjkim blocks[i].c[11] = (u8)(len >> 8); 292290207Sjkim blocks[i].c[12] = (u8)(len); 293290207Sjkim 294290207Sjkim memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13); 295290207Sjkim hash_d[i].ptr += 64 - 13; 296290207Sjkim hash_d[i].blocks = (len - (64 - 13)) / 64; 297290207Sjkim 298290207Sjkim edges[i].ptr = blocks[i].c; 299290207Sjkim edges[i].blocks = 1; 300290207Sjkim } 301290207Sjkim 302290207Sjkim /* hash 13-byte headers and first 64-13 bytes of inputs */ 303290207Sjkim sha1_multi_block(ctx, edges, n4x); 304290207Sjkim /* hash bulk inputs */ 305290207Sjkim# define MAXCHUNKSIZE 2048 306290207Sjkim# if MAXCHUNKSIZE%64 307290207Sjkim# error "MAXCHUNKSIZE is not divisible by 64" 308290207Sjkim# elif MAXCHUNKSIZE 309290207Sjkim /* 310290207Sjkim * goal is to minimize pressure on L1 cache by moving in shorter steps, 311290207Sjkim * so that hashed data is still in the cache by the time we encrypt it 312290207Sjkim */ 313290207Sjkim minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64; 314290207Sjkim if (minblocks > MAXCHUNKSIZE / 64) { 315290207Sjkim for (i = 0; i < x4; i++) { 316290207Sjkim edges[i].ptr = hash_d[i].ptr; 317290207Sjkim edges[i].blocks = MAXCHUNKSIZE / 64; 318290207Sjkim ciph_d[i].blocks = MAXCHUNKSIZE / 16; 319290207Sjkim } 320290207Sjkim do { 321290207Sjkim sha1_multi_block(ctx, edges, n4x); 322290207Sjkim aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); 323290207Sjkim 324290207Sjkim for (i = 0; i < x4; i++) { 325290207Sjkim edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE; 326290207Sjkim hash_d[i].blocks -= MAXCHUNKSIZE / 64; 327290207Sjkim edges[i].blocks = MAXCHUNKSIZE / 64; 328290207Sjkim ciph_d[i].inp += MAXCHUNKSIZE; 329290207Sjkim ciph_d[i].out += MAXCHUNKSIZE; 330290207Sjkim ciph_d[i].blocks = MAXCHUNKSIZE / 16; 331290207Sjkim memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16); 332290207Sjkim } 333290207Sjkim processed += MAXCHUNKSIZE; 334290207Sjkim minblocks -= MAXCHUNKSIZE / 64; 335290207Sjkim } while (minblocks > MAXCHUNKSIZE / 64); 336290207Sjkim } 337290207Sjkim# endif 338290207Sjkim# undef MAXCHUNKSIZE 339290207Sjkim sha1_multi_block(ctx, hash_d, n4x); 340290207Sjkim 341290207Sjkim memset(blocks, 0, sizeof(blocks)); 342290207Sjkim for (i = 0; i < x4; i++) { 343290207Sjkim unsigned int len = (i == (x4 - 1) ? last : frag), 344290207Sjkim off = hash_d[i].blocks * 64; 345290207Sjkim const unsigned char *ptr = hash_d[i].ptr + off; 346290207Sjkim 347290207Sjkim off = (len - processed) - (64 - 13) - off; /* remainder actually */ 348290207Sjkim memcpy(blocks[i].c, ptr, off); 349290207Sjkim blocks[i].c[off] = 0x80; 350290207Sjkim len += 64 + 13; /* 64 is HMAC header */ 351290207Sjkim len *= 8; /* convert to bits */ 352290207Sjkim if (off < (64 - 8)) { 353290207Sjkim# ifdef BSWAP4 354290207Sjkim blocks[i].d[15] = BSWAP4(len); 355290207Sjkim# else 356290207Sjkim PUTU32(blocks[i].c + 60, len); 357290207Sjkim# endif 358290207Sjkim edges[i].blocks = 1; 359290207Sjkim } else { 360290207Sjkim# ifdef BSWAP4 361290207Sjkim blocks[i].d[31] = BSWAP4(len); 362290207Sjkim# else 363290207Sjkim PUTU32(blocks[i].c + 124, len); 364290207Sjkim# endif 365290207Sjkim edges[i].blocks = 2; 366290207Sjkim } 367290207Sjkim edges[i].ptr = blocks[i].c; 368290207Sjkim } 369290207Sjkim 370290207Sjkim /* hash input tails and finalize */ 371290207Sjkim sha1_multi_block(ctx, edges, n4x); 372290207Sjkim 373290207Sjkim memset(blocks, 0, sizeof(blocks)); 374290207Sjkim for (i = 0; i < x4; i++) { 375290207Sjkim# ifdef BSWAP4 376290207Sjkim blocks[i].d[0] = BSWAP4(ctx->A[i]); 377290207Sjkim ctx->A[i] = key->tail.h0; 378290207Sjkim blocks[i].d[1] = BSWAP4(ctx->B[i]); 379290207Sjkim ctx->B[i] = key->tail.h1; 380290207Sjkim blocks[i].d[2] = BSWAP4(ctx->C[i]); 381290207Sjkim ctx->C[i] = key->tail.h2; 382290207Sjkim blocks[i].d[3] = BSWAP4(ctx->D[i]); 383290207Sjkim ctx->D[i] = key->tail.h3; 384290207Sjkim blocks[i].d[4] = BSWAP4(ctx->E[i]); 385290207Sjkim ctx->E[i] = key->tail.h4; 386290207Sjkim blocks[i].c[20] = 0x80; 387290207Sjkim blocks[i].d[15] = BSWAP4((64 + 20) * 8); 388290207Sjkim# else 389290207Sjkim PUTU32(blocks[i].c + 0, ctx->A[i]); 390290207Sjkim ctx->A[i] = key->tail.h0; 391290207Sjkim PUTU32(blocks[i].c + 4, ctx->B[i]); 392290207Sjkim ctx->B[i] = key->tail.h1; 393290207Sjkim PUTU32(blocks[i].c + 8, ctx->C[i]); 394290207Sjkim ctx->C[i] = key->tail.h2; 395290207Sjkim PUTU32(blocks[i].c + 12, ctx->D[i]); 396290207Sjkim ctx->D[i] = key->tail.h3; 397290207Sjkim PUTU32(blocks[i].c + 16, ctx->E[i]); 398290207Sjkim ctx->E[i] = key->tail.h4; 399290207Sjkim blocks[i].c[20] = 0x80; 400290207Sjkim PUTU32(blocks[i].c + 60, (64 + 20) * 8); 401290207Sjkim# endif 402290207Sjkim edges[i].ptr = blocks[i].c; 403290207Sjkim edges[i].blocks = 1; 404290207Sjkim } 405290207Sjkim 406290207Sjkim /* finalize MACs */ 407290207Sjkim sha1_multi_block(ctx, edges, n4x); 408290207Sjkim 409290207Sjkim for (i = 0; i < x4; i++) { 410290207Sjkim unsigned int len = (i == (x4 - 1) ? last : frag), pad, j; 411290207Sjkim unsigned char *out0 = out; 412290207Sjkim 413290207Sjkim memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed); 414290207Sjkim ciph_d[i].inp = ciph_d[i].out; 415290207Sjkim 416290207Sjkim out += 5 + 16 + len; 417290207Sjkim 418290207Sjkim /* write MAC */ 419290207Sjkim PUTU32(out + 0, ctx->A[i]); 420290207Sjkim PUTU32(out + 4, ctx->B[i]); 421290207Sjkim PUTU32(out + 8, ctx->C[i]); 422290207Sjkim PUTU32(out + 12, ctx->D[i]); 423290207Sjkim PUTU32(out + 16, ctx->E[i]); 424290207Sjkim out += 20; 425290207Sjkim len += 20; 426290207Sjkim 427290207Sjkim /* pad */ 428290207Sjkim pad = 15 - len % 16; 429290207Sjkim for (j = 0; j <= pad; j++) 430290207Sjkim *(out++) = pad; 431290207Sjkim len += pad + 1; 432290207Sjkim 433290207Sjkim ciph_d[i].blocks = (len - processed) / 16; 434290207Sjkim len += 16; /* account for explicit iv */ 435290207Sjkim 436290207Sjkim /* arrange header */ 437290207Sjkim out0[0] = ((u8 *)key->md.data)[8]; 438290207Sjkim out0[1] = ((u8 *)key->md.data)[9]; 439290207Sjkim out0[2] = ((u8 *)key->md.data)[10]; 440290207Sjkim out0[3] = (u8)(len >> 8); 441290207Sjkim out0[4] = (u8)(len); 442290207Sjkim 443290207Sjkim ret += len + 5; 444290207Sjkim inp += frag; 445290207Sjkim } 446290207Sjkim 447290207Sjkim aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); 448290207Sjkim 449290207Sjkim OPENSSL_cleanse(blocks, sizeof(blocks)); 450290207Sjkim OPENSSL_cleanse(ctx, sizeof(*ctx)); 451290207Sjkim 452290207Sjkim return ret; 453290207Sjkim} 454290207Sjkim# endif 455290207Sjkim 456238384Sjkimstatic int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 457280297Sjkim const unsigned char *in, size_t len) 458280297Sjkim{ 459280297Sjkim EVP_AES_HMAC_SHA1 *key = data(ctx); 460280297Sjkim unsigned int l; 461280297Sjkim size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and 462280297Sjkim * later */ 463280297Sjkim sha_off = 0; 464280297Sjkim# if defined(STITCHED_CALL) 465280297Sjkim size_t aes_off = 0, blocks; 466238384Sjkim 467280297Sjkim sha_off = SHA_CBLOCK - key->md.num; 468280297Sjkim# endif 469238384Sjkim 470280297Sjkim key->payload_length = NO_PAYLOAD_LENGTH; 471246772Sjkim 472280297Sjkim if (len % AES_BLOCK_SIZE) 473280297Sjkim return 0; 474238384Sjkim 475280297Sjkim if (ctx->encrypt) { 476280297Sjkim if (plen == NO_PAYLOAD_LENGTH) 477280297Sjkim plen = len; 478280297Sjkim else if (len != 479280297Sjkim ((plen + SHA_DIGEST_LENGTH + 480280297Sjkim AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)) 481280297Sjkim return 0; 482280297Sjkim else if (key->aux.tls_ver >= TLS1_1_VERSION) 483280297Sjkim iv = AES_BLOCK_SIZE; 484238384Sjkim 485280297Sjkim# if defined(STITCHED_CALL) 486280297Sjkim if (plen > (sha_off + iv) 487280297Sjkim && (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) { 488280297Sjkim SHA1_Update(&key->md, in + iv, sha_off); 489238384Sjkim 490280297Sjkim aesni_cbc_sha1_enc(in, out, blocks, &key->ks, 491280297Sjkim ctx->iv, &key->md, in + iv + sha_off); 492280297Sjkim blocks *= SHA_CBLOCK; 493280297Sjkim aes_off += blocks; 494280297Sjkim sha_off += blocks; 495280297Sjkim key->md.Nh += blocks >> 29; 496280297Sjkim key->md.Nl += blocks <<= 3; 497280297Sjkim if (key->md.Nl < (unsigned int)blocks) 498280297Sjkim key->md.Nh++; 499280297Sjkim } else { 500280297Sjkim sha_off = 0; 501280297Sjkim } 502280297Sjkim# endif 503280297Sjkim sha_off += iv; 504280297Sjkim SHA1_Update(&key->md, in + sha_off, plen - sha_off); 505238384Sjkim 506280297Sjkim if (plen != len) { /* "TLS" mode of operation */ 507280297Sjkim if (in != out) 508280297Sjkim memcpy(out + aes_off, in + aes_off, plen - aes_off); 509238384Sjkim 510280297Sjkim /* calculate HMAC and append it to payload */ 511280297Sjkim SHA1_Final(out + plen, &key->md); 512280297Sjkim key->md = key->tail; 513280297Sjkim SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH); 514280297Sjkim SHA1_Final(out + plen, &key->md); 515238384Sjkim 516280297Sjkim /* pad the payload|hmac */ 517280297Sjkim plen += SHA_DIGEST_LENGTH; 518280297Sjkim for (l = len - plen - 1; plen < len; plen++) 519280297Sjkim out[plen] = l; 520280297Sjkim /* encrypt HMAC|padding at once */ 521280297Sjkim aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off, 522280297Sjkim &key->ks, ctx->iv, 1); 523280297Sjkim } else { 524280297Sjkim aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off, 525280297Sjkim &key->ks, ctx->iv, 1); 526280297Sjkim } 527280297Sjkim } else { 528280297Sjkim union { 529280297Sjkim unsigned int u[SHA_DIGEST_LENGTH / sizeof(unsigned int)]; 530280297Sjkim unsigned char c[32 + SHA_DIGEST_LENGTH]; 531280297Sjkim } mac, *pmac; 532238384Sjkim 533280297Sjkim /* arrange cache line alignment */ 534280297Sjkim pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32)); 535246772Sjkim 536290207Sjkim if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ 537280297Sjkim size_t inp_len, mask, j, i; 538280297Sjkim unsigned int res, maxpad, pad, bitlen; 539280297Sjkim int ret = 1; 540280297Sjkim union { 541280297Sjkim unsigned int u[SHA_LBLOCK]; 542280297Sjkim unsigned char c[SHA_CBLOCK]; 543280297Sjkim } *data = (void *)key->md.data; 544290207Sjkim# if defined(STITCHED_DECRYPT_CALL) 545290207Sjkim unsigned char tail_iv[AES_BLOCK_SIZE]; 546290207Sjkim int stitch = 0; 547290207Sjkim# endif 548238384Sjkim 549280297Sjkim if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3]) 550290207Sjkim >= TLS1_1_VERSION) { 551290207Sjkim if (len < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1)) 552290207Sjkim return 0; 553238384Sjkim 554290207Sjkim /* omit explicit iv */ 555290207Sjkim memcpy(ctx->iv, in, AES_BLOCK_SIZE); 556290207Sjkim in += AES_BLOCK_SIZE; 557290207Sjkim out += AES_BLOCK_SIZE; 558290207Sjkim len -= AES_BLOCK_SIZE; 559290207Sjkim } else if (len < (SHA_DIGEST_LENGTH + 1)) 560280297Sjkim return 0; 561238384Sjkim 562290207Sjkim# if defined(STITCHED_DECRYPT_CALL) 563290207Sjkim if (len >= 1024 && ctx->key_len == 32) { 564290207Sjkim /* decrypt last block */ 565290207Sjkim memcpy(tail_iv, in + len - 2 * AES_BLOCK_SIZE, 566290207Sjkim AES_BLOCK_SIZE); 567290207Sjkim aesni_cbc_encrypt(in + len - AES_BLOCK_SIZE, 568290207Sjkim out + len - AES_BLOCK_SIZE, AES_BLOCK_SIZE, 569290207Sjkim &key->ks, tail_iv, 0); 570290207Sjkim stitch = 1; 571290207Sjkim } else 572290207Sjkim# endif 573290207Sjkim /* decrypt HMAC|padding at once */ 574290207Sjkim aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0); 575246772Sjkim 576280297Sjkim /* figure out payload length */ 577280297Sjkim pad = out[len - 1]; 578280297Sjkim maxpad = len - (SHA_DIGEST_LENGTH + 1); 579280297Sjkim maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); 580280297Sjkim maxpad &= 255; 581246772Sjkim 582325337Sjkim mask = constant_time_ge(maxpad, pad); 583325337Sjkim ret &= mask; 584325337Sjkim /* 585325337Sjkim * If pad is invalid then we will fail the above test but we must 586325337Sjkim * continue anyway because we are in constant time code. However, 587325337Sjkim * we'll use the maxpad value instead of the supplied pad to make 588325337Sjkim * sure we perform well defined pointer arithmetic. 589325337Sjkim */ 590325337Sjkim pad = constant_time_select(mask, pad, maxpad); 591298998Sjkim 592280297Sjkim inp_len = len - (SHA_DIGEST_LENGTH + pad + 1); 593246772Sjkim 594280297Sjkim key->aux.tls_aad[plen - 2] = inp_len >> 8; 595280297Sjkim key->aux.tls_aad[plen - 1] = inp_len; 596246772Sjkim 597280297Sjkim /* calculate HMAC */ 598280297Sjkim key->md = key->head; 599280297Sjkim SHA1_Update(&key->md, key->aux.tls_aad, plen); 600238384Sjkim 601290207Sjkim# if defined(STITCHED_DECRYPT_CALL) 602290207Sjkim if (stitch) { 603290207Sjkim blocks = (len - (256 + 32 + SHA_CBLOCK)) / SHA_CBLOCK; 604290207Sjkim aes_off = len - AES_BLOCK_SIZE - blocks * SHA_CBLOCK; 605290207Sjkim sha_off = SHA_CBLOCK - plen; 606290207Sjkim 607290207Sjkim aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0); 608290207Sjkim 609290207Sjkim SHA1_Update(&key->md, out, sha_off); 610290207Sjkim aesni256_cbc_sha1_dec(in + aes_off, 611290207Sjkim out + aes_off, blocks, &key->ks, 612290207Sjkim ctx->iv, &key->md, out + sha_off); 613290207Sjkim 614290207Sjkim sha_off += blocks *= SHA_CBLOCK; 615290207Sjkim out += sha_off; 616290207Sjkim len -= sha_off; 617290207Sjkim inp_len -= sha_off; 618290207Sjkim 619290207Sjkim key->md.Nl += (blocks << 3); /* at most 18 bits */ 620290207Sjkim memcpy(ctx->iv, tail_iv, AES_BLOCK_SIZE); 621290207Sjkim } 622290207Sjkim# endif 623290207Sjkim 624280297Sjkim# if 1 625280297Sjkim len -= SHA_DIGEST_LENGTH; /* amend mac */ 626280297Sjkim if (len >= (256 + SHA_CBLOCK)) { 627280297Sjkim j = (len - (256 + SHA_CBLOCK)) & (0 - SHA_CBLOCK); 628280297Sjkim j += SHA_CBLOCK - key->md.num; 629280297Sjkim SHA1_Update(&key->md, out, j); 630280297Sjkim out += j; 631280297Sjkim len -= j; 632280297Sjkim inp_len -= j; 633280297Sjkim } 634246772Sjkim 635280297Sjkim /* but pretend as if we hashed padded payload */ 636280297Sjkim bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */ 637290207Sjkim# ifdef BSWAP4 638290207Sjkim bitlen = BSWAP4(bitlen); 639280297Sjkim# else 640280297Sjkim mac.c[0] = 0; 641280297Sjkim mac.c[1] = (unsigned char)(bitlen >> 16); 642280297Sjkim mac.c[2] = (unsigned char)(bitlen >> 8); 643280297Sjkim mac.c[3] = (unsigned char)bitlen; 644280297Sjkim bitlen = mac.u[0]; 645280297Sjkim# endif 646246772Sjkim 647280297Sjkim pmac->u[0] = 0; 648280297Sjkim pmac->u[1] = 0; 649280297Sjkim pmac->u[2] = 0; 650280297Sjkim pmac->u[3] = 0; 651280297Sjkim pmac->u[4] = 0; 652246772Sjkim 653280297Sjkim for (res = key->md.num, j = 0; j < len; j++) { 654280297Sjkim size_t c = out[j]; 655280297Sjkim mask = (j - inp_len) >> (sizeof(j) * 8 - 8); 656280297Sjkim c &= mask; 657280297Sjkim c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8)); 658280297Sjkim data->c[res++] = (unsigned char)c; 659246772Sjkim 660280297Sjkim if (res != SHA_CBLOCK) 661280297Sjkim continue; 662246772Sjkim 663280297Sjkim /* j is not incremented yet */ 664280297Sjkim mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1)); 665280297Sjkim data->u[SHA_LBLOCK - 1] |= bitlen & mask; 666280297Sjkim sha1_block_data_order(&key->md, data, 1); 667280297Sjkim mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1)); 668280297Sjkim pmac->u[0] |= key->md.h0 & mask; 669280297Sjkim pmac->u[1] |= key->md.h1 & mask; 670280297Sjkim pmac->u[2] |= key->md.h2 & mask; 671280297Sjkim pmac->u[3] |= key->md.h3 & mask; 672280297Sjkim pmac->u[4] |= key->md.h4 & mask; 673280297Sjkim res = 0; 674280297Sjkim } 675246772Sjkim 676280297Sjkim for (i = res; i < SHA_CBLOCK; i++, j++) 677280297Sjkim data->c[i] = 0; 678246772Sjkim 679280297Sjkim if (res > SHA_CBLOCK - 8) { 680280297Sjkim mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1)); 681280297Sjkim data->u[SHA_LBLOCK - 1] |= bitlen & mask; 682280297Sjkim sha1_block_data_order(&key->md, data, 1); 683280297Sjkim mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); 684280297Sjkim pmac->u[0] |= key->md.h0 & mask; 685280297Sjkim pmac->u[1] |= key->md.h1 & mask; 686280297Sjkim pmac->u[2] |= key->md.h2 & mask; 687280297Sjkim pmac->u[3] |= key->md.h3 & mask; 688280297Sjkim pmac->u[4] |= key->md.h4 & mask; 689246772Sjkim 690280297Sjkim memset(data, 0, SHA_CBLOCK); 691280297Sjkim j += 64; 692280297Sjkim } 693280297Sjkim data->u[SHA_LBLOCK - 1] = bitlen; 694280297Sjkim sha1_block_data_order(&key->md, data, 1); 695280297Sjkim mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); 696280297Sjkim pmac->u[0] |= key->md.h0 & mask; 697280297Sjkim pmac->u[1] |= key->md.h1 & mask; 698280297Sjkim pmac->u[2] |= key->md.h2 & mask; 699280297Sjkim pmac->u[3] |= key->md.h3 & mask; 700280297Sjkim pmac->u[4] |= key->md.h4 & mask; 701246772Sjkim 702290207Sjkim# ifdef BSWAP4 703290207Sjkim pmac->u[0] = BSWAP4(pmac->u[0]); 704290207Sjkim pmac->u[1] = BSWAP4(pmac->u[1]); 705290207Sjkim pmac->u[2] = BSWAP4(pmac->u[2]); 706290207Sjkim pmac->u[3] = BSWAP4(pmac->u[3]); 707290207Sjkim pmac->u[4] = BSWAP4(pmac->u[4]); 708280297Sjkim# else 709280297Sjkim for (i = 0; i < 5; i++) { 710280297Sjkim res = pmac->u[i]; 711280297Sjkim pmac->c[4 * i + 0] = (unsigned char)(res >> 24); 712280297Sjkim pmac->c[4 * i + 1] = (unsigned char)(res >> 16); 713280297Sjkim pmac->c[4 * i + 2] = (unsigned char)(res >> 8); 714280297Sjkim pmac->c[4 * i + 3] = (unsigned char)res; 715280297Sjkim } 716280297Sjkim# endif 717280297Sjkim len += SHA_DIGEST_LENGTH; 718280297Sjkim# else 719280297Sjkim SHA1_Update(&key->md, out, inp_len); 720280297Sjkim res = key->md.num; 721280297Sjkim SHA1_Final(pmac->c, &key->md); 722246772Sjkim 723280297Sjkim { 724280297Sjkim unsigned int inp_blocks, pad_blocks; 725246772Sjkim 726280297Sjkim /* but pretend as if we hashed padded payload */ 727280297Sjkim inp_blocks = 728280297Sjkim 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); 729280297Sjkim res += (unsigned int)(len - inp_len); 730280297Sjkim pad_blocks = res / SHA_CBLOCK; 731280297Sjkim res %= SHA_CBLOCK; 732280297Sjkim pad_blocks += 733280297Sjkim 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); 734280297Sjkim for (; inp_blocks < pad_blocks; inp_blocks++) 735280297Sjkim sha1_block_data_order(&key->md, data, 1); 736280297Sjkim } 737280297Sjkim# endif 738280297Sjkim key->md = key->tail; 739280297Sjkim SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH); 740280297Sjkim SHA1_Final(pmac->c, &key->md); 741238384Sjkim 742280297Sjkim /* verify HMAC */ 743280297Sjkim out += inp_len; 744280297Sjkim len -= inp_len; 745280297Sjkim# if 1 746280297Sjkim { 747280297Sjkim unsigned char *p = out + len - 1 - maxpad - SHA_DIGEST_LENGTH; 748280297Sjkim size_t off = out - p; 749280297Sjkim unsigned int c, cmask; 750246772Sjkim 751280297Sjkim maxpad += SHA_DIGEST_LENGTH; 752280297Sjkim for (res = 0, i = 0, j = 0; j < maxpad; j++) { 753280297Sjkim c = p[j]; 754280297Sjkim cmask = 755280297Sjkim ((int)(j - off - SHA_DIGEST_LENGTH)) >> (sizeof(int) * 756280297Sjkim 8 - 1); 757280297Sjkim res |= (c ^ pad) & ~cmask; /* ... and padding */ 758280297Sjkim cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1); 759280297Sjkim res |= (c ^ pmac->c[i]) & cmask; 760280297Sjkim i += 1 & cmask; 761280297Sjkim } 762280297Sjkim maxpad -= SHA_DIGEST_LENGTH; 763246772Sjkim 764280297Sjkim res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); 765280297Sjkim ret &= (int)~res; 766280297Sjkim } 767280297Sjkim# else 768280297Sjkim for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++) 769280297Sjkim res |= out[i] ^ pmac->c[i]; 770280297Sjkim res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); 771280297Sjkim ret &= (int)~res; 772246772Sjkim 773280297Sjkim /* verify padding */ 774280297Sjkim pad = (pad & ~res) | (maxpad & res); 775280297Sjkim out = out + len - 1 - pad; 776280297Sjkim for (res = 0, i = 0; i < pad; i++) 777280297Sjkim res |= out[i] ^ pad; 778246772Sjkim 779280297Sjkim res = (0 - res) >> (sizeof(res) * 8 - 1); 780280297Sjkim ret &= (int)~res; 781280297Sjkim# endif 782280297Sjkim return ret; 783280297Sjkim } else { 784290207Sjkim# if defined(STITCHED_DECRYPT_CALL) 785290207Sjkim if (len >= 1024 && ctx->key_len == 32) { 786290207Sjkim if (sha_off %= SHA_CBLOCK) 787290207Sjkim blocks = (len - 3 * SHA_CBLOCK) / SHA_CBLOCK; 788290207Sjkim else 789290207Sjkim blocks = (len - 2 * SHA_CBLOCK) / SHA_CBLOCK; 790290207Sjkim aes_off = len - blocks * SHA_CBLOCK; 791290207Sjkim 792290207Sjkim aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0); 793290207Sjkim SHA1_Update(&key->md, out, sha_off); 794290207Sjkim aesni256_cbc_sha1_dec(in + aes_off, 795290207Sjkim out + aes_off, blocks, &key->ks, 796290207Sjkim ctx->iv, &key->md, out + sha_off); 797290207Sjkim 798290207Sjkim sha_off += blocks *= SHA_CBLOCK; 799290207Sjkim out += sha_off; 800290207Sjkim len -= sha_off; 801290207Sjkim 802290207Sjkim key->md.Nh += blocks >> 29; 803290207Sjkim key->md.Nl += blocks <<= 3; 804290207Sjkim if (key->md.Nl < (unsigned int)blocks) 805290207Sjkim key->md.Nh++; 806290207Sjkim } else 807290207Sjkim# endif 808290207Sjkim /* decrypt HMAC|padding at once */ 809290207Sjkim aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0); 810290207Sjkim 811280297Sjkim SHA1_Update(&key->md, out, len); 812280297Sjkim } 813280297Sjkim } 814238384Sjkim 815280297Sjkim return 1; 816280297Sjkim} 817238384Sjkim 818280297Sjkimstatic int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, 819280297Sjkim void *ptr) 820280297Sjkim{ 821280297Sjkim EVP_AES_HMAC_SHA1 *key = data(ctx); 822238384Sjkim 823280297Sjkim switch (type) { 824280297Sjkim case EVP_CTRL_AEAD_SET_MAC_KEY: 825280297Sjkim { 826280297Sjkim unsigned int i; 827280297Sjkim unsigned char hmac_key[64]; 828238384Sjkim 829280297Sjkim memset(hmac_key, 0, sizeof(hmac_key)); 830238384Sjkim 831280297Sjkim if (arg > (int)sizeof(hmac_key)) { 832280297Sjkim SHA1_Init(&key->head); 833280297Sjkim SHA1_Update(&key->head, ptr, arg); 834280297Sjkim SHA1_Final(hmac_key, &key->head); 835280297Sjkim } else { 836280297Sjkim memcpy(hmac_key, ptr, arg); 837280297Sjkim } 838238384Sjkim 839280297Sjkim for (i = 0; i < sizeof(hmac_key); i++) 840280297Sjkim hmac_key[i] ^= 0x36; /* ipad */ 841280297Sjkim SHA1_Init(&key->head); 842280297Sjkim SHA1_Update(&key->head, hmac_key, sizeof(hmac_key)); 843238384Sjkim 844280297Sjkim for (i = 0; i < sizeof(hmac_key); i++) 845280297Sjkim hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ 846280297Sjkim SHA1_Init(&key->tail); 847280297Sjkim SHA1_Update(&key->tail, hmac_key, sizeof(hmac_key)); 848238384Sjkim 849280297Sjkim OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); 850246772Sjkim 851280297Sjkim return 1; 852280297Sjkim } 853280297Sjkim case EVP_CTRL_AEAD_TLS1_AAD: 854280297Sjkim { 855280297Sjkim unsigned char *p = ptr; 856284283Sjkim unsigned int len; 857238384Sjkim 858284283Sjkim if (arg != EVP_AEAD_TLS1_AAD_LEN) 859284283Sjkim return -1; 860284283Sjkim 861284283Sjkim len = p[arg - 2] << 8 | p[arg - 1]; 862284283Sjkim 863280297Sjkim if (ctx->encrypt) { 864280297Sjkim key->payload_length = len; 865280297Sjkim if ((key->aux.tls_ver = 866280297Sjkim p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { 867325335Sjkim if (len < AES_BLOCK_SIZE) 868325335Sjkim return 0; 869280297Sjkim len -= AES_BLOCK_SIZE; 870280297Sjkim p[arg - 2] = len >> 8; 871280297Sjkim p[arg - 1] = len; 872280297Sjkim } 873280297Sjkim key->md = key->head; 874280297Sjkim SHA1_Update(&key->md, p, arg); 875238384Sjkim 876280297Sjkim return (int)(((len + SHA_DIGEST_LENGTH + 877280297Sjkim AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) 878280297Sjkim - len); 879280297Sjkim } else { 880280297Sjkim memcpy(key->aux.tls_aad, ptr, arg); 881280297Sjkim key->payload_length = arg; 882238384Sjkim 883280297Sjkim return SHA_DIGEST_LENGTH; 884280297Sjkim } 885280297Sjkim } 886290207Sjkim# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 887290207Sjkim case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE: 888290207Sjkim return (int)(5 + 16 + ((arg + 20 + 16) & -16)); 889290207Sjkim case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD: 890290207Sjkim { 891290207Sjkim EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = 892290207Sjkim (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; 893290207Sjkim unsigned int n4x = 1, x4; 894290207Sjkim unsigned int frag, last, packlen, inp_len; 895290207Sjkim 896290207Sjkim if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM)) 897290207Sjkim return -1; 898290207Sjkim 899290207Sjkim inp_len = param->inp[11] << 8 | param->inp[12]; 900290207Sjkim 901290207Sjkim if (ctx->encrypt) { 902290207Sjkim if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION) 903290207Sjkim return -1; 904290207Sjkim 905290207Sjkim if (inp_len) { 906290207Sjkim if (inp_len < 4096) 907290207Sjkim return 0; /* too short */ 908290207Sjkim 909290207Sjkim if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5)) 910290207Sjkim n4x = 2; /* AVX2 */ 911290207Sjkim } else if ((n4x = param->interleave / 4) && n4x <= 2) 912290207Sjkim inp_len = param->len; 913290207Sjkim else 914290207Sjkim return -1; 915290207Sjkim 916290207Sjkim key->md = key->head; 917290207Sjkim SHA1_Update(&key->md, param->inp, 13); 918290207Sjkim 919290207Sjkim x4 = 4 * n4x; 920290207Sjkim n4x += 1; 921290207Sjkim 922290207Sjkim frag = inp_len >> n4x; 923290207Sjkim last = inp_len + frag - (frag << n4x); 924290207Sjkim if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) { 925290207Sjkim frag++; 926290207Sjkim last -= x4 - 1; 927290207Sjkim } 928290207Sjkim 929290207Sjkim packlen = 5 + 16 + ((frag + 20 + 16) & -16); 930290207Sjkim packlen = (packlen << n4x) - packlen; 931290207Sjkim packlen += 5 + 16 + ((last + 20 + 16) & -16); 932290207Sjkim 933290207Sjkim param->interleave = x4; 934290207Sjkim 935290207Sjkim return (int)packlen; 936290207Sjkim } else 937290207Sjkim return -1; /* not yet */ 938290207Sjkim } 939290207Sjkim case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT: 940290207Sjkim { 941290207Sjkim EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = 942290207Sjkim (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; 943290207Sjkim 944290207Sjkim return (int)tls1_1_multi_block_encrypt(key, param->out, 945290207Sjkim param->inp, param->len, 946290207Sjkim param->interleave / 4); 947290207Sjkim } 948290207Sjkim case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT: 949290207Sjkim# endif 950280297Sjkim default: 951280297Sjkim return -1; 952280297Sjkim } 953280297Sjkim} 954238384Sjkim 955280297Sjkimstatic EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = { 956280297Sjkim# ifdef NID_aes_128_cbc_hmac_sha1 957280297Sjkim NID_aes_128_cbc_hmac_sha1, 958280297Sjkim# else 959280297Sjkim NID_undef, 960280297Sjkim# endif 961280297Sjkim 16, 16, 16, 962280297Sjkim EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | 963290207Sjkim EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, 964280297Sjkim aesni_cbc_hmac_sha1_init_key, 965280297Sjkim aesni_cbc_hmac_sha1_cipher, 966280297Sjkim NULL, 967280297Sjkim sizeof(EVP_AES_HMAC_SHA1), 968280297Sjkim EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, 969280297Sjkim EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, 970280297Sjkim aesni_cbc_hmac_sha1_ctrl, 971280297Sjkim NULL 972280297Sjkim}; 973238384Sjkim 974280297Sjkimstatic EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = { 975280297Sjkim# ifdef NID_aes_256_cbc_hmac_sha1 976280297Sjkim NID_aes_256_cbc_hmac_sha1, 977280297Sjkim# else 978280297Sjkim NID_undef, 979280297Sjkim# endif 980280297Sjkim 16, 32, 16, 981280297Sjkim EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | 982290207Sjkim EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, 983280297Sjkim aesni_cbc_hmac_sha1_init_key, 984280297Sjkim aesni_cbc_hmac_sha1_cipher, 985280297Sjkim NULL, 986280297Sjkim sizeof(EVP_AES_HMAC_SHA1), 987280297Sjkim EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, 988280297Sjkim EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, 989280297Sjkim aesni_cbc_hmac_sha1_ctrl, 990280297Sjkim NULL 991280297Sjkim}; 992238384Sjkim 993238384Sjkimconst EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void) 994280297Sjkim{ 995280297Sjkim return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ? 996280297Sjkim &aesni_128_cbc_hmac_sha1_cipher : NULL); 997280297Sjkim} 998238384Sjkim 999238384Sjkimconst EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void) 1000280297Sjkim{ 1001280297Sjkim return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ? 1002280297Sjkim &aesni_256_cbc_hmac_sha1_cipher : NULL); 1003280297Sjkim} 1004280297Sjkim# else 1005238384Sjkimconst EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void) 1006280297Sjkim{ 1007280297Sjkim return NULL; 1008280297Sjkim} 1009280297Sjkim 1010238384Sjkimconst EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void) 1011280297Sjkim{ 1012280297Sjkim return NULL; 1013280297Sjkim} 1014280297Sjkim# endif 1015238384Sjkim#endif 1016