Blame SOURCES/0001-Encrypt-unwrap-symmetric-key-in-FIPS-mode-678.patch

bd9a92
From 3cc2f62eaca0e616dadc3053919180615b48bf54 Mon Sep 17 00:00:00 2001
bd9a92
From: Alexander Scheel <alexander.m.scheel@gmail.com>
bd9a92
Date: Fri, 12 Mar 2021 20:41:51 -0500
bd9a92
Subject: [PATCH] Encrypt & unwrap symmetric key in FIPS mode (#678)
bd9a92
bd9a92
NSS doesn't generally allow keys to be imported in FIPS mode. However,
bd9a92
for portability with other JCA providers, we sometimes need to import
bd9a92
keys from byte arrays. Do this in the JNI layer by executing a PKCS#11
bd9a92
encrypt and then unwrap using the same key. This lets us effectively
bd9a92
"import" a key into a token, if the token supports using the given
bd9a92
mechanism for both encryption and unwrapping operations. Some HSMs are
bd9a92
getting stricter about this and forbid using the same key for encrypt
bd9a92
and unwrap operations.
bd9a92
bd9a92
Resolves: #334
bd9a92
bd9a92
Signed-off-by: Alexander Scheel <ascheel@redhat.com>
bd9a92
Signed-off-by: Alexander Scheel <alexander.m.scheel@gmail.com>
bd9a92
---
bd9a92
 org/mozilla/jss/pkcs11/PK11KeyWrapper.c | 62 ++++++++++++++++++++++++-
bd9a92
 1 file changed, 60 insertions(+), 2 deletions(-)
bd9a92
bd9a92
diff --git a/org/mozilla/jss/pkcs11/PK11KeyWrapper.c b/org/mozilla/jss/pkcs11/PK11KeyWrapper.c
bd9a92
index f39a3796..e8e9da16 100644
bd9a92
--- a/org/mozilla/jss/pkcs11/PK11KeyWrapper.c
bd9a92
+++ b/org/mozilla/jss/pkcs11/PK11KeyWrapper.c
bd9a92
@@ -712,6 +712,61 @@ finish:
bd9a92
     return keyObj;
bd9a92
 }
bd9a92
 
bd9a92
+PK11SymKey *JSS_PK11_ImportSymKeyWithFlagsFIPS(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
bd9a92
+        CK_ATTRIBUTE_TYPE operation, SECItem *key, CK_FLAGS flags,
bd9a92
+        PRBool isPerm, void *wincx)
bd9a92
+{
bd9a92
+    PK11SymKey *result = NULL;
bd9a92
+    PK11SymKey *wrapper = NULL;
bd9a92
+    SECStatus ret = SECFailure;
bd9a92
+    unsigned int wrapped_len = 0;
bd9a92
+    unsigned int wrapped_max = key->len + 64;
bd9a92
+    unsigned char *wrapped_key = calloc(wrapped_max, sizeof(unsigned char));
bd9a92
+    SECItem wrapped_item = { siBuffer, wrapped_key, 0 };
bd9a92
+    SECItem *param = NULL;
bd9a92
+
bd9a92
+    /* Steps:
bd9a92
+     * 1. Generate a temporary key to encrypt and unwrap with,
bd9a92
+     * 2. Encrypt our key to import using the wrapping key,
bd9a92
+     * 3. Unwrap into the token using the wrapping key.
bd9a92
+     */
bd9a92
+
bd9a92
+#define FIPS_KEYGEN_ALGO CKM_AES_KEY_GEN
bd9a92
+#define FIPS_ENCRYPT_UNWRAP_ALGO CKM_AES_KEY_WRAP_PAD
bd9a92
+
bd9a92
+    wrapper = PK11_KeyGen(slot, FIPS_KEYGEN_ALGO, NULL, 32, wincx);
bd9a92
+    if (wrapper == NULL) {
bd9a92
+        goto done;
bd9a92
+    }
bd9a92
+
bd9a92
+    param = PK11_GenerateNewParam(FIPS_ENCRYPT_UNWRAP_ALGO, wrapper);
bd9a92
+    if (param == NULL) {
bd9a92
+        goto done;
bd9a92
+    }
bd9a92
+
bd9a92
+    ret = PK11_Encrypt(wrapper, FIPS_ENCRYPT_UNWRAP_ALGO, param,
bd9a92
+            wrapped_key, &wrapped_len, wrapped_max,
bd9a92
+            key->data, key->len);
bd9a92
+    if (ret != SECSuccess) {
bd9a92
+        goto done;
bd9a92
+    }
bd9a92
+
bd9a92
+    wrapped_item.len = wrapped_len;
bd9a92
+
bd9a92
+    result = PK11_UnwrapSymKeyWithFlagsPerm(wrapper, FIPS_ENCRYPT_UNWRAP_ALGO,
bd9a92
+            param, &wrapped_item, type, operation, key->len, flags,
bd9a92
+            isPerm);
bd9a92
+
bd9a92
+done:
bd9a92
+    free(wrapped_key);
bd9a92
+    SECITEM_FreeItem(param, PR_TRUE);
bd9a92
+    if (wrapper != NULL) {
bd9a92
+        PK11_DeleteTokenSymKey(wrapper);
bd9a92
+        PK11_FreeSymKey(wrapper);
bd9a92
+    }
bd9a92
+    return result;
bd9a92
+}
bd9a92
+
bd9a92
 /***********************************************************************
bd9a92
  *
bd9a92
  * PK11KeyWrapper.nativeUnwrapSymPlaintext
bd9a92
@@ -765,8 +820,11 @@ Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymPlaintext
bd9a92
     }
bd9a92
 
bd9a92
     /* pull in the key */
bd9a92
-    symKey = PK11_ImportSymKeyWithFlags(slot, keyTypeMech, PK11_OriginUnwrap,
bd9a92
-        operation, wrappedKey, flags, isPerm, NULL);
bd9a92
+    if (PK11_IsFIPS()) {
bd9a92
+        symKey = JSS_PK11_ImportSymKeyWithFlagsFIPS(slot, keyTypeMech, operation, wrappedKey, flags, isPerm, NULL);
bd9a92
+    } else {
bd9a92
+        symKey = PK11_ImportSymKeyWithFlags(slot, keyTypeMech, PK11_OriginUnwrap, operation, wrappedKey, flags, isPerm, NULL);
bd9a92
+    }
bd9a92
     if( symKey == NULL ) {
bd9a92
         JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to unwrap key");
bd9a92
         goto finish;
bd9a92
-- 
bd9a92
2.26.2
bd9a92