diff --git a/.cryptsetup.metadata b/.cryptsetup.metadata new file mode 100644 index 0000000..0274ab2 --- /dev/null +++ b/.cryptsetup.metadata @@ -0,0 +1 @@ +7aae3037a6eba63df19fd89310e325ac9b75aebd SOURCES/cryptsetup-2.4.0.tar.xz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f4e3f7f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/cryptsetup-2.4.0.tar.xz diff --git a/SOURCES/cryptsetup-2.4.1-Adapt-crypto-backend-to-openssl3-lib-context.patch b/SOURCES/cryptsetup-2.4.1-Adapt-crypto-backend-to-openssl3-lib-context.patch new file mode 100644 index 0000000..0178126 --- /dev/null +++ b/SOURCES/cryptsetup-2.4.1-Adapt-crypto-backend-to-openssl3-lib-context.patch @@ -0,0 +1,386 @@ +From 6c9d3863031d5809cee6e157a0e53e7c4ef56940 Mon Sep 17 00:00:00 2001 +From: Ondrej Kozina +Date: Thu, 2 Sep 2021 15:36:15 +0200 +Subject: [PATCH 01/11] Adapt crypto backend to openssl3 lib context. + +Fully leverage openssl custom library context for various +providers (default, legacy). It can be used to properly +free all openssl resources used by libcryptsetup when +libcryptsetup is unloaded (and destructor is triggered). +--- + lib/crypto_backend/crypto_openssl.c | 188 +++++++++++++++++++++++----- + 1 file changed, 155 insertions(+), 33 deletions(-) + +diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c +index 19960a07..a5ec4048 100644 +--- a/lib/crypto_backend/crypto_openssl.c ++++ b/lib/crypto_backend/crypto_openssl.c +@@ -41,8 +41,10 @@ + #include "crypto_backend_internal.h" + #if OPENSSL_VERSION_MAJOR >= 3 + #include ++#include + static OSSL_PROVIDER *ossl_legacy = NULL; + static OSSL_PROVIDER *ossl_default = NULL; ++static OSSL_LIB_CTX *ossl_ctx = NULL; + #endif + + #define CONST_CAST(x) (x)(uintptr_t) +@@ -68,6 +70,7 @@ struct crypt_cipher { + struct { + EVP_CIPHER_CTX *hd_enc; + EVP_CIPHER_CTX *hd_dec; ++ const EVP_CIPHER *cipher_type; + size_t iv_length; + } lib; + } u; +@@ -130,31 +133,41 @@ static void HMAC_CTX_free(HMAC_CTX *md) + free(md); + } + #else +-static void openssl_backend_init(void) ++static int openssl_backend_init(void) + { + /* + * OpenSSL >= 3.0.0 provides some algorithms in legacy provider + */ + #if OPENSSL_VERSION_MAJOR >= 3 +- OPENSSL_init_crypto(OPENSSL_INIT_NO_ATEXIT, NULL); +- ossl_legacy = OSSL_PROVIDER_try_load(NULL, "legacy", 0); +- ossl_default = OSSL_PROVIDER_try_load(NULL, "default", 0); ++ ossl_ctx = OSSL_LIB_CTX_new(); ++ if (!ossl_ctx) ++ return -EINVAL; ++ ++ ossl_default = OSSL_PROVIDER_try_load(ossl_ctx, "default", 0); ++ if (!ossl_default) { ++ OSSL_LIB_CTX_free(ossl_ctx); ++ return -EINVAL; ++ } ++ ++ /* Optional */ ++ ossl_legacy = OSSL_PROVIDER_try_load(ossl_ctx, "legacy", 0); + #endif ++ return 0; + } + + static void openssl_backend_exit(void) + { + #if OPENSSL_VERSION_MAJOR >= 3 +- /* +- * If Destructor was already called, we must not call it again +- */ +- if (OPENSSL_init_crypto(0, NULL) != 0) { ++ if (ossl_legacy) + OSSL_PROVIDER_unload(ossl_legacy); ++ if (ossl_default) + OSSL_PROVIDER_unload(ossl_default); +- OPENSSL_cleanup(); +- } ++ if (ossl_ctx) ++ OSSL_LIB_CTX_free(ossl_ctx); ++ + ossl_legacy = NULL; + ossl_default = NULL; ++ ossl_ctx = NULL; + #endif + } + +@@ -169,7 +182,8 @@ int crypt_backend_init(void) + if (crypto_backend_initialised) + return 0; + +- openssl_backend_init(); ++ if (openssl_backend_init()) ++ return -EINVAL; + + crypto_backend_initialised = 1; + return 0; +@@ -177,7 +191,14 @@ int crypt_backend_init(void) + + void crypt_backend_destroy(void) + { ++ /* ++ * If Destructor was already called, we must not call it again ++ */ ++ if (!crypto_backend_initialised) ++ return; ++ + crypto_backend_initialised = 0; ++ + openssl_backend_exit(); + } + +@@ -215,16 +236,51 @@ static const char *crypt_hash_compat_name(const char *name) + return hash_name; + } + ++static const EVP_MD *hash_id_get(const char *name) ++{ ++#if OPENSSL_VERSION_MAJOR >= 3 ++ return EVP_MD_fetch(ossl_ctx, crypt_hash_compat_name(name), NULL); ++#else ++ return EVP_get_digestbyname(crypt_hash_compat_name(name)); ++#endif ++} ++ ++static void hash_id_free(const EVP_MD *hash_id) ++{ ++#if OPENSSL_VERSION_MAJOR >= 3 ++ EVP_MD_free(CONST_CAST(EVP_MD*)hash_id); ++#endif ++} ++ ++static const EVP_CIPHER *cipher_type_get(const char *name) ++{ ++#if OPENSSL_VERSION_MAJOR >= 3 ++ return EVP_CIPHER_fetch(ossl_ctx, name, NULL); ++#else ++ return EVP_get_cipherbyname(name); ++#endif ++} ++ ++static void cipher_type_free(const EVP_CIPHER *cipher_type) ++{ ++#if OPENSSL_VERSION_MAJOR >= 3 ++ EVP_CIPHER_free(CONST_CAST(EVP_CIPHER*)cipher_type); ++#endif ++} ++ + /* HASH */ + int crypt_hash_size(const char *name) + { ++ int size; + const EVP_MD *hash_id; + +- hash_id = EVP_get_digestbyname(crypt_hash_compat_name(name)); ++ hash_id = hash_id_get(name); + if (!hash_id) + return -EINVAL; + +- return EVP_MD_size(hash_id); ++ size = EVP_MD_size(hash_id); ++ hash_id_free(hash_id); ++ return size; + } + + int crypt_hash_init(struct crypt_hash **ctx, const char *name) +@@ -241,7 +297,7 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name) + return -ENOMEM; + } + +- h->hash_id = EVP_get_digestbyname(crypt_hash_compat_name(name)); ++ h->hash_id = hash_id_get(name); + if (!h->hash_id) { + EVP_MD_CTX_free(h->md); + free(h); +@@ -249,6 +305,7 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name) + } + + if (EVP_DigestInit_ex(h->md, h->hash_id, NULL) != 1) { ++ hash_id_free(h->hash_id); + EVP_MD_CTX_free(h->md); + free(h); + return -EINVAL; +@@ -300,6 +357,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length) + + void crypt_hash_destroy(struct crypt_hash *ctx) + { ++ hash_id_free(ctx->hash_id); + EVP_MD_CTX_free(ctx->md); + memset(ctx, 0, sizeof(*ctx)); + free(ctx); +@@ -326,7 +384,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name, + return -ENOMEM; + } + +- h->hash_id = EVP_get_digestbyname(crypt_hash_compat_name(name)); ++ h->hash_id = hash_id_get(name); + if (!h->hash_id) { + HMAC_CTX_free(h->md); + free(h); +@@ -374,6 +432,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length) + + void crypt_hmac_destroy(struct crypt_hmac *ctx) + { ++ hash_id_free(ctx->hash_id); + HMAC_CTX_free(ctx->md); + memset(ctx, 0, sizeof(*ctx)); + free(ctx); +@@ -389,6 +448,67 @@ int crypt_backend_rng(char *buffer, size_t length, + return 0; + } + ++static int pbkdf2(const char *password, size_t password_length, ++ const char *salt, size_t salt_length, ++ uint32_t iterations, const char *hash, size_t key_length, ++ unsigned char *key) ++{ ++#if OPENSSL_VERSION_MAJOR >= 3 ++ EVP_KDF_CTX *ctx; ++ EVP_KDF *pbkdf2; ++ int r; ++ OSSL_PARAM params[] = { ++ { .key = "pass", ++ .data_type = OSSL_PARAM_OCTET_STRING, ++ .data = CONST_CAST(void*)password, ++ .data_size = password_length ++ }, ++ { .key = "salt", ++ .data_type = OSSL_PARAM_OCTET_STRING, ++ .data = CONST_CAST(void*)salt, ++ .data_size = salt_length ++ }, ++ { .key = "iter", ++ .data_type = OSSL_PARAM_UNSIGNED_INTEGER, ++ .data = &iterations, ++ .data_size = sizeof(iterations) ++ }, ++ { .key = "digest", ++ .data_type = OSSL_PARAM_UTF8_STRING, ++ .data = CONST_CAST(void*)hash, ++ .data_size = strlen(hash) ++ }, ++ { NULL, 0, NULL, 0, 0 } ++ }; ++ ++ pbkdf2 = EVP_KDF_fetch(ossl_ctx, "pbkdf2", NULL); ++ if (!pbkdf2) ++ return 0; ++ ++ ctx = EVP_KDF_CTX_new(pbkdf2); ++ if (!ctx) { ++ EVP_KDF_free(pbkdf2); ++ return 0; ++ } ++ ++ r = EVP_KDF_derive(ctx, key, key_length, params); ++ ++ EVP_KDF_CTX_free(ctx); ++ EVP_KDF_free(pbkdf2); ++ ++ /* _derive() returns 0 or negative value on error, 1 on success */ ++ return r <= 0 ? 0 : 1; ++#else ++ const EVP_MD *hash_id = EVP_get_digestbyname(crypt_hash_compat_name(hash)); ++ if (!hash_id) ++ return 0; ++ ++ return PKCS5_PBKDF2_HMAC(password, (int)password_length, (const unsigned char *)salt, ++ (int)salt_length, iterations, hash_id, ++ (int)key_length, key); ++#endif ++} ++ + /* PBKDF */ + int crypt_pbkdf(const char *kdf, const char *hash, + const char *password, size_t password_length, +@@ -397,19 +517,12 @@ int crypt_pbkdf(const char *kdf, const char *hash, + uint32_t iterations, uint32_t memory, uint32_t parallel) + + { +- const EVP_MD *hash_id; +- + if (!kdf) + return -EINVAL; + + if (!strcmp(kdf, "pbkdf2")) { +- hash_id = EVP_get_digestbyname(crypt_hash_compat_name(hash)); +- if (!hash_id) +- return -EINVAL; +- +- if (!PKCS5_PBKDF2_HMAC(password, (int)password_length, +- (const unsigned char *)salt, (int)salt_length, +- (int)iterations, hash_id, (int)key_length, (unsigned char *)key)) ++ if (!pbkdf2(password, password_length, ++ salt, salt_length, iterations, hash, key_length, (unsigned char *)key)) + return -EINVAL; + return 0; + } else if (!strncmp(kdf, "argon2", 6)) { +@@ -421,16 +534,19 @@ int crypt_pbkdf(const char *kdf, const char *hash, + } + + /* Block ciphers */ +-static void _cipher_destroy(EVP_CIPHER_CTX **hd_enc, EVP_CIPHER_CTX **hd_dec) ++static void _cipher_destroy(EVP_CIPHER_CTX **hd_enc, EVP_CIPHER_CTX **hd_dec, const EVP_CIPHER **cipher_type) + { + EVP_CIPHER_CTX_free(*hd_enc); + *hd_enc = NULL; + + EVP_CIPHER_CTX_free(*hd_dec); + *hd_dec = NULL; ++ ++ cipher_type_free(*cipher_type); ++ *cipher_type = NULL; + } + +-static int _cipher_init(EVP_CIPHER_CTX **hd_enc, EVP_CIPHER_CTX **hd_dec, const char *name, ++static int _cipher_init(EVP_CIPHER_CTX **hd_enc, EVP_CIPHER_CTX **hd_dec, const EVP_CIPHER **cipher_type, const char *name, + const char *mode, const void *key, size_t key_length, size_t *iv_length) + { + char cipher_name[256]; +@@ -445,32 +561,38 @@ static int _cipher_init(EVP_CIPHER_CTX **hd_enc, EVP_CIPHER_CTX **hd_dec, const + if (r < 0 || (size_t)r >= sizeof(cipher_name)) + return -EINVAL; + +- type = EVP_get_cipherbyname(cipher_name); ++ type = cipher_type_get(cipher_name); + if (!type) + return -ENOENT; + +- if (EVP_CIPHER_key_length(type) != (int)key_length) ++ if (EVP_CIPHER_key_length(type) != (int)key_length) { ++ cipher_type_free(type); + return -EINVAL; ++ } + + *hd_enc = EVP_CIPHER_CTX_new(); + *hd_dec = EVP_CIPHER_CTX_new(); + *iv_length = EVP_CIPHER_iv_length(type); + +- if (!*hd_enc || !*hd_dec) ++ if (!*hd_enc || !*hd_dec) { ++ cipher_type_free(type); + return -EINVAL; ++ } + + if (EVP_EncryptInit_ex(*hd_enc, type, NULL, key, NULL) != 1 || + EVP_DecryptInit_ex(*hd_dec, type, NULL, key, NULL) != 1) { +- _cipher_destroy(hd_enc, hd_dec); ++ _cipher_destroy(hd_enc, hd_dec, &type); + return -EINVAL; + } + + if (EVP_CIPHER_CTX_set_padding(*hd_enc, 0) != 1 || + EVP_CIPHER_CTX_set_padding(*hd_dec, 0) != 1) { +- _cipher_destroy(hd_enc, hd_dec); ++ _cipher_destroy(hd_enc, hd_dec, &type); + return -EINVAL; + } + ++ *cipher_type = type; ++ + return 0; + } + +@@ -484,7 +606,7 @@ int crypt_cipher_init(struct crypt_cipher **ctx, const char *name, + if (!h) + return -ENOMEM; + +- if (!_cipher_init(&h->u.lib.hd_enc, &h->u.lib.hd_dec, name, mode, key, ++ if (!_cipher_init(&h->u.lib.hd_enc, &h->u.lib.hd_dec, &h->u.lib.cipher_type, name, mode, key, + key_length, &h->u.lib.iv_length)) { + h->use_kernel = false; + *ctx = h; +@@ -507,7 +629,7 @@ void crypt_cipher_destroy(struct crypt_cipher *ctx) + if (ctx->use_kernel) + crypt_cipher_destroy_kernel(&ctx->u.kernel); + else +- _cipher_destroy(&ctx->u.lib.hd_enc, &ctx->u.lib.hd_dec); ++ _cipher_destroy(&ctx->u.lib.hd_enc, &ctx->u.lib.hd_dec, &ctx->u.lib.cipher_type); + free(ctx); + } + +-- +2.27.0 + diff --git a/SOURCES/cryptsetup-2.4.1-Cache-FIPS-mode-check.patch b/SOURCES/cryptsetup-2.4.1-Cache-FIPS-mode-check.patch new file mode 100644 index 0000000..d64cbee --- /dev/null +++ b/SOURCES/cryptsetup-2.4.1-Cache-FIPS-mode-check.patch @@ -0,0 +1,42 @@ +From 75e45462f097a9a75747b3f44d7672f2547e63e9 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Tue, 14 Sep 2021 09:56:05 +0200 +Subject: [PATCH 04/11] Cache FIPS mode check. + +We do not support switch while the crypto backend is already initialized, +so it does not make sense to check repeatedly for the FIPS mode status. +--- + lib/utils_fips.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/lib/utils_fips.c b/lib/utils_fips.c +index 0c2b6434..640ff0e3 100644 +--- a/lib/utils_fips.c ++++ b/lib/utils_fips.c +@@ -26,6 +26,9 @@ + #if !ENABLE_FIPS + bool crypt_fips_mode(void) { return false; } + #else ++static bool fips_checked = false; ++static bool fips_mode = false; ++ + static bool kernel_fips_mode(void) + { + int fd; +@@ -41,6 +44,12 @@ static bool kernel_fips_mode(void) + + bool crypt_fips_mode(void) + { +- return kernel_fips_mode() && !access("/etc/system-fips", F_OK); ++ if (fips_checked) ++ return fips_mode; ++ ++ fips_mode = kernel_fips_mode() && !access("/etc/system-fips", F_OK); ++ fips_checked = true; ++ ++ return fips_mode; + } + #endif /* ENABLE_FIPS */ +-- +2.27.0 + diff --git a/SOURCES/cryptsetup-2.4.1-Do-not-load-own-OpenSSL-backend-context-in-FIPS-mode.patch b/SOURCES/cryptsetup-2.4.1-Do-not-load-own-OpenSSL-backend-context-in-FIPS-mode.patch new file mode 100644 index 0000000..928e65e --- /dev/null +++ b/SOURCES/cryptsetup-2.4.1-Do-not-load-own-OpenSSL-backend-context-in-FIPS-mode.patch @@ -0,0 +1,236 @@ +From f8eb7b225affe8b6b9f02ab6a90fd2e73181a526 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Mon, 13 Sep 2021 19:45:05 +0200 +Subject: [PATCH 03/11] Do not load own OpenSSL backend context in FIPS mode. + +In the FIPS mode keep configuration up to the system wide config. +--- + lib/crypto_backend/crypto_backend.h | 2 +- + lib/crypto_backend/crypto_gcrypt.c | 2 +- + lib/crypto_backend/crypto_kernel.c | 2 +- + lib/crypto_backend/crypto_nettle.c | 2 +- + lib/crypto_backend/crypto_nss.c | 2 +- + lib/crypto_backend/crypto_openssl.c | 39 +++++++++++++++++------------ + lib/setup.c | 2 +- + lib/utils_fips.c | 8 +++--- + lib/utils_fips.h | 4 ++- + tests/crypto-vectors.c | 2 +- + 10 files changed, 37 insertions(+), 28 deletions(-) + +diff --git a/lib/crypto_backend/crypto_backend.h b/lib/crypto_backend/crypto_backend.h +index 5278c345..88cc2d59 100644 +--- a/lib/crypto_backend/crypto_backend.h ++++ b/lib/crypto_backend/crypto_backend.h +@@ -31,7 +31,7 @@ struct crypt_hmac; + struct crypt_cipher; + struct crypt_storage; + +-int crypt_backend_init(void); ++int crypt_backend_init(bool fips); + void crypt_backend_destroy(void); + + #define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */ +diff --git a/lib/crypto_backend/crypto_gcrypt.c b/lib/crypto_backend/crypto_gcrypt.c +index 2845382e..67f26067 100644 +--- a/lib/crypto_backend/crypto_gcrypt.c ++++ b/lib/crypto_backend/crypto_gcrypt.c +@@ -94,7 +94,7 @@ static void crypt_hash_test_whirlpool_bug(void) + crypto_backend_whirlpool_bug = 1; + } + +-int crypt_backend_init(void) ++int crypt_backend_init(bool fips __attribute__((unused))) + { + int r; + +diff --git a/lib/crypto_backend/crypto_kernel.c b/lib/crypto_backend/crypto_kernel.c +index 2e3d65b2..ce84cfac 100644 +--- a/lib/crypto_backend/crypto_kernel.c ++++ b/lib/crypto_backend/crypto_kernel.c +@@ -117,7 +117,7 @@ static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *op + return 0; + } + +-int crypt_backend_init(void) ++int crypt_backend_init(bool fips __attribute__((unused))) + { + struct utsname uts; + struct sockaddr_alg sa = { +diff --git a/lib/crypto_backend/crypto_nettle.c b/lib/crypto_backend/crypto_nettle.c +index 0860a52d..c9b9f5f8 100644 +--- a/lib/crypto_backend/crypto_nettle.c ++++ b/lib/crypto_backend/crypto_nettle.c +@@ -213,7 +213,7 @@ static struct hash_alg *_get_alg(const char *name) + return NULL; + } + +-int crypt_backend_init(void) ++int crypt_backend_init(bool fips __attribute__((unused))) + { + return 0; + } +diff --git a/lib/crypto_backend/crypto_nss.c b/lib/crypto_backend/crypto_nss.c +index ebe9de0e..a84d3d65 100644 +--- a/lib/crypto_backend/crypto_nss.c ++++ b/lib/crypto_backend/crypto_nss.c +@@ -75,7 +75,7 @@ static struct hash_alg *_get_alg(const char *name) + return NULL; + } + +-int crypt_backend_init(void) ++int crypt_backend_init(bool fips __attribute__((unused))) + { + int r; + +diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c +index 92eeb33c..2a490ce5 100644 +--- a/lib/crypto_backend/crypto_openssl.c ++++ b/lib/crypto_backend/crypto_openssl.c +@@ -88,7 +88,7 @@ struct hash_alg { + #if OPENSSL_VERSION_NUMBER < 0x10100000L || \ + (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) + +-static void openssl_backend_init(void) ++static void openssl_backend_init(bool fips __attribute__((unused))) + { + OpenSSL_add_all_algorithms(); + } +@@ -150,7 +150,7 @@ static void openssl_backend_exit(void) + #endif + } + +-static int openssl_backend_init(void) ++static int openssl_backend_init(bool fips) + { + /* + * OpenSSL >= 3.0.0 provides some algorithms in legacy provider +@@ -158,23 +158,30 @@ static int openssl_backend_init(void) + #if OPENSSL_VERSION_MAJOR >= 3 + int r; + +- ossl_ctx = OSSL_LIB_CTX_new(); +- if (!ossl_ctx) +- return -EINVAL; ++ /* ++ * In FIPS mode we keep default OpenSSL context & global config ++ */ ++ if (!fips) { ++ ossl_ctx = OSSL_LIB_CTX_new(); ++ if (!ossl_ctx) ++ return -EINVAL; + +- ossl_default = OSSL_PROVIDER_try_load(ossl_ctx, "default", 0); +- if (!ossl_default) { +- OSSL_LIB_CTX_free(ossl_ctx); +- return -EINVAL; +- } ++ ossl_default = OSSL_PROVIDER_try_load(ossl_ctx, "default", 0); ++ if (!ossl_default) { ++ OSSL_LIB_CTX_free(ossl_ctx); ++ return -EINVAL; ++ } + +- /* Optional */ +- ossl_legacy = OSSL_PROVIDER_try_load(ossl_ctx, "legacy", 0); ++ /* Optional */ ++ ossl_legacy = OSSL_PROVIDER_try_load(ossl_ctx, "legacy", 0); ++ } + +- r = snprintf(backend_version, sizeof(backend_version), "%s %s%s", ++ r = snprintf(backend_version, sizeof(backend_version), "%s %s%s%s", + OpenSSL_version(OPENSSL_VERSION), + ossl_default ? "[default]" : "", +- ossl_legacy ? "[legacy]" : ""); ++ ossl_legacy ? "[legacy]" : "", ++ fips ? "[fips]" : ""); ++ + if (r < 0 || (size_t)r >= sizeof(backend_version)) { + openssl_backend_exit(); + return -EINVAL; +@@ -193,12 +200,12 @@ static const char *openssl_backend_version(void) + } + #endif + +-int crypt_backend_init(void) ++int crypt_backend_init(bool fips) + { + if (crypto_backend_initialised) + return 0; + +- if (openssl_backend_init()) ++ if (openssl_backend_init(fips)) + return -EINVAL; + + crypto_backend_initialised = 1; +diff --git a/lib/setup.c b/lib/setup.c +index dc5459f5..a5dfd843 100644 +--- a/lib/setup.c ++++ b/lib/setup.c +@@ -227,7 +227,7 @@ int init_crypto(struct crypt_device *ctx) + return r; + } + +- r = crypt_backend_init(); ++ r = crypt_backend_init(crypt_fips_mode()); + if (r < 0) + log_err(ctx, _("Cannot initialize crypto backend.")); + +diff --git a/lib/utils_fips.c b/lib/utils_fips.c +index 4fa22fb9..0c2b6434 100644 +--- a/lib/utils_fips.c ++++ b/lib/utils_fips.c +@@ -24,9 +24,9 @@ + #include "utils_fips.h" + + #if !ENABLE_FIPS +-int crypt_fips_mode(void) { return 0; } ++bool crypt_fips_mode(void) { return false; } + #else +-static int kernel_fips_mode(void) ++static bool kernel_fips_mode(void) + { + int fd; + char buf[1] = ""; +@@ -36,10 +36,10 @@ static int kernel_fips_mode(void) + close(fd); + } + +- return (buf[0] == '1') ? 1 : 0; ++ return (buf[0] == '1'); + } + +-int crypt_fips_mode(void) ++bool crypt_fips_mode(void) + { + return kernel_fips_mode() && !access("/etc/system-fips", F_OK); + } +diff --git a/lib/utils_fips.h b/lib/utils_fips.h +index 51b110b5..13cfc9fb 100644 +--- a/lib/utils_fips.h ++++ b/lib/utils_fips.h +@@ -21,6 +21,8 @@ + #ifndef _UTILS_FIPS_H + #define _UTILS_FIPS_H + +-int crypt_fips_mode(void); ++#include ++ ++bool crypt_fips_mode(void); + + #endif /* _UTILS_FIPS_H */ +diff --git a/tests/crypto-vectors.c b/tests/crypto-vectors.c +index 025585de..6484e97a 100644 +--- a/tests/crypto-vectors.c ++++ b/tests/crypto-vectors.c +@@ -1301,7 +1301,7 @@ int main(__attribute__ ((unused)) int argc, __attribute__ ((unused))char *argv[] + exit(77); + } + +- if (crypt_backend_init()) ++ if (crypt_backend_init(fips_mode())) + exit_test("Crypto backend init error.", EXIT_FAILURE); + + printf("Test vectors using %s crypto backend.\n", crypt_backend_version()); +-- +2.27.0 + diff --git a/SOURCES/cryptsetup-2.4.1-OpenSSL-backend-make-legacy-for-OpenSSL3-optional-an.patch b/SOURCES/cryptsetup-2.4.1-OpenSSL-backend-make-legacy-for-OpenSSL3-optional-an.patch new file mode 100644 index 0000000..060b1ef --- /dev/null +++ b/SOURCES/cryptsetup-2.4.1-OpenSSL-backend-make-legacy-for-OpenSSL3-optional-an.patch @@ -0,0 +1,100 @@ +From 29ea07ef66be59c8ab62058b2ce3e92765e2be10 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Mon, 13 Sep 2021 14:48:15 +0200 +Subject: [PATCH 02/11] OpenSSL backend: make legacy for OpenSSL3 optional and + report loaded providers + +--- + lib/crypto_backend/crypto_openssl.c | 48 +++++++++++++++++++---------- + 1 file changed, 32 insertions(+), 16 deletions(-) + +diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c +index a5ec4048..92eeb33c 100644 +--- a/lib/crypto_backend/crypto_openssl.c ++++ b/lib/crypto_backend/crypto_openssl.c +@@ -45,6 +45,7 @@ + static OSSL_PROVIDER *ossl_legacy = NULL; + static OSSL_PROVIDER *ossl_default = NULL; + static OSSL_LIB_CTX *ossl_ctx = NULL; ++static char backend_version[256] = "OpenSSL"; + #endif + + #define CONST_CAST(x) (x)(uintptr_t) +@@ -133,12 +134,30 @@ static void HMAC_CTX_free(HMAC_CTX *md) + free(md); + } + #else ++static void openssl_backend_exit(void) ++{ ++#if OPENSSL_VERSION_MAJOR >= 3 ++ if (ossl_legacy) ++ OSSL_PROVIDER_unload(ossl_legacy); ++ if (ossl_default) ++ OSSL_PROVIDER_unload(ossl_default); ++ if (ossl_ctx) ++ OSSL_LIB_CTX_free(ossl_ctx); ++ ++ ossl_legacy = NULL; ++ ossl_default = NULL; ++ ossl_ctx = NULL; ++#endif ++} ++ + static int openssl_backend_init(void) + { + /* + * OpenSSL >= 3.0.0 provides some algorithms in legacy provider + */ + #if OPENSSL_VERSION_MAJOR >= 3 ++ int r; ++ + ossl_ctx = OSSL_LIB_CTX_new(); + if (!ossl_ctx) + return -EINVAL; +@@ -151,30 +170,27 @@ static int openssl_backend_init(void) + + /* Optional */ + ossl_legacy = OSSL_PROVIDER_try_load(ossl_ctx, "legacy", 0); ++ ++ r = snprintf(backend_version, sizeof(backend_version), "%s %s%s", ++ OpenSSL_version(OPENSSL_VERSION), ++ ossl_default ? "[default]" : "", ++ ossl_legacy ? "[legacy]" : ""); ++ if (r < 0 || (size_t)r >= sizeof(backend_version)) { ++ openssl_backend_exit(); ++ return -EINVAL; ++ } + #endif + return 0; + } + +-static void openssl_backend_exit(void) ++static const char *openssl_backend_version(void) + { + #if OPENSSL_VERSION_MAJOR >= 3 +- if (ossl_legacy) +- OSSL_PROVIDER_unload(ossl_legacy); +- if (ossl_default) +- OSSL_PROVIDER_unload(ossl_default); +- if (ossl_ctx) +- OSSL_LIB_CTX_free(ossl_ctx); +- +- ossl_legacy = NULL; +- ossl_default = NULL; +- ossl_ctx = NULL; ++ return backend_version; ++#else ++ return OpenSSL_version(OPENSSL_VERSION); + #endif + } +- +-static const char *openssl_backend_version(void) +-{ +- return OpenSSL_version(OPENSSL_VERSION); +-} + #endif + + int crypt_backend_init(void) +-- +2.27.0 + diff --git a/SOURCES/cryptsetup-add-system-library-paths.patch b/SOURCES/cryptsetup-add-system-library-paths.patch new file mode 100644 index 0000000..0a5d753 --- /dev/null +++ b/SOURCES/cryptsetup-add-system-library-paths.patch @@ -0,0 +1,22 @@ +diff -rupN cryptsetup-2.2.0.old/configure cryptsetup-2.2.0/configure +--- cryptsetup-2.2.0.old/configure 2019-08-14 20:45:07.000000000 +0200 ++++ cryptsetup-2.2.0/configure 2019-08-15 09:11:14.775184005 +0200 +@@ -12294,6 +12294,9 @@ fi + # before this can be enabled. + hardcode_into_libs=yes + ++ # Add ABI-specific directories to the system library path. ++ sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" ++ + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command +@@ -12302,7 +12305,7 @@ fi + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` +- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on diff --git a/SPECS/cryptsetup.spec b/SPECS/cryptsetup.spec new file mode 100644 index 0000000..3d879b5 --- /dev/null +++ b/SPECS/cryptsetup.spec @@ -0,0 +1,158 @@ +Summary: Utility for setting up encrypted disks +Name: cryptsetup +Version: 2.4.0 +Release: 2%{?dist} +License: GPLv2+ and LGPLv2+ +URL: https://gitlab.com/cryptsetup/cryptsetup +BuildRequires: openssl-devel, popt-devel, device-mapper-devel +BuildRequires: libuuid-devel, gcc, json-c-devel +BuildRequires: libpwquality-devel, libblkid-devel +BuildRequires: make +Requires: cryptsetup-libs = %{version}-%{release} +Requires: libpwquality >= 1.2.0 + +%global upstream_version %{version} +Source0: https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/cryptsetup-%{upstream_version}.tar.xz +# Following patch has to applied last +Patch0000: %{name}-2.4.1-Adapt-crypto-backend-to-openssl3-lib-context.patch +Patch0001: %{name}-2.4.1-OpenSSL-backend-make-legacy-for-OpenSSL3-optional-an.patch +Patch0002: %{name}-2.4.1-Do-not-load-own-OpenSSL-backend-context-in-FIPS-mode.patch +Patch0003: %{name}-2.4.1-Cache-FIPS-mode-check.patch +Patch9999: %{name}-add-system-library-paths.patch + +%description +The cryptsetup package contains a utility for setting up +disk encryption using dm-crypt kernel module. + +%package devel +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: pkgconfig +Summary: Headers and libraries for using encrypted file systems + +%description devel +The cryptsetup-devel package contains libraries and header files +used for writing code that makes use of disk encryption. + +%package libs +Summary: Cryptsetup shared library + +%description libs +This package contains the cryptsetup shared library, libcryptsetup. + +%package -n veritysetup +Summary: A utility for setting up dm-verity volumes +Requires: cryptsetup-libs = %{version}-%{release} + +%description -n veritysetup +The veritysetup package contains a utility for setting up +disk verification using dm-verity kernel module. + +%package -n integritysetup +Summary: A utility for setting up dm-integrity volumes +Requires: cryptsetup-libs = %{version}-%{release} + +%description -n integritysetup +The integritysetup package contains a utility for setting up +disk integrity protection using dm-integrity kernel module. + +%package reencrypt +Summary: A utility for offline reencryption of LUKS encrypted disks +Requires: cryptsetup-libs = %{version}-%{release} + +%description reencrypt +This package contains cryptsetup-reencrypt utility which +can be used for offline reencryption of disk in situ. + +%prep +%autosetup -n cryptsetup-%{upstream_version} -p 1 +chmod -x misc/dracut_90reencrypt/* + +%build +%configure --enable-fips --enable-pwquality --enable-internal-sse-argon2 --disable-ssh-token +%make_build + +%install +%make_install +rm -rf %{buildroot}%{_libdir}/*.la + +%find_lang cryptsetup + +%ldconfig_scriptlets -n cryptsetup-libs + +%files +%license COPYING +%doc AUTHORS FAQ docs/*ReleaseNotes +%{_mandir}/man8/cryptsetup.8.gz +%{_sbindir}/cryptsetup + +%files -n veritysetup +%license COPYING +%{_mandir}/man8/veritysetup.8.gz +%{_sbindir}/veritysetup + +%files -n integritysetup +%license COPYING +%{_mandir}/man8/integritysetup.8.gz +%{_sbindir}/integritysetup + +%files reencrypt +%license COPYING +%doc misc/dracut_90reencrypt +%{_mandir}/man8/cryptsetup-reencrypt.8.gz +%{_sbindir}/cryptsetup-reencrypt + +%files devel +%doc docs/examples/* +%{_includedir}/libcryptsetup.h +%{_libdir}/libcryptsetup.so +%{_libdir}/pkgconfig/libcryptsetup.pc + +%files libs -f cryptsetup.lang +%license COPYING COPYING.LGPL +%{_libdir}/libcryptsetup.so.* +%dir %{_libdir}/%{name}/ +%{_tmpfilesdir}/cryptsetup.conf +%ghost %attr(700, -, -) %dir /run/cryptsetup + +%changelog +* Thu Sep 09 2021 Ondrej Kozina - 2.4.0-2 +- Fix openssl crypto backend teardown in library destructor + Resolves: #1998921 + +* Thu Aug 19 2021 Ondrej Kozina - 2.4.0-1 +- Update to cryptsetup 2.4.0. + Resolves: #1869553 #1972722 #1974271 #1975799 + +* Mon Aug 09 2021 Mohan Boddu - 2.3.6-3 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Thu Jun 17 2021 Mohan Boddu - 2.3.6-2 +- Specbump for openssl 3.0 + Related: rhbz#1971065 + +* Wed Jun 16 2021 Ondrej Kozina - 2.3.6-1 +- Update to cryptsetup 2.3.6. +- Resolves: #1961291 #1970932 + +* Tue Jun 15 2021 Mohan Boddu - 2.3.5-5 +- Rebuilt for RHEL 9 BETA for openssl 3.0 + +Related: rhbz#1971065 + +* Tue Apr 27 2021 Ondrej Kozina - 2.3.5-4 +- Drop dependency on libargon2 +- Resolves: #1936959 + +* Thu Apr 15 2021 Mohan Boddu - 2.3.5-3 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Thu Mar 11 2021 Milan Broz - 2.3.5-1 +- Update to cryptsetup 2.3.5. + +* Tue Jan 26 2021 Fedora Release Engineering - 2.3.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Thu Sep 03 2020 Milan Broz - 2.3.4-1 +- Update to cryptsetup 2.3.4. +- Fix for CVE-2020-14382 (#1874712)