summaryrefslogtreecommitdiffstats
path: root/providers/common
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2019-09-14 09:27:49 +1000
committerShane Lontis <shane.lontis@oracle.com>2019-09-14 09:27:49 +1000
commit3a9f26f3308c5b3e59ec0e589310fd137b0399f6 (patch)
tree7eee906072dbc4679fbb2007ab8bf14f4ee91637 /providers/common
parent88d870824f1f913877f0f978ae60879575daf56d (diff)
Add aes_xts cipher to providers
Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/9327)
Diffstat (limited to 'providers/common')
-rw-r--r--providers/common/ciphers/build.info4
-rw-r--r--providers/common/ciphers/cipher_aes_xts.c286
-rw-r--r--providers/common/ciphers/cipher_aes_xts.h29
-rw-r--r--providers/common/ciphers/cipher_aes_xts_hw.c153
-rw-r--r--providers/common/include/internal/provider_algs.h2
-rw-r--r--providers/common/include/internal/providercommonerr.h2
-rw-r--r--providers/common/provider_err.c4
7 files changed, 479 insertions, 1 deletions
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 <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);
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}
};