diff options
Diffstat (limited to 'lib/crypto_backend')
-rw-r--r-- | lib/crypto_backend/argon2/meson.build | 28 | ||||
-rw-r--r-- | lib/crypto_backend/argon2_generic.c | 39 | ||||
-rw-r--r-- | lib/crypto_backend/base64.c | 2 | ||||
-rw-r--r-- | lib/crypto_backend/cipher_check.c | 4 | ||||
-rw-r--r-- | lib/crypto_backend/cipher_generic.c | 5 | ||||
-rw-r--r-- | lib/crypto_backend/crc32.c | 4 | ||||
-rw-r--r-- | lib/crypto_backend/crypto_backend.h | 6 | ||||
-rw-r--r-- | lib/crypto_backend/crypto_backend_internal.h | 4 | ||||
-rw-r--r-- | lib/crypto_backend/crypto_cipher_kernel.c | 7 | ||||
-rw-r--r-- | lib/crypto_backend/crypto_gcrypt.c | 150 | ||||
-rw-r--r-- | lib/crypto_backend/crypto_kernel.c | 6 | ||||
-rw-r--r-- | lib/crypto_backend/crypto_nettle.c | 4 | ||||
-rw-r--r-- | lib/crypto_backend/crypto_nss.c | 4 | ||||
-rw-r--r-- | lib/crypto_backend/crypto_openssl.c | 90 | ||||
-rw-r--r-- | lib/crypto_backend/crypto_storage.c | 2 | ||||
-rw-r--r-- | lib/crypto_backend/meson.build | 40 | ||||
-rw-r--r-- | lib/crypto_backend/pbkdf2_generic.c | 4 | ||||
-rw-r--r-- | lib/crypto_backend/pbkdf_check.c | 4 | ||||
-rw-r--r-- | lib/crypto_backend/utf8.c | 2 |
19 files changed, 356 insertions, 49 deletions
diff --git a/lib/crypto_backend/argon2/meson.build b/lib/crypto_backend/argon2/meson.build new file mode 100644 index 0000000..bb68516 --- /dev/null +++ b/lib/crypto_backend/argon2/meson.build @@ -0,0 +1,28 @@ +libargon2_sources = files( + 'blake2/blake2b.c', + 'argon2.c', + 'core.c', + 'encoding.c', + 'thread.c', +) + +if use_internal_sse_argon2 + libargon2_sources += files( + 'opt.c', + ) +else + libargon2_sources += files( + 'ref.c', + ) +endif + +libargon2 = static_library('argon2', + libargon2_sources, + override_options : ['c_std=c89', 'optimization=3'], + build_by_default : false, + include_directories: include_directories( + 'blake2', + ), + dependencies : [ + threads, + ]) diff --git a/lib/crypto_backend/argon2_generic.c b/lib/crypto_backend/argon2_generic.c index 0ce67da..eca575b 100644 --- a/lib/crypto_backend/argon2_generic.c +++ b/lib/crypto_backend/argon2_generic.c @@ -1,8 +1,8 @@ /* * Argon2 PBKDF2 library wrapper * - * Copyright (C) 2016-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2016-2023 Milan Broz + * Copyright (C) 2016-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2016-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,14 +29,12 @@ #define CONST_CAST(x) (x)(uintptr_t) +#if USE_INTERNAL_ARGON2 || HAVE_ARGON2_H int argon2(const char *type, const char *password, size_t password_length, const char *salt, size_t salt_length, char *key, size_t key_length, uint32_t iterations, uint32_t memory, uint32_t parallel) { -#if !USE_INTERNAL_ARGON2 && !HAVE_ARGON2_H - return -EINVAL; -#else argon2_type atype; argon2_context context = { .flags = ARGON2_DEFAULT_FLAGS, @@ -54,6 +52,9 @@ int argon2(const char *type, const char *password, size_t password_length, }; int r; + /* This code must not be run if crypt backend library natively supports Argon2 */ + assert(!(crypt_backend_flags() & CRYPT_BACKEND_ARGON2)); + if (!strcmp(type, "argon2i")) atype = Argon2_i; else if(!strcmp(type, "argon2id")) @@ -75,5 +76,33 @@ int argon2(const char *type, const char *password, size_t password_length, } return r; +} + +#else /* USE_INTERNAL_ARGON2 || HAVE_ARGON2_H */ +#pragma GCC diagnostic ignored "-Wunused-parameter" + +int argon2(const char *type, const char *password, size_t password_length, + const char *salt, size_t salt_length, + char *key, size_t key_length, + uint32_t iterations, uint32_t memory, uint32_t parallel) +{ + return -EINVAL; +} + +#endif + +/* Additional string for crypt backend version */ +const char *crypt_argon2_version(void) +{ + const char *version = ""; + + if (crypt_backend_flags() & CRYPT_BACKEND_ARGON2) + return version; + +#if HAVE_ARGON2_H /* this has priority over internal argon2 */ + version = " [external libargon2]"; +#elif USE_INTERNAL_ARGON2 + version = " [cryptsetup libargon2]"; #endif + return version; } diff --git a/lib/crypto_backend/base64.c b/lib/crypto_backend/base64.c index 42f70cb..92e558a 100644 --- a/lib/crypto_backend/base64.c +++ b/lib/crypto_backend/base64.c @@ -4,7 +4,7 @@ * Copyright (C) 2010 Lennart Poettering * * cryptsetup related changes - * Copyright (C) 2021-2023 Milan Broz + * Copyright (C) 2021-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/lib/crypto_backend/cipher_check.c b/lib/crypto_backend/cipher_check.c index 98ec1a5..25200a4 100644 --- a/lib/crypto_backend/cipher_check.c +++ b/lib/crypto_backend/cipher_check.c @@ -1,8 +1,8 @@ /* * Cipher performance check * - * Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2018-2023 Milan Broz + * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2018-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/lib/crypto_backend/cipher_generic.c b/lib/crypto_backend/cipher_generic.c index b3a4407..746cfcf 100644 --- a/lib/crypto_backend/cipher_generic.c +++ b/lib/crypto_backend/cipher_generic.c @@ -1,8 +1,8 @@ /* * Linux kernel cipher generic utilities * - * Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2018-2023 Milan Broz + * Copyright (C) 2018-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2018-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -51,6 +51,7 @@ static const struct cipher_alg cipher_algs[] = { { "xchacha12,aes", "adiantum", 32, false }, { "xchacha20,aes", "adiantum", 32, false }, { "sm4", NULL, 16, false }, + { "aria", NULL, 16, false }, { NULL, NULL, 0, false } }; diff --git a/lib/crypto_backend/crc32.c b/lib/crypto_backend/crc32.c index 9009b02..7a12a8e 100644 --- a/lib/crypto_backend/crc32.c +++ b/lib/crypto_backend/crc32.c @@ -158,7 +158,7 @@ static const uint32_t crc32c_tab[] = { * whatever they need. */ static uint32_t compute_crc32( - const uint32_t *crc32_tab, + const uint32_t *crc32_table, uint32_t seed, const unsigned char *buf, size_t len) @@ -167,7 +167,7 @@ static uint32_t compute_crc32( const unsigned char *p = buf; while(len-- > 0) - crc = crc32_tab[(crc ^ *p++) & 0xff] ^ (crc >> 8); + crc = crc32_table[(crc ^ *p++) & 0xff] ^ (crc >> 8); return crc; } diff --git a/lib/crypto_backend/crypto_backend.h b/lib/crypto_backend/crypto_backend.h index 88562e9..15ed745 100644 --- a/lib/crypto_backend/crypto_backend.h +++ b/lib/crypto_backend/crypto_backend.h @@ -1,8 +1,8 @@ /* * crypto backend implementation * - * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2023 Milan Broz + * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -43,9 +43,11 @@ void crypt_backend_destroy(void); #define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */ #define CRYPT_BACKEND_PBKDF2_INT (1 << 1) /* Iteration in PBKDF2 is signed int and can overflow */ +#define CRYPT_BACKEND_ARGON2 (1 << 2) /* Backend provides native Argon2 implementation */ uint32_t crypt_backend_flags(void); const char *crypt_backend_version(void); +const char *crypt_argon2_version(void); /* HASH */ int crypt_hash_size(const char *name); diff --git a/lib/crypto_backend/crypto_backend_internal.h b/lib/crypto_backend/crypto_backend_internal.h index 9b1cc69..539f11a 100644 --- a/lib/crypto_backend/crypto_backend_internal.h +++ b/lib/crypto_backend/crypto_backend_internal.h @@ -1,8 +1,8 @@ /* * crypto backend implementation * - * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2023 Milan Broz + * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/lib/crypto_backend/crypto_cipher_kernel.c b/lib/crypto_backend/crypto_cipher_kernel.c index 3460717..77b3643 100644 --- a/lib/crypto_backend/crypto_cipher_kernel.c +++ b/lib/crypto_backend/crypto_cipher_kernel.c @@ -1,8 +1,8 @@ /* * Linux kernel userspace API crypto backend implementation (skcipher) * - * Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2012-2023 Milan Broz + * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -109,6 +109,7 @@ int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name, } /* The in/out should be aligned to page boundary */ +/* coverity[ -taint_source : arg-3 ] */ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx, const char *in, size_t in_length, char *out, size_t out_length, @@ -312,6 +313,8 @@ int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length, } #else /* ENABLE_AF_ALG */ +#pragma GCC diagnostic ignored "-Wunused-parameter" + int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name, const char *mode, const void *key, size_t key_length) { diff --git a/lib/crypto_backend/crypto_gcrypt.c b/lib/crypto_backend/crypto_gcrypt.c index e974aa8..8e3f14e 100644 --- a/lib/crypto_backend/crypto_gcrypt.c +++ b/lib/crypto_backend/crypto_gcrypt.c @@ -1,8 +1,8 @@ /* * GCRYPT crypto backend implementation * - * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2023 Milan Broz + * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,6 +23,7 @@ #include <stdio.h> #include <errno.h> #include <gcrypt.h> +#include <pthread.h> #include "crypto_backend_internal.h" static int crypto_backend_initialised = 0; @@ -126,10 +127,11 @@ int crypt_backend_init(bool fips __attribute__((unused))) crypto_backend_initialised = 1; crypt_hash_test_whirlpool_bug(); - r = snprintf(version, sizeof(version), "gcrypt %s%s%s", + r = snprintf(version, sizeof(version), "gcrypt %s%s%s%s", gcry_check_version(NULL), crypto_backend_secmem ? "" : ", secmem disabled", - crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : ""); + crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : "", + crypt_backend_flags() & CRYPT_BACKEND_ARGON2 ? ", argon2" : ""); if (r < 0 || (size_t)r >= sizeof(version)) return -EINVAL; @@ -151,7 +153,11 @@ const char *crypt_backend_version(void) uint32_t crypt_backend_flags(void) { - return 0; + uint32_t flags = 0; +#if HAVE_DECL_GCRY_KDF_ARGON2 && !USE_INTERNAL_ARGON2 + flags |= CRYPT_BACKEND_ARGON2; +#endif + return flags; } static const char *crypt_hash_compat_name(const char *name, unsigned int *flags) @@ -266,7 +272,6 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length) void crypt_hash_destroy(struct crypt_hash *ctx) { gcry_md_close(ctx->hd); - memset(ctx, 0, sizeof(*ctx)); free(ctx); } @@ -341,7 +346,6 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length) void crypt_hmac_destroy(struct crypt_hmac *ctx) { gcry_md_close(ctx->hd); - memset(ctx, 0, sizeof(*ctx)); free(ctx); } @@ -386,6 +390,130 @@ static int pbkdf2(const char *hash, #endif /* USE_INTERNAL_PBKDF2 */ } +#if HAVE_DECL_GCRY_KDF_ARGON2 && !USE_INTERNAL_ARGON2 +struct gcrypt_thread_job +{ + pthread_t thread; + struct job_thread_param { + gcry_kdf_job_fn_t job; + void *p; + } work; +}; + +struct gcrypt_threads +{ + pthread_attr_t attr; + unsigned int num_threads; + unsigned int max_threads; + struct gcrypt_thread_job *jobs_ctx; +}; + +static void *gcrypt_job_thread(void *p) +{ + struct job_thread_param *param = p; + param->job(param->p); + pthread_exit(NULL); +} + +static int gcrypt_wait_all_jobs(void *ctx) +{ + unsigned int i; + struct gcrypt_threads *threads = ctx; + + for (i = 0; i < threads->num_threads; i++) { + pthread_join(threads->jobs_ctx[i].thread, NULL); + threads->jobs_ctx[i].thread = 0; + } + + threads->num_threads = 0; + return 0; +} + +static int gcrypt_dispatch_job(void *ctx, gcry_kdf_job_fn_t job, void *p) +{ + struct gcrypt_threads *threads = ctx; + + if (threads->num_threads >= threads->max_threads) + return -1; + + threads->jobs_ctx[threads->num_threads].work.job = job; + threads->jobs_ctx[threads->num_threads].work.p = p; + + if (pthread_create(&threads->jobs_ctx[threads->num_threads].thread, &threads->attr, + gcrypt_job_thread, &threads->jobs_ctx[threads->num_threads].work)) + return -1; + + threads->num_threads++; + return 0; +} + +static int gcrypt_argon2(const char *type, + const char *password, size_t password_length, + const char *salt, size_t salt_length, + char *key, size_t key_length, + uint32_t iterations, uint32_t memory, uint32_t parallel) +{ + gcry_kdf_hd_t hd; + int atype, r = -EINVAL; + unsigned long param[4]; + struct gcrypt_threads threads = { + .max_threads = parallel, + .num_threads = 0 + }; + const gcry_kdf_thread_ops_t ops = { + .jobs_context = &threads, + .dispatch_job = gcrypt_dispatch_job, + .wait_all_jobs = gcrypt_wait_all_jobs + }; + + if (!strcmp(type, "argon2i")) + atype = GCRY_KDF_ARGON2I; + else if (!strcmp(type, "argon2id")) + atype = GCRY_KDF_ARGON2ID; + else + return -EINVAL; + + param[0] = key_length; + param[1] = iterations; + param[2] = memory; + param[3] = parallel; + + if (gcry_kdf_open(&hd, GCRY_KDF_ARGON2, atype, param, 4, + password, password_length, salt, salt_length, + NULL, 0, NULL, 0)) { + free(threads.jobs_ctx); + return -EINVAL; + } + + if (parallel == 1) { + /* Do not use threads here */ + if (gcry_kdf_compute(hd, NULL)) + goto out; + } else { + threads.jobs_ctx = calloc(threads.max_threads, + sizeof(struct gcrypt_thread_job)); + if (!threads.jobs_ctx) + goto out; + + if (pthread_attr_init(&threads.attr)) + goto out; + + if (gcry_kdf_compute(hd, &ops)) + goto out; + } + + if (gcry_kdf_final(hd, key_length, key)) + goto out; + r = 0; +out: + gcry_kdf_close(hd); + pthread_attr_destroy(&threads.attr); + free(threads.jobs_ctx); + + return r; +} +#endif + /* PBKDF */ int crypt_pbkdf(const char *kdf, const char *hash, const char *password, size_t password_length, @@ -400,8 +528,13 @@ int crypt_pbkdf(const char *kdf, const char *hash, return pbkdf2(hash, password, password_length, salt, salt_length, key, key_length, iterations); else if (!strncmp(kdf, "argon2", 6)) +#if HAVE_DECL_GCRY_KDF_ARGON2 && !USE_INTERNAL_ARGON2 + return gcrypt_argon2(kdf, password, password_length, salt, salt_length, + key, key_length, iterations, memory, parallel); +#else return argon2(kdf, password, password_length, salt, salt_length, key, key_length, iterations, memory, parallel); +#endif return -EINVAL; } @@ -565,6 +698,9 @@ bool crypt_fips_mode(void) if (fips_checked) return fips_mode; + if (crypt_backend_init(false /* ignored */)) + return false; + fips_mode = gcry_fips_mode_active(); fips_checked = true; diff --git a/lib/crypto_backend/crypto_kernel.c b/lib/crypto_backend/crypto_kernel.c index 8493c0a..be6051a 100644 --- a/lib/crypto_backend/crypto_kernel.c +++ b/lib/crypto_backend/crypto_kernel.c @@ -1,8 +1,8 @@ /* * Linux kernel userspace API crypto backend implementation * - * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2023 Milan Broz + * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -245,7 +245,6 @@ void crypt_hash_destroy(struct crypt_hash *ctx) close(ctx->tfmfd); if (ctx->opfd >= 0) close(ctx->opfd); - memset(ctx, 0, sizeof(*ctx)); free(ctx); } @@ -324,7 +323,6 @@ void crypt_hmac_destroy(struct crypt_hmac *ctx) close(ctx->tfmfd); if (ctx->opfd >= 0) close(ctx->opfd); - memset(ctx, 0, sizeof(*ctx)); free(ctx); } diff --git a/lib/crypto_backend/crypto_nettle.c b/lib/crypto_backend/crypto_nettle.c index 086e4fc..f08db74 100644 --- a/lib/crypto_backend/crypto_nettle.c +++ b/lib/crypto_backend/crypto_nettle.c @@ -1,8 +1,8 @@ /* * Nettle crypto backend implementation * - * Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2011-2023 Milan Broz + * Copyright (C) 2011-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2011-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/lib/crypto_backend/crypto_nss.c b/lib/crypto_backend/crypto_nss.c index c154812..6b390a4 100644 --- a/lib/crypto_backend/crypto_nss.c +++ b/lib/crypto_backend/crypto_nss.c @@ -1,8 +1,8 @@ /* * NSS crypto backend implementation * - * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2023 Milan Broz + * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c index 607ec38..4e85384 100644 --- a/lib/crypto_backend/crypto_openssl.c +++ b/lib/crypto_backend/crypto_openssl.c @@ -1,8 +1,8 @@ /* * OPENSSL crypto backend implementation * - * Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2010-2023 Milan Broz + * Copyright (C) 2010-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2010-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -44,9 +44,20 @@ 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"; + +#define MAX_THREADS 8 +#if !HAVE_DECL_OSSL_GET_MAX_THREADS +static int OSSL_set_max_threads(OSSL_LIB_CTX *ctx __attribute__((unused)), + uint64_t max_threads __attribute__((unused))) { return 0; } +static uint64_t OSSL_get_max_threads(OSSL_LIB_CTX *ctx __attribute__((unused))) { return 0; } +#else +#include <openssl/thread.h> +#endif + #endif #define CONST_CAST(x) (x)(uintptr_t) +#define UNUSED(x) (void)(x) static int crypto_backend_initialised = 0; @@ -162,6 +173,7 @@ static int openssl_backend_init(bool fips) */ #if OPENSSL_VERSION_MAJOR >= 3 int r; + bool ossl_threads = false; /* * In FIPS mode we keep default OpenSSL context & global config @@ -181,16 +193,24 @@ static int openssl_backend_init(bool fips) ossl_legacy = OSSL_PROVIDER_try_load(ossl_ctx, "legacy", 0); } - r = snprintf(backend_version, sizeof(backend_version), "%s %s%s%s", + if (OSSL_set_max_threads(ossl_ctx, MAX_THREADS) == 1 && + OSSL_get_max_threads(ossl_ctx) == MAX_THREADS) + ossl_threads = true; + + r = snprintf(backend_version, sizeof(backend_version), "%s %s%s%s%s%s", OpenSSL_version(OPENSSL_VERSION), ossl_default ? "[default]" : "", ossl_legacy ? "[legacy]" : "", - fips ? "[fips]" : ""); + fips ? "[fips]" : "", + ossl_threads ? "[threads]" : "", + crypt_backend_flags() & CRYPT_BACKEND_ARGON2 ? "[argon2]" : ""); if (r < 0 || (size_t)r >= sizeof(backend_version)) { openssl_backend_exit(); return -EINVAL; } +#else + UNUSED(fips); #endif return 0; } @@ -232,11 +252,14 @@ void crypt_backend_destroy(void) uint32_t crypt_backend_flags(void) { -#if OPENSSL_VERSION_MAJOR >= 3 - return 0; -#else - return CRYPT_BACKEND_PBKDF2_INT; + uint32_t flags = 0; +#if OPENSSL_VERSION_MAJOR < 3 + flags |= CRYPT_BACKEND_PBKDF2_INT; +#endif +#if HAVE_DECL_OSSL_KDF_PARAM_ARGON2_VERSION + flags |= CRYPT_BACKEND_ARGON2; #endif + return flags; } const char *crypt_backend_version(void) @@ -281,6 +304,8 @@ static void hash_id_free(const EVP_MD *hash_id) { #if OPENSSL_VERSION_MAJOR >= 3 EVP_MD_free(CONST_CAST(EVP_MD*)hash_id); +#else + UNUSED(hash_id); #endif } @@ -297,6 +322,8 @@ static void cipher_type_free(const EVP_CIPHER *cipher_type) { #if OPENSSL_VERSION_MAJOR >= 3 EVP_CIPHER_free(CONST_CAST(EVP_CIPHER*)cipher_type); +#else + UNUSED(cipher_type); #endif } @@ -391,7 +418,6 @@ 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); } @@ -527,7 +553,6 @@ void crypt_hmac_destroy(struct crypt_hmac *ctx) hash_id_free(ctx->hash_id); HMAC_CTX_free(ctx->md); #endif - memset(ctx, 0, sizeof(*ctx)); free(ctx); } @@ -593,8 +618,53 @@ static int openssl_argon2(const char *type, const char *password, size_t passwor const char *salt, size_t salt_length, char *key, size_t key_length, uint32_t iterations, uint32_t memory, uint32_t parallel) { +#if HAVE_DECL_OSSL_KDF_PARAM_ARGON2_VERSION + EVP_KDF_CTX *ctx; + EVP_KDF *argon2; + unsigned int threads = parallel; + int r; + OSSL_PARAM params[] = { + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD, + CONST_CAST(void*)password, password_length), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, + CONST_CAST(void*)salt, salt_length), + OSSL_PARAM_uint32(OSSL_KDF_PARAM_ITER, &iterations), + OSSL_PARAM_uint(OSSL_KDF_PARAM_THREADS, &threads), + OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_LANES, ¶llel), + OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_MEMCOST, &memory), + OSSL_PARAM_END + }; + + if (OSSL_get_max_threads(ossl_ctx) == 0) + threads = 1; + + argon2 = EVP_KDF_fetch(ossl_ctx, type, NULL); + if (!argon2) + return -EINVAL; + + ctx = EVP_KDF_CTX_new(argon2); + if (!ctx) { + EVP_KDF_free(argon2); + return -EINVAL;; + } + + if (EVP_KDF_CTX_set_params(ctx, params) != 1) { + EVP_KDF_CTX_free(ctx); + EVP_KDF_free(argon2); + return -EINVAL; + } + + r = EVP_KDF_derive(ctx, (unsigned char*)key, key_length, NULL /*params*/); + + EVP_KDF_CTX_free(ctx); + EVP_KDF_free(argon2); + + /* _derive() returns 0 or negative value on error, 1 on success */ + return r == 1 ? 0 : -EINVAL; +#else return argon2(type, password, password_length, salt, salt_length, key, key_length, iterations, memory, parallel); +#endif } /* PBKDF */ diff --git a/lib/crypto_backend/crypto_storage.c b/lib/crypto_backend/crypto_storage.c index 13479dd..6c8f991 100644 --- a/lib/crypto_backend/crypto_storage.c +++ b/lib/crypto_backend/crypto_storage.c @@ -2,7 +2,7 @@ * Generic wrapper for storage encryption modes and Initial Vectors * (reimplementation of some functions from Linux dm-crypt kernel) * - * Copyright (C) 2014-2023 Milan Broz + * Copyright (C) 2014-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/lib/crypto_backend/meson.build b/lib/crypto_backend/meson.build new file mode 100644 index 0000000..d6c31fd --- /dev/null +++ b/lib/crypto_backend/meson.build @@ -0,0 +1,40 @@ +if use_internal_argon2 + subdir('argon2') +endif + +libcrypto_backend_dependencies = [ + crypto_backend_library, + clock_gettime, +] +libcrypto_backend_link_with = [] + +libcrypto_backend_sources = files( + 'argon2_generic.c', + 'base64.c', + 'cipher_check.c', + 'cipher_generic.c', + 'crc32.c', + 'crypto_cipher_kernel.c', + 'crypto_storage.c', + 'pbkdf_check.c', + 'utf8.c', +) + +crypto_backend = get_option('crypto-backend') +libcrypto_backend_sources += files('crypto_@0@.c'.format(crypto_backend)) + +if use_internal_pbkdf2 + libcrypto_backend_sources += files('pbkdf2_generic.c') +endif + +if use_internal_argon2 and get_option('argon-implementation') == 'internal' + libcrypto_backend_link_with += libargon2 +elif get_option('argon-implementation') == 'libargon2' + libcrypto_backend_dependencies += libargon2_external +endif + +libcrypto_backend = static_library('crypto_backend', + libcrypto_backend_sources, + include_directories: includes_lib, + dependencies: libcrypto_backend_dependencies, + link_with: libcrypto_backend_link_with) diff --git a/lib/crypto_backend/pbkdf2_generic.c b/lib/crypto_backend/pbkdf2_generic.c index 9e87e19..f7fe5bc 100644 --- a/lib/crypto_backend/pbkdf2_generic.c +++ b/lib/crypto_backend/pbkdf2_generic.c @@ -4,8 +4,8 @@ * Copyright (C) 2004 Free Software Foundation * * cryptsetup related changes - * Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2012-2023 Milan Broz + * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2024 Milan Broz * * This file is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/lib/crypto_backend/pbkdf_check.c b/lib/crypto_backend/pbkdf_check.c index 53a2da9..54d6a34 100644 --- a/lib/crypto_backend/pbkdf_check.c +++ b/lib/crypto_backend/pbkdf_check.c @@ -1,7 +1,7 @@ /* * PBKDF performance check - * Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved. - * Copyright (C) 2012-2023 Milan Broz + * Copyright (C) 2012-2024 Red Hat, Inc. All rights reserved. + * Copyright (C) 2012-2024 Milan Broz * Copyright (C) 2016-2020 Ondrej Mosnacek * * This file is free software; you can redistribute it and/or diff --git a/lib/crypto_backend/utf8.c b/lib/crypto_backend/utf8.c index 24e0d8d..c13e953 100644 --- a/lib/crypto_backend/utf8.c +++ b/lib/crypto_backend/utf8.c @@ -4,7 +4,7 @@ * Copyright (C) 2010 Lennart Poettering * * cryptsetup related changes - * Copyright (C) 2021-2023 Vojtech Trefny + * Copyright (C) 2021-2024 Vojtech Trefny * Parts of the original systemd implementation are based on the GLIB utf8 * validation functions. |