pgreco / rpms / ipa

Forked from forks/areguera/rpms/ipa 4 years ago
Clone

Blame SOURCES/0039-Fix-OTP-validation-in-FIPS-mode.patch

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