1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * AES low level APIs are deprecated for public use, but still ok for internal 12e1051a39Sopenharmony_ci * use where we're using them to implement the higher level EVP interface, as is 13e1051a39Sopenharmony_ci * the case here. 14e1051a39Sopenharmony_ci */ 15e1051a39Sopenharmony_ci#include "internal/deprecated.h" 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci#include <stdio.h> 18e1051a39Sopenharmony_ci#include <string.h> 19e1051a39Sopenharmony_ci#include <openssl/opensslconf.h> 20e1051a39Sopenharmony_ci#include <openssl/evp.h> 21e1051a39Sopenharmony_ci#include <openssl/objects.h> 22e1051a39Sopenharmony_ci#include <openssl/aes.h> 23e1051a39Sopenharmony_ci#include <openssl/sha.h> 24e1051a39Sopenharmony_ci#include <openssl/rand.h> 25e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 26e1051a39Sopenharmony_ci#include "crypto/modes.h" 27e1051a39Sopenharmony_ci#include "crypto/evp.h" 28e1051a39Sopenharmony_ci#include "internal/constant_time.h" 29e1051a39Sopenharmony_ci#include "evp_local.h" 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_citypedef struct { 32e1051a39Sopenharmony_ci AES_KEY ks; 33e1051a39Sopenharmony_ci SHA_CTX head, tail, md; 34e1051a39Sopenharmony_ci size_t payload_length; /* AAD length in decrypt case */ 35e1051a39Sopenharmony_ci union { 36e1051a39Sopenharmony_ci unsigned int tls_ver; 37e1051a39Sopenharmony_ci unsigned char tls_aad[16]; /* 13 used */ 38e1051a39Sopenharmony_ci } aux; 39e1051a39Sopenharmony_ci} EVP_AES_HMAC_SHA1; 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_ci#define NO_PAYLOAD_LENGTH ((size_t)-1) 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_ci#if defined(AES_ASM) && ( \ 44e1051a39Sopenharmony_ci defined(__x86_64) || defined(__x86_64__) || \ 45e1051a39Sopenharmony_ci defined(_M_AMD64) || defined(_M_X64) ) 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_ci# define AESNI_CAPABLE (1<<(57-32)) 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_ciint aesni_set_encrypt_key(const unsigned char *userKey, int bits, 50e1051a39Sopenharmony_ci AES_KEY *key); 51e1051a39Sopenharmony_ciint aesni_set_decrypt_key(const unsigned char *userKey, int bits, 52e1051a39Sopenharmony_ci AES_KEY *key); 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_civoid aesni_cbc_encrypt(const unsigned char *in, 55e1051a39Sopenharmony_ci unsigned char *out, 56e1051a39Sopenharmony_ci size_t length, 57e1051a39Sopenharmony_ci const AES_KEY *key, unsigned char *ivec, int enc); 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_civoid aesni_cbc_sha1_enc(const void *inp, void *out, size_t blocks, 60e1051a39Sopenharmony_ci const AES_KEY *key, unsigned char iv[16], 61e1051a39Sopenharmony_ci SHA_CTX *ctx, const void *in0); 62e1051a39Sopenharmony_ci 63e1051a39Sopenharmony_civoid aesni256_cbc_sha1_dec(const void *inp, void *out, size_t blocks, 64e1051a39Sopenharmony_ci const AES_KEY *key, unsigned char iv[16], 65e1051a39Sopenharmony_ci SHA_CTX *ctx, const void *in0); 66e1051a39Sopenharmony_ci 67e1051a39Sopenharmony_ci# define data(ctx) ((EVP_AES_HMAC_SHA1 *)EVP_CIPHER_CTX_get_cipher_data(ctx)) 68e1051a39Sopenharmony_ci 69e1051a39Sopenharmony_cistatic int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, 70e1051a39Sopenharmony_ci const unsigned char *inkey, 71e1051a39Sopenharmony_ci const unsigned char *iv, int enc) 72e1051a39Sopenharmony_ci{ 73e1051a39Sopenharmony_ci EVP_AES_HMAC_SHA1 *key = data(ctx); 74e1051a39Sopenharmony_ci int ret; 75e1051a39Sopenharmony_ci 76e1051a39Sopenharmony_ci if (enc) 77e1051a39Sopenharmony_ci ret = aesni_set_encrypt_key(inkey, 78e1051a39Sopenharmony_ci EVP_CIPHER_CTX_get_key_length(ctx) * 8, 79e1051a39Sopenharmony_ci &key->ks); 80e1051a39Sopenharmony_ci else 81e1051a39Sopenharmony_ci ret = aesni_set_decrypt_key(inkey, 82e1051a39Sopenharmony_ci EVP_CIPHER_CTX_get_key_length(ctx) * 8, 83e1051a39Sopenharmony_ci &key->ks); 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_ci SHA1_Init(&key->head); /* handy when benchmarking */ 86e1051a39Sopenharmony_ci key->tail = key->head; 87e1051a39Sopenharmony_ci key->md = key->head; 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci key->payload_length = NO_PAYLOAD_LENGTH; 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ci return ret < 0 ? 0 : 1; 92e1051a39Sopenharmony_ci} 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_ci# define STITCHED_CALL 95e1051a39Sopenharmony_ci# undef STITCHED_DECRYPT_CALL 96e1051a39Sopenharmony_ci 97e1051a39Sopenharmony_ci# if !defined(STITCHED_CALL) 98e1051a39Sopenharmony_ci# define aes_off 0 99e1051a39Sopenharmony_ci# endif 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_civoid sha1_block_data_order(void *c, const void *p, size_t len); 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_cistatic void sha1_update(SHA_CTX *c, const void *data, size_t len) 104e1051a39Sopenharmony_ci{ 105e1051a39Sopenharmony_ci const unsigned char *ptr = data; 106e1051a39Sopenharmony_ci size_t res; 107e1051a39Sopenharmony_ci 108e1051a39Sopenharmony_ci if ((res = c->num)) { 109e1051a39Sopenharmony_ci res = SHA_CBLOCK - res; 110e1051a39Sopenharmony_ci if (len < res) 111e1051a39Sopenharmony_ci res = len; 112e1051a39Sopenharmony_ci SHA1_Update(c, ptr, res); 113e1051a39Sopenharmony_ci ptr += res; 114e1051a39Sopenharmony_ci len -= res; 115e1051a39Sopenharmony_ci } 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_ci res = len % SHA_CBLOCK; 118e1051a39Sopenharmony_ci len -= res; 119e1051a39Sopenharmony_ci 120e1051a39Sopenharmony_ci if (len) { 121e1051a39Sopenharmony_ci sha1_block_data_order(c, ptr, len / SHA_CBLOCK); 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ci ptr += len; 124e1051a39Sopenharmony_ci c->Nh += len >> 29; 125e1051a39Sopenharmony_ci c->Nl += len <<= 3; 126e1051a39Sopenharmony_ci if (c->Nl < (unsigned int)len) 127e1051a39Sopenharmony_ci c->Nh++; 128e1051a39Sopenharmony_ci } 129e1051a39Sopenharmony_ci 130e1051a39Sopenharmony_ci if (res) 131e1051a39Sopenharmony_ci SHA1_Update(c, ptr, res); 132e1051a39Sopenharmony_ci} 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_ci# ifdef SHA1_Update 135e1051a39Sopenharmony_ci# undef SHA1_Update 136e1051a39Sopenharmony_ci# endif 137e1051a39Sopenharmony_ci# define SHA1_Update sha1_update 138e1051a39Sopenharmony_ci 139e1051a39Sopenharmony_ci# if !defined(OPENSSL_NO_MULTIBLOCK) 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_citypedef struct { 142e1051a39Sopenharmony_ci unsigned int A[8], B[8], C[8], D[8], E[8]; 143e1051a39Sopenharmony_ci} SHA1_MB_CTX; 144e1051a39Sopenharmony_citypedef struct { 145e1051a39Sopenharmony_ci const unsigned char *ptr; 146e1051a39Sopenharmony_ci int blocks; 147e1051a39Sopenharmony_ci} HASH_DESC; 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_civoid sha1_multi_block(SHA1_MB_CTX *, const HASH_DESC *, int); 150e1051a39Sopenharmony_ci 151e1051a39Sopenharmony_citypedef struct { 152e1051a39Sopenharmony_ci const unsigned char *inp; 153e1051a39Sopenharmony_ci unsigned char *out; 154e1051a39Sopenharmony_ci int blocks; 155e1051a39Sopenharmony_ci u64 iv[2]; 156e1051a39Sopenharmony_ci} CIPH_DESC; 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_civoid aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int); 159e1051a39Sopenharmony_ci 160e1051a39Sopenharmony_cistatic size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA1 *key, 161e1051a39Sopenharmony_ci unsigned char *out, 162e1051a39Sopenharmony_ci const unsigned char *inp, 163e1051a39Sopenharmony_ci size_t inp_len, int n4x) 164e1051a39Sopenharmony_ci{ /* n4x is 1 or 2 */ 165e1051a39Sopenharmony_ci HASH_DESC hash_d[8], edges[8]; 166e1051a39Sopenharmony_ci CIPH_DESC ciph_d[8]; 167e1051a39Sopenharmony_ci unsigned char storage[sizeof(SHA1_MB_CTX) + 32]; 168e1051a39Sopenharmony_ci union { 169e1051a39Sopenharmony_ci u64 q[16]; 170e1051a39Sopenharmony_ci u32 d[32]; 171e1051a39Sopenharmony_ci u8 c[128]; 172e1051a39Sopenharmony_ci } blocks[8]; 173e1051a39Sopenharmony_ci SHA1_MB_CTX *ctx; 174e1051a39Sopenharmony_ci unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed = 175e1051a39Sopenharmony_ci 0; 176e1051a39Sopenharmony_ci size_t ret = 0; 177e1051a39Sopenharmony_ci u8 *IVs; 178e1051a39Sopenharmony_ci# if defined(BSWAP8) 179e1051a39Sopenharmony_ci u64 seqnum; 180e1051a39Sopenharmony_ci# endif 181e1051a39Sopenharmony_ci 182e1051a39Sopenharmony_ci /* ask for IVs in bulk */ 183e1051a39Sopenharmony_ci if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0) 184e1051a39Sopenharmony_ci return 0; 185e1051a39Sopenharmony_ci 186e1051a39Sopenharmony_ci ctx = (SHA1_MB_CTX *) (storage + 32 - ((size_t)storage % 32)); /* align */ 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ci frag = (unsigned int)inp_len >> (1 + n4x); 189e1051a39Sopenharmony_ci last = (unsigned int)inp_len + frag - (frag << (1 + n4x)); 190e1051a39Sopenharmony_ci if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) { 191e1051a39Sopenharmony_ci frag++; 192e1051a39Sopenharmony_ci last -= x4 - 1; 193e1051a39Sopenharmony_ci } 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci packlen = 5 + 16 + ((frag + 20 + 16) & -16); 196e1051a39Sopenharmony_ci 197e1051a39Sopenharmony_ci /* populate descriptors with pointers and IVs */ 198e1051a39Sopenharmony_ci hash_d[0].ptr = inp; 199e1051a39Sopenharmony_ci ciph_d[0].inp = inp; 200e1051a39Sopenharmony_ci /* 5+16 is place for header and explicit IV */ 201e1051a39Sopenharmony_ci ciph_d[0].out = out + 5 + 16; 202e1051a39Sopenharmony_ci memcpy(ciph_d[0].out - 16, IVs, 16); 203e1051a39Sopenharmony_ci memcpy(ciph_d[0].iv, IVs, 16); 204e1051a39Sopenharmony_ci IVs += 16; 205e1051a39Sopenharmony_ci 206e1051a39Sopenharmony_ci for (i = 1; i < x4; i++) { 207e1051a39Sopenharmony_ci ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag; 208e1051a39Sopenharmony_ci ciph_d[i].out = ciph_d[i - 1].out + packlen; 209e1051a39Sopenharmony_ci memcpy(ciph_d[i].out - 16, IVs, 16); 210e1051a39Sopenharmony_ci memcpy(ciph_d[i].iv, IVs, 16); 211e1051a39Sopenharmony_ci IVs += 16; 212e1051a39Sopenharmony_ci } 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_ci# if defined(BSWAP8) 215e1051a39Sopenharmony_ci memcpy(blocks[0].c, key->md.data, 8); 216e1051a39Sopenharmony_ci seqnum = BSWAP8(blocks[0].q[0]); 217e1051a39Sopenharmony_ci# endif 218e1051a39Sopenharmony_ci for (i = 0; i < x4; i++) { 219e1051a39Sopenharmony_ci unsigned int len = (i == (x4 - 1) ? last : frag); 220e1051a39Sopenharmony_ci# if !defined(BSWAP8) 221e1051a39Sopenharmony_ci unsigned int carry, j; 222e1051a39Sopenharmony_ci# endif 223e1051a39Sopenharmony_ci 224e1051a39Sopenharmony_ci ctx->A[i] = key->md.h0; 225e1051a39Sopenharmony_ci ctx->B[i] = key->md.h1; 226e1051a39Sopenharmony_ci ctx->C[i] = key->md.h2; 227e1051a39Sopenharmony_ci ctx->D[i] = key->md.h3; 228e1051a39Sopenharmony_ci ctx->E[i] = key->md.h4; 229e1051a39Sopenharmony_ci 230e1051a39Sopenharmony_ci /* fix seqnum */ 231e1051a39Sopenharmony_ci# if defined(BSWAP8) 232e1051a39Sopenharmony_ci blocks[i].q[0] = BSWAP8(seqnum + i); 233e1051a39Sopenharmony_ci# else 234e1051a39Sopenharmony_ci for (carry = i, j = 8; j--;) { 235e1051a39Sopenharmony_ci blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry; 236e1051a39Sopenharmony_ci carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1); 237e1051a39Sopenharmony_ci } 238e1051a39Sopenharmony_ci# endif 239e1051a39Sopenharmony_ci blocks[i].c[8] = ((u8 *)key->md.data)[8]; 240e1051a39Sopenharmony_ci blocks[i].c[9] = ((u8 *)key->md.data)[9]; 241e1051a39Sopenharmony_ci blocks[i].c[10] = ((u8 *)key->md.data)[10]; 242e1051a39Sopenharmony_ci /* fix length */ 243e1051a39Sopenharmony_ci blocks[i].c[11] = (u8)(len >> 8); 244e1051a39Sopenharmony_ci blocks[i].c[12] = (u8)(len); 245e1051a39Sopenharmony_ci 246e1051a39Sopenharmony_ci memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13); 247e1051a39Sopenharmony_ci hash_d[i].ptr += 64 - 13; 248e1051a39Sopenharmony_ci hash_d[i].blocks = (len - (64 - 13)) / 64; 249e1051a39Sopenharmony_ci 250e1051a39Sopenharmony_ci edges[i].ptr = blocks[i].c; 251e1051a39Sopenharmony_ci edges[i].blocks = 1; 252e1051a39Sopenharmony_ci } 253e1051a39Sopenharmony_ci 254e1051a39Sopenharmony_ci /* hash 13-byte headers and first 64-13 bytes of inputs */ 255e1051a39Sopenharmony_ci sha1_multi_block(ctx, edges, n4x); 256e1051a39Sopenharmony_ci /* hash bulk inputs */ 257e1051a39Sopenharmony_ci# define MAXCHUNKSIZE 2048 258e1051a39Sopenharmony_ci# if MAXCHUNKSIZE%64 259e1051a39Sopenharmony_ci# error "MAXCHUNKSIZE is not divisible by 64" 260e1051a39Sopenharmony_ci# elif MAXCHUNKSIZE 261e1051a39Sopenharmony_ci /* 262e1051a39Sopenharmony_ci * goal is to minimize pressure on L1 cache by moving in shorter steps, 263e1051a39Sopenharmony_ci * so that hashed data is still in the cache by the time we encrypt it 264e1051a39Sopenharmony_ci */ 265e1051a39Sopenharmony_ci minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64; 266e1051a39Sopenharmony_ci if (minblocks > MAXCHUNKSIZE / 64) { 267e1051a39Sopenharmony_ci for (i = 0; i < x4; i++) { 268e1051a39Sopenharmony_ci edges[i].ptr = hash_d[i].ptr; 269e1051a39Sopenharmony_ci edges[i].blocks = MAXCHUNKSIZE / 64; 270e1051a39Sopenharmony_ci ciph_d[i].blocks = MAXCHUNKSIZE / 16; 271e1051a39Sopenharmony_ci } 272e1051a39Sopenharmony_ci do { 273e1051a39Sopenharmony_ci sha1_multi_block(ctx, edges, n4x); 274e1051a39Sopenharmony_ci aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); 275e1051a39Sopenharmony_ci 276e1051a39Sopenharmony_ci for (i = 0; i < x4; i++) { 277e1051a39Sopenharmony_ci edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE; 278e1051a39Sopenharmony_ci hash_d[i].blocks -= MAXCHUNKSIZE / 64; 279e1051a39Sopenharmony_ci edges[i].blocks = MAXCHUNKSIZE / 64; 280e1051a39Sopenharmony_ci ciph_d[i].inp += MAXCHUNKSIZE; 281e1051a39Sopenharmony_ci ciph_d[i].out += MAXCHUNKSIZE; 282e1051a39Sopenharmony_ci ciph_d[i].blocks = MAXCHUNKSIZE / 16; 283e1051a39Sopenharmony_ci memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16); 284e1051a39Sopenharmony_ci } 285e1051a39Sopenharmony_ci processed += MAXCHUNKSIZE; 286e1051a39Sopenharmony_ci minblocks -= MAXCHUNKSIZE / 64; 287e1051a39Sopenharmony_ci } while (minblocks > MAXCHUNKSIZE / 64); 288e1051a39Sopenharmony_ci } 289e1051a39Sopenharmony_ci# endif 290e1051a39Sopenharmony_ci# undef MAXCHUNKSIZE 291e1051a39Sopenharmony_ci sha1_multi_block(ctx, hash_d, n4x); 292e1051a39Sopenharmony_ci 293e1051a39Sopenharmony_ci memset(blocks, 0, sizeof(blocks)); 294e1051a39Sopenharmony_ci for (i = 0; i < x4; i++) { 295e1051a39Sopenharmony_ci unsigned int len = (i == (x4 - 1) ? last : frag), 296e1051a39Sopenharmony_ci off = hash_d[i].blocks * 64; 297e1051a39Sopenharmony_ci const unsigned char *ptr = hash_d[i].ptr + off; 298e1051a39Sopenharmony_ci 299e1051a39Sopenharmony_ci off = (len - processed) - (64 - 13) - off; /* remainder actually */ 300e1051a39Sopenharmony_ci memcpy(blocks[i].c, ptr, off); 301e1051a39Sopenharmony_ci blocks[i].c[off] = 0x80; 302e1051a39Sopenharmony_ci len += 64 + 13; /* 64 is HMAC header */ 303e1051a39Sopenharmony_ci len *= 8; /* convert to bits */ 304e1051a39Sopenharmony_ci if (off < (64 - 8)) { 305e1051a39Sopenharmony_ci# ifdef BSWAP4 306e1051a39Sopenharmony_ci blocks[i].d[15] = BSWAP4(len); 307e1051a39Sopenharmony_ci# else 308e1051a39Sopenharmony_ci PUTU32(blocks[i].c + 60, len); 309e1051a39Sopenharmony_ci# endif 310e1051a39Sopenharmony_ci edges[i].blocks = 1; 311e1051a39Sopenharmony_ci } else { 312e1051a39Sopenharmony_ci# ifdef BSWAP4 313e1051a39Sopenharmony_ci blocks[i].d[31] = BSWAP4(len); 314e1051a39Sopenharmony_ci# else 315e1051a39Sopenharmony_ci PUTU32(blocks[i].c + 124, len); 316e1051a39Sopenharmony_ci# endif 317e1051a39Sopenharmony_ci edges[i].blocks = 2; 318e1051a39Sopenharmony_ci } 319e1051a39Sopenharmony_ci edges[i].ptr = blocks[i].c; 320e1051a39Sopenharmony_ci } 321e1051a39Sopenharmony_ci 322e1051a39Sopenharmony_ci /* hash input tails and finalize */ 323e1051a39Sopenharmony_ci sha1_multi_block(ctx, edges, n4x); 324e1051a39Sopenharmony_ci 325e1051a39Sopenharmony_ci memset(blocks, 0, sizeof(blocks)); 326e1051a39Sopenharmony_ci for (i = 0; i < x4; i++) { 327e1051a39Sopenharmony_ci# ifdef BSWAP4 328e1051a39Sopenharmony_ci blocks[i].d[0] = BSWAP4(ctx->A[i]); 329e1051a39Sopenharmony_ci ctx->A[i] = key->tail.h0; 330e1051a39Sopenharmony_ci blocks[i].d[1] = BSWAP4(ctx->B[i]); 331e1051a39Sopenharmony_ci ctx->B[i] = key->tail.h1; 332e1051a39Sopenharmony_ci blocks[i].d[2] = BSWAP4(ctx->C[i]); 333e1051a39Sopenharmony_ci ctx->C[i] = key->tail.h2; 334e1051a39Sopenharmony_ci blocks[i].d[3] = BSWAP4(ctx->D[i]); 335e1051a39Sopenharmony_ci ctx->D[i] = key->tail.h3; 336e1051a39Sopenharmony_ci blocks[i].d[4] = BSWAP4(ctx->E[i]); 337e1051a39Sopenharmony_ci ctx->E[i] = key->tail.h4; 338e1051a39Sopenharmony_ci blocks[i].c[20] = 0x80; 339e1051a39Sopenharmony_ci blocks[i].d[15] = BSWAP4((64 + 20) * 8); 340e1051a39Sopenharmony_ci# else 341e1051a39Sopenharmony_ci PUTU32(blocks[i].c + 0, ctx->A[i]); 342e1051a39Sopenharmony_ci ctx->A[i] = key->tail.h0; 343e1051a39Sopenharmony_ci PUTU32(blocks[i].c + 4, ctx->B[i]); 344e1051a39Sopenharmony_ci ctx->B[i] = key->tail.h1; 345e1051a39Sopenharmony_ci PUTU32(blocks[i].c + 8, ctx->C[i]); 346e1051a39Sopenharmony_ci ctx->C[i] = key->tail.h2; 347e1051a39Sopenharmony_ci PUTU32(blocks[i].c + 12, ctx->D[i]); 348e1051a39Sopenharmony_ci ctx->D[i] = key->tail.h3; 349e1051a39Sopenharmony_ci PUTU32(blocks[i].c + 16, ctx->E[i]); 350e1051a39Sopenharmony_ci ctx->E[i] = key->tail.h4; 351e1051a39Sopenharmony_ci blocks[i].c[20] = 0x80; 352e1051a39Sopenharmony_ci PUTU32(blocks[i].c + 60, (64 + 20) * 8); 353e1051a39Sopenharmony_ci# endif 354e1051a39Sopenharmony_ci edges[i].ptr = blocks[i].c; 355e1051a39Sopenharmony_ci edges[i].blocks = 1; 356e1051a39Sopenharmony_ci } 357e1051a39Sopenharmony_ci 358e1051a39Sopenharmony_ci /* finalize MACs */ 359e1051a39Sopenharmony_ci sha1_multi_block(ctx, edges, n4x); 360e1051a39Sopenharmony_ci 361e1051a39Sopenharmony_ci for (i = 0; i < x4; i++) { 362e1051a39Sopenharmony_ci unsigned int len = (i == (x4 - 1) ? last : frag), pad, j; 363e1051a39Sopenharmony_ci unsigned char *out0 = out; 364e1051a39Sopenharmony_ci 365e1051a39Sopenharmony_ci memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed); 366e1051a39Sopenharmony_ci ciph_d[i].inp = ciph_d[i].out; 367e1051a39Sopenharmony_ci 368e1051a39Sopenharmony_ci out += 5 + 16 + len; 369e1051a39Sopenharmony_ci 370e1051a39Sopenharmony_ci /* write MAC */ 371e1051a39Sopenharmony_ci PUTU32(out + 0, ctx->A[i]); 372e1051a39Sopenharmony_ci PUTU32(out + 4, ctx->B[i]); 373e1051a39Sopenharmony_ci PUTU32(out + 8, ctx->C[i]); 374e1051a39Sopenharmony_ci PUTU32(out + 12, ctx->D[i]); 375e1051a39Sopenharmony_ci PUTU32(out + 16, ctx->E[i]); 376e1051a39Sopenharmony_ci out += 20; 377e1051a39Sopenharmony_ci len += 20; 378e1051a39Sopenharmony_ci 379e1051a39Sopenharmony_ci /* pad */ 380e1051a39Sopenharmony_ci pad = 15 - len % 16; 381e1051a39Sopenharmony_ci for (j = 0; j <= pad; j++) 382e1051a39Sopenharmony_ci *(out++) = pad; 383e1051a39Sopenharmony_ci len += pad + 1; 384e1051a39Sopenharmony_ci 385e1051a39Sopenharmony_ci ciph_d[i].blocks = (len - processed) / 16; 386e1051a39Sopenharmony_ci len += 16; /* account for explicit iv */ 387e1051a39Sopenharmony_ci 388e1051a39Sopenharmony_ci /* arrange header */ 389e1051a39Sopenharmony_ci out0[0] = ((u8 *)key->md.data)[8]; 390e1051a39Sopenharmony_ci out0[1] = ((u8 *)key->md.data)[9]; 391e1051a39Sopenharmony_ci out0[2] = ((u8 *)key->md.data)[10]; 392e1051a39Sopenharmony_ci out0[3] = (u8)(len >> 8); 393e1051a39Sopenharmony_ci out0[4] = (u8)(len); 394e1051a39Sopenharmony_ci 395e1051a39Sopenharmony_ci ret += len + 5; 396e1051a39Sopenharmony_ci inp += frag; 397e1051a39Sopenharmony_ci } 398e1051a39Sopenharmony_ci 399e1051a39Sopenharmony_ci aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); 400e1051a39Sopenharmony_ci 401e1051a39Sopenharmony_ci OPENSSL_cleanse(blocks, sizeof(blocks)); 402e1051a39Sopenharmony_ci OPENSSL_cleanse(ctx, sizeof(*ctx)); 403e1051a39Sopenharmony_ci 404e1051a39Sopenharmony_ci return ret; 405e1051a39Sopenharmony_ci} 406e1051a39Sopenharmony_ci# endif 407e1051a39Sopenharmony_ci 408e1051a39Sopenharmony_cistatic int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 409e1051a39Sopenharmony_ci const unsigned char *in, size_t len) 410e1051a39Sopenharmony_ci{ 411e1051a39Sopenharmony_ci EVP_AES_HMAC_SHA1 *key = data(ctx); 412e1051a39Sopenharmony_ci unsigned int l; 413e1051a39Sopenharmony_ci size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and 414e1051a39Sopenharmony_ci * later */ 415e1051a39Sopenharmony_ci sha_off = 0; 416e1051a39Sopenharmony_ci# if defined(STITCHED_CALL) 417e1051a39Sopenharmony_ci size_t aes_off = 0, blocks; 418e1051a39Sopenharmony_ci 419e1051a39Sopenharmony_ci sha_off = SHA_CBLOCK - key->md.num; 420e1051a39Sopenharmony_ci# endif 421e1051a39Sopenharmony_ci 422e1051a39Sopenharmony_ci key->payload_length = NO_PAYLOAD_LENGTH; 423e1051a39Sopenharmony_ci 424e1051a39Sopenharmony_ci if (len % AES_BLOCK_SIZE) 425e1051a39Sopenharmony_ci return 0; 426e1051a39Sopenharmony_ci 427e1051a39Sopenharmony_ci if (EVP_CIPHER_CTX_is_encrypting(ctx)) { 428e1051a39Sopenharmony_ci if (plen == NO_PAYLOAD_LENGTH) 429e1051a39Sopenharmony_ci plen = len; 430e1051a39Sopenharmony_ci else if (len != 431e1051a39Sopenharmony_ci ((plen + SHA_DIGEST_LENGTH + 432e1051a39Sopenharmony_ci AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)) 433e1051a39Sopenharmony_ci return 0; 434e1051a39Sopenharmony_ci else if (key->aux.tls_ver >= TLS1_1_VERSION) 435e1051a39Sopenharmony_ci iv = AES_BLOCK_SIZE; 436e1051a39Sopenharmony_ci 437e1051a39Sopenharmony_ci# if defined(STITCHED_CALL) 438e1051a39Sopenharmony_ci if (plen > (sha_off + iv) 439e1051a39Sopenharmony_ci && (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) { 440e1051a39Sopenharmony_ci SHA1_Update(&key->md, in + iv, sha_off); 441e1051a39Sopenharmony_ci 442e1051a39Sopenharmony_ci aesni_cbc_sha1_enc(in, out, blocks, &key->ks, ctx->iv, 443e1051a39Sopenharmony_ci &key->md, in + iv + sha_off); 444e1051a39Sopenharmony_ci blocks *= SHA_CBLOCK; 445e1051a39Sopenharmony_ci aes_off += blocks; 446e1051a39Sopenharmony_ci sha_off += blocks; 447e1051a39Sopenharmony_ci key->md.Nh += blocks >> 29; 448e1051a39Sopenharmony_ci key->md.Nl += blocks <<= 3; 449e1051a39Sopenharmony_ci if (key->md.Nl < (unsigned int)blocks) 450e1051a39Sopenharmony_ci key->md.Nh++; 451e1051a39Sopenharmony_ci } else { 452e1051a39Sopenharmony_ci sha_off = 0; 453e1051a39Sopenharmony_ci } 454e1051a39Sopenharmony_ci# endif 455e1051a39Sopenharmony_ci sha_off += iv; 456e1051a39Sopenharmony_ci SHA1_Update(&key->md, in + sha_off, plen - sha_off); 457e1051a39Sopenharmony_ci 458e1051a39Sopenharmony_ci if (plen != len) { /* "TLS" mode of operation */ 459e1051a39Sopenharmony_ci if (in != out) 460e1051a39Sopenharmony_ci memcpy(out + aes_off, in + aes_off, plen - aes_off); 461e1051a39Sopenharmony_ci 462e1051a39Sopenharmony_ci /* calculate HMAC and append it to payload */ 463e1051a39Sopenharmony_ci SHA1_Final(out + plen, &key->md); 464e1051a39Sopenharmony_ci key->md = key->tail; 465e1051a39Sopenharmony_ci SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH); 466e1051a39Sopenharmony_ci SHA1_Final(out + plen, &key->md); 467e1051a39Sopenharmony_ci 468e1051a39Sopenharmony_ci /* pad the payload|hmac */ 469e1051a39Sopenharmony_ci plen += SHA_DIGEST_LENGTH; 470e1051a39Sopenharmony_ci for (l = len - plen - 1; plen < len; plen++) 471e1051a39Sopenharmony_ci out[plen] = l; 472e1051a39Sopenharmony_ci /* encrypt HMAC|padding at once */ 473e1051a39Sopenharmony_ci aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off, 474e1051a39Sopenharmony_ci &key->ks, ctx->iv, 1); 475e1051a39Sopenharmony_ci } else { 476e1051a39Sopenharmony_ci aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off, 477e1051a39Sopenharmony_ci &key->ks, ctx->iv, 1); 478e1051a39Sopenharmony_ci } 479e1051a39Sopenharmony_ci } else { 480e1051a39Sopenharmony_ci union { 481e1051a39Sopenharmony_ci unsigned int u[SHA_DIGEST_LENGTH / sizeof(unsigned int)]; 482e1051a39Sopenharmony_ci unsigned char c[32 + SHA_DIGEST_LENGTH]; 483e1051a39Sopenharmony_ci } mac, *pmac; 484e1051a39Sopenharmony_ci 485e1051a39Sopenharmony_ci /* arrange cache line alignment */ 486e1051a39Sopenharmony_ci pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32)); 487e1051a39Sopenharmony_ci 488e1051a39Sopenharmony_ci if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ 489e1051a39Sopenharmony_ci size_t inp_len, mask, j, i; 490e1051a39Sopenharmony_ci unsigned int res, maxpad, pad, bitlen; 491e1051a39Sopenharmony_ci int ret = 1; 492e1051a39Sopenharmony_ci union { 493e1051a39Sopenharmony_ci unsigned int u[SHA_LBLOCK]; 494e1051a39Sopenharmony_ci unsigned char c[SHA_CBLOCK]; 495e1051a39Sopenharmony_ci } *data = (void *)key->md.data; 496e1051a39Sopenharmony_ci# if defined(STITCHED_DECRYPT_CALL) 497e1051a39Sopenharmony_ci unsigned char tail_iv[AES_BLOCK_SIZE]; 498e1051a39Sopenharmony_ci int stitch = 0; 499e1051a39Sopenharmony_ci# endif 500e1051a39Sopenharmony_ci 501e1051a39Sopenharmony_ci if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3]) 502e1051a39Sopenharmony_ci >= TLS1_1_VERSION) { 503e1051a39Sopenharmony_ci if (len < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1)) 504e1051a39Sopenharmony_ci return 0; 505e1051a39Sopenharmony_ci 506e1051a39Sopenharmony_ci /* omit explicit iv */ 507e1051a39Sopenharmony_ci memcpy(ctx->iv, in, AES_BLOCK_SIZE); 508e1051a39Sopenharmony_ci 509e1051a39Sopenharmony_ci in += AES_BLOCK_SIZE; 510e1051a39Sopenharmony_ci out += AES_BLOCK_SIZE; 511e1051a39Sopenharmony_ci len -= AES_BLOCK_SIZE; 512e1051a39Sopenharmony_ci } else if (len < (SHA_DIGEST_LENGTH + 1)) 513e1051a39Sopenharmony_ci return 0; 514e1051a39Sopenharmony_ci 515e1051a39Sopenharmony_ci# if defined(STITCHED_DECRYPT_CALL) 516e1051a39Sopenharmony_ci if (len >= 1024 && ctx->key_len == 32) { 517e1051a39Sopenharmony_ci /* decrypt last block */ 518e1051a39Sopenharmony_ci memcpy(tail_iv, in + len - 2 * AES_BLOCK_SIZE, 519e1051a39Sopenharmony_ci AES_BLOCK_SIZE); 520e1051a39Sopenharmony_ci aesni_cbc_encrypt(in + len - AES_BLOCK_SIZE, 521e1051a39Sopenharmony_ci out + len - AES_BLOCK_SIZE, AES_BLOCK_SIZE, 522e1051a39Sopenharmony_ci &key->ks, tail_iv, 0); 523e1051a39Sopenharmony_ci stitch = 1; 524e1051a39Sopenharmony_ci } else 525e1051a39Sopenharmony_ci# endif 526e1051a39Sopenharmony_ci /* decrypt HMAC|padding at once */ 527e1051a39Sopenharmony_ci aesni_cbc_encrypt(in, out, len, &key->ks, 528e1051a39Sopenharmony_ci ctx->iv, 0); 529e1051a39Sopenharmony_ci 530e1051a39Sopenharmony_ci /* figure out payload length */ 531e1051a39Sopenharmony_ci pad = out[len - 1]; 532e1051a39Sopenharmony_ci maxpad = len - (SHA_DIGEST_LENGTH + 1); 533e1051a39Sopenharmony_ci maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); 534e1051a39Sopenharmony_ci maxpad &= 255; 535e1051a39Sopenharmony_ci 536e1051a39Sopenharmony_ci mask = constant_time_ge(maxpad, pad); 537e1051a39Sopenharmony_ci ret &= mask; 538e1051a39Sopenharmony_ci /* 539e1051a39Sopenharmony_ci * If pad is invalid then we will fail the above test but we must 540e1051a39Sopenharmony_ci * continue anyway because we are in constant time code. However, 541e1051a39Sopenharmony_ci * we'll use the maxpad value instead of the supplied pad to make 542e1051a39Sopenharmony_ci * sure we perform well defined pointer arithmetic. 543e1051a39Sopenharmony_ci */ 544e1051a39Sopenharmony_ci pad = constant_time_select(mask, pad, maxpad); 545e1051a39Sopenharmony_ci 546e1051a39Sopenharmony_ci inp_len = len - (SHA_DIGEST_LENGTH + pad + 1); 547e1051a39Sopenharmony_ci 548e1051a39Sopenharmony_ci key->aux.tls_aad[plen - 2] = inp_len >> 8; 549e1051a39Sopenharmony_ci key->aux.tls_aad[plen - 1] = inp_len; 550e1051a39Sopenharmony_ci 551e1051a39Sopenharmony_ci /* calculate HMAC */ 552e1051a39Sopenharmony_ci key->md = key->head; 553e1051a39Sopenharmony_ci SHA1_Update(&key->md, key->aux.tls_aad, plen); 554e1051a39Sopenharmony_ci 555e1051a39Sopenharmony_ci# if defined(STITCHED_DECRYPT_CALL) 556e1051a39Sopenharmony_ci if (stitch) { 557e1051a39Sopenharmony_ci blocks = (len - (256 + 32 + SHA_CBLOCK)) / SHA_CBLOCK; 558e1051a39Sopenharmony_ci aes_off = len - AES_BLOCK_SIZE - blocks * SHA_CBLOCK; 559e1051a39Sopenharmony_ci sha_off = SHA_CBLOCK - plen; 560e1051a39Sopenharmony_ci 561e1051a39Sopenharmony_ci aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0); 562e1051a39Sopenharmony_ci 563e1051a39Sopenharmony_ci SHA1_Update(&key->md, out, sha_off); 564e1051a39Sopenharmony_ci aesni256_cbc_sha1_dec(in + aes_off, 565e1051a39Sopenharmony_ci out + aes_off, blocks, &key->ks, 566e1051a39Sopenharmony_ci ctx->iv, &key->md, out + sha_off); 567e1051a39Sopenharmony_ci 568e1051a39Sopenharmony_ci sha_off += blocks *= SHA_CBLOCK; 569e1051a39Sopenharmony_ci out += sha_off; 570e1051a39Sopenharmony_ci len -= sha_off; 571e1051a39Sopenharmony_ci inp_len -= sha_off; 572e1051a39Sopenharmony_ci 573e1051a39Sopenharmony_ci key->md.Nl += (blocks << 3); /* at most 18 bits */ 574e1051a39Sopenharmony_ci memcpy(ctx->iv, tail_iv, AES_BLOCK_SIZE); 575e1051a39Sopenharmony_ci } 576e1051a39Sopenharmony_ci# endif 577e1051a39Sopenharmony_ci 578e1051a39Sopenharmony_ci# if 1 /* see original reference version in #else */ 579e1051a39Sopenharmony_ci len -= SHA_DIGEST_LENGTH; /* amend mac */ 580e1051a39Sopenharmony_ci if (len >= (256 + SHA_CBLOCK)) { 581e1051a39Sopenharmony_ci j = (len - (256 + SHA_CBLOCK)) & (0 - SHA_CBLOCK); 582e1051a39Sopenharmony_ci j += SHA_CBLOCK - key->md.num; 583e1051a39Sopenharmony_ci SHA1_Update(&key->md, out, j); 584e1051a39Sopenharmony_ci out += j; 585e1051a39Sopenharmony_ci len -= j; 586e1051a39Sopenharmony_ci inp_len -= j; 587e1051a39Sopenharmony_ci } 588e1051a39Sopenharmony_ci 589e1051a39Sopenharmony_ci /* but pretend as if we hashed padded payload */ 590e1051a39Sopenharmony_ci bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */ 591e1051a39Sopenharmony_ci# ifdef BSWAP4 592e1051a39Sopenharmony_ci bitlen = BSWAP4(bitlen); 593e1051a39Sopenharmony_ci# else 594e1051a39Sopenharmony_ci mac.c[0] = 0; 595e1051a39Sopenharmony_ci mac.c[1] = (unsigned char)(bitlen >> 16); 596e1051a39Sopenharmony_ci mac.c[2] = (unsigned char)(bitlen >> 8); 597e1051a39Sopenharmony_ci mac.c[3] = (unsigned char)bitlen; 598e1051a39Sopenharmony_ci bitlen = mac.u[0]; 599e1051a39Sopenharmony_ci# endif 600e1051a39Sopenharmony_ci 601e1051a39Sopenharmony_ci pmac->u[0] = 0; 602e1051a39Sopenharmony_ci pmac->u[1] = 0; 603e1051a39Sopenharmony_ci pmac->u[2] = 0; 604e1051a39Sopenharmony_ci pmac->u[3] = 0; 605e1051a39Sopenharmony_ci pmac->u[4] = 0; 606e1051a39Sopenharmony_ci 607e1051a39Sopenharmony_ci for (res = key->md.num, j = 0; j < len; j++) { 608e1051a39Sopenharmony_ci size_t c = out[j]; 609e1051a39Sopenharmony_ci mask = (j - inp_len) >> (sizeof(j) * 8 - 8); 610e1051a39Sopenharmony_ci c &= mask; 611e1051a39Sopenharmony_ci c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8)); 612e1051a39Sopenharmony_ci data->c[res++] = (unsigned char)c; 613e1051a39Sopenharmony_ci 614e1051a39Sopenharmony_ci if (res != SHA_CBLOCK) 615e1051a39Sopenharmony_ci continue; 616e1051a39Sopenharmony_ci 617e1051a39Sopenharmony_ci /* j is not incremented yet */ 618e1051a39Sopenharmony_ci mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1)); 619e1051a39Sopenharmony_ci data->u[SHA_LBLOCK - 1] |= bitlen & mask; 620e1051a39Sopenharmony_ci sha1_block_data_order(&key->md, data, 1); 621e1051a39Sopenharmony_ci mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1)); 622e1051a39Sopenharmony_ci pmac->u[0] |= key->md.h0 & mask; 623e1051a39Sopenharmony_ci pmac->u[1] |= key->md.h1 & mask; 624e1051a39Sopenharmony_ci pmac->u[2] |= key->md.h2 & mask; 625e1051a39Sopenharmony_ci pmac->u[3] |= key->md.h3 & mask; 626e1051a39Sopenharmony_ci pmac->u[4] |= key->md.h4 & mask; 627e1051a39Sopenharmony_ci res = 0; 628e1051a39Sopenharmony_ci } 629e1051a39Sopenharmony_ci 630e1051a39Sopenharmony_ci for (i = res; i < SHA_CBLOCK; i++, j++) 631e1051a39Sopenharmony_ci data->c[i] = 0; 632e1051a39Sopenharmony_ci 633e1051a39Sopenharmony_ci if (res > SHA_CBLOCK - 8) { 634e1051a39Sopenharmony_ci mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1)); 635e1051a39Sopenharmony_ci data->u[SHA_LBLOCK - 1] |= bitlen & mask; 636e1051a39Sopenharmony_ci sha1_block_data_order(&key->md, data, 1); 637e1051a39Sopenharmony_ci mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); 638e1051a39Sopenharmony_ci pmac->u[0] |= key->md.h0 & mask; 639e1051a39Sopenharmony_ci pmac->u[1] |= key->md.h1 & mask; 640e1051a39Sopenharmony_ci pmac->u[2] |= key->md.h2 & mask; 641e1051a39Sopenharmony_ci pmac->u[3] |= key->md.h3 & mask; 642e1051a39Sopenharmony_ci pmac->u[4] |= key->md.h4 & mask; 643e1051a39Sopenharmony_ci 644e1051a39Sopenharmony_ci memset(data, 0, SHA_CBLOCK); 645e1051a39Sopenharmony_ci j += 64; 646e1051a39Sopenharmony_ci } 647e1051a39Sopenharmony_ci data->u[SHA_LBLOCK - 1] = bitlen; 648e1051a39Sopenharmony_ci sha1_block_data_order(&key->md, data, 1); 649e1051a39Sopenharmony_ci mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); 650e1051a39Sopenharmony_ci pmac->u[0] |= key->md.h0 & mask; 651e1051a39Sopenharmony_ci pmac->u[1] |= key->md.h1 & mask; 652e1051a39Sopenharmony_ci pmac->u[2] |= key->md.h2 & mask; 653e1051a39Sopenharmony_ci pmac->u[3] |= key->md.h3 & mask; 654e1051a39Sopenharmony_ci pmac->u[4] |= key->md.h4 & mask; 655e1051a39Sopenharmony_ci 656e1051a39Sopenharmony_ci# ifdef BSWAP4 657e1051a39Sopenharmony_ci pmac->u[0] = BSWAP4(pmac->u[0]); 658e1051a39Sopenharmony_ci pmac->u[1] = BSWAP4(pmac->u[1]); 659e1051a39Sopenharmony_ci pmac->u[2] = BSWAP4(pmac->u[2]); 660e1051a39Sopenharmony_ci pmac->u[3] = BSWAP4(pmac->u[3]); 661e1051a39Sopenharmony_ci pmac->u[4] = BSWAP4(pmac->u[4]); 662e1051a39Sopenharmony_ci# else 663e1051a39Sopenharmony_ci for (i = 0; i < 5; i++) { 664e1051a39Sopenharmony_ci res = pmac->u[i]; 665e1051a39Sopenharmony_ci pmac->c[4 * i + 0] = (unsigned char)(res >> 24); 666e1051a39Sopenharmony_ci pmac->c[4 * i + 1] = (unsigned char)(res >> 16); 667e1051a39Sopenharmony_ci pmac->c[4 * i + 2] = (unsigned char)(res >> 8); 668e1051a39Sopenharmony_ci pmac->c[4 * i + 3] = (unsigned char)res; 669e1051a39Sopenharmony_ci } 670e1051a39Sopenharmony_ci# endif 671e1051a39Sopenharmony_ci len += SHA_DIGEST_LENGTH; 672e1051a39Sopenharmony_ci# else /* pre-lucky-13 reference version of above */ 673e1051a39Sopenharmony_ci SHA1_Update(&key->md, out, inp_len); 674e1051a39Sopenharmony_ci res = key->md.num; 675e1051a39Sopenharmony_ci SHA1_Final(pmac->c, &key->md); 676e1051a39Sopenharmony_ci 677e1051a39Sopenharmony_ci { 678e1051a39Sopenharmony_ci unsigned int inp_blocks, pad_blocks; 679e1051a39Sopenharmony_ci 680e1051a39Sopenharmony_ci /* but pretend as if we hashed padded payload */ 681e1051a39Sopenharmony_ci inp_blocks = 682e1051a39Sopenharmony_ci 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); 683e1051a39Sopenharmony_ci res += (unsigned int)(len - inp_len); 684e1051a39Sopenharmony_ci pad_blocks = res / SHA_CBLOCK; 685e1051a39Sopenharmony_ci res %= SHA_CBLOCK; 686e1051a39Sopenharmony_ci pad_blocks += 687e1051a39Sopenharmony_ci 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); 688e1051a39Sopenharmony_ci for (; inp_blocks < pad_blocks; inp_blocks++) 689e1051a39Sopenharmony_ci sha1_block_data_order(&key->md, data, 1); 690e1051a39Sopenharmony_ci } 691e1051a39Sopenharmony_ci# endif 692e1051a39Sopenharmony_ci key->md = key->tail; 693e1051a39Sopenharmony_ci SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH); 694e1051a39Sopenharmony_ci SHA1_Final(pmac->c, &key->md); 695e1051a39Sopenharmony_ci 696e1051a39Sopenharmony_ci /* verify HMAC */ 697e1051a39Sopenharmony_ci out += inp_len; 698e1051a39Sopenharmony_ci len -= inp_len; 699e1051a39Sopenharmony_ci# if 1 /* see original reference version in #else */ 700e1051a39Sopenharmony_ci { 701e1051a39Sopenharmony_ci unsigned char *p = out + len - 1 - maxpad - SHA_DIGEST_LENGTH; 702e1051a39Sopenharmony_ci size_t off = out - p; 703e1051a39Sopenharmony_ci unsigned int c, cmask; 704e1051a39Sopenharmony_ci 705e1051a39Sopenharmony_ci for (res = 0, i = 0, j = 0; j < maxpad + SHA_DIGEST_LENGTH; j++) { 706e1051a39Sopenharmony_ci c = p[j]; 707e1051a39Sopenharmony_ci cmask = 708e1051a39Sopenharmony_ci ((int)(j - off - SHA_DIGEST_LENGTH)) >> (sizeof(int) * 709e1051a39Sopenharmony_ci 8 - 1); 710e1051a39Sopenharmony_ci res |= (c ^ pad) & ~cmask; /* ... and padding */ 711e1051a39Sopenharmony_ci cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1); 712e1051a39Sopenharmony_ci res |= (c ^ pmac->c[i]) & cmask; 713e1051a39Sopenharmony_ci i += 1 & cmask; 714e1051a39Sopenharmony_ci } 715e1051a39Sopenharmony_ci 716e1051a39Sopenharmony_ci res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); 717e1051a39Sopenharmony_ci ret &= (int)~res; 718e1051a39Sopenharmony_ci } 719e1051a39Sopenharmony_ci# else /* pre-lucky-13 reference version of above */ 720e1051a39Sopenharmony_ci for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++) 721e1051a39Sopenharmony_ci res |= out[i] ^ pmac->c[i]; 722e1051a39Sopenharmony_ci res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); 723e1051a39Sopenharmony_ci ret &= (int)~res; 724e1051a39Sopenharmony_ci 725e1051a39Sopenharmony_ci /* verify padding */ 726e1051a39Sopenharmony_ci pad = (pad & ~res) | (maxpad & res); 727e1051a39Sopenharmony_ci out = out + len - 1 - pad; 728e1051a39Sopenharmony_ci for (res = 0, i = 0; i < pad; i++) 729e1051a39Sopenharmony_ci res |= out[i] ^ pad; 730e1051a39Sopenharmony_ci 731e1051a39Sopenharmony_ci res = (0 - res) >> (sizeof(res) * 8 - 1); 732e1051a39Sopenharmony_ci ret &= (int)~res; 733e1051a39Sopenharmony_ci# endif 734e1051a39Sopenharmony_ci return ret; 735e1051a39Sopenharmony_ci } else { 736e1051a39Sopenharmony_ci# if defined(STITCHED_DECRYPT_CALL) 737e1051a39Sopenharmony_ci if (len >= 1024 && ctx->key_len == 32) { 738e1051a39Sopenharmony_ci if (sha_off %= SHA_CBLOCK) 739e1051a39Sopenharmony_ci blocks = (len - 3 * SHA_CBLOCK) / SHA_CBLOCK; 740e1051a39Sopenharmony_ci else 741e1051a39Sopenharmony_ci blocks = (len - 2 * SHA_CBLOCK) / SHA_CBLOCK; 742e1051a39Sopenharmony_ci aes_off = len - blocks * SHA_CBLOCK; 743e1051a39Sopenharmony_ci 744e1051a39Sopenharmony_ci aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0); 745e1051a39Sopenharmony_ci SHA1_Update(&key->md, out, sha_off); 746e1051a39Sopenharmony_ci aesni256_cbc_sha1_dec(in + aes_off, 747e1051a39Sopenharmony_ci out + aes_off, blocks, &key->ks, 748e1051a39Sopenharmony_ci ctx->iv, &key->md, out + sha_off); 749e1051a39Sopenharmony_ci 750e1051a39Sopenharmony_ci sha_off += blocks *= SHA_CBLOCK; 751e1051a39Sopenharmony_ci out += sha_off; 752e1051a39Sopenharmony_ci len -= sha_off; 753e1051a39Sopenharmony_ci 754e1051a39Sopenharmony_ci key->md.Nh += blocks >> 29; 755e1051a39Sopenharmony_ci key->md.Nl += blocks <<= 3; 756e1051a39Sopenharmony_ci if (key->md.Nl < (unsigned int)blocks) 757e1051a39Sopenharmony_ci key->md.Nh++; 758e1051a39Sopenharmony_ci } else 759e1051a39Sopenharmony_ci# endif 760e1051a39Sopenharmony_ci /* decrypt HMAC|padding at once */ 761e1051a39Sopenharmony_ci aesni_cbc_encrypt(in, out, len, &key->ks, 762e1051a39Sopenharmony_ci ctx->iv, 0); 763e1051a39Sopenharmony_ci 764e1051a39Sopenharmony_ci SHA1_Update(&key->md, out, len); 765e1051a39Sopenharmony_ci } 766e1051a39Sopenharmony_ci } 767e1051a39Sopenharmony_ci 768e1051a39Sopenharmony_ci return 1; 769e1051a39Sopenharmony_ci} 770e1051a39Sopenharmony_ci 771e1051a39Sopenharmony_cistatic int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, 772e1051a39Sopenharmony_ci void *ptr) 773e1051a39Sopenharmony_ci{ 774e1051a39Sopenharmony_ci EVP_AES_HMAC_SHA1 *key = data(ctx); 775e1051a39Sopenharmony_ci 776e1051a39Sopenharmony_ci switch (type) { 777e1051a39Sopenharmony_ci case EVP_CTRL_AEAD_SET_MAC_KEY: 778e1051a39Sopenharmony_ci { 779e1051a39Sopenharmony_ci unsigned int i; 780e1051a39Sopenharmony_ci unsigned char hmac_key[64]; 781e1051a39Sopenharmony_ci 782e1051a39Sopenharmony_ci memset(hmac_key, 0, sizeof(hmac_key)); 783e1051a39Sopenharmony_ci 784e1051a39Sopenharmony_ci if (arg > (int)sizeof(hmac_key)) { 785e1051a39Sopenharmony_ci SHA1_Init(&key->head); 786e1051a39Sopenharmony_ci SHA1_Update(&key->head, ptr, arg); 787e1051a39Sopenharmony_ci SHA1_Final(hmac_key, &key->head); 788e1051a39Sopenharmony_ci } else { 789e1051a39Sopenharmony_ci memcpy(hmac_key, ptr, arg); 790e1051a39Sopenharmony_ci } 791e1051a39Sopenharmony_ci 792e1051a39Sopenharmony_ci for (i = 0; i < sizeof(hmac_key); i++) 793e1051a39Sopenharmony_ci hmac_key[i] ^= 0x36; /* ipad */ 794e1051a39Sopenharmony_ci SHA1_Init(&key->head); 795e1051a39Sopenharmony_ci SHA1_Update(&key->head, hmac_key, sizeof(hmac_key)); 796e1051a39Sopenharmony_ci 797e1051a39Sopenharmony_ci for (i = 0; i < sizeof(hmac_key); i++) 798e1051a39Sopenharmony_ci hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ 799e1051a39Sopenharmony_ci SHA1_Init(&key->tail); 800e1051a39Sopenharmony_ci SHA1_Update(&key->tail, hmac_key, sizeof(hmac_key)); 801e1051a39Sopenharmony_ci 802e1051a39Sopenharmony_ci OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); 803e1051a39Sopenharmony_ci 804e1051a39Sopenharmony_ci return 1; 805e1051a39Sopenharmony_ci } 806e1051a39Sopenharmony_ci case EVP_CTRL_AEAD_TLS1_AAD: 807e1051a39Sopenharmony_ci { 808e1051a39Sopenharmony_ci unsigned char *p = ptr; 809e1051a39Sopenharmony_ci unsigned int len; 810e1051a39Sopenharmony_ci 811e1051a39Sopenharmony_ci if (arg != EVP_AEAD_TLS1_AAD_LEN) 812e1051a39Sopenharmony_ci return -1; 813e1051a39Sopenharmony_ci 814e1051a39Sopenharmony_ci len = p[arg - 2] << 8 | p[arg - 1]; 815e1051a39Sopenharmony_ci 816e1051a39Sopenharmony_ci if (EVP_CIPHER_CTX_is_encrypting(ctx)) { 817e1051a39Sopenharmony_ci key->payload_length = len; 818e1051a39Sopenharmony_ci if ((key->aux.tls_ver = 819e1051a39Sopenharmony_ci p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { 820e1051a39Sopenharmony_ci if (len < AES_BLOCK_SIZE) 821e1051a39Sopenharmony_ci return 0; 822e1051a39Sopenharmony_ci len -= AES_BLOCK_SIZE; 823e1051a39Sopenharmony_ci p[arg - 2] = len >> 8; 824e1051a39Sopenharmony_ci p[arg - 1] = len; 825e1051a39Sopenharmony_ci } 826e1051a39Sopenharmony_ci key->md = key->head; 827e1051a39Sopenharmony_ci SHA1_Update(&key->md, p, arg); 828e1051a39Sopenharmony_ci 829e1051a39Sopenharmony_ci return (int)(((len + SHA_DIGEST_LENGTH + 830e1051a39Sopenharmony_ci AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) 831e1051a39Sopenharmony_ci - len); 832e1051a39Sopenharmony_ci } else { 833e1051a39Sopenharmony_ci memcpy(key->aux.tls_aad, ptr, arg); 834e1051a39Sopenharmony_ci key->payload_length = arg; 835e1051a39Sopenharmony_ci 836e1051a39Sopenharmony_ci return SHA_DIGEST_LENGTH; 837e1051a39Sopenharmony_ci } 838e1051a39Sopenharmony_ci } 839e1051a39Sopenharmony_ci# if !defined(OPENSSL_NO_MULTIBLOCK) 840e1051a39Sopenharmony_ci case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE: 841e1051a39Sopenharmony_ci return (int)(5 + 16 + ((arg + 20 + 16) & -16)); 842e1051a39Sopenharmony_ci case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD: 843e1051a39Sopenharmony_ci { 844e1051a39Sopenharmony_ci EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = 845e1051a39Sopenharmony_ci (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; 846e1051a39Sopenharmony_ci unsigned int n4x = 1, x4; 847e1051a39Sopenharmony_ci unsigned int frag, last, packlen, inp_len; 848e1051a39Sopenharmony_ci 849e1051a39Sopenharmony_ci if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM)) 850e1051a39Sopenharmony_ci return -1; 851e1051a39Sopenharmony_ci 852e1051a39Sopenharmony_ci inp_len = param->inp[11] << 8 | param->inp[12]; 853e1051a39Sopenharmony_ci 854e1051a39Sopenharmony_ci if (EVP_CIPHER_CTX_is_encrypting(ctx)) { 855e1051a39Sopenharmony_ci if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION) 856e1051a39Sopenharmony_ci return -1; 857e1051a39Sopenharmony_ci 858e1051a39Sopenharmony_ci if (inp_len) { 859e1051a39Sopenharmony_ci if (inp_len < 4096) 860e1051a39Sopenharmony_ci return 0; /* too short */ 861e1051a39Sopenharmony_ci 862e1051a39Sopenharmony_ci if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5)) 863e1051a39Sopenharmony_ci n4x = 2; /* AVX2 */ 864e1051a39Sopenharmony_ci } else if ((n4x = param->interleave / 4) && n4x <= 2) 865e1051a39Sopenharmony_ci inp_len = param->len; 866e1051a39Sopenharmony_ci else 867e1051a39Sopenharmony_ci return -1; 868e1051a39Sopenharmony_ci 869e1051a39Sopenharmony_ci key->md = key->head; 870e1051a39Sopenharmony_ci SHA1_Update(&key->md, param->inp, 13); 871e1051a39Sopenharmony_ci 872e1051a39Sopenharmony_ci x4 = 4 * n4x; 873e1051a39Sopenharmony_ci n4x += 1; 874e1051a39Sopenharmony_ci 875e1051a39Sopenharmony_ci frag = inp_len >> n4x; 876e1051a39Sopenharmony_ci last = inp_len + frag - (frag << n4x); 877e1051a39Sopenharmony_ci if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) { 878e1051a39Sopenharmony_ci frag++; 879e1051a39Sopenharmony_ci last -= x4 - 1; 880e1051a39Sopenharmony_ci } 881e1051a39Sopenharmony_ci 882e1051a39Sopenharmony_ci packlen = 5 + 16 + ((frag + 20 + 16) & -16); 883e1051a39Sopenharmony_ci packlen = (packlen << n4x) - packlen; 884e1051a39Sopenharmony_ci packlen += 5 + 16 + ((last + 20 + 16) & -16); 885e1051a39Sopenharmony_ci 886e1051a39Sopenharmony_ci param->interleave = x4; 887e1051a39Sopenharmony_ci 888e1051a39Sopenharmony_ci return (int)packlen; 889e1051a39Sopenharmony_ci } else 890e1051a39Sopenharmony_ci return -1; /* not yet */ 891e1051a39Sopenharmony_ci } 892e1051a39Sopenharmony_ci case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT: 893e1051a39Sopenharmony_ci { 894e1051a39Sopenharmony_ci EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = 895e1051a39Sopenharmony_ci (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; 896e1051a39Sopenharmony_ci 897e1051a39Sopenharmony_ci return (int)tls1_1_multi_block_encrypt(key, param->out, 898e1051a39Sopenharmony_ci param->inp, param->len, 899e1051a39Sopenharmony_ci param->interleave / 4); 900e1051a39Sopenharmony_ci } 901e1051a39Sopenharmony_ci case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT: 902e1051a39Sopenharmony_ci# endif 903e1051a39Sopenharmony_ci default: 904e1051a39Sopenharmony_ci return -1; 905e1051a39Sopenharmony_ci } 906e1051a39Sopenharmony_ci} 907e1051a39Sopenharmony_ci 908e1051a39Sopenharmony_cistatic EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = { 909e1051a39Sopenharmony_ci# ifdef NID_aes_128_cbc_hmac_sha1 910e1051a39Sopenharmony_ci NID_aes_128_cbc_hmac_sha1, 911e1051a39Sopenharmony_ci# else 912e1051a39Sopenharmony_ci NID_undef, 913e1051a39Sopenharmony_ci# endif 914e1051a39Sopenharmony_ci AES_BLOCK_SIZE, 16, AES_BLOCK_SIZE, 915e1051a39Sopenharmony_ci EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | 916e1051a39Sopenharmony_ci EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, 917e1051a39Sopenharmony_ci EVP_ORIG_GLOBAL, 918e1051a39Sopenharmony_ci aesni_cbc_hmac_sha1_init_key, 919e1051a39Sopenharmony_ci aesni_cbc_hmac_sha1_cipher, 920e1051a39Sopenharmony_ci NULL, 921e1051a39Sopenharmony_ci sizeof(EVP_AES_HMAC_SHA1), 922e1051a39Sopenharmony_ci EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, 923e1051a39Sopenharmony_ci EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, 924e1051a39Sopenharmony_ci aesni_cbc_hmac_sha1_ctrl, 925e1051a39Sopenharmony_ci NULL 926e1051a39Sopenharmony_ci}; 927e1051a39Sopenharmony_ci 928e1051a39Sopenharmony_cistatic EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = { 929e1051a39Sopenharmony_ci# ifdef NID_aes_256_cbc_hmac_sha1 930e1051a39Sopenharmony_ci NID_aes_256_cbc_hmac_sha1, 931e1051a39Sopenharmony_ci# else 932e1051a39Sopenharmony_ci NID_undef, 933e1051a39Sopenharmony_ci# endif 934e1051a39Sopenharmony_ci AES_BLOCK_SIZE, 32, AES_BLOCK_SIZE, 935e1051a39Sopenharmony_ci EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | 936e1051a39Sopenharmony_ci EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, 937e1051a39Sopenharmony_ci EVP_ORIG_GLOBAL, 938e1051a39Sopenharmony_ci aesni_cbc_hmac_sha1_init_key, 939e1051a39Sopenharmony_ci aesni_cbc_hmac_sha1_cipher, 940e1051a39Sopenharmony_ci NULL, 941e1051a39Sopenharmony_ci sizeof(EVP_AES_HMAC_SHA1), 942e1051a39Sopenharmony_ci EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, 943e1051a39Sopenharmony_ci EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, 944e1051a39Sopenharmony_ci aesni_cbc_hmac_sha1_ctrl, 945e1051a39Sopenharmony_ci NULL 946e1051a39Sopenharmony_ci}; 947e1051a39Sopenharmony_ci 948e1051a39Sopenharmony_ciconst EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void) 949e1051a39Sopenharmony_ci{ 950e1051a39Sopenharmony_ci return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ? 951e1051a39Sopenharmony_ci &aesni_128_cbc_hmac_sha1_cipher : NULL); 952e1051a39Sopenharmony_ci} 953e1051a39Sopenharmony_ci 954e1051a39Sopenharmony_ciconst EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void) 955e1051a39Sopenharmony_ci{ 956e1051a39Sopenharmony_ci return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ? 957e1051a39Sopenharmony_ci &aesni_256_cbc_hmac_sha1_cipher : NULL); 958e1051a39Sopenharmony_ci} 959e1051a39Sopenharmony_ci#else 960e1051a39Sopenharmony_ciconst EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void) 961e1051a39Sopenharmony_ci{ 962e1051a39Sopenharmony_ci return NULL; 963e1051a39Sopenharmony_ci} 964e1051a39Sopenharmony_ci 965e1051a39Sopenharmony_ciconst EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void) 966e1051a39Sopenharmony_ci{ 967e1051a39Sopenharmony_ci return NULL; 968e1051a39Sopenharmony_ci} 969e1051a39Sopenharmony_ci#endif 970