File openssl-fips-xts_nonidentical_key_parts.patch of Package openssl
Index: openssl-1.0.2j/crypto/evp/e_aes.c
===================================================================
--- openssl-1.0.2j.orig/crypto/evp/e_aes.c 2017-02-06 14:16:20.979865575 +0100
+++ openssl-1.0.2j/crypto/evp/e_aes.c 2017-02-06 14:44:58.683606664 +0100
@@ -177,6 +177,26 @@ void AES_xts_decrypt(const char *inp, ch
# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks
# endif
+static int xts_check_key(const unsigned char *key, unsigned int key_len)
+{
+ /*
+ * key consists of two keys of equal size concatenated,
+ * therefore the length must be even
+ */
+ if (key_len % 2)
+ return 0;
+
+# ifdef OPENSSL_FIPS
+ /* FIPS 140-2 IG A.9 mandates that the key parts mustn't match */
+ if (FIPS_module_mode() &&
+ CRYPTO_memcmp(key, key + (key_len / 2), key_len / 2) == 0) {
+ return 0;
+ }
+# endif
+
+ return 1;
+}
+
# if defined(AES_ASM) && !defined(I386_ONLY) && ( \
((defined(__i386) || defined(__i386__) || \
defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
@@ -387,6 +407,9 @@ static int aesni_xts_init_key(EVP_CIPHER
return 1;
if (key) {
+ if (xts_check_key(key, ctx->key_len) == 0)
+ return 0;
+
/* key_len is two AES keys */
if (enc) {
aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
@@ -707,6 +730,9 @@ static int aes_t4_xts_init_key(EVP_CIPHE
return 1;
if (key) {
+ if (xts_check_key(key, ctx->key_len) == 0)
+ return 0;
+
int bits = ctx->key_len * 4;
xctx->stream = NULL;
/* key_len is two AES keys */
@@ -1651,6 +1677,9 @@ static int aes_xts_init_key(EVP_CIPHER_C
return 1;
if (key)
+ if (xts_check_key(key, ctx->key_len) == 0)
+ return 0;
+
do {
# ifdef AES_XTS_ASM
xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;