summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAngus Gratton <gus@projectgus.com>2021-06-09 21:41:36 +1000
committerGitHub <noreply@github.com>2021-06-09 07:41:36 -0400
commitf0715b835ed5d71cf0b38f165ac6d28e003b4bb5 (patch)
tree50dd42fa63606689196aff6c7e0f95470df3a2fb /src
parent1eeee2b8431b81b52a006881d2381ef97c2d1914 (diff)
downloadcryptography-f0715b835ed5d71cf0b38f165ac6d28e003b4bb5.tar.gz
Added handling for OpenSSL "xts duplicated keys" error. (#6085)
* Added handling for OpenSSL "xts duplicated keys" error. Closes #5998 This error value was added pre-OpenSSL 1.1.1d here: https://github.com/openssl/openssl/commit/2a5f63c9a61be7582620c4b5da202bb3fd7e4138 and refined to only cover encryption shortly after: https://github.com/openssl/openssl/commit/58ae5a47da1e4843b0cd1846eb297b341d0e7201 * test_aes: Remove unnecessary assignment * xts: Update duplicated keys check for OpenSSL 3 providers Also, change the exception message slightly: - Now matches the tense used by openssl - Turns out decryption *is* checked for duplicate keys by OpenSSL 3 when in FIPS mode
Diffstat (limited to 'src')
-rw-r--r--src/_cffi_src/openssl/cryptography.py3
-rw-r--r--src/_cffi_src/openssl/err.py5
-rw-r--r--src/_cffi_src/openssl/provider.py2
-rw-r--r--src/cryptography/hazmat/backends/openssl/ciphers.py23
4 files changed, 32 insertions, 1 deletions
diff --git a/src/_cffi_src/openssl/cryptography.py b/src/_cffi_src/openssl/cryptography.py
index e9a9a522e..802a72acb 100644
--- a/src/_cffi_src/openssl/cryptography.py
+++ b/src/_cffi_src/openssl/cryptography.py
@@ -41,6 +41,8 @@ INCLUDES = """
#define CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER \
(OPENSSL_VERSION_NUMBER >= 0x1010006f && !CRYPTOGRAPHY_IS_LIBRESSL)
+#define CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER \
+ (OPENSSL_VERSION_NUMBER >= 0x10101040 && !CRYPTOGRAPHY_IS_LIBRESSL)
#define CRYPTOGRAPHY_OPENSSL_300_OR_GREATER \
(OPENSSL_VERSION_NUMBER >= 0x30000000 && !CRYPTOGRAPHY_IS_LIBRESSL)
@@ -62,6 +64,7 @@ INCLUDES = """
TYPES = """
static const int CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER;
+static const int CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER;
static const int CRYPTOGRAPHY_OPENSSL_300_OR_GREATER;
static const int CRYPTOGRAPHY_OPENSSL_LESS_THAN_111;
diff --git a/src/_cffi_src/openssl/err.py b/src/_cffi_src/openssl/err.py
index 8cfeaf5ba..54dd1e44c 100644
--- a/src/_cffi_src/openssl/err.py
+++ b/src/_cffi_src/openssl/err.py
@@ -15,6 +15,7 @@ static const int EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM;
static const int PKCS12_R_PKCS12_CIPHERFINAL_ERROR;
static const int PEM_R_UNSUPPORTED_ENCRYPTION;
static const int EVP_R_UNKNOWN_PBE_ALGORITHM;
+static const int EVP_R_XTS_DUPLICATED_KEYS;
static const int ERR_LIB_EVP;
static const int ERR_LIB_PEM;
@@ -51,4 +52,8 @@ CUSTOMIZATIONS = """
#ifndef ERR_LIB_PROV
#define ERR_LIB_PROV 0
#endif
+
+#if !CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER
+static const int EVP_R_XTS_DUPLICATED_KEYS = 0;
+#endif
"""
diff --git a/src/_cffi_src/openssl/provider.py b/src/_cffi_src/openssl/provider.py
index d7d659ea5..d741ad7e4 100644
--- a/src/_cffi_src/openssl/provider.py
+++ b/src/_cffi_src/openssl/provider.py
@@ -17,6 +17,7 @@ typedef ... OSSL_PROVIDER;
typedef ... OSSL_LIB_CTX;
static const long PROV_R_BAD_DECRYPT;
+static const long PROV_R_XTS_DUPLICATED_KEYS;
static const long PROV_R_WRONG_FINAL_BLOCK_LENGTH;
"""
@@ -33,6 +34,7 @@ static const long Cryptography_HAS_PROVIDERS = 0;
typedef void OSSL_PROVIDER;
typedef void OSSL_LIB_CTX;
static const long PROV_R_BAD_DECRYPT = 0;
+static const long PROV_R_XTS_DUPLICATED_KEYS = 0;
static const long PROV_R_WRONG_FINAL_BLOCK_LENGTH = 0;
OSSL_PROVIDER *(*OSSL_PROVIDER_load)(OSSL_LIB_CTX *, const char *) = NULL;
int (*OSSL_PROVIDER_unload)(OSSL_PROVIDER *) = NULL;
diff --git a/src/cryptography/hazmat/backends/openssl/ciphers.py b/src/cryptography/hazmat/backends/openssl/ciphers.py
index eb302e44f..ec272e04d 100644
--- a/src/cryptography/hazmat/backends/openssl/ciphers.py
+++ b/src/cryptography/hazmat/backends/openssl/ciphers.py
@@ -112,7 +112,28 @@ class _CipherContext(object):
iv_nonce,
operation,
)
- self._backend.openssl_assert(res != 0)
+
+ # Check for XTS mode duplicate keys error
+ errors = self._backend._consume_errors()
+ lib = self._backend._lib
+ if res == 0 and (
+ (
+ lib.CRYPTOGRAPHY_OPENSSL_111D_OR_GREATER
+ and errors[0]._lib_reason_match(
+ lib.ERR_LIB_EVP, lib.EVP_R_XTS_DUPLICATED_KEYS
+ )
+ )
+ or (
+ lib.Cryptography_HAS_PROVIDERS
+ and errors[0]._lib_reason_match(
+ lib.ERR_LIB_PROV, lib.PROV_R_XTS_DUPLICATED_KEYS
+ )
+ )
+ ):
+ raise ValueError("In XTS mode duplicated keys are not allowed")
+
+ self._backend.openssl_assert(res != 0, errors=errors)
+
# We purposely disable padding here as it's handled higher up in the
# API.
self._backend._lib.EVP_CIPHER_CTX_set_padding(ctx, 0)