|
|
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 |
|