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