/*
- * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2013-2021 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
-#include <openssl/opensslconf.h>
+/*
+ * AES low level APIs are deprecated for public use, but still ok for internal
+ * use where we're using them to implement the higher level EVP interface, as is
+ * the case here.
+ */
+#include "internal/deprecated.h"
#include <stdio.h>
#include <string.h>
-
-
+#include <openssl/opensslconf.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/aes.h>
#include <openssl/sha.h>
#include <openssl/rand.h>
-#include "modes_lcl.h"
-#include "internal/constant_time_locl.h"
-#include "internal/evp_int.h"
+#include "internal/cryptlib.h"
+#include "crypto/modes.h"
+#include "internal/constant_time.h"
+#include "crypto/evp.h"
+#include "evp_local.h"
typedef struct {
AES_KEY ks;
defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined(_M_X64) )
-extern unsigned int OPENSSL_ia32cap_P[];
# define AESNI_CAPABLE (1<<(57-32))
int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
if (enc)
ret = aesni_set_encrypt_key(inkey,
- EVP_CIPHER_CTX_key_length(ctx) * 8,
+ EVP_CIPHER_CTX_get_key_length(ctx) * 8,
&key->ks);
else
ret = aesni_set_decrypt_key(inkey,
- EVP_CIPHER_CTX_key_length(ctx) * 8,
+ EVP_CIPHER_CTX_get_key_length(ctx) * 8,
&key->ks);
SHA256_Init(&key->head); /* handy when benchmarking */
if (len % AES_BLOCK_SIZE)
return 0;
- if (EVP_CIPHER_CTX_encrypting(ctx)) {
+ if (EVP_CIPHER_CTX_is_encrypting(ctx)) {
if (plen == NO_PAYLOAD_LENGTH)
plen = len;
else if (len !=
* to identify it and avoid stitch invocation. So that after we
* establish that current CPU supports AVX, we even see if it's
* either even XOP-capable Bulldozer-based or GenuineIntel one.
+ * But SHAEXT-capable go ahead...
*/
- if (OPENSSL_ia32cap_P[1] & (1 << (60 - 32)) && /* AVX? */
- ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */
- | (OPENSSL_ia32cap_P[0] & (1<<30))) && /* "Intel CPU"? */
+ if (((OPENSSL_ia32cap_P[2] & (1 << 29)) || /* SHAEXT? */
+ ((OPENSSL_ia32cap_P[1] & (1 << (60 - 32))) && /* AVX? */
+ ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */
+ | (OPENSSL_ia32cap_P[0] & (1 << 30))))) && /* "Intel CPU"? */
plen > (sha_off + iv) &&
(blocks = (plen - (sha_off + iv)) / SHA256_CBLOCK)) {
SHA256_Update(&key->md, in + iv, sha_off);
(void)aesni_cbc_sha256_enc(in, out, blocks, &key->ks,
- EVP_CIPHER_CTX_iv_noconst(ctx),
- &key->md, in + iv + sha_off);
+ ctx->iv, &key->md, in + iv + sha_off);
blocks *= SHA256_CBLOCK;
aes_off += blocks;
sha_off += blocks;
out[plen] = l;
/* encrypt HMAC|padding at once */
aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off,
- &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
+ &key->ks, ctx->iv, 1);
} else {
aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off,
- &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
+ &key->ks, ctx->iv, 1);
}
} else {
union {
/* decrypt HMAC|padding at once */
aesni_cbc_encrypt(in, out, len, &key->ks,
- EVP_CIPHER_CTX_iv_noconst(ctx), 0);
+ ctx->iv, 0);
if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
size_t inp_len, mask, j, i;
maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
maxpad &= 255;
- ret &= constant_time_ge(maxpad, pad);
+ mask = constant_time_ge(maxpad, pad);
+ ret &= mask;
+ /*
+ * If pad is invalid then we will fail the above test but we must
+ * continue anyway because we are in constant time code. However,
+ * we'll use the maxpad value instead of the supplied pad to make
+ * sure we perform well defined pointer arithmetic.
+ */
+ pad = constant_time_select(mask, pad, maxpad);
inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1);
- mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1)));
- inp_len &= mask;
- ret &= (int)mask;
key->aux.tls_aad[plen - 2] = inp_len >> 8;
key->aux.tls_aad[plen - 1] = inp_len;
size_t off = out - p;
unsigned int c, cmask;
- maxpad += SHA256_DIGEST_LENGTH;
- for (res = 0, i = 0, j = 0; j < maxpad; j++) {
+ for (res = 0, i = 0, j = 0; j < maxpad + SHA256_DIGEST_LENGTH;
+ j++) {
c = p[j];
cmask =
((int)(j - off - SHA256_DIGEST_LENGTH)) >>
res |= (c ^ pmac->c[i]) & cmask;
i += 1 & cmask;
}
- maxpad -= SHA256_DIGEST_LENGTH;
res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
ret &= (int)~res;
len = p[arg - 2] << 8 | p[arg - 1];
- if (EVP_CIPHER_CTX_encrypting(ctx)) {
+ if (EVP_CIPHER_CTX_is_encrypting(ctx)) {
key->payload_length = len;
if ((key->aux.tls_ver =
p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
inp_len = param->inp[11] << 8 | param->inp[12];
- if (EVP_CIPHER_CTX_encrypting(ctx)) {
+ if (EVP_CIPHER_CTX_is_encrypting(ctx)) {
if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION)
return -1;
AES_BLOCK_SIZE, 16, AES_BLOCK_SIZE,
EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+ EVP_ORIG_GLOBAL,
aesni_cbc_hmac_sha256_init_key,
aesni_cbc_hmac_sha256_cipher,
NULL,
AES_BLOCK_SIZE, 32, AES_BLOCK_SIZE,
EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+ EVP_ORIG_GLOBAL,
aesni_cbc_hmac_sha256_init_key,
aesni_cbc_hmac_sha256_cipher,
NULL,