From: Shane Lontis Date: Fri, 13 Sep 2019 23:27:49 +0000 (+1000) Subject: Add aes_xts cipher to providers X-Git-Tag: openssl-3.0.0-alpha1~1358 X-Git-Url: https://git.openssl.org/?p=openssl.git;a=commitdiff_plain;h=3a9f26f3308c5b3e59ec0e589310fd137b0399f6 Add aes_xts cipher to providers Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/9327) --- diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index f74659c599..700f1da20f 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2706,6 +2706,8 @@ PROV_R_UNSUPPORTED_MAC_TYPE:137:unsupported mac type PROV_R_VALUE_ERROR:138:value error PROV_R_WRONG_FINAL_BLOCK_LENGTH:107:wrong final block length PROV_R_WRONG_OUTPUT_BUFFER_SIZE:139:wrong output buffer size +PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE:148:xts data unit is too large +PROV_R_XTS_DUPLICATED_KEYS:149:xts duplicated keys RAND_R_ADDITIONAL_INPUT_TOO_LONG:102:additional input too long RAND_R_ALREADY_INSTANTIATED:103:already instantiated RAND_R_ARGUMENT_OUT_OF_RANGE:105:argument out of range diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 466a03dbf3..6d657f76cd 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -163,6 +163,8 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, case NID_aes_256_ctr: case NID_aes_192_ctr: case NID_aes_128_ctr: + case NID_aes_128_xts: + case NID_aes_256_xts: case NID_aes_256_gcm: case NID_aes_192_gcm: case NID_aes_128_gcm: diff --git a/crypto/modes/build.info b/crypto/modes/build.info index fa5e52f50e..506e04d5fa 100644 --- a/crypto/modes/build.info +++ b/crypto/modes/build.info @@ -48,9 +48,10 @@ IF[{- !$disabled{asm} -}] ENDIF ENDIF -$COMMON=cbc128.c ctr128.c cfb128.c ofb128.c gcm128.c ccm128.c $MODESASM +$COMMON=cbc128.c ctr128.c cfb128.c ofb128.c gcm128.c ccm128.c xts128.c $MODESASM SOURCE[../../libcrypto]=$COMMON \ - cts128.c xts128.c wrap128.c ocb128.c siv128.c + cts128.c wrap128.c ocb128.c siv128.c + DEFINE[../../libcrypto]=$MODESDEF SOURCE[../../providers/fips]=$COMMON DEFINE[../../providers/fips]=$MODESDEF diff --git a/providers/common/ciphers/build.info b/providers/common/ciphers/build.info index 0302cf151e..3f303e96b0 100644 --- a/providers/common/ciphers/build.info +++ b/providers/common/ciphers/build.info @@ -6,6 +6,7 @@ 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 \ cipher_gcm.c cipher_gcm_hw.c \ cipher_aes_gcm.c cipher_aes_gcm_hw.c \ cipher_ccm.c cipher_ccm_hw.c \ @@ -16,4 +17,5 @@ SOURCE[../../../libcrypto]=$COMMON INCLUDE[../../../libcrypto]=. ../../../crypto SOURCE[../../fips]=$COMMON -INCLUDE[../../fips]=. ../../../crypto \ No newline at end of file +INCLUDE[../../fips]=. ../../../crypto + diff --git a/providers/common/ciphers/cipher_aes_xts.c b/providers/common/ciphers/cipher_aes_xts.c new file mode 100644 index 0000000000..feaa36991f --- /dev/null +++ b/providers/common/ciphers/cipher_aes_xts.c @@ -0,0 +1,286 @@ +/* + * 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, 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, + 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; + return 1; + + *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; + } + + *outl = inl; + 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, 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); diff --git a/providers/common/ciphers/cipher_aes_xts.h b/providers/common/ciphers/cipher_aes_xts.h new file mode 100644 index 0000000000..daad274328 --- /dev/null +++ b/providers/common/ciphers/cipher_aes_xts.h @@ -0,0 +1,29 @@ +/* + * 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 +#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); diff --git a/providers/common/ciphers/cipher_aes_xts_hw.c b/providers/common/ciphers/cipher_aes_xts_hw.c new file mode 100644 index 0000000000..2b06c5bb4b --- /dev/null +++ b/providers/common/ciphers/cipher_aes_xts_hw.c @@ -0,0 +1,153 @@ +/* + * 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_xts_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; +} diff --git a/providers/common/include/internal/provider_algs.h b/providers/common/include/internal/provider_algs.h index 92aa64772e..e6da5f32a8 100644 --- a/providers/common/include/internal/provider_algs.h +++ b/providers/common/include/internal/provider_algs.h @@ -56,6 +56,8 @@ extern const OSSL_DISPATCH aes128cfb8_functions[]; extern const OSSL_DISPATCH aes256ctr_functions[]; extern const OSSL_DISPATCH aes192ctr_functions[]; extern const OSSL_DISPATCH aes128ctr_functions[]; +extern const OSSL_DISPATCH aes256xts_functions[]; +extern const OSSL_DISPATCH aes128xts_functions[]; extern const OSSL_DISPATCH aes256gcm_functions[]; extern const OSSL_DISPATCH aes192gcm_functions[]; extern const OSSL_DISPATCH aes128gcm_functions[]; diff --git a/providers/common/include/internal/providercommonerr.h b/providers/common/include/internal/providercommonerr.h index 39f56b4950..81e5931d84 100644 --- a/providers/common/include/internal/providercommonerr.h +++ b/providers/common/include/internal/providercommonerr.h @@ -97,5 +97,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_VALUE_ERROR 138 # define PROV_R_WRONG_FINAL_BLOCK_LENGTH 107 # define PROV_R_WRONG_OUTPUT_BUFFER_SIZE 139 +# define PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE 148 +# define PROV_R_XTS_DUPLICATED_KEYS 149 #endif diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index f9524a7f62..27d6837af3 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -83,6 +83,10 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "wrong final block length"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_OUTPUT_BUFFER_SIZE), "wrong output buffer size"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE), + "xts data unit is too large"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_XTS_DUPLICATED_KEYS), + "xts duplicated keys"}, {0, NULL} }; diff --git a/providers/default/defltprov.c b/providers/default/defltprov.c index 3f2ad610a9..e829dbfac0 100644 --- a/providers/default/defltprov.c +++ b/providers/default/defltprov.c @@ -114,6 +114,8 @@ static const OSSL_ALGORITHM deflt_ciphers[] = { { "AES-256-CTR", "default=yes", aes256ctr_functions }, { "AES-192-CTR", "default=yes", aes192ctr_functions }, { "AES-128-CTR", "default=yes", aes128ctr_functions }, + { "AES-256-XTS", "default=yes", aes256xts_functions }, + { "AES-128-XTS", "default=yes", aes128xts_functions }, /* TODO(3.0) Add aliases when they are supported */ { "id-aes256-GCM", "default=yes", aes256gcm_functions }, { "id-aes192-GCM", "default=yes", aes192gcm_functions }, diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index e5bb9b41d6..cff172921c 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -268,6 +268,10 @@ const char *ossl_prov_util_nid_to_name(int nid) return "AES-192-CTR"; case NID_aes_128_ctr: return "AES-128-CTR"; + case NID_aes_256_xts: + return "AES-256-XTS"; + case NID_aes_128_xts: + return "AES-128-XTS"; /* TODO(3.0) Change these when we have aliases */ case NID_aes_256_gcm: return "id-aes256-GCM"; @@ -320,6 +324,8 @@ static const OSSL_ALGORITHM fips_ciphers[] = { { "AES-256-CTR", "fips=yes", aes256ctr_functions }, { "AES-192-CTR", "fips=yes", aes192ctr_functions }, { "AES-128-CTR", "fips=yes", aes128ctr_functions }, + { "AES-256-XTS", "fips=yes", aes256xts_functions }, + { "AES-128-XTS", "fips=yes", aes128xts_functions }, /* TODO(3.0) Add aliases for these ciphers */ { "id-aes256-GCM", "fips=yes", aes256gcm_functions }, { "id-aes192-GCM", "fips=yes", aes192gcm_functions }, diff --git a/test/recipes/30-test_evp_data/evpciph.txt b/test/recipes/30-test_evp_data/evpciph.txt index 28820ecf52..3d7d817bc8 100644 --- a/test/recipes/30-test_evp_data/evpciph.txt +++ b/test/recipes/30-test_evp_data/evpciph.txt @@ -1258,18 +1258,18 @@ Ciphertext = 917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e Result = KEY_SET_ERROR # Using the same key twice for decryption is banned in FIPS mode. -#Cipher = aes-128-xts -#FIPS = YES -#Operation = DECRYPT -#Key = 0000000000000000000000000000000000000000000000000000000000000000 -#IV = 00000000000000000000000000000000 -#Plaintext = 0000000000000000000000000000000000000000000000000000000000000000 -#Ciphertext = 917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e -#Result = KEY_SET_ERROR +Cipher = aes-128-xts +Availablein = fips +Operation = DECRYPT +Key = 0000000000000000000000000000000000000000000000000000000000000000 +IV = 00000000000000000000000000000000 +Plaintext = 0000000000000000000000000000000000000000000000000000000000000000 +Ciphertext = 917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e +Result = KEY_SET_ERROR # Using the same key twice for decryption is allowed outside of FIPS mode. Cipher = aes-128-xts -#FIPS = NO +Availablein = default Operation = DECRYPT Key = 0000000000000000000000000000000000000000000000000000000000000000 IV = 00000000000000000000000000000000