Make volume_key FIPS compliant
Resolves: RHEL-74047
This commit is contained in:
parent
c442e00a21
commit
929a4182cb
146
volume_key-0.3.12-FIPS.patch
Normal file
146
volume_key-0.3.12-FIPS.patch
Normal file
@ -0,0 +1,146 @@
|
||||
diff --git a/lib/crypto.c b/lib/crypto.c
|
||||
index 4b9006a..5b562d1 100644
|
||||
--- a/lib/crypto.c
|
||||
+++ b/lib/crypto.c
|
||||
@@ -69,6 +69,115 @@ error_from_pr (GError **error)
|
||||
g_free (err);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * FIPS compliant implementation of PK11_ImportSymKey().
|
||||
+ * Source: https://github.com/ceph/ceph/pull/27104/files
|
||||
+ */
|
||||
+static PK11SymKey *
|
||||
+import_sym_key (PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11Origin origin,
|
||||
+ CK_ATTRIBUTE_TYPE operation, SECItem *key, void *wincx)
|
||||
+{
|
||||
+ CK_MECHANISM_TYPE wrap_mechanism = 0UL;
|
||||
+ PK11SymKey *wrapping_key = NULL, *sym_key = NULL;
|
||||
+ SECItem tmp_sec_item, wrapped_key_item, *raw_key_aligned = NULL;
|
||||
+ PK11Context *wrap_key_crypt_context = NULL;
|
||||
+ int block_size = 0;
|
||||
+ size_t wrapped_key_size = 0;
|
||||
+ unsigned char *wrapped_key = NULL;
|
||||
+ int out_len = 0;
|
||||
+ SECStatus ret = 0;
|
||||
+
|
||||
+ /* Fall back to PK11_ImportSymKey() if FIPS mode is disabled. */
|
||||
+ if (PK11_IsFIPS () == PR_FALSE)
|
||||
+ return PK11_ImportSymKey (slot, type, origin, operation, key, wincx);
|
||||
+
|
||||
+ /* Get the best mechanism for the wrapping operation. */
|
||||
+ wrap_mechanism = PK11_GetBestWrapMechanism (slot);
|
||||
+
|
||||
+ /* Based on that mechanism, generate a symetric key <wrapping_key>. */
|
||||
+ wrapping_key = PK11_KeyGen (slot, wrap_mechanism, NULL,
|
||||
+ PK11_GetBestKeyLength (slot, wrap_mechanism),
|
||||
+ NULL);
|
||||
+ if (wrapping_key == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* Create the context for the wrapping operation. The context contains:
|
||||
+ * - <wrapping_key>
|
||||
+ * - operation to perform (CKA_ENCRYPT)
|
||||
+ */
|
||||
+ memset (&tmp_sec_item, 0, sizeof (tmp_sec_item));
|
||||
+ wrap_key_crypt_context = PK11_CreateContextBySymKey (wrap_mechanism,
|
||||
+ CKA_ENCRYPT,
|
||||
+ wrapping_key,
|
||||
+ &tmp_sec_item);
|
||||
+ if (wrap_key_crypt_context == NULL) {
|
||||
+ PK11_FreeSymKey (wrapping_key);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* Align <key> to the block size specified by the wrapping mechanism. */
|
||||
+ block_size = PK11_GetBlockSize (wrap_mechanism, NULL);
|
||||
+ raw_key_aligned = PK11_BlockData (key, block_size);
|
||||
+ if (raw_key_aligned == NULL) {
|
||||
+ PK11_DestroyContext (wrap_key_crypt_context, PR_TRUE);
|
||||
+ PK11_FreeSymKey (wrapping_key);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* Prepare for <key> wrap. First, allocate enough space for
|
||||
+ * the wrapped <key>. Add the padding of the size of one block behind the
|
||||
+ * aligned <key> to make sure the wrapping operation will not hit the wall.
|
||||
+ */
|
||||
+ wrapped_key_size = raw_key_aligned->len + block_size;
|
||||
+ wrapped_key = g_try_malloc0 (wrapped_key_size);
|
||||
+ if (wrapped_key == NULL) {
|
||||
+ SECITEM_FreeItem (raw_key_aligned, PR_TRUE);
|
||||
+ PK11_DestroyContext (wrap_key_crypt_context, PR_TRUE);
|
||||
+ PK11_FreeSymKey (wrapping_key);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* Do the wrap operation. <wrapped_key> is now a pair (<wrapping_key>, <key>)
|
||||
+ * expressing that raw key <key> is now encrypted with the <wrapping_key>.
|
||||
+ */
|
||||
+ ret = PK11_CipherOp (wrap_key_crypt_context, wrapped_key, &out_len,
|
||||
+ wrapped_key_size, raw_key_aligned->data,
|
||||
+ raw_key_aligned->len);
|
||||
+ if (ret != SECSuccess) {
|
||||
+ g_free (wrapped_key);
|
||||
+ SECITEM_FreeItem (raw_key_aligned, PR_TRUE);
|
||||
+ PK11_DestroyContext (wrap_key_crypt_context, PR_TRUE);
|
||||
+ PK11_FreeSymKey (wrapping_key);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* Finish the wrapping operation and release no more needed resources. */
|
||||
+ ret = PK11_Finalize (wrap_key_crypt_context);
|
||||
+ SECITEM_FreeItem (raw_key_aligned, PR_TRUE);
|
||||
+ PK11_DestroyContext (wrap_key_crypt_context, PR_TRUE);
|
||||
+ if (ret != SECSuccess) {
|
||||
+ g_free (wrapped_key);
|
||||
+ PK11_FreeSymKey (wrapping_key);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* Prepare for unwrapping the <key>. */
|
||||
+ memset (&tmp_sec_item, 0, sizeof (tmp_sec_item));
|
||||
+ memset (&wrapped_key_item, 0, sizeof (wrapped_key_item));
|
||||
+ wrapped_key_item.data = wrapped_key;
|
||||
+ wrapped_key_item.len = wrapped_key_size;
|
||||
+
|
||||
+ /* Unwrap the <key>. First, decrypt the <key> with the <wrapping_key> to get
|
||||
+ * its raw form. Then make a symmetric key (<key>, <type>, <operation>). This
|
||||
+ * makes a symmetric key from the raw <key> in a FIPS compliant manner.
|
||||
+ */
|
||||
+ sym_key = PK11_UnwrapSymKey (wrapping_key, wrap_mechanism, &tmp_sec_item,
|
||||
+ &wrapped_key_item, type, operation, key->len);
|
||||
+ g_free (wrapped_key);
|
||||
+ PK11_FreeSymKey (wrapping_key);
|
||||
+ return sym_key;
|
||||
+}
|
||||
+
|
||||
/* LIBVK_PACKET_FORMAT_ASYMMETRIC */
|
||||
|
||||
/* Encrypt DATA of SIZE for CERT.
|
||||
@@ -291,9 +400,9 @@ wrap_asymmetric (void **wrapped_secret, size_t *wrapped_secret_size,
|
||||
CKM_GENERIC_SECRET_KEY_GEN. */
|
||||
clear_secret_item.data = (void *)clear_secret_data;
|
||||
clear_secret_item.len = clear_secret_size;
|
||||
- secret_key = PK11_ImportSymKey (slot, CKM_GENERIC_SECRET_KEY_GEN,
|
||||
- PK11_OriginUnwrap, CKA_WRAP,
|
||||
- &clear_secret_item, pwfn_arg);
|
||||
+ secret_key = import_sym_key (slot, CKM_GENERIC_SECRET_KEY_GEN,
|
||||
+ PK11_OriginUnwrap, CKA_WRAP,
|
||||
+ &clear_secret_item, pwfn_arg);
|
||||
PK11_FreeSlot (slot);
|
||||
if (secret_key == NULL)
|
||||
{
|
||||
@@ -471,9 +580,9 @@ wrap_symmetric (void **wrapped_secret, size_t *wrapped_secret_size, void **iv,
|
||||
/* The disk encryption mechanism might not have a PKCS11 name, and we don't
|
||||
really need to tell NSS specifics anyway, so just use
|
||||
CKM_GENERIC_SECRET_KEY_GEN. */
|
||||
- secret_key = PK11_ImportSymKey (slot, CKM_GENERIC_SECRET_KEY_GEN,
|
||||
- PK11_OriginUnwrap, CKA_WRAP,
|
||||
- &clear_secret_item, pwfn_arg);
|
||||
+ secret_key = import_sym_key (slot, CKM_GENERIC_SECRET_KEY_GEN,
|
||||
+ PK11_OriginUnwrap, CKA_WRAP,
|
||||
+ &clear_secret_item, pwfn_arg);
|
||||
PK11_FreeSlot (slot);
|
||||
if (secret_key == NULL)
|
||||
{
|
@ -32,7 +32,7 @@
|
||||
Summary: An utility for manipulating storage encryption keys and passphrases
|
||||
Name: volume_key
|
||||
Version: 0.3.12
|
||||
Release: 23%{?dist}
|
||||
Release: 24%{?dist}
|
||||
License: GPL-2.0-only AND (MPL-1.1 OR GPL-2.0-or-later OR LGPL-2.1-or-later)
|
||||
URL: https://pagure.io/%{name}/
|
||||
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
|
||||
@ -44,6 +44,7 @@ Patch0: volume_key-0.3.12-support_LUKS2_and_more.patch
|
||||
# Fix resource leaks
|
||||
# - backport of bf6618ec0b09b4e51fc97fa021e687fbd87599ba
|
||||
Patch1: volume_key-0.3.12-fix_resource_leaks.patch
|
||||
Patch2: volume_key-0.3.12-FIPS.patch
|
||||
BuildRequires: autoconf, automake, libtool
|
||||
BuildRequires: make
|
||||
BuildRequires: gcc
|
||||
@ -122,6 +123,7 @@ Requires: %{name}-libs%{?_isa} = %{version}-%{release}
|
||||
%setup -q
|
||||
%patch0 -p1
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
autoreconf -fiv
|
||||
|
||||
%build
|
||||
@ -173,6 +175,10 @@ exit 1; \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Jan 15 2025 Vojtech Trefny <vtrefny@redhat.com> - 0.3.12-24
|
||||
- Make volume_key FIPS compliant
|
||||
Resolves: RHEL-74047
|
||||
|
||||
* Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 0.3.12-23
|
||||
- Bump release for October 2024 mass rebuild:
|
||||
Resolves: RHEL-64018
|
||||
|
Loading…
Reference in New Issue
Block a user