Latest update.
This commit is contained in:
@@ -8,8 +8,8 @@
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "cipher_locl.h"
|
||||
#include "internal/providercommonerr.h"
|
||||
#include "cipher_local.h"
|
||||
#include "prov/providercommonerr.h"
|
||||
|
||||
/*
|
||||
* Fills a single block of buffered data from the input, and returns the amount
|
||||
|
||||
@@ -1,21 +1,5 @@
|
||||
LIBS=../../../libcrypto
|
||||
|
||||
IF[{- !$disabled{des} -}]
|
||||
$COMMON_DES=cipher_tdes.c cipher_tdes_hw.c
|
||||
ENDIF
|
||||
|
||||
$COMMON=cipher_common.c cipher_common_hw.c block.c \
|
||||
cipher_aes.c cipher_aes_hw.c \
|
||||
cipher_aes_xts.c cipher_aes_xts_hw.c \
|
||||
# This source is common building blocks for all ciphers in all our providers.
|
||||
SOURCE[../../libcommon.a]=\
|
||||
cipher_common.c cipher_common_hw.c block.c \
|
||||
cipher_gcm.c cipher_gcm_hw.c \
|
||||
cipher_aes_gcm.c cipher_aes_gcm_hw.c \
|
||||
cipher_ccm.c cipher_ccm_hw.c \
|
||||
cipher_aes_ccm.c cipher_aes_ccm_hw.c \
|
||||
cipher_aes_wrp.c \
|
||||
$COMMON_DES
|
||||
|
||||
SOURCE[../../../libcrypto]=$COMMON
|
||||
INCLUDE[../../../libcrypto]=. ../../../crypto
|
||||
|
||||
SOURCE[../../fips]=$COMMON
|
||||
INCLUDE[../../fips]=. ../../../crypto
|
||||
cipher_ccm.c cipher_ccm_hw.c
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* Dispatch functions for AES cipher modes ecb, cbc, ofb, cfb, ctr */
|
||||
|
||||
#include "cipher_aes.h"
|
||||
#include "internal/provider_algs.h"
|
||||
|
||||
static OSSL_OP_cipher_freectx_fn aes_freectx;
|
||||
static OSSL_OP_cipher_dupctx_fn aes_dupctx;
|
||||
|
||||
static void aes_freectx(void *vctx)
|
||||
{
|
||||
PROV_AES_CTX *ctx = (PROV_AES_CTX *)vctx;
|
||||
|
||||
OPENSSL_clear_free(ctx, sizeof(*ctx));
|
||||
}
|
||||
|
||||
static void *aes_dupctx(void *ctx)
|
||||
{
|
||||
PROV_AES_CTX *in = (PROV_AES_CTX *)ctx;
|
||||
PROV_AES_CTX *ret = OPENSSL_malloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
*ret = *in;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* aes256ecb_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, ecb, ECB, 0, 256, 128, 0, block)
|
||||
/* aes192ecb_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, ecb, ECB, 0, 192, 128, 0, block)
|
||||
/* aes128ecb_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, ecb, ECB, 0, 128, 128, 0, block)
|
||||
/* aes256cbc_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cbc, CBC, 0, 256, 128, 128, block)
|
||||
/* aes192cbc_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cbc, CBC, 0, 192, 128, 128, block)
|
||||
/* aes128cbc_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cbc, CBC, 0, 128, 128, 128, block)
|
||||
/* aes256ofb_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, ofb, OFB, 0, 256, 8, 128, stream)
|
||||
/* aes192ofb_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, ofb, OFB, 0, 192, 8, 128, stream)
|
||||
/* aes128ofb_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, ofb, OFB, 0, 128, 8, 128, stream)
|
||||
/* aes256cfb_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 256, 8, 128, stream)
|
||||
/* aes192cfb_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 192, 8, 128, stream)
|
||||
/* aes128cfb_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 128, 8, 128, stream)
|
||||
/* aes256cfb1_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 256, 8, 128, stream)
|
||||
/* aes192cfb1_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 192, 8, 128, stream)
|
||||
/* aes128cfb1_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 128, 8, 128, stream)
|
||||
/* aes256cfb8_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 256, 8, 128, stream)
|
||||
/* aes192cfb8_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 192, 8, 128, stream)
|
||||
/* aes128cfb8_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 128, 8, 128, stream)
|
||||
/* aes256ctr_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, ctr, CTR, 0, 256, 8, 128, stream)
|
||||
/* aes192ctr_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, ctr, CTR, 0, 192, 8, 128, stream)
|
||||
/* aes128ctr_functions */
|
||||
IMPLEMENT_generic_cipher(aes, AES, ctr, CTR, 0, 128, 8, 128, stream)
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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/aes.h>
|
||||
#include "internal/ciphers/ciphercommon.h"
|
||||
|
||||
typedef struct prov_aes_ctx_st {
|
||||
PROV_CIPHER_CTX base; /* Must be first */
|
||||
union {
|
||||
OSSL_UNION_ALIGN;
|
||||
AES_KEY ks;
|
||||
} ks;
|
||||
|
||||
/* Platform specific data */
|
||||
union {
|
||||
int dummy;
|
||||
#if defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
|
||||
struct {
|
||||
union {
|
||||
OSSL_UNION_ALIGN;
|
||||
/*-
|
||||
* KM-AES parameter block - begin
|
||||
* (see z/Architecture Principles of Operation >= SA22-7832-06)
|
||||
*/
|
||||
struct {
|
||||
unsigned char k[32];
|
||||
} km;
|
||||
/* KM-AES parameter block - end */
|
||||
/*-
|
||||
* KMO-AES/KMF-AES parameter block - begin
|
||||
* (see z/Architecture Principles of Operation >= SA22-7832-08)
|
||||
*/
|
||||
struct {
|
||||
unsigned char cv[16];
|
||||
unsigned char k[32];
|
||||
} kmo_kmf;
|
||||
/* KMO-AES/KMF-AES parameter block - end */
|
||||
} param;
|
||||
unsigned int fc;
|
||||
int res;
|
||||
} s390x;
|
||||
#endif /* defined(OPENSSL_CPUID_OBJ) && defined(__s390__) */
|
||||
} plat;
|
||||
|
||||
} PROV_AES_CTX;
|
||||
|
||||
#define PROV_CIPHER_HW_aes_ofb PROV_CIPHER_HW_aes_ofb128
|
||||
#define PROV_CIPHER_HW_aes_cfb PROV_CIPHER_HW_aes_cfb128
|
||||
const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_ecb(size_t keybits);
|
||||
const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_cbc(size_t keybits);
|
||||
const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_ofb128(size_t keybits);
|
||||
const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_cfb128(size_t keybits);
|
||||
const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_cfb1(size_t keybits);
|
||||
const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_cfb8(size_t keybits);
|
||||
const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_ctr(size_t keybits);
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* Dispatch functions for AES CCM mode */
|
||||
|
||||
#include "cipher_locl.h"
|
||||
#include "internal/ciphers/cipher_ccm.h"
|
||||
#include "internal/provider_algs.h"
|
||||
|
||||
static void *aes_ccm_newctx(void *provctx, size_t keybits)
|
||||
{
|
||||
PROV_AES_CCM_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
|
||||
|
||||
if (ctx != NULL)
|
||||
ccm_initctx(&ctx->base, keybits, PROV_AES_HW_ccm(keybits));
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static OSSL_OP_cipher_freectx_fn aes_ccm_freectx;
|
||||
static void aes_ccm_freectx(void *vctx)
|
||||
{
|
||||
PROV_AES_CCM_CTX *ctx = (PROV_AES_CCM_CTX *)vctx;
|
||||
|
||||
ccm_finalctx((PROV_CCM_CTX *)ctx);
|
||||
OPENSSL_clear_free(ctx, sizeof(*ctx));
|
||||
}
|
||||
|
||||
/* aes128ccm_functions */
|
||||
IMPLEMENT_aead_cipher(aes, ccm, CCM, AEAD_FLAGS, 128, 8, 96);
|
||||
/* aes192ccm_functions */
|
||||
IMPLEMENT_aead_cipher(aes, ccm, CCM, AEAD_FLAGS, 192, 8, 96);
|
||||
/* aes256ccm_functions */
|
||||
IMPLEMENT_aead_cipher(aes, ccm, CCM, AEAD_FLAGS, 256, 8, 96);
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* AES CCM mode */
|
||||
|
||||
#include "cipher_locl.h"
|
||||
#include "internal/ciphers/cipher_ccm.h"
|
||||
|
||||
#define AES_HW_CCM_SET_KEY_FN(fn_set_enc_key, fn_blk, fn_ccm_enc, fn_ccm_dec) \
|
||||
fn_set_enc_key(key, keylen * 8, &actx->ccm.ks.ks); \
|
||||
CRYPTO_ccm128_init(&ctx->ccm_ctx, ctx->m, ctx->l, &actx->ccm.ks.ks, \
|
||||
(block128_f)fn_blk); \
|
||||
ctx->str = ctx->enc ? (ccm128_f)fn_ccm_enc : (ccm128_f)fn_ccm_dec; \
|
||||
ctx->key_set = 1;
|
||||
|
||||
static int ccm_generic_aes_initkey(PROV_CCM_CTX *ctx, const unsigned char *key,
|
||||
size_t keylen)
|
||||
{
|
||||
PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx;
|
||||
|
||||
#ifdef HWAES_CAPABLE
|
||||
if (HWAES_CAPABLE) {
|
||||
AES_HW_CCM_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_encrypt, NULL, NULL);
|
||||
} else
|
||||
#endif /* HWAES_CAPABLE */
|
||||
|
||||
#ifdef VPAES_CAPABLE
|
||||
if (VPAES_CAPABLE) {
|
||||
AES_HW_CCM_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_encrypt, NULL, NULL);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
AES_HW_CCM_SET_KEY_FN(AES_set_encrypt_key, AES_encrypt, NULL, NULL)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const PROV_CCM_HW aes_ccm = {
|
||||
ccm_generic_aes_initkey,
|
||||
ccm_generic_setiv,
|
||||
ccm_generic_setaad,
|
||||
ccm_generic_auth_encrypt,
|
||||
ccm_generic_auth_decrypt,
|
||||
ccm_generic_gettag
|
||||
};
|
||||
|
||||
#if defined(S390X_aes_128_CAPABLE)
|
||||
# include "cipher_aes_ccm_hw_s390x.inc"
|
||||
#elif defined(AESNI_CAPABLE)
|
||||
# include "cipher_aes_ccm_hw_aesni.inc"
|
||||
#elif defined(SPARC_AES_CAPABLE)
|
||||
# include "cipher_aes_ccm_hw_t4.inc"
|
||||
#else
|
||||
const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits)
|
||||
{
|
||||
return &aes_ccm;
|
||||
}
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*-
|
||||
* AES-NI support for AES CCM.
|
||||
* This file is included by cipher_ccm_hw.c
|
||||
*/
|
||||
|
||||
static int ccm_aesni_initkey(PROV_CCM_CTX *ctx, const unsigned char *key,
|
||||
size_t keylen)
|
||||
{
|
||||
PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx;
|
||||
|
||||
AES_HW_CCM_SET_KEY_FN(aesni_set_encrypt_key, aesni_encrypt,
|
||||
aesni_ccm64_encrypt_blocks,
|
||||
aesni_ccm64_decrypt_blocks);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const PROV_CCM_HW aesni_ccm = {
|
||||
ccm_aesni_initkey,
|
||||
ccm_generic_setiv,
|
||||
ccm_generic_setaad,
|
||||
ccm_generic_auth_encrypt,
|
||||
ccm_generic_auth_decrypt,
|
||||
ccm_generic_gettag
|
||||
};
|
||||
|
||||
const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits)
|
||||
{
|
||||
return AESNI_CAPABLE ? &aesni_ccm : &aes_ccm;
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*-
|
||||
* S390X support for AES CCM.
|
||||
* This file is included by cipher_ccm_hw.c
|
||||
*/
|
||||
|
||||
#define S390X_CCM_AAD_FLAG 0x40
|
||||
|
||||
static int s390x_aes_ccm_initkey(PROV_CCM_CTX *ctx,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
PROV_AES_CCM_CTX *sctx = (PROV_AES_CCM_CTX *)ctx;
|
||||
|
||||
sctx->ccm.s390x.fc = S390X_AES_FC(keylen);
|
||||
memcpy(&sctx->ccm.s390x.kmac.k, key, keylen);
|
||||
/* Store encoded m and l. */
|
||||
sctx->ccm.s390x.nonce.b[0] = ((ctx->l - 1) & 0x7)
|
||||
| (((ctx->m - 2) >> 1) & 0x7) << 3;
|
||||
memset(sctx->ccm.s390x.nonce.b + 1, 0, sizeof(sctx->ccm.s390x.nonce.b));
|
||||
sctx->ccm.s390x.blocks = 0;
|
||||
ctx->key_set = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_aes_ccm_setiv(PROV_CCM_CTX *ctx,
|
||||
const unsigned char *nonce, size_t noncelen,
|
||||
size_t mlen)
|
||||
{
|
||||
PROV_AES_CCM_CTX *sctx = (PROV_AES_CCM_CTX *)ctx;
|
||||
|
||||
sctx->ccm.s390x.nonce.b[0] &= ~S390X_CCM_AAD_FLAG;
|
||||
sctx->ccm.s390x.nonce.g[1] = mlen;
|
||||
memcpy(sctx->ccm.s390x.nonce.b + 1, nonce, 15 - ctx->l);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Process additional authenticated data. Code is big-endian.
|
||||
*/
|
||||
static int s390x_aes_ccm_setaad(PROV_CCM_CTX *ctx,
|
||||
const unsigned char *aad, size_t alen)
|
||||
{
|
||||
PROV_AES_CCM_CTX *sctx = (PROV_AES_CCM_CTX *)ctx;
|
||||
unsigned char *ptr;
|
||||
int i, rem;
|
||||
|
||||
if (!alen)
|
||||
return 1;
|
||||
|
||||
sctx->ccm.s390x.nonce.b[0] |= S390X_CCM_AAD_FLAG;
|
||||
|
||||
/* Suppress 'type-punned pointer dereference' warning. */
|
||||
ptr = sctx->ccm.s390x.buf.b;
|
||||
|
||||
if (alen < ((1 << 16) - (1 << 8))) {
|
||||
*(uint16_t *)ptr = alen;
|
||||
i = 2;
|
||||
} else if (sizeof(alen) == 8
|
||||
&& alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) {
|
||||
*(uint16_t *)ptr = 0xffff;
|
||||
*(uint64_t *)(ptr + 2) = alen;
|
||||
i = 10;
|
||||
} else {
|
||||
*(uint16_t *)ptr = 0xfffe;
|
||||
*(uint32_t *)(ptr + 2) = alen;
|
||||
i = 6;
|
||||
}
|
||||
|
||||
while (i < 16 && alen) {
|
||||
sctx->ccm.s390x.buf.b[i] = *aad;
|
||||
++aad;
|
||||
--alen;
|
||||
++i;
|
||||
}
|
||||
while (i < 16) {
|
||||
sctx->ccm.s390x.buf.b[i] = 0;
|
||||
++i;
|
||||
}
|
||||
|
||||
sctx->ccm.s390x.kmac.icv.g[0] = 0;
|
||||
sctx->ccm.s390x.kmac.icv.g[1] = 0;
|
||||
s390x_kmac(sctx->ccm.s390x.nonce.b, 32, sctx->ccm.s390x.fc,
|
||||
&sctx->ccm.s390x.kmac);
|
||||
sctx->ccm.s390x.blocks += 2;
|
||||
|
||||
rem = alen & 0xf;
|
||||
alen &= ~(size_t)0xf;
|
||||
if (alen) {
|
||||
s390x_kmac(aad, alen, sctx->ccm.s390x.fc, &sctx->ccm.s390x.kmac);
|
||||
sctx->ccm.s390x.blocks += alen >> 4;
|
||||
aad += alen;
|
||||
}
|
||||
if (rem) {
|
||||
for (i = 0; i < rem; i++)
|
||||
sctx->ccm.s390x.kmac.icv.b[i] ^= aad[i];
|
||||
|
||||
s390x_km(sctx->ccm.s390x.kmac.icv.b, 16,
|
||||
sctx->ccm.s390x.kmac.icv.b, sctx->ccm.s390x.fc,
|
||||
sctx->ccm.s390x.kmac.k);
|
||||
sctx->ccm.s390x.blocks++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* En/de-crypt plain/cipher-text. Compute tag from plaintext. Returns 1 for
|
||||
* success.
|
||||
*/
|
||||
static int s390x_aes_ccm_auth_encdec(PROV_CCM_CTX *ctx,
|
||||
const unsigned char *in,
|
||||
unsigned char *out, size_t len, int enc)
|
||||
{
|
||||
PROV_AES_CCM_CTX *sctx = (PROV_AES_CCM_CTX *)ctx;
|
||||
size_t n, rem;
|
||||
unsigned int i, l, num;
|
||||
unsigned char flags;
|
||||
|
||||
flags = sctx->ccm.s390x.nonce.b[0];
|
||||
if (!(flags & S390X_CCM_AAD_FLAG)) {
|
||||
s390x_km(sctx->ccm.s390x.nonce.b, 16, sctx->ccm.s390x.kmac.icv.b,
|
||||
sctx->ccm.s390x.fc, sctx->ccm.s390x.kmac.k);
|
||||
sctx->ccm.s390x.blocks++;
|
||||
}
|
||||
l = flags & 0x7;
|
||||
sctx->ccm.s390x.nonce.b[0] = l;
|
||||
|
||||
/*-
|
||||
* Reconstruct length from encoded length field
|
||||
* and initialize it with counter value.
|
||||
*/
|
||||
n = 0;
|
||||
for (i = 15 - l; i < 15; i++) {
|
||||
n |= sctx->ccm.s390x.nonce.b[i];
|
||||
sctx->ccm.s390x.nonce.b[i] = 0;
|
||||
n <<= 8;
|
||||
}
|
||||
n |= sctx->ccm.s390x.nonce.b[15];
|
||||
sctx->ccm.s390x.nonce.b[15] = 1;
|
||||
|
||||
if (n != len)
|
||||
return 0; /* length mismatch */
|
||||
|
||||
if (enc) {
|
||||
/* Two operations per block plus one for tag encryption */
|
||||
sctx->ccm.s390x.blocks += (((len + 15) >> 4) << 1) + 1;
|
||||
if (sctx->ccm.s390x.blocks > (1ULL << 61))
|
||||
return 0; /* too much data */
|
||||
}
|
||||
|
||||
num = 0;
|
||||
rem = len & 0xf;
|
||||
len &= ~(size_t)0xf;
|
||||
|
||||
if (enc) {
|
||||
/* mac-then-encrypt */
|
||||
if (len)
|
||||
s390x_kmac(in, len, sctx->ccm.s390x.fc, &sctx->ccm.s390x.kmac);
|
||||
if (rem) {
|
||||
for (i = 0; i < rem; i++)
|
||||
sctx->ccm.s390x.kmac.icv.b[i] ^= in[len + i];
|
||||
|
||||
s390x_km(sctx->ccm.s390x.kmac.icv.b, 16,
|
||||
sctx->ccm.s390x.kmac.icv.b,
|
||||
sctx->ccm.s390x.fc, sctx->ccm.s390x.kmac.k);
|
||||
}
|
||||
|
||||
CRYPTO_ctr128_encrypt_ctr32(in, out, len + rem, &sctx->ccm.ks.ks,
|
||||
sctx->ccm.s390x.nonce.b, sctx->ccm.s390x.buf.b,
|
||||
&num, (ctr128_f)AES_ctr32_encrypt);
|
||||
} else {
|
||||
/* decrypt-then-mac */
|
||||
CRYPTO_ctr128_encrypt_ctr32(in, out, len + rem, &sctx->ccm.ks.ks,
|
||||
sctx->ccm.s390x.nonce.b, sctx->ccm.s390x.buf.b,
|
||||
&num, (ctr128_f)AES_ctr32_encrypt);
|
||||
|
||||
if (len)
|
||||
s390x_kmac(out, len, sctx->ccm.s390x.fc, &sctx->ccm.s390x.kmac);
|
||||
if (rem) {
|
||||
for (i = 0; i < rem; i++)
|
||||
sctx->ccm.s390x.kmac.icv.b[i] ^= out[len + i];
|
||||
|
||||
s390x_km(sctx->ccm.s390x.kmac.icv.b, 16,
|
||||
sctx->ccm.s390x.kmac.icv.b,
|
||||
sctx->ccm.s390x.fc, sctx->ccm.s390x.kmac.k);
|
||||
}
|
||||
}
|
||||
/* encrypt tag */
|
||||
for (i = 15 - l; i < 16; i++)
|
||||
sctx->ccm.s390x.nonce.b[i] = 0;
|
||||
|
||||
s390x_km(sctx->ccm.s390x.nonce.b, 16, sctx->ccm.s390x.buf.b,
|
||||
sctx->ccm.s390x.fc, sctx->ccm.s390x.kmac.k);
|
||||
sctx->ccm.s390x.kmac.icv.g[0] ^= sctx->ccm.s390x.buf.g[0];
|
||||
sctx->ccm.s390x.kmac.icv.g[1] ^= sctx->ccm.s390x.buf.g[1];
|
||||
|
||||
sctx->ccm.s390x.nonce.b[0] = flags; /* restore flags field */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int s390x_aes_ccm_gettag(PROV_CCM_CTX *ctx,
|
||||
unsigned char *tag, size_t tlen)
|
||||
{
|
||||
PROV_AES_CCM_CTX *sctx = (PROV_AES_CCM_CTX *)ctx;
|
||||
|
||||
if (tlen > ctx->m)
|
||||
return 0;
|
||||
memcpy(tag, sctx->ccm.s390x.kmac.icv.b, tlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_aes_ccm_auth_encrypt(PROV_CCM_CTX *ctx,
|
||||
const unsigned char *in,
|
||||
unsigned char *out, size_t len,
|
||||
unsigned char *tag, size_t taglen)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = s390x_aes_ccm_auth_encdec(ctx, in, out, len, 1);
|
||||
if (rv && tag != NULL)
|
||||
rv = s390x_aes_ccm_gettag(ctx, tag, taglen);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int s390x_aes_ccm_auth_decrypt(PROV_CCM_CTX *ctx,
|
||||
const unsigned char *in,
|
||||
unsigned char *out, size_t len,
|
||||
unsigned char *expected_tag,
|
||||
size_t taglen)
|
||||
{
|
||||
int rv = 0;
|
||||
PROV_AES_CCM_CTX *sctx = (PROV_AES_CCM_CTX *)ctx;
|
||||
|
||||
rv = s390x_aes_ccm_auth_encdec(ctx, in, out, len, 0);
|
||||
if (rv) {
|
||||
if (CRYPTO_memcmp(sctx->ccm.s390x.kmac.icv.b, expected_tag, ctx->m) != 0)
|
||||
rv = 0;
|
||||
}
|
||||
if (rv == 0)
|
||||
OPENSSL_cleanse(out, len);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static const PROV_CCM_HW s390x_aes_ccm = {
|
||||
s390x_aes_ccm_initkey,
|
||||
s390x_aes_ccm_setiv,
|
||||
s390x_aes_ccm_setaad,
|
||||
s390x_aes_ccm_auth_encrypt,
|
||||
s390x_aes_ccm_auth_decrypt,
|
||||
s390x_aes_ccm_gettag
|
||||
};
|
||||
|
||||
const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits)
|
||||
{
|
||||
if ((keybits == 128 && S390X_aes_128_ccm_CAPABLE)
|
||||
|| (keybits == 192 && S390X_aes_192_ccm_CAPABLE)
|
||||
|| (keybits == 256 && S390X_aes_256_ccm_CAPABLE))
|
||||
return &s390x_aes_ccm;
|
||||
return &aes_ccm;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Fujitsu SPARC64 X support for AES CCM.
|
||||
* This file is included by cipher_ccm_hw.c
|
||||
*/
|
||||
|
||||
static int ccm_t4_aes_initkey(PROV_CCM_CTX *ctx, const unsigned char *key,
|
||||
size_t keylen)
|
||||
{
|
||||
PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx;
|
||||
|
||||
AES_HW_CCM_SET_KEY_FN(aes_t4_set_encrypt_key, aes_t4_encrypt, NULL, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const PROV_CCM_HW t4_aes_ccm = {
|
||||
ccm_t4_aes_initkey,
|
||||
ccm_generic_setiv,
|
||||
ccm_generic_setaad,
|
||||
ccm_generic_auth_encrypt,
|
||||
ccm_generic_auth_decrypt,
|
||||
ccm_generic_gettag
|
||||
};
|
||||
|
||||
const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits)
|
||||
{
|
||||
return SPARC_AES_CAPABLE ? &t4_aes_ccm : &aes_ccm;
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* Dispatch functions for AES GCM mode */
|
||||
|
||||
#include "cipher_locl.h"
|
||||
#include "internal/ciphers/cipher_gcm.h"
|
||||
#include "internal/provider_algs.h"
|
||||
|
||||
static void *aes_gcm_newctx(void *provctx, size_t keybits)
|
||||
{
|
||||
PROV_AES_GCM_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
|
||||
|
||||
if (ctx != NULL)
|
||||
gcm_initctx(provctx, &ctx->base, keybits, PROV_AES_HW_gcm(keybits), 8);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static OSSL_OP_cipher_freectx_fn aes_gcm_freectx;
|
||||
static void aes_gcm_freectx(void *vctx)
|
||||
{
|
||||
PROV_AES_GCM_CTX *ctx = (PROV_AES_GCM_CTX *)vctx;
|
||||
|
||||
gcm_deinitctx((PROV_GCM_CTX *)ctx);
|
||||
OPENSSL_clear_free(ctx, sizeof(*ctx));
|
||||
}
|
||||
|
||||
/* aes128gcm_functions */
|
||||
IMPLEMENT_aead_cipher(aes, gcm, GCM, AEAD_FLAGS, 128, 8, 96);
|
||||
/* aes192gcm_functions */
|
||||
IMPLEMENT_aead_cipher(aes, gcm, GCM, AEAD_FLAGS, 192, 8, 96);
|
||||
/* aes256gcm_functions */
|
||||
IMPLEMENT_aead_cipher(aes, gcm, GCM, AEAD_FLAGS, 256, 8, 96);
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* Dispatch functions for AES GCM mode */
|
||||
|
||||
#include "cipher_locl.h"
|
||||
#include "internal/ciphers/cipher_gcm.h"
|
||||
|
||||
static int generic_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
|
||||
size_t keylen)
|
||||
{
|
||||
PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
|
||||
AES_KEY *ks = &actx->ks.ks;
|
||||
|
||||
# ifdef HWAES_CAPABLE
|
||||
if (HWAES_CAPABLE) {
|
||||
# ifdef HWAES_ctr32_encrypt_blocks
|
||||
GCM_HW_SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt,
|
||||
HWAES_ctr32_encrypt_blocks);
|
||||
# else
|
||||
GCM_HW_SET_KEY_CTR_FN(ks, HWAES_set_encrypt_key, HWAES_encrypt, NULL);
|
||||
# endif /* HWAES_ctr32_encrypt_blocks */
|
||||
} else
|
||||
# endif /* HWAES_CAPABLE */
|
||||
|
||||
# ifdef BSAES_CAPABLE
|
||||
if (BSAES_CAPABLE) {
|
||||
GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt,
|
||||
bsaes_ctr32_encrypt_blocks);
|
||||
} else
|
||||
# endif /* BSAES_CAPABLE */
|
||||
|
||||
# ifdef VPAES_CAPABLE
|
||||
if (VPAES_CAPABLE) {
|
||||
GCM_HW_SET_KEY_CTR_FN(ks, vpaes_set_encrypt_key, vpaes_encrypt, NULL);
|
||||
} else
|
||||
# endif /* VPAES_CAPABLE */
|
||||
|
||||
{
|
||||
# ifdef AES_CTR_ASM
|
||||
GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt,
|
||||
AES_ctr32_encrypt);
|
||||
# else
|
||||
GCM_HW_SET_KEY_CTR_FN(ks, AES_set_encrypt_key, AES_encrypt, NULL);
|
||||
# endif /* AES_CTR_ASM */
|
||||
}
|
||||
ctx->key_set = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const PROV_GCM_HW aes_gcm = {
|
||||
generic_aes_gcm_initkey,
|
||||
gcm_setiv,
|
||||
gcm_aad_update,
|
||||
gcm_cipher_update,
|
||||
gcm_cipher_final,
|
||||
gcm_one_shot
|
||||
};
|
||||
|
||||
#if defined(S390X_aes_128_CAPABLE)
|
||||
# include "cipher_aes_gcm_hw_s390x.inc"
|
||||
#elif defined(AESNI_CAPABLE)
|
||||
# include "cipher_aes_gcm_hw_aesni.inc"
|
||||
#elif defined(SPARC_AES_CAPABLE)
|
||||
# include "cipher_aes_gcm_hw_t4.inc"
|
||||
#else
|
||||
const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits)
|
||||
{
|
||||
return &aes_gcm;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*-
|
||||
* AES-NI support for AES GCM.
|
||||
* This file is included by cipher_gcm_hw.c
|
||||
*/
|
||||
|
||||
static int aesni_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
|
||||
size_t keylen)
|
||||
{
|
||||
PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
|
||||
AES_KEY *ks = &actx->ks.ks;
|
||||
GCM_HW_SET_KEY_CTR_FN(ks, aesni_set_encrypt_key, aesni_encrypt,
|
||||
aesni_ctr32_encrypt_blocks);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const PROV_GCM_HW aesni_gcm = {
|
||||
aesni_gcm_initkey,
|
||||
gcm_setiv,
|
||||
gcm_aad_update,
|
||||
gcm_cipher_update,
|
||||
gcm_cipher_final,
|
||||
gcm_one_shot
|
||||
};
|
||||
|
||||
const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits)
|
||||
{
|
||||
return AESNI_CAPABLE ? &aesni_gcm : &aes_gcm;
|
||||
}
|
||||
|
||||
@@ -1,300 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*-
|
||||
* IBM S390X support for AES GCM.
|
||||
* This file is included by cipher_gcm_hw.c
|
||||
*/
|
||||
|
||||
/* iv + padding length for iv lengths != 12 */
|
||||
#define S390X_gcm_ivpadlen(i) ((((i) + 15) >> 4 << 4) + 16)
|
||||
|
||||
static int s390x_aes_gcm_initkey(PROV_GCM_CTX *ctx,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
|
||||
|
||||
ctx->key_set = 1;
|
||||
memcpy(&actx->plat.s390x.param.kma.k, key, keylen);
|
||||
actx->plat.s390x.fc = S390X_AES_FC(keylen);
|
||||
if (!ctx->enc)
|
||||
actx->plat.s390x.fc |= S390X_DECRYPT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_aes_gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv,
|
||||
size_t ivlen)
|
||||
{
|
||||
PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
|
||||
S390X_KMA_PARAMS *kma = &actx->plat.s390x.param.kma;
|
||||
|
||||
kma->t.g[0] = 0;
|
||||
kma->t.g[1] = 0;
|
||||
kma->tpcl = 0;
|
||||
kma->taadl = 0;
|
||||
actx->plat.s390x.mreslen = 0;
|
||||
actx->plat.s390x.areslen = 0;
|
||||
actx->plat.s390x.kreslen = 0;
|
||||
|
||||
if (ivlen == GCM_IV_DEFAULT_SIZE) {
|
||||
memcpy(&kma->j0, iv, ivlen);
|
||||
kma->j0.w[3] = 1;
|
||||
kma->cv.w = 1;
|
||||
} else {
|
||||
unsigned long long ivbits = ivlen << 3;
|
||||
size_t len = S390X_gcm_ivpadlen(ivlen);
|
||||
unsigned char iv_zero_pad[S390X_gcm_ivpadlen(GCM_IV_MAX_SIZE)];
|
||||
/*
|
||||
* The IV length needs to be zero padded to be a multiple of 16 bytes
|
||||
* followed by 8 bytes of zeros and 8 bytes for the IV length.
|
||||
* The GHASH of this value can then be calculated.
|
||||
*/
|
||||
memcpy(iv_zero_pad, iv, ivlen);
|
||||
memset(iv_zero_pad + ivlen, 0, len - ivlen);
|
||||
memcpy(iv_zero_pad + len - sizeof(ivbits), &ivbits, sizeof(ivbits));
|
||||
/*
|
||||
* Calculate the ghash of the iv - the result is stored into the tag
|
||||
* param.
|
||||
*/
|
||||
s390x_kma(iv_zero_pad, len, NULL, 0, NULL, actx->plat.s390x.fc, kma);
|
||||
actx->plat.s390x.fc |= S390X_KMA_HS; /* The hash subkey is set */
|
||||
|
||||
/* Copy the 128 bit GHASH result into J0 and clear the tag */
|
||||
kma->j0.g[0] = kma->t.g[0];
|
||||
kma->j0.g[1] = kma->t.g[1];
|
||||
kma->t.g[0] = 0;
|
||||
kma->t.g[1] = 0;
|
||||
/* Set the 32 bit counter */
|
||||
kma->cv.w = kma->j0.w[3];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_aes_gcm_cipher_final(PROV_GCM_CTX *ctx, unsigned char *tag)
|
||||
{
|
||||
PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
|
||||
S390X_KMA_PARAMS *kma = &actx->plat.s390x.param.kma;
|
||||
unsigned char out[AES_BLOCK_SIZE];
|
||||
int rc;
|
||||
|
||||
kma->taadl <<= 3;
|
||||
kma->tpcl <<= 3;
|
||||
s390x_kma(actx->plat.s390x.ares, actx->plat.s390x.areslen,
|
||||
actx->plat.s390x.mres, actx->plat.s390x.mreslen, out,
|
||||
actx->plat.s390x.fc | S390X_KMA_LAAD | S390X_KMA_LPC, kma);
|
||||
|
||||
/* gctx->mres already returned to the caller */
|
||||
OPENSSL_cleanse(out, actx->plat.s390x.mreslen);
|
||||
|
||||
if (ctx->enc) {
|
||||
ctx->taglen = GCM_TAG_MAX_SIZE;
|
||||
memcpy(tag, kma->t.b, ctx->taglen);
|
||||
rc = 1;
|
||||
} else {
|
||||
rc = (CRYPTO_memcmp(tag, kma->t.b, ctx->taglen) == 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int s390x_aes_gcm_one_shot(PROV_GCM_CTX *ctx,
|
||||
unsigned char *aad, size_t aad_len,
|
||||
const unsigned char *in, size_t in_len,
|
||||
unsigned char *out,
|
||||
unsigned char *tag, size_t taglen)
|
||||
{
|
||||
PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
|
||||
S390X_KMA_PARAMS *kma = &actx->plat.s390x.param.kma;
|
||||
int rc;
|
||||
|
||||
kma->taadl = aad_len << 3;
|
||||
kma->tpcl = in_len << 3;
|
||||
s390x_kma(aad, aad_len, in, in_len, out,
|
||||
actx->plat.s390x.fc | S390X_KMA_LAAD | S390X_KMA_LPC, kma);
|
||||
|
||||
if (ctx->enc) {
|
||||
memcpy(tag, kma->t.b, taglen);
|
||||
rc = 1;
|
||||
} else {
|
||||
rc = (CRYPTO_memcmp(tag, kma->t.b, taglen) == 0);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process additional authenticated data. Returns 1 on success. Code is
|
||||
* big-endian.
|
||||
*/
|
||||
static int s390x_aes_gcm_aad_update(PROV_GCM_CTX *ctx,
|
||||
const unsigned char *aad, size_t len)
|
||||
{
|
||||
PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
|
||||
S390X_KMA_PARAMS *kma = &actx->plat.s390x.param.kma;
|
||||
unsigned long long alen;
|
||||
int n, rem;
|
||||
|
||||
/* If already processed pt/ct then error */
|
||||
if (kma->tpcl != 0)
|
||||
return 0;
|
||||
|
||||
/* update the total aad length */
|
||||
alen = kma->taadl + len;
|
||||
if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len))
|
||||
return 0;
|
||||
kma->taadl = alen;
|
||||
|
||||
/* check if there is any existing aad data from a previous add */
|
||||
n = actx->plat.s390x.areslen;
|
||||
if (n) {
|
||||
/* add additional data to a buffer until it has 16 bytes */
|
||||
while (n && len) {
|
||||
actx->plat.s390x.ares[n] = *aad;
|
||||
++aad;
|
||||
--len;
|
||||
n = (n + 1) & 0xf;
|
||||
}
|
||||
/* ctx->ares contains a complete block if offset has wrapped around */
|
||||
if (!n) {
|
||||
s390x_kma(actx->plat.s390x.ares, 16, NULL, 0, NULL,
|
||||
actx->plat.s390x.fc, kma);
|
||||
actx->plat.s390x.fc |= S390X_KMA_HS;
|
||||
}
|
||||
actx->plat.s390x.areslen = n;
|
||||
}
|
||||
|
||||
/* If there are leftover bytes (< 128 bits) save them for next time */
|
||||
rem = len & 0xf;
|
||||
/* Add any remaining 16 byte blocks (128 bit each) */
|
||||
len &= ~(size_t)0xf;
|
||||
if (len) {
|
||||
s390x_kma(aad, len, NULL, 0, NULL, actx->plat.s390x.fc, kma);
|
||||
actx->plat.s390x.fc |= S390X_KMA_HS;
|
||||
aad += len;
|
||||
}
|
||||
|
||||
if (rem) {
|
||||
actx->plat.s390x.areslen = rem;
|
||||
|
||||
do {
|
||||
--rem;
|
||||
actx->plat.s390x.ares[rem] = aad[rem];
|
||||
} while (rem);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* En/de-crypt plain/cipher-text and authenticate ciphertext. Returns 1 for
|
||||
* success. Code is big-endian.
|
||||
*/
|
||||
static int s390x_aes_gcm_cipher_update(PROV_GCM_CTX *ctx,
|
||||
const unsigned char *in, size_t len,
|
||||
unsigned char *out)
|
||||
{
|
||||
PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
|
||||
S390X_KMA_PARAMS *kma = &actx->plat.s390x.param.kma;
|
||||
const unsigned char *inptr;
|
||||
unsigned long long mlen;
|
||||
union {
|
||||
unsigned int w[4];
|
||||
unsigned char b[16];
|
||||
} buf;
|
||||
size_t inlen;
|
||||
int n, rem, i;
|
||||
|
||||
mlen = kma->tpcl + len;
|
||||
if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
|
||||
return 0;
|
||||
kma->tpcl = mlen;
|
||||
|
||||
n = actx->plat.s390x.mreslen;
|
||||
if (n) {
|
||||
inptr = in;
|
||||
inlen = len;
|
||||
while (n && inlen) {
|
||||
actx->plat.s390x.mres[n] = *inptr;
|
||||
n = (n + 1) & 0xf;
|
||||
++inptr;
|
||||
--inlen;
|
||||
}
|
||||
/* ctx->mres contains a complete block if offset has wrapped around */
|
||||
if (!n) {
|
||||
s390x_kma(actx->plat.s390x.ares, actx->plat.s390x.areslen,
|
||||
actx->plat.s390x.mres, 16, buf.b,
|
||||
actx->plat.s390x.fc | S390X_KMA_LAAD, kma);
|
||||
actx->plat.s390x.fc |= S390X_KMA_HS;
|
||||
actx->plat.s390x.areslen = 0;
|
||||
|
||||
/* previous call already encrypted/decrypted its remainder,
|
||||
* see comment below */
|
||||
n = actx->plat.s390x.mreslen;
|
||||
while (n) {
|
||||
*out = buf.b[n];
|
||||
n = (n + 1) & 0xf;
|
||||
++out;
|
||||
++in;
|
||||
--len;
|
||||
}
|
||||
actx->plat.s390x.mreslen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
rem = len & 0xf;
|
||||
|
||||
len &= ~(size_t)0xf;
|
||||
if (len) {
|
||||
s390x_kma(actx->plat.s390x.ares, actx->plat.s390x.areslen, in, len, out,
|
||||
actx->plat.s390x.fc | S390X_KMA_LAAD, kma);
|
||||
in += len;
|
||||
out += len;
|
||||
actx->plat.s390x.fc |= S390X_KMA_HS;
|
||||
actx->plat.s390x.areslen = 0;
|
||||
}
|
||||
|
||||
/*-
|
||||
* If there is a remainder, it has to be saved such that it can be
|
||||
* processed by kma later. However, we also have to do the for-now
|
||||
* unauthenticated encryption/decryption part here and now...
|
||||
*/
|
||||
if (rem) {
|
||||
if (!actx->plat.s390x.mreslen) {
|
||||
buf.w[0] = kma->j0.w[0];
|
||||
buf.w[1] = kma->j0.w[1];
|
||||
buf.w[2] = kma->j0.w[2];
|
||||
buf.w[3] = kma->cv.w + 1;
|
||||
s390x_km(buf.b, 16, actx->plat.s390x.kres,
|
||||
actx->plat.s390x.fc & 0x1f, &kma->k);
|
||||
}
|
||||
|
||||
n = actx->plat.s390x.mreslen;
|
||||
for (i = 0; i < rem; i++) {
|
||||
actx->plat.s390x.mres[n + i] = in[i];
|
||||
out[i] = in[i] ^ actx->plat.s390x.kres[n + i];
|
||||
}
|
||||
actx->plat.s390x.mreslen += rem;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const PROV_GCM_HW s390x_aes_gcm = {
|
||||
s390x_aes_gcm_initkey,
|
||||
s390x_aes_gcm_setiv,
|
||||
s390x_aes_gcm_aad_update,
|
||||
s390x_aes_gcm_cipher_update,
|
||||
s390x_aes_gcm_cipher_final,
|
||||
s390x_aes_gcm_one_shot
|
||||
};
|
||||
|
||||
const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits)
|
||||
{
|
||||
if ((keybits == 128 && S390X_aes_128_gcm_CAPABLE)
|
||||
|| (keybits == 192 && S390X_aes_192_gcm_CAPABLE)
|
||||
|| (keybits == 256 && S390X_aes_256_gcm_CAPABLE))
|
||||
return &s390x_aes_gcm;
|
||||
return &aes_gcm;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Fujitsu SPARC64 X support for AES GCM.
|
||||
* This file is included by cipher_gcm_hw.c
|
||||
*/
|
||||
|
||||
static int t4_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
|
||||
size_t keylen)
|
||||
{
|
||||
ctr128_f ctr;
|
||||
PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
|
||||
AES_KEY *ks = &actx->ks.ks;
|
||||
|
||||
|
||||
switch (keylen) {
|
||||
case 16:
|
||||
ctr = (ctr128_f)aes128_t4_ctr32_encrypt;
|
||||
break;
|
||||
case 24:
|
||||
ctr = (ctr128_f)aes192_t4_ctr32_encrypt;
|
||||
break;
|
||||
case 32:
|
||||
ctr = (ctr128_f)aes256_t4_ctr32_encrypt;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
GCM_HW_SET_KEY_CTR_FN(ks, aes_t4_set_encrypt_key, aes_t4_encrypt, ctr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const PROV_GCM_HW t4_aes_gcm = {
|
||||
t4_aes_gcm_initkey,
|
||||
gcm_setiv,
|
||||
gcm_aad_update,
|
||||
gcm_cipher_update,
|
||||
gcm_cipher_final,
|
||||
gcm_one_shot
|
||||
};
|
||||
const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits)
|
||||
{
|
||||
return SPARC_AES_CAPABLE ? &t4_aes_gcm : &aes_gcm;
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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 "cipher_aes.h"
|
||||
#include "internal/providercommonerr.h"
|
||||
|
||||
static int cipher_hw_aes_initkey(PROV_CIPHER_CTX *dat,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
int ret;
|
||||
PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
|
||||
AES_KEY *ks = &adat->ks.ks;
|
||||
|
||||
dat->ks = ks;
|
||||
|
||||
if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE)
|
||||
&& !dat->enc) {
|
||||
#ifdef HWAES_CAPABLE
|
||||
if (HWAES_CAPABLE) {
|
||||
ret = HWAES_set_decrypt_key(key, keylen * 8, ks);
|
||||
dat->block = (block128_f)HWAES_decrypt;
|
||||
dat->stream.cbc = NULL;
|
||||
# ifdef HWAES_cbc_encrypt
|
||||
if (dat->mode == EVP_CIPH_CBC_MODE)
|
||||
dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
|
||||
# endif
|
||||
} else
|
||||
#endif
|
||||
#ifdef BSAES_CAPABLE
|
||||
if (BSAES_CAPABLE && dat->mode == EVP_CIPH_CBC_MODE) {
|
||||
ret = AES_set_decrypt_key(key, keylen * 8, ks);
|
||||
dat->block = (block128_f)AES_decrypt;
|
||||
dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt;
|
||||
} else
|
||||
#endif
|
||||
#ifdef VPAES_CAPABLE
|
||||
if (VPAES_CAPABLE) {
|
||||
ret = vpaes_set_decrypt_key(key, keylen * 8, ks);
|
||||
dat->block = (block128_f)vpaes_decrypt;
|
||||
dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
|
||||
?(cbc128_f)vpaes_cbc_encrypt : NULL;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ret = AES_set_decrypt_key(key, keylen * 8, ks);
|
||||
dat->block = (block128_f)AES_decrypt;
|
||||
dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
|
||||
? (cbc128_f)AES_cbc_encrypt : NULL;
|
||||
}
|
||||
} else
|
||||
#ifdef HWAES_CAPABLE
|
||||
if (HWAES_CAPABLE) {
|
||||
ret = HWAES_set_encrypt_key(key, keylen * 8, ks);
|
||||
dat->block = (block128_f)HWAES_encrypt;
|
||||
dat->stream.cbc = NULL;
|
||||
# ifdef HWAES_cbc_encrypt
|
||||
if (dat->mode == EVP_CIPH_CBC_MODE)
|
||||
dat->stream.cbc = (cbc128_f)HWAES_cbc_encrypt;
|
||||
else
|
||||
# endif
|
||||
# ifdef HWAES_ctr32_encrypt_blocks
|
||||
if (dat->mode == EVP_CIPH_CTR_MODE)
|
||||
dat->stream.ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks;
|
||||
else
|
||||
# endif
|
||||
(void)0; /* terminate potentially open 'else' */
|
||||
} else
|
||||
#endif
|
||||
#ifdef BSAES_CAPABLE
|
||||
if (BSAES_CAPABLE && dat->mode == EVP_CIPH_CTR_MODE) {
|
||||
ret = AES_set_encrypt_key(key, keylen * 8, ks);
|
||||
dat->block = (block128_f)AES_encrypt;
|
||||
dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
|
||||
} else
|
||||
#endif
|
||||
#ifdef VPAES_CAPABLE
|
||||
if (VPAES_CAPABLE) {
|
||||
ret = vpaes_set_encrypt_key(key, keylen * 8, ks);
|
||||
dat->block = (block128_f)vpaes_encrypt;
|
||||
dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
|
||||
? (cbc128_f)vpaes_cbc_encrypt : NULL;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ret = AES_set_encrypt_key(key, keylen * 8, ks);
|
||||
dat->block = (block128_f)AES_encrypt;
|
||||
dat->stream.cbc = (dat->mode == EVP_CIPH_CBC_MODE)
|
||||
? (cbc128_f)AES_cbc_encrypt : NULL;
|
||||
#ifdef AES_CTR_ASM
|
||||
if (dat->mode == EVP_CIPH_CTR_MODE)
|
||||
dat->stream.ctr = (ctr128_f)AES_ctr32_encrypt;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_AES_KEY_SETUP_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define PROV_CIPHER_HW_aes_mode(mode) \
|
||||
static const PROV_CIPHER_HW aes_##mode = { \
|
||||
cipher_hw_aes_initkey, \
|
||||
cipher_hw_generic_##mode \
|
||||
}; \
|
||||
PROV_CIPHER_HW_declare(mode) \
|
||||
const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_##mode(size_t keybits) \
|
||||
{ \
|
||||
PROV_CIPHER_HW_select(mode) \
|
||||
return &aes_##mode; \
|
||||
}
|
||||
|
||||
#if defined(AESNI_CAPABLE)
|
||||
# include "cipher_aes_hw_aesni.inc"
|
||||
#elif defined(SPARC_AES_CAPABLE)
|
||||
# include "cipher_aes_hw_t4.inc"
|
||||
#elif defined(S390X_aes_128_CAPABLE)
|
||||
# include "cipher_aes_hw_s390x.inc"
|
||||
#else
|
||||
/* The generic case */
|
||||
# define PROV_CIPHER_HW_declare(mode)
|
||||
# define PROV_CIPHER_HW_select(mode)
|
||||
#endif
|
||||
|
||||
PROV_CIPHER_HW_aes_mode(cbc)
|
||||
PROV_CIPHER_HW_aes_mode(ecb)
|
||||
PROV_CIPHER_HW_aes_mode(ofb128)
|
||||
PROV_CIPHER_HW_aes_mode(cfb128)
|
||||
PROV_CIPHER_HW_aes_mode(cfb1)
|
||||
PROV_CIPHER_HW_aes_mode(cfb8)
|
||||
PROV_CIPHER_HW_aes_mode(ctr)
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*-
|
||||
* AES-NI support for AES modes ecb, cbc, ofb, cfb, ctr.
|
||||
* This file is included by cipher_aes_hw.c
|
||||
*/
|
||||
|
||||
#define cipher_hw_aesni_ofb128 cipher_hw_generic_ofb128
|
||||
#define cipher_hw_aesni_cfb128 cipher_hw_generic_cfb128
|
||||
#define cipher_hw_aesni_cfb8 cipher_hw_generic_cfb8
|
||||
#define cipher_hw_aesni_cfb1 cipher_hw_generic_cfb1
|
||||
#define cipher_hw_aesni_ctr cipher_hw_generic_ctr
|
||||
|
||||
static int cipher_hw_aesni_initkey(PROV_CIPHER_CTX *dat,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
int ret;
|
||||
PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
|
||||
AES_KEY *ks = &adat->ks.ks;
|
||||
|
||||
dat->ks = ks;
|
||||
|
||||
if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE)
|
||||
&& !dat->enc) {
|
||||
ret = aesni_set_decrypt_key(key, keylen * 8, ks);
|
||||
dat->block = (block128_f) aesni_decrypt;
|
||||
dat->stream.cbc = dat->mode == EVP_CIPH_CBC_MODE ?
|
||||
(cbc128_f) aesni_cbc_encrypt : NULL;
|
||||
} else {
|
||||
ret = aesni_set_encrypt_key(key, keylen * 8, ks);
|
||||
dat->block = (block128_f) aesni_encrypt;
|
||||
if (dat->mode == EVP_CIPH_CBC_MODE)
|
||||
dat->stream.cbc = (cbc128_f) aesni_cbc_encrypt;
|
||||
else if (dat->mode == EVP_CIPH_CTR_MODE)
|
||||
dat->stream.ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
|
||||
else
|
||||
dat->stream.cbc = NULL;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_AES_KEY_SETUP_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cipher_hw_aesni_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
const AES_KEY *ks = ctx->ks;
|
||||
|
||||
aesni_cbc_encrypt(in, out, len, ks, ctx->iv, ctx->enc);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cipher_hw_aesni_ecb(PROV_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
if (len < ctx->blocksize)
|
||||
return 1;
|
||||
|
||||
aesni_ecb_encrypt(in, out, len, ctx->ks, ctx->enc);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define PROV_CIPHER_HW_declare(mode) \
|
||||
static const PROV_CIPHER_HW aesni_##mode = { \
|
||||
cipher_hw_aesni_initkey, \
|
||||
cipher_hw_aesni_##mode \
|
||||
};
|
||||
#define PROV_CIPHER_HW_select(mode) \
|
||||
if (AESNI_CAPABLE) \
|
||||
return &aesni_##mode;
|
||||
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* IBM S390X support for AES modes ecb, cbc, ofb, cfb, ctr.
|
||||
* This file is included by cipher_aes_hw.c
|
||||
*/
|
||||
|
||||
#include "s390x_arch.h"
|
||||
|
||||
#define s390x_aes_cbc_initkey cipher_hw_aes_initkey
|
||||
#define s390x_aes_cfb1_initkey cipher_hw_aes_initkey
|
||||
#define s390x_aes_ctr_initkey cipher_hw_aes_initkey
|
||||
#define s390x_aes_cbc_cipher_hw cipher_hw_generic_cbc
|
||||
#define s390x_aes_cfb1_cipher_hw cipher_hw_generic_cfb1
|
||||
#define s390x_aes_ctr_cipher_hw cipher_hw_generic_ctr
|
||||
|
||||
#define S390X_aes_128_ofb128_CAPABLE S390X_aes_128_ofb_CAPABLE
|
||||
#define S390X_aes_192_ofb128_CAPABLE S390X_aes_192_ofb_CAPABLE
|
||||
#define S390X_aes_256_ofb128_CAPABLE S390X_aes_256_ofb_CAPABLE
|
||||
#define S390X_aes_128_cfb128_CAPABLE S390X_aes_128_cfb_CAPABLE
|
||||
#define S390X_aes_192_cfb128_CAPABLE S390X_aes_192_cfb_CAPABLE
|
||||
#define S390X_aes_256_cfb128_CAPABLE S390X_aes_256_cfb_CAPABLE
|
||||
|
||||
static int s390x_aes_ecb_initkey(PROV_CIPHER_CTX *dat,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
|
||||
|
||||
adat->plat.s390x.fc = S390X_AES_FC(keylen);
|
||||
if (!dat->enc)
|
||||
adat->plat.s390x.fc |= S390X_DECRYPT;
|
||||
|
||||
memcpy(adat->plat.s390x.param.km.k, key, keylen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_aes_ecb_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
|
||||
|
||||
s390x_km(in, len, out, adat->plat.s390x.fc, &adat->plat.s390x.param.km);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_aes_ofb128_initkey(PROV_CIPHER_CTX *dat,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
|
||||
|
||||
memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
|
||||
memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
|
||||
adat->plat.s390x.fc = S390X_AES_FC(keylen);
|
||||
adat->plat.s390x.res = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_aes_ofb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
|
||||
int n = adat->plat.s390x.res;
|
||||
int rem;
|
||||
|
||||
while (n && len) {
|
||||
*out = *in ^ adat->plat.s390x.param.kmo_kmf.cv[n];
|
||||
n = (n + 1) & 0xf;
|
||||
--len;
|
||||
++in;
|
||||
++out;
|
||||
}
|
||||
|
||||
rem = len & 0xf;
|
||||
|
||||
len &= ~(size_t)0xf;
|
||||
if (len) {
|
||||
s390x_kmo(in, len, out, adat->plat.s390x.fc,
|
||||
&adat->plat.s390x.param.kmo_kmf);
|
||||
|
||||
out += len;
|
||||
in += len;
|
||||
}
|
||||
|
||||
if (rem) {
|
||||
s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16,
|
||||
adat->plat.s390x.param.kmo_kmf.cv, adat->plat.s390x.fc,
|
||||
adat->plat.s390x.param.kmo_kmf.k);
|
||||
|
||||
while (rem--) {
|
||||
out[n] = in[n] ^ adat->plat.s390x.param.kmo_kmf.cv[n];
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
adat->plat.s390x.res = n;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_aes_cfb128_initkey(PROV_CIPHER_CTX *dat,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
|
||||
|
||||
adat->plat.s390x.fc = S390X_AES_FC(keylen);
|
||||
adat->plat.s390x.fc |= 16 << 24; /* 16 bytes cipher feedback */
|
||||
if (!dat->enc)
|
||||
adat->plat.s390x.fc |= S390X_DECRYPT;
|
||||
|
||||
adat->plat.s390x.res = 0;
|
||||
memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
|
||||
memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_aes_cfb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
|
||||
int n = adat->plat.s390x.res;
|
||||
int rem;
|
||||
unsigned char tmp;
|
||||
|
||||
while (n && len) {
|
||||
tmp = *in;
|
||||
*out = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
|
||||
adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? *out : tmp;
|
||||
n = (n + 1) & 0xf;
|
||||
--len;
|
||||
++in;
|
||||
++out;
|
||||
}
|
||||
|
||||
rem = len & 0xf;
|
||||
|
||||
len &= ~(size_t)0xf;
|
||||
if (len) {
|
||||
s390x_kmf(in, len, out, adat->plat.s390x.fc,
|
||||
&adat->plat.s390x.param.kmo_kmf);
|
||||
|
||||
out += len;
|
||||
in += len;
|
||||
}
|
||||
|
||||
if (rem) {
|
||||
s390x_km(adat->plat.s390x.param.kmo_kmf.cv, 16,
|
||||
adat->plat.s390x.param.kmo_kmf.cv,
|
||||
S390X_AES_FC(dat->keylen), adat->plat.s390x.param.kmo_kmf.k);
|
||||
|
||||
while (rem--) {
|
||||
tmp = in[n];
|
||||
out[n] = adat->plat.s390x.param.kmo_kmf.cv[n] ^ tmp;
|
||||
adat->plat.s390x.param.kmo_kmf.cv[n] = dat->enc ? out[n] : tmp;
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
adat->plat.s390x.res = n;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_aes_cfb8_initkey(PROV_CIPHER_CTX *dat,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
|
||||
|
||||
adat->plat.s390x.fc = S390X_AES_FC(keylen);
|
||||
adat->plat.s390x.fc |= 1 << 24; /* 1 byte cipher feedback */
|
||||
if (!dat->enc)
|
||||
adat->plat.s390x.fc |= S390X_DECRYPT;
|
||||
|
||||
memcpy(adat->plat.s390x.param.kmo_kmf.cv, dat->iv, dat->ivlen);
|
||||
memcpy(adat->plat.s390x.param.kmo_kmf.k, key, keylen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int s390x_aes_cfb8_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
|
||||
|
||||
s390x_kmf(in, len, out, adat->plat.s390x.fc,
|
||||
&adat->plat.s390x.param.kmo_kmf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define PROV_CIPHER_HW_declare(mode) \
|
||||
static const PROV_CIPHER_HW s390x_aes_##mode = { \
|
||||
s390x_aes_##mode##_initkey, \
|
||||
s390x_aes_##mode##_cipher_hw \
|
||||
};
|
||||
#define PROV_CIPHER_HW_select(mode) \
|
||||
if ((keybits == 128 && S390X_aes_128_##mode##_CAPABLE) \
|
||||
|| (keybits == 192 && S390X_aes_192_##mode##_CAPABLE) \
|
||||
|| (keybits == 256 && S390X_aes_256_##mode##_CAPABLE)) \
|
||||
return &s390x_aes_##mode;
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Sparc t4 support for AES modes ecb, cbc, ofb, cfb, ctr.
|
||||
* This file is included by cipher_aes_hw.c
|
||||
*/
|
||||
|
||||
static int cipher_hw_aes_t4_initkey(PROV_CIPHER_CTX *dat,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
int ret, bits;
|
||||
PROV_AES_CTX *adat = (PROV_AES_CTX *)dat;
|
||||
AES_KEY *ks = &adat->ks.ks;
|
||||
|
||||
dat->ks = (const void *)ks; /* used by cipher_hw_generic_XXX */
|
||||
|
||||
bits = keylen * 8;
|
||||
if ((dat->mode == EVP_CIPH_ECB_MODE || dat->mode == EVP_CIPH_CBC_MODE)
|
||||
&& !dat->enc) {
|
||||
ret = 0;
|
||||
aes_t4_set_decrypt_key(key, bits, ks);
|
||||
dat->block = (block128_f)aes_t4_decrypt;
|
||||
switch (bits) {
|
||||
case 128:
|
||||
dat->stream.cbc = dat->mode == EVP_CIPH_CBC_MODE ?
|
||||
(cbc128_f)aes128_t4_cbc_decrypt : NULL;
|
||||
break;
|
||||
case 192:
|
||||
dat->stream.cbc = dat->mode == EVP_CIPH_CBC_MODE ?
|
||||
(cbc128_f)aes192_t4_cbc_decrypt : NULL;
|
||||
break;
|
||||
case 256:
|
||||
dat->stream.cbc = dat->mode == EVP_CIPH_CBC_MODE ?
|
||||
(cbc128_f)aes256_t4_cbc_decrypt : NULL;
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
ret = 0;
|
||||
aes_t4_set_encrypt_key(key, bits, ks);
|
||||
dat->block = (block128_f)aes_t4_encrypt;
|
||||
switch (bits) {
|
||||
case 128:
|
||||
if (dat->mode == EVP_CIPH_CBC_MODE)
|
||||
dat->stream.cbc = (cbc128_f)aes128_t4_cbc_encrypt;
|
||||
else if (dat->mode == EVP_CIPH_CTR_MODE)
|
||||
dat->stream.ctr = (ctr128_f)aes128_t4_ctr32_encrypt;
|
||||
else
|
||||
dat->stream.cbc = NULL;
|
||||
break;
|
||||
case 192:
|
||||
if (dat->mode == EVP_CIPH_CBC_MODE)
|
||||
dat->stream.cbc = (cbc128_f)aes192_t4_cbc_encrypt;
|
||||
else if (dat->mode == EVP_CIPH_CTR_MODE)
|
||||
dat->stream.ctr = (ctr128_f)aes192_t4_ctr32_encrypt;
|
||||
else
|
||||
dat->stream.cbc = NULL;
|
||||
break;
|
||||
case 256:
|
||||
if (dat->mode == EVP_CIPH_CBC_MODE)
|
||||
dat->stream.cbc = (cbc128_f)aes256_t4_cbc_encrypt;
|
||||
else if (dat->mode == EVP_CIPH_CTR_MODE)
|
||||
dat->stream.ctr = (ctr128_f)aes256_t4_ctr32_encrypt;
|
||||
else
|
||||
dat->stream.cbc = NULL;
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_AES_KEY_SETUP_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define PROV_CIPHER_HW_declare(mode) \
|
||||
static const PROV_CIPHER_HW aes_t4_##mode = { \
|
||||
cipher_hw_aes_t4_initkey, \
|
||||
cipher_hw_generic_##mode \
|
||||
};
|
||||
#define PROV_CIPHER_HW_select(mode) \
|
||||
if (SPARC_AES_CAPABLE) \
|
||||
return &aes_t4_##mode;
|
||||
@@ -1,246 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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 "cipher_aes.h"
|
||||
#include "internal/providercommonerr.h"
|
||||
#include "internal/provider_algs.h"
|
||||
|
||||
/* AES wrap with padding has IV length of 4, without padding 8 */
|
||||
#define AES_WRAP_PAD_IVLEN 4
|
||||
#define AES_WRAP_NOPAD_IVLEN 8
|
||||
|
||||
/* TODO(3.0) Figure out what flags need to be passed */
|
||||
#define WRAP_FLAGS (EVP_CIPH_WRAP_MODE \
|
||||
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
|
||||
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1)
|
||||
|
||||
typedef size_t (*aeswrap_fn)(void *key, const unsigned char *iv,
|
||||
unsigned char *out, const unsigned char *in,
|
||||
size_t inlen, block128_f block);
|
||||
|
||||
static OSSL_OP_cipher_encrypt_init_fn aes_wrap_einit;
|
||||
static OSSL_OP_cipher_decrypt_init_fn aes_wrap_dinit;
|
||||
static OSSL_OP_cipher_update_fn aes_wrap_cipher;
|
||||
static OSSL_OP_cipher_final_fn aes_wrap_final;
|
||||
static OSSL_OP_cipher_freectx_fn aes_wrap_freectx;
|
||||
|
||||
typedef struct prov_aes_wrap_ctx_st {
|
||||
PROV_CIPHER_CTX base;
|
||||
union {
|
||||
OSSL_UNION_ALIGN;
|
||||
AES_KEY ks;
|
||||
} ks;
|
||||
unsigned int iv_set : 1;
|
||||
aeswrap_fn wrapfn;
|
||||
|
||||
} PROV_AES_WRAP_CTX;
|
||||
|
||||
|
||||
static void *aes_wrap_newctx(size_t kbits, size_t blkbits,
|
||||
size_t ivbits, unsigned int mode, uint64_t flags)
|
||||
{
|
||||
PROV_AES_WRAP_CTX *wctx = OPENSSL_zalloc(sizeof(*wctx));
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)wctx;
|
||||
|
||||
if (ctx != NULL) {
|
||||
cipher_generic_initkey(ctx, kbits, blkbits, ivbits, mode, flags,
|
||||
NULL, NULL);
|
||||
ctx->pad = (ctx->ivlen == AES_WRAP_PAD_IVLEN);
|
||||
}
|
||||
return wctx;
|
||||
}
|
||||
|
||||
static void aes_wrap_freectx(void *vctx)
|
||||
{
|
||||
PROV_AES_WRAP_CTX *wctx = (PROV_AES_WRAP_CTX *)vctx;
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
|
||||
OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv));
|
||||
OPENSSL_clear_free(wctx, sizeof(*wctx));
|
||||
}
|
||||
|
||||
static int aes_wrap_init(void *vctx, const unsigned char *key,
|
||||
size_t keylen, const unsigned char *iv,
|
||||
size_t ivlen, int enc)
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
PROV_AES_WRAP_CTX *wctx = (PROV_AES_WRAP_CTX *)vctx;
|
||||
|
||||
ctx->enc = enc;
|
||||
ctx->block = enc ? (block128_f)AES_encrypt : (block128_f)AES_decrypt;
|
||||
if (ctx->pad)
|
||||
wctx->wrapfn = enc ? CRYPTO_128_wrap_pad : CRYPTO_128_unwrap_pad;
|
||||
else
|
||||
wctx->wrapfn = enc ? CRYPTO_128_wrap : CRYPTO_128_unwrap;
|
||||
|
||||
if (iv != NULL) {
|
||||
ctx->ivlen = ivlen;
|
||||
memcpy(ctx->iv, iv, ivlen);
|
||||
wctx->iv_set = 1;
|
||||
}
|
||||
if (key != NULL) {
|
||||
if (keylen != ctx->keylen) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->enc)
|
||||
AES_set_encrypt_key(key, keylen * 8, &wctx->ks.ks);
|
||||
else
|
||||
AES_set_decrypt_key(key, keylen * 8, &wctx->ks.ks);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aes_wrap_einit(void *ctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return aes_wrap_init(ctx, key, keylen, iv, ivlen, 1);
|
||||
}
|
||||
|
||||
static int aes_wrap_dinit(void *ctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return aes_wrap_init(ctx, key, keylen, iv, ivlen, 0);
|
||||
}
|
||||
|
||||
static int aes_wrap_cipher_internal(void *vctx, unsigned char *out,
|
||||
const unsigned char *in, size_t inlen)
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
PROV_AES_WRAP_CTX *wctx = (PROV_AES_WRAP_CTX *)vctx;
|
||||
size_t rv;
|
||||
int pad = ctx->pad;
|
||||
|
||||
/* No final operation so always return zero length */
|
||||
if (in == NULL)
|
||||
return 0;
|
||||
|
||||
/* Input length must always be non-zero */
|
||||
if (inlen == 0)
|
||||
return -1;
|
||||
|
||||
/* If decrypting need at least 16 bytes and multiple of 8 */
|
||||
if (!ctx->enc && (inlen < 16 || inlen & 0x7))
|
||||
return -1;
|
||||
|
||||
/* If not padding input must be multiple of 8 */
|
||||
if (!pad && inlen & 0x7)
|
||||
return -1;
|
||||
|
||||
if (out == NULL) {
|
||||
if (ctx->enc) {
|
||||
/* If padding round up to multiple of 8 */
|
||||
if (pad)
|
||||
inlen = (inlen + 7) / 8 * 8;
|
||||
/* 8 byte prefix */
|
||||
return inlen + 8;
|
||||
} else {
|
||||
/*
|
||||
* If not padding output will be exactly 8 bytes smaller than
|
||||
* input. If padding it will be at least 8 bytes smaller but we
|
||||
* don't know how much.
|
||||
*/
|
||||
return inlen - 8;
|
||||
}
|
||||
}
|
||||
|
||||
rv = wctx->wrapfn(&wctx->ks.ks, wctx->iv_set ? ctx->iv : NULL, out, in,
|
||||
inlen, ctx->block);
|
||||
return rv ? (int)rv : -1;
|
||||
}
|
||||
|
||||
static int aes_wrap_final(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize)
|
||||
{
|
||||
*outl = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aes_wrap_cipher(void *vctx,
|
||||
unsigned char *out, size_t *outl, size_t outsize,
|
||||
const unsigned char *in, size_t inl)
|
||||
{
|
||||
PROV_AES_WRAP_CTX *ctx = (PROV_AES_WRAP_CTX *)vctx;
|
||||
size_t len;
|
||||
|
||||
if (outsize < inl) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = aes_wrap_cipher_internal(ctx, out, in, inl);
|
||||
if (len == 0)
|
||||
return -1;
|
||||
|
||||
*outl = len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aes_wrap_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
const OSSL_PARAM *p;
|
||||
size_t keylen = 0;
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
|
||||
if (p != NULL) {
|
||||
if (!OSSL_PARAM_get_size_t(p, &keylen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->keylen != keylen) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define IMPLEMENT_cipher(mode, fname, UCMODE, flags, kbits, blkbits, ivbits) \
|
||||
static OSSL_OP_cipher_get_params_fn aes_##kbits##_##fname##_get_params; \
|
||||
static int aes_##kbits##_##fname##_get_params(OSSL_PARAM params[]) \
|
||||
{ \
|
||||
return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \
|
||||
flags, kbits, blkbits, ivbits); \
|
||||
} \
|
||||
static OSSL_OP_cipher_newctx_fn aes_##kbits##fname##_newctx; \
|
||||
static void *aes_##kbits##fname##_newctx(void *provctx) \
|
||||
{ \
|
||||
return aes_##mode##_newctx(kbits, blkbits, ivbits, \
|
||||
EVP_CIPH_##UCMODE##_MODE, flags); \
|
||||
} \
|
||||
const OSSL_DISPATCH aes##kbits##fname##_functions[] = { \
|
||||
{ OSSL_FUNC_CIPHER_NEWCTX, \
|
||||
(void (*)(void))aes_##kbits##fname##_newctx }, \
|
||||
{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_##mode##_einit }, \
|
||||
{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_##mode##_dinit }, \
|
||||
{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_##mode##_cipher }, \
|
||||
{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_##mode##_final }, \
|
||||
{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_##mode##_freectx }, \
|
||||
{ OSSL_FUNC_CIPHER_GET_PARAMS, \
|
||||
(void (*)(void))aes_##kbits##_##fname##_get_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \
|
||||
(void (*)(void))cipher_generic_gettable_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \
|
||||
(void (*)(void))cipher_generic_get_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \
|
||||
(void (*)(void))aes_wrap_set_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \
|
||||
(void (*)(void))cipher_generic_gettable_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \
|
||||
(void (*)(void))cipher_generic_settable_ctx_params }, \
|
||||
{ 0, NULL } \
|
||||
}
|
||||
|
||||
IMPLEMENT_cipher(wrap, wrap, WRAP, WRAP_FLAGS, 256, 64, AES_WRAP_NOPAD_IVLEN * 8);
|
||||
IMPLEMENT_cipher(wrap, wrap, WRAP, WRAP_FLAGS, 192, 64, AES_WRAP_NOPAD_IVLEN * 8);
|
||||
IMPLEMENT_cipher(wrap, wrap, WRAP, WRAP_FLAGS, 128, 64, AES_WRAP_NOPAD_IVLEN * 8);
|
||||
IMPLEMENT_cipher(wrap, wrappad, WRAP, WRAP_FLAGS, 256, 64, AES_WRAP_PAD_IVLEN * 8);
|
||||
IMPLEMENT_cipher(wrap, wrappad, WRAP, WRAP_FLAGS, 192, 64, AES_WRAP_PAD_IVLEN * 8);
|
||||
IMPLEMENT_cipher(wrap, wrappad, WRAP, WRAP_FLAGS, 128, 64, AES_WRAP_PAD_IVLEN * 8);
|
||||
@@ -1,284 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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 "cipher_aes_xts.h"
|
||||
#include "internal/provider_algs.h"
|
||||
#include "internal/providercommonerr.h"
|
||||
|
||||
/* TODO (3.0) Figure out what flags need to be set */
|
||||
#define AES_XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \
|
||||
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
|
||||
| EVP_CIPH_CUSTOM_COPY)
|
||||
|
||||
#define AES_XTS_IV_BITS 128
|
||||
#define AES_XTS_BLOCK_BITS 8
|
||||
|
||||
#ifdef FIPS_MODE
|
||||
static const int allow_insecure_decrypt = 0;
|
||||
#else
|
||||
static const int allow_insecure_decrypt = 1;
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
/* forward declarations */
|
||||
static OSSL_OP_cipher_encrypt_init_fn aes_xts_einit;
|
||||
static OSSL_OP_cipher_decrypt_init_fn aes_xts_dinit;
|
||||
static OSSL_OP_cipher_update_fn aes_xts_stream_update;
|
||||
static OSSL_OP_cipher_final_fn aes_xts_stream_final;
|
||||
static OSSL_OP_cipher_cipher_fn aes_xts_cipher;
|
||||
static OSSL_OP_cipher_freectx_fn aes_xts_freectx;
|
||||
static OSSL_OP_cipher_dupctx_fn aes_xts_dupctx;
|
||||
static OSSL_OP_cipher_set_ctx_params_fn aes_xts_set_ctx_params;
|
||||
static OSSL_OP_cipher_settable_ctx_params_fn aes_xts_settable_ctx_params;
|
||||
|
||||
/*
|
||||
* Verify that the two keys are different.
|
||||
*
|
||||
* This addresses the vulnerability described in Rogaway's
|
||||
* September 2004 paper:
|
||||
*
|
||||
* "Efficient Instantiations of Tweakable Blockciphers and
|
||||
* Refinements to Modes OCB and PMAC".
|
||||
* (http://web.cs.ucdavis.edu/~rogaway/papers/offsets.pdf)
|
||||
*
|
||||
* FIPS 140-2 IG A.9 XTS-AES Key Generation Requirements states
|
||||
* that:
|
||||
* "The check for Key_1 != Key_2 shall be done at any place
|
||||
* BEFORE using the keys in the XTS-AES algorithm to process
|
||||
* data with them."
|
||||
*/
|
||||
static int aes_xts_check_keys_differ(const unsigned char *key, size_t bytes,
|
||||
int enc)
|
||||
{
|
||||
if ((!allow_insecure_decrypt || enc)
|
||||
&& CRYPTO_memcmp(key, key + bytes, bytes) == 0) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_XTS_DUPLICATED_KEYS);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Provider dispatch functions
|
||||
*/
|
||||
static int aes_xts_init(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen, int enc)
|
||||
{
|
||||
PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)vctx;
|
||||
PROV_CIPHER_CTX *ctx = &xctx->base;
|
||||
|
||||
ctx->enc = enc;
|
||||
|
||||
if (iv != NULL) {
|
||||
if (ivlen != ctx->ivlen) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
memcpy(ctx->iv, iv, ivlen);
|
||||
xctx->iv_set = 1;
|
||||
}
|
||||
if (key != NULL) {
|
||||
if (keylen != ctx->keylen) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
if (!aes_xts_check_keys_differ(key, keylen / 2, enc))
|
||||
return 0;
|
||||
return ctx->hw->init(ctx, key, keylen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aes_xts_einit(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return aes_xts_init(vctx, key, keylen, iv, ivlen, 1);
|
||||
}
|
||||
|
||||
static int aes_xts_dinit(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return aes_xts_init(vctx, key, keylen, iv, ivlen, 0);
|
||||
}
|
||||
|
||||
static void *aes_xts_newctx(void *provctx, unsigned int mode, uint64_t flags,
|
||||
size_t kbits, size_t blkbits, size_t ivbits)
|
||||
{
|
||||
PROV_AES_XTS_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
|
||||
|
||||
if (ctx != NULL) {
|
||||
cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits, mode, flags,
|
||||
PROV_CIPHER_HW_aes_xts(kbits), NULL);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void aes_xts_freectx(void *vctx)
|
||||
{
|
||||
PROV_AES_XTS_CTX *ctx = (PROV_AES_XTS_CTX *)vctx;
|
||||
|
||||
OPENSSL_clear_free(ctx, sizeof(*ctx));
|
||||
}
|
||||
|
||||
static void *aes_xts_dupctx(void *vctx)
|
||||
{
|
||||
PROV_AES_XTS_CTX *in = (PROV_AES_XTS_CTX *)vctx;
|
||||
PROV_AES_XTS_CTX *ret = NULL;
|
||||
|
||||
if (in->xts.key1 != NULL) {
|
||||
if (in->xts.key1 != &in->ks1)
|
||||
return NULL;
|
||||
}
|
||||
if (in->xts.key2 != NULL) {
|
||||
if (in->xts.key2 != &in->ks2)
|
||||
return NULL;
|
||||
}
|
||||
ret = OPENSSL_malloc(sizeof(*ret));
|
||||
if (ret == NULL) {
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
*ret = *in;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aes_xts_cipher(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize, const unsigned char *in, size_t inl)
|
||||
{
|
||||
PROV_AES_XTS_CTX *ctx = (PROV_AES_XTS_CTX *)vctx;
|
||||
|
||||
if (ctx->xts.key1 == NULL
|
||||
|| ctx->xts.key2 == NULL
|
||||
|| !ctx->iv_set
|
||||
|| out == NULL
|
||||
|| in == NULL
|
||||
|| inl < AES_BLOCK_SIZE)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Impose a limit of 2^20 blocks per data unit as specifed by
|
||||
* IEEE Std 1619-2018. The earlier and obsolete IEEE Std 1619-2007
|
||||
* indicated that this was a SHOULD NOT rather than a MUST NOT.
|
||||
* NIST SP 800-38E mandates the same limit.
|
||||
*/
|
||||
if (inl > XTS_MAX_BLOCKS_PER_DATA_UNIT * AES_BLOCK_SIZE) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->stream != NULL)
|
||||
(*ctx->stream)(in, out, inl, ctx->xts.key1, ctx->xts.key2, ctx->base.iv);
|
||||
else if (CRYPTO_xts128_encrypt(&ctx->xts, ctx->base.iv, in, out, inl,
|
||||
ctx->base.enc))
|
||||
return 0;
|
||||
|
||||
*outl = inl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aes_xts_stream_update(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize, const unsigned char *in,
|
||||
size_t inl)
|
||||
{
|
||||
PROV_AES_XTS_CTX *ctx = (PROV_AES_XTS_CTX *)vctx;
|
||||
|
||||
if (outsize < inl) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!aes_xts_cipher(ctx, out, outl, outsize, in, inl)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aes_xts_stream_final(void *vctx, unsigned char *out, size_t *outl,
|
||||
size_t outsize)
|
||||
{
|
||||
*outl = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const OSSL_PARAM aes_xts_known_settable_ctx_params[] = {
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
|
||||
static const OSSL_PARAM *aes_xts_settable_ctx_params(void)
|
||||
{
|
||||
return aes_xts_known_settable_ctx_params;
|
||||
}
|
||||
|
||||
static int aes_xts_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
/*
|
||||
* TODO(3.0) We need a general solution for handling missing parameters
|
||||
* inside set_params and get_params methods.
|
||||
*/
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
|
||||
if (p != NULL) {
|
||||
size_t keylen;
|
||||
|
||||
if (!OSSL_PARAM_get_size_t(p, &keylen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
/* The key length can not be modified for xts mode */
|
||||
if (keylen != ctx->keylen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define IMPLEMENT_cipher(lcmode, UCMODE, kbits, flags) \
|
||||
static OSSL_OP_cipher_get_params_fn aes_##kbits##_##lcmode##_get_params; \
|
||||
static int aes_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \
|
||||
{ \
|
||||
return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \
|
||||
flags, 2 * kbits, AES_XTS_BLOCK_BITS, \
|
||||
AES_XTS_IV_BITS); \
|
||||
} \
|
||||
static OSSL_OP_cipher_newctx_fn aes_##kbits##_xts_newctx; \
|
||||
static void *aes_##kbits##_xts_newctx(void *provctx) \
|
||||
{ \
|
||||
return aes_xts_newctx(provctx, EVP_CIPH_##UCMODE##_MODE, flags, 2 * kbits, \
|
||||
AES_XTS_BLOCK_BITS, AES_XTS_IV_BITS); \
|
||||
} \
|
||||
const OSSL_DISPATCH aes##kbits##xts_functions[] = { \
|
||||
{ OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##kbits##_xts_newctx }, \
|
||||
{ OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_xts_einit }, \
|
||||
{ OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_xts_dinit }, \
|
||||
{ OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))aes_xts_stream_update }, \
|
||||
{ OSSL_FUNC_CIPHER_FINAL, (void (*)(void))aes_xts_stream_final }, \
|
||||
{ OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))aes_xts_cipher }, \
|
||||
{ OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))aes_xts_freectx }, \
|
||||
{ OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))aes_xts_dupctx }, \
|
||||
{ OSSL_FUNC_CIPHER_GET_PARAMS, \
|
||||
(void (*)(void))aes_##kbits##_##lcmode##_get_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \
|
||||
(void (*)(void))cipher_generic_gettable_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \
|
||||
(void (*)(void))cipher_generic_get_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \
|
||||
(void (*)(void))cipher_generic_gettable_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \
|
||||
(void (*)(void))aes_xts_set_ctx_params }, \
|
||||
{ OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \
|
||||
(void (*)(void))aes_xts_settable_ctx_params }, \
|
||||
{ 0, NULL } \
|
||||
}
|
||||
|
||||
IMPLEMENT_cipher(xts, XTS, 256, AES_XTS_FLAGS);
|
||||
IMPLEMENT_cipher(xts, XTS, 128, AES_XTS_FLAGS);
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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/aes.h>
|
||||
#include "internal/ciphers/ciphercommon.h"
|
||||
|
||||
PROV_CIPHER_FUNC(void, xts_stream,
|
||||
(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const AES_KEY *key1, const AES_KEY *key2,
|
||||
const unsigned char iv[16]));
|
||||
|
||||
typedef struct prov_aes_xts_ctx_st {
|
||||
PROV_CIPHER_CTX base; /* Must be first */
|
||||
union {
|
||||
OSSL_UNION_ALIGN;
|
||||
AES_KEY ks;
|
||||
} ks1, ks2; /* AES key schedules to use */
|
||||
XTS128_CONTEXT xts;
|
||||
OSSL_xts_stream_fn stream;
|
||||
unsigned int iv_set : 1; /* Set if an iv is set */
|
||||
} PROV_AES_XTS_CTX;
|
||||
|
||||
const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_xts(size_t keybits);
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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 "cipher_aes_xts.h"
|
||||
|
||||
#define XTS_SET_KEY_FN(fn_set_enc_key, fn_set_dec_key, \
|
||||
fn_block_enc, fn_block_dec, \
|
||||
fn_stream_enc, fn_stream_dec) { \
|
||||
size_t bytes = keylen / 2; \
|
||||
size_t bits = bytes * 8; \
|
||||
\
|
||||
if (ctx->enc) { \
|
||||
fn_set_enc_key(key, bits, &xctx->ks1.ks); \
|
||||
xctx->xts.block1 = (block128_f)fn_block_enc; \
|
||||
} else { \
|
||||
fn_set_dec_key(key, bits, &xctx->ks1.ks); \
|
||||
xctx->xts.block1 = (block128_f)fn_block_dec; \
|
||||
} \
|
||||
fn_set_enc_key(key + bytes, bits, &xctx->ks2.ks); \
|
||||
xctx->xts.block2 = (block128_f)fn_block_enc; \
|
||||
xctx->xts.key1 = &xctx->ks1; \
|
||||
xctx->xts.key2 = &xctx->ks2; \
|
||||
xctx->stream = ctx->enc ? fn_stream_enc : fn_stream_dec; \
|
||||
}
|
||||
|
||||
static int cipher_hw_aes_xts_generic_initkey(PROV_CIPHER_CTX *ctx,
|
||||
const unsigned char *key,
|
||||
size_t keylen)
|
||||
{
|
||||
PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;
|
||||
OSSL_xts_stream_fn stream_enc = NULL;
|
||||
OSSL_xts_stream_fn stream_dec = NULL;
|
||||
|
||||
#ifdef AES_XTS_ASM
|
||||
stream_enc = AES_xts_encrypt;
|
||||
stream_dec = AES_xts_decrypt;
|
||||
#endif /* AES_XTS_ASM */
|
||||
|
||||
#ifdef HWAES_CAPABLE
|
||||
if (HWAES_CAPABLE) {
|
||||
# ifdef HWAES_xts_encrypt
|
||||
stream_enc = HWAES_xts_encrypt;
|
||||
# endif /* HWAES_xts_encrypt */
|
||||
# ifdef HWAES_xts_decrypt
|
||||
stream_dec = HWAES_xts_decrypt;
|
||||
# endif /* HWAES_xts_decrypt */
|
||||
XTS_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_set_decrypt_key,
|
||||
HWAES_encrypt, HWAES_decrypt,
|
||||
stream_enc, stream_dec);
|
||||
} else
|
||||
#endif /* HWAES_CAPABLE */
|
||||
|
||||
#ifdef BSAES_CAPABLE
|
||||
if (BSAES_CAPABLE) {
|
||||
stream_enc = bsaes_xts_encrypt;
|
||||
stream_dec = bsaes_xts_decrypt;
|
||||
}
|
||||
#endif /* BSAES_CAPABLE */
|
||||
|
||||
#ifdef VPAES_CAPABLE
|
||||
if (VPAES_CAPABLE) {
|
||||
XTS_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_set_decrypt_key,
|
||||
vpaes_encrypt, vpaes_decrypt, stream_enc, stream_dec);
|
||||
} else
|
||||
#endif /* VPAES_CAPABLE */
|
||||
{
|
||||
XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_decrypt_key,
|
||||
AES_encrypt, AES_decrypt, stream_enc, stream_dec);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined(AESNI_CAPABLE)
|
||||
|
||||
static int cipher_hw_aesni_xts_initkey(PROV_CIPHER_CTX *ctx,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;
|
||||
|
||||
XTS_SET_KEY_FN(aesni_set_encrypt_key, aesni_set_decrypt_key,
|
||||
aesni_encrypt, aesni_decrypt,
|
||||
aesni_xts_encrypt, aesni_xts_decrypt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
# define PROV_CIPHER_HW_declare_xts() \
|
||||
static const PROV_CIPHER_HW aesni_xts = { \
|
||||
cipher_hw_aesni_xts_initkey, \
|
||||
NULL \
|
||||
};
|
||||
# define PROV_CIPHER_HW_select_xts() \
|
||||
if (AESNI_CAPABLE) \
|
||||
return &aesni_xts;
|
||||
|
||||
# elif defined(SPARC_AES_CAPABLE)
|
||||
|
||||
static int cipher_hw_aes_xts_t4_initkey(PROV_CIPHER_CTX *ctx,
|
||||
const unsigned char *key, size_t keylen)
|
||||
{
|
||||
PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx;
|
||||
OSSL_xts_stream_fn stream_enc = NULL;
|
||||
OSSL_xts_stream_fn stream_dec = NULL;
|
||||
|
||||
/* Note: keylen is the size of 2 keys */
|
||||
switch (keylen) {
|
||||
case 32:
|
||||
stream_enc = aes128_t4_xts_encrypt;
|
||||
stream_dec = aes128_t4_xts_decrypt;
|
||||
break;
|
||||
case 64:
|
||||
stream_enc = aes256_t4_xts_encrypt;
|
||||
stream_dec = aes256_t4_xts_decrypt;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
XTS_SET_KEY_FN(aes_t4_set_encrypt_key, aes_t4_set_decrypt_key,
|
||||
aes_t4_encrypt, aes_t4_decrypt,
|
||||
stream_enc, stream_dec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
# define PROV_CIPHER_HW_declare_xts() \
|
||||
static const PROV_CIPHER_HW aes_xts_t4 = { \
|
||||
cipher_hw_aes_xts_t4_initkey, \
|
||||
NULL \
|
||||
};
|
||||
# define PROV_CIPHER_HW_select_xts() \
|
||||
if (SPARC_AES_CAPABLE) \
|
||||
return &aes_xts_t4;
|
||||
# else
|
||||
/* The generic case */
|
||||
# define PROV_CIPHER_HW_declare_xts()
|
||||
# define PROV_CIPHER_HW_select_xts()
|
||||
#endif
|
||||
|
||||
static const PROV_CIPHER_HW aes_generic_xts = {
|
||||
cipher_hw_aes_xts_generic_initkey,
|
||||
NULL
|
||||
};
|
||||
PROV_CIPHER_HW_declare_xts()
|
||||
const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_xts(size_t keybits)
|
||||
{
|
||||
PROV_CIPHER_HW_select_xts()
|
||||
return &aes_generic_xts;
|
||||
}
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
/* Dispatch functions for ccm mode */
|
||||
|
||||
#include "cipher_locl.h"
|
||||
#include "internal/ciphers/cipher_ccm.h"
|
||||
#include "internal/providercommonerr.h"
|
||||
#include "prov/ciphercommon.h"
|
||||
#include "prov/cipher_ccm.h"
|
||||
#include "prov/providercommonerr.h"
|
||||
|
||||
static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out,
|
||||
size_t *padlen, const unsigned char *in,
|
||||
@@ -213,7 +213,6 @@ static int ccm_init(void *vctx, const unsigned char *key, size_t keylen,
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(ctx->iv, iv, ivlen);
|
||||
ctx->iv_set = 1;
|
||||
}
|
||||
@@ -279,11 +278,11 @@ int ccm_cipher(void *vctx,
|
||||
|
||||
if (outsize < inl) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ccm_cipher_internal(ctx, out, outl, in, inl) <= 0)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
*outl = inl;
|
||||
return 1;
|
||||
@@ -420,7 +419,3 @@ void ccm_initctx(PROV_CCM_CTX *ctx, size_t keybits, const PROV_CCM_HW *hw)
|
||||
ctx->hw = hw;
|
||||
}
|
||||
|
||||
void ccm_finalctx(PROV_CCM_CTX *ctx)
|
||||
{
|
||||
OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv));
|
||||
}
|
||||
@@ -7,8 +7,8 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "internal/ciphers/ciphercommon.h"
|
||||
#include "internal/ciphers/cipher_ccm.h"
|
||||
#include "prov/ciphercommon.h"
|
||||
#include "prov/cipher_ccm.h"
|
||||
|
||||
int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
|
||||
size_t nlen, size_t mlen)
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
* Generic dispatch table functions for ciphers.
|
||||
*/
|
||||
|
||||
#include "cipher_locl.h"
|
||||
#include "internal/provider_ctx.h"
|
||||
#include "internal/providercommonerr.h"
|
||||
#include "cipher_local.h"
|
||||
#include "prov/provider_ctx.h"
|
||||
#include "prov/providercommonerr.h"
|
||||
|
||||
/*-
|
||||
* Generic cipher functions for OSSL_PARAM gettables and settables
|
||||
@@ -68,16 +68,8 @@ int cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
|
||||
CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(cipher_generic)
|
||||
CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(cipher_generic)
|
||||
|
||||
static const OSSL_PARAM cipher_known_settable_ctx_params[] = {
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
|
||||
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL),
|
||||
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
const OSSL_PARAM *cipher_generic_settable_ctx_params(void)
|
||||
{
|
||||
return cipher_known_settable_ctx_params;
|
||||
}
|
||||
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(cipher_generic)
|
||||
CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(cipher_generic)
|
||||
|
||||
/*-
|
||||
* AEAD cipher functions for OSSL_PARAM gettables and settables
|
||||
@@ -117,11 +109,8 @@ static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx,
|
||||
ctx->enc = enc ? 1 : 0;
|
||||
|
||||
if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) {
|
||||
if (ivlen != ctx->ivlen) {
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
|
||||
if (!cipher_generic_initiv(ctx, iv, ivlen))
|
||||
return 0;
|
||||
}
|
||||
memcpy(ctx->iv, iv, ctx->ivlen);
|
||||
}
|
||||
if (key != NULL) {
|
||||
if ((ctx->flags & EVP_CIPH_VARIABLE_LENGTH) == 0) {
|
||||
@@ -330,8 +319,8 @@ int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
||||
}
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV);
|
||||
if (p != NULL
|
||||
&& !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)
|
||||
&& !OSSL_PARAM_set_octet_string(p, &ctx->iv, ctx->ivlen)) {
|
||||
&& !OSSL_PARAM_set_octet_ptr(p, &ctx->oiv, ctx->ivlen)
|
||||
&& !OSSL_PARAM_set_octet_string(p, &ctx->oiv, ctx->ivlen)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
@@ -345,7 +334,6 @@ int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -387,6 +375,20 @@ int cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv,
|
||||
size_t ivlen)
|
||||
{
|
||||
if (ivlen != ctx->ivlen
|
||||
|| ivlen > sizeof(ctx->iv)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
|
||||
return 0;
|
||||
}
|
||||
ctx->iv_set = 1;
|
||||
memcpy(ctx->iv, iv, ivlen);
|
||||
memcpy(ctx->oiv, iv, ivlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
|
||||
size_t ivbits, unsigned int mode, uint64_t flags,
|
||||
const PROV_CIPHER_HW *hw, void *provctx)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "cipher_locl.h"
|
||||
#include "prov/ciphercommon.h"
|
||||
|
||||
/*-
|
||||
* The generic cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr.
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
/* Dispatch functions for gcm mode */
|
||||
|
||||
#include "cipher_locl.h"
|
||||
#include "internal/ciphers/cipher_gcm.h"
|
||||
#include "internal/providercommonerr.h"
|
||||
#include "internal/rand_int.h"
|
||||
#include "internal/provider_ctx.h"
|
||||
#include "prov/ciphercommon.h"
|
||||
#include "prov/cipher_gcm.h"
|
||||
#include "prov/providercommonerr.h"
|
||||
#include "crypto/rand.h"
|
||||
#include "prov/provider_ctx.h"
|
||||
|
||||
static int gcm_tls_init(PROV_GCM_CTX *dat, unsigned char *aad, size_t aad_len);
|
||||
static int gcm_tls_iv_set_fixed(PROV_GCM_CTX *ctx, unsigned char *iv,
|
||||
@@ -38,11 +38,6 @@ void gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits,
|
||||
ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
|
||||
}
|
||||
|
||||
void gcm_deinitctx(PROV_GCM_CTX *ctx)
|
||||
{
|
||||
OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv));
|
||||
}
|
||||
|
||||
static int gcm_init(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen, int enc)
|
||||
{
|
||||
@@ -56,7 +51,7 @@ static int gcm_init(void *vctx, const unsigned char *key, size_t keylen,
|
||||
return 0;
|
||||
}
|
||||
ctx->ivlen = ivlen;
|
||||
memcpy(ctx->iv, iv, ctx->ivlen);
|
||||
memcpy(ctx->iv, iv, ivlen);
|
||||
ctx->iv_state = IV_STATE_BUFFERED;
|
||||
}
|
||||
|
||||
@@ -268,11 +263,11 @@ int gcm_cipher(void *vctx,
|
||||
|
||||
if (outsize < inl) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gcm_cipher_internal(ctx, out, outl, in, inl) <= 0)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
*outl = inl;
|
||||
return 1;
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include "cipher_locl.h"
|
||||
#include "internal/ciphers/cipher_gcm.h"
|
||||
#include "prov/ciphercommon.h"
|
||||
#include "prov/cipher_gcm.h"
|
||||
|
||||
|
||||
int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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 "prov/ciphercommon.h"
|
||||
|
||||
void padblock(unsigned char *buf, size_t *buflen, size_t blocksize);
|
||||
int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize);
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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 "internal/ciphers/ciphercommon.h"
|
||||
|
||||
#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name) \
|
||||
static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), \
|
||||
OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), \
|
||||
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \
|
||||
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), \
|
||||
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
|
||||
|
||||
#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name) \
|
||||
OSSL_PARAM_END \
|
||||
}; \
|
||||
const OSSL_PARAM * name##_gettable_ctx_params(void) \
|
||||
{ \
|
||||
return name##_known_gettable_ctx_params; \
|
||||
}
|
||||
|
||||
void padblock(unsigned char *buf, size_t *buflen, size_t blocksize);
|
||||
int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize);
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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 "cipher_locl.h"
|
||||
#include "internal/ciphers/cipher_tdes.h"
|
||||
#include "internal/rand_int.h"
|
||||
#include "internal/provider_algs.h"
|
||||
#include "internal/providercommonerr.h"
|
||||
|
||||
void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
|
||||
size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw)
|
||||
{
|
||||
PROV_TDES_CTX *tctx = OPENSSL_zalloc(sizeof(*tctx));
|
||||
|
||||
if (tctx != NULL)
|
||||
cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, flags, hw,
|
||||
provctx);
|
||||
return tctx;
|
||||
}
|
||||
|
||||
void tdes_freectx(void *vctx)
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
|
||||
OPENSSL_clear_free(ctx, sizeof(*ctx));
|
||||
}
|
||||
|
||||
static int tdes_init(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen, int enc)
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
|
||||
ctx->enc = enc;
|
||||
|
||||
if (iv != NULL) {
|
||||
if (ivlen != TDES_IVLEN) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN);
|
||||
return 0;
|
||||
}
|
||||
memcpy(ctx->iv, iv, TDES_IVLEN);
|
||||
}
|
||||
|
||||
if (key != NULL) {
|
||||
if (keylen != ctx->keylen) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEYLEN);
|
||||
return 0;
|
||||
}
|
||||
return ctx->hw->init(ctx, key, ctx->keylen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tdes_einit(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return tdes_init(vctx, key, keylen, iv, ivlen, 1);
|
||||
}
|
||||
|
||||
int tdes_dinit(void *vctx, const unsigned char *key, size_t keylen,
|
||||
const unsigned char *iv, size_t ivlen)
|
||||
{
|
||||
return tdes_init(vctx, key, keylen, iv, ivlen, 0);
|
||||
}
|
||||
|
||||
static int tdes_generatekey(PROV_CIPHER_CTX *ctx, void *ptr)
|
||||
{
|
||||
|
||||
DES_cblock *deskey = ptr;
|
||||
size_t kl = ctx->keylen;
|
||||
|
||||
if (kl == 0 || rand_priv_bytes_ex(ctx->libctx, ptr, kl) <= 0)
|
||||
return 0;
|
||||
DES_set_odd_parity(deskey);
|
||||
if (kl >= 16)
|
||||
DES_set_odd_parity(deskey + 1);
|
||||
if (kl >= 24) {
|
||||
DES_set_odd_parity(deskey + 2);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(tdes)
|
||||
OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0),
|
||||
CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(tdes)
|
||||
|
||||
int tdes_get_ctx_params(void *vctx, OSSL_PARAM params[])
|
||||
{
|
||||
PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
|
||||
OSSL_PARAM *p;
|
||||
|
||||
if (!cipher_generic_get_ctx_params(vctx, params))
|
||||
return 0;
|
||||
|
||||
p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY);
|
||||
if (p != NULL && !tdes_generatekey(ctx, p->data)) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO(3.0) - ECB mode does not use an IV - but existing test code is setting
|
||||
* an IV. Fixing this could potentially make applications break.
|
||||
*/
|
||||
|
||||
/* tdes_ede3_ecb_functions */
|
||||
IMPLEMENT_tdes_cipher(ede3, EDE3, ecb, ECB, TDES_FLAGS, 64*3, 64, 64, block);
|
||||
/* tdes_ede3_cbc_functions */
|
||||
IMPLEMENT_tdes_cipher(ede3, EDE3, cbc, CBC, TDES_FLAGS, 64*3, 64, 64, block);
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* 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 "cipher_locl.h"
|
||||
#include "internal/ciphers/cipher_tdes.h"
|
||||
|
||||
#define ks1 tks.ks[0]
|
||||
#define ks2 tks.ks[1]
|
||||
#define ks3 tks.ks[2]
|
||||
|
||||
int cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
size_t keylen)
|
||||
{
|
||||
PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
|
||||
DES_cblock *deskey = (DES_cblock *)key;
|
||||
|
||||
tctx->tstream.cbc = NULL;
|
||||
# if defined(SPARC_DES_CAPABLE)
|
||||
if (SPARC_DES_CAPABLE) {
|
||||
if (ctx->mode == EVP_CIPH_CBC_MODE) {
|
||||
des_t4_key_expand(&deskey[0], &tctx->ks1);
|
||||
des_t4_key_expand(&deskey[1], &tctx->ks2);
|
||||
des_t4_key_expand(&deskey[2], &tctx->ks3);
|
||||
tctx->tstream.cbc = ctx->enc ? des_t4_ede3_cbc_encrypt :
|
||||
des_t4_ede3_cbc_decrypt;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
DES_set_key_unchecked(&deskey[0], &tctx->ks1);
|
||||
DES_set_key_unchecked(&deskey[1], &tctx->ks2);
|
||||
DES_set_key_unchecked(&deskey[2], &tctx->ks3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_hw_tdes_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t inl)
|
||||
{
|
||||
PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
|
||||
|
||||
if (tctx->tstream.cbc != NULL) {
|
||||
(*tctx->tstream.cbc) (in, out, inl, tctx->tks.ks, ctx->iv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (inl >= MAXCHUNK) {
|
||||
DES_ede3_cbc_encrypt(in, out, (long)MAXCHUNK, &tctx->ks1, &tctx->ks2,
|
||||
&tctx->ks3, (DES_cblock *)ctx->iv, ctx->enc);
|
||||
inl -= MAXCHUNK;
|
||||
in += MAXCHUNK;
|
||||
out += MAXCHUNK;
|
||||
}
|
||||
if (inl > 0)
|
||||
DES_ede3_cbc_encrypt(in, out, (long)inl, &tctx->ks1, &tctx->ks2,
|
||||
&tctx->ks3, (DES_cblock *)ctx->iv, ctx->enc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cipher_hw_tdes_ecb(PROV_CIPHER_CTX *ctx, unsigned char *out,
|
||||
const unsigned char *in, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx;
|
||||
|
||||
if (len < DES_BLOCK_SIZE)
|
||||
return 1;
|
||||
|
||||
for (i = 0, len -= DES_BLOCK_SIZE; i <= len; i += DES_BLOCK_SIZE) {
|
||||
DES_ecb3_encrypt((const_DES_cblock *)(in + i), (DES_cblock *)(out + i),
|
||||
&tctx->ks1, &tctx->ks2, &tctx->ks3, ctx->enc);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
PROV_CIPHER_HW_tdes_mode(ede3, ecb)
|
||||
PROV_CIPHER_HW_tdes_mode(ede3, cbc)
|
||||
Reference in New Issue
Block a user