|
|
beb795 |
From 20ab0c731eea95327c8c2dc296461b612c6e98ae Mon Sep 17 00:00:00 2001
|
|
|
beb795 |
From: Nathaniel McCallum <npmccallum@redhat.com>
|
|
|
beb795 |
Date: Wed, 21 Feb 2018 23:39:55 -0500
|
|
|
beb795 |
Subject: [PATCH] Fix OTP validation in FIPS mode
|
|
|
beb795 |
|
|
|
beb795 |
NSS doesn't allow keys to be loaded directly in FIPS mode. To work around
|
|
|
beb795 |
this, we encrypt the input key using an ephemeral key and then unwrap the
|
|
|
beb795 |
encrypted key.
|
|
|
beb795 |
|
|
|
beb795 |
https://pagure.io/freeipa/issue/7168
|
|
|
beb795 |
|
|
|
beb795 |
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
|
beb795 |
Reviewed-By: Christian Heimes <cheimes@redhat.com>
|
|
|
beb795 |
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
|
beb795 |
---
|
|
|
beb795 |
daemons/ipa-slapi-plugins/libotp/hotp.c | 47 +++++++++++++++++++++++++++++++--
|
|
|
beb795 |
1 file changed, 45 insertions(+), 2 deletions(-)
|
|
|
beb795 |
|
|
|
beb795 |
diff --git a/daemons/ipa-slapi-plugins/libotp/hotp.c b/daemons/ipa-slapi-plugins/libotp/hotp.c
|
|
|
beb795 |
index 619bc63ab1bee99d71c2f0fb887809762107c94c..0c9de96d37183e597867b736d6324db60fa1b3bb 100644
|
|
|
beb795 |
--- a/daemons/ipa-slapi-plugins/libotp/hotp.c
|
|
|
beb795 |
+++ b/daemons/ipa-slapi-plugins/libotp/hotp.c
|
|
|
beb795 |
@@ -46,6 +46,7 @@
|
|
|
beb795 |
#include <time.h>
|
|
|
beb795 |
|
|
|
beb795 |
#include <nss.h>
|
|
|
beb795 |
+#include <blapit.h>
|
|
|
beb795 |
#include <pk11pub.h>
|
|
|
beb795 |
#include <hasht.h>
|
|
|
beb795 |
#include <prnetdb.h>
|
|
|
beb795 |
@@ -66,6 +67,49 @@ static const struct {
|
|
|
beb795 |
{ }
|
|
|
beb795 |
};
|
|
|
beb795 |
|
|
|
beb795 |
+static PK11SymKey *
|
|
|
beb795 |
+import_key(PK11SlotInfo *slot, CK_MECHANISM_TYPE mech, SECItem *key)
|
|
|
beb795 |
+{
|
|
|
beb795 |
+ uint8_t ct[(key->len / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE];
|
|
|
beb795 |
+ uint8_t iv[AES_BLOCK_SIZE] = {};
|
|
|
beb795 |
+ SECItem ivitem = { .data = iv, .len = sizeof(iv), .type = siBuffer };
|
|
|
beb795 |
+ SECItem ctitem = { .data = ct, .len = sizeof(ct), .type = siBuffer };
|
|
|
beb795 |
+ PK11SymKey *ekey = NULL;
|
|
|
beb795 |
+ PK11SymKey *skey = NULL;
|
|
|
beb795 |
+
|
|
|
beb795 |
+ /* Try to import the key directly. */
|
|
|
beb795 |
+ skey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap,
|
|
|
beb795 |
+ CKA_SIGN, key, NULL);
|
|
|
beb795 |
+ if (skey)
|
|
|
beb795 |
+ return skey;
|
|
|
beb795 |
+
|
|
|
beb795 |
+ /* If we get here, we are probably in FIPS mode. Let's encrypt the key so
|
|
|
beb795 |
+ * that we can unseal it instead of loading it directly. */
|
|
|
beb795 |
+
|
|
|
beb795 |
+ /* Generate an ephemeral key. */
|
|
|
beb795 |
+ ekey = PK11_TokenKeyGenWithFlags(slot, CKM_AES_CBC_PAD, NULL,
|
|
|
beb795 |
+ AES_128_KEY_LENGTH, NULL,
|
|
|
beb795 |
+ CKF_ENCRYPT | CKF_UNWRAP,
|
|
|
beb795 |
+ PK11_ATTR_SESSION |
|
|
|
beb795 |
+ PK11_ATTR_PRIVATE |
|
|
|
beb795 |
+ PK11_ATTR_SENSITIVE, NULL);
|
|
|
beb795 |
+ if (!ekey)
|
|
|
beb795 |
+ goto egress;
|
|
|
beb795 |
+
|
|
|
beb795 |
+ /* Encrypt the input key. */
|
|
|
beb795 |
+ if (PK11_Encrypt(ekey, CKM_AES_CBC_PAD, &ivitem, ctitem.data, &ctitem.len,
|
|
|
beb795 |
+ ctitem.len, key->data, key->len) != SECSuccess)
|
|
|
beb795 |
+ goto egress;
|
|
|
beb795 |
+
|
|
|
beb795 |
+ /* Unwrap the input key. */
|
|
|
beb795 |
+ skey = PK11_UnwrapSymKey(ekey, CKM_AES_CBC_PAD, &ivitem,
|
|
|
beb795 |
+ &ctitem, mech, CKA_SIGN, key->len);
|
|
|
beb795 |
+
|
|
|
beb795 |
+egress:
|
|
|
beb795 |
+ PK11_FreeSymKey(ekey);
|
|
|
beb795 |
+ return skey;
|
|
|
beb795 |
+}
|
|
|
beb795 |
+
|
|
|
beb795 |
/*
|
|
|
beb795 |
* This code is mostly cargo-cult taken from here:
|
|
|
beb795 |
* http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn5.html
|
|
|
beb795 |
@@ -90,8 +134,7 @@ static bool hmac(SECItem *key, CK_MECHANISM_TYPE mech, const SECItem *in,
|
|
|
beb795 |
}
|
|
|
beb795 |
}
|
|
|
beb795 |
|
|
|
beb795 |
- symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap,
|
|
|
beb795 |
- CKA_SIGN, key, NULL);
|
|
|
beb795 |
+ symkey = import_key(slot, mech, key);
|
|
|
beb795 |
if (symkey == NULL)
|
|
|
beb795 |
goto done;
|
|
|
beb795 |
|
|
|
beb795 |
--
|
|
|
beb795 |
2.14.3
|
|
|
beb795 |
|