URL: https://github.com/freeipa/freeipa/pull/1621 Author: npmccallum Title: #1621: OTP FIPS mode fixes Action: opened
PR body: """ The following patches add various fixes for using OTP on a server running in FIPS mode. """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/1621/head:pr1621 git checkout pr1621
From 4c14a5eb61e01c682674275cb31f6ef2fcaf2999 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum <npmccal...@redhat.com> Date: Wed, 21 Feb 2018 23:39:55 -0500 Subject: [PATCH 1/3] Fix OTP validation in FIPS mode NSS doesn't allow keys to be loaded directly in FIPS mode. To work around this, we encrypt the input key using an ephemeral key and then unwrap the encrypted key. --- daemons/ipa-slapi-plugins/libotp/hotp.c | 47 +++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/daemons/ipa-slapi-plugins/libotp/hotp.c b/daemons/ipa-slapi-plugins/libotp/hotp.c index 619bc63ab1..0c9de96d37 100644 --- a/daemons/ipa-slapi-plugins/libotp/hotp.c +++ b/daemons/ipa-slapi-plugins/libotp/hotp.c @@ -46,6 +46,7 @@ #include <time.h> #include <nss.h> +#include <blapit.h> #include <pk11pub.h> #include <hasht.h> #include <prnetdb.h> @@ -66,6 +67,49 @@ static const struct { { } }; +static PK11SymKey * +import_key(PK11SlotInfo *slot, CK_MECHANISM_TYPE mech, SECItem *key) +{ + uint8_t ct[(key->len / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE]; + uint8_t iv[AES_BLOCK_SIZE] = {}; + SECItem ivitem = { .data = iv, .len = sizeof(iv), .type = siBuffer }; + SECItem ctitem = { .data = ct, .len = sizeof(ct), .type = siBuffer }; + PK11SymKey *ekey = NULL; + PK11SymKey *skey = NULL; + + /* Try to import the key directly. */ + skey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, + CKA_SIGN, key, NULL); + if (skey) + return skey; + + /* If we get here, we are probably in FIPS mode. Let's encrypt the key so + * that we can unseal it instead of loading it directly. */ + + /* Generate an ephemeral key. */ + ekey = PK11_TokenKeyGenWithFlags(slot, CKM_AES_CBC_PAD, NULL, + AES_128_KEY_LENGTH, NULL, + CKF_ENCRYPT | CKF_UNWRAP, + PK11_ATTR_SESSION | + PK11_ATTR_PRIVATE | + PK11_ATTR_SENSITIVE, NULL); + if (!ekey) + goto egress; + + /* Encrypt the input key. */ + if (PK11_Encrypt(ekey, CKM_AES_CBC_PAD, &ivitem, ctitem.data, &ctitem.len, + ctitem.len, key->data, key->len) != SECSuccess) + goto egress; + + /* Unwrap the input key. */ + skey = PK11_UnwrapSymKey(ekey, CKM_AES_CBC_PAD, &ivitem, + &ctitem, mech, CKA_SIGN, key->len); + +egress: + PK11_FreeSymKey(ekey); + return skey; +} + /* * This code is mostly cargo-cult taken from here: * http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn5.html @@ -90,8 +134,7 @@ static bool hmac(SECItem *key, CK_MECHANISM_TYPE mech, const SECItem *in, } } - symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, - CKA_SIGN, key, NULL); + symkey = import_key(slot, mech, key); if (symkey == NULL) goto done; From c66a93f8f5f3c307995d3dbe5c0388259d93c37d Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum <npmccal...@redhat.com> Date: Thu, 22 Feb 2018 14:04:10 -0500 Subject: [PATCH 2/3] Increase the default token key size The previous default token key size would fail in FIPS mode for the sha384 and sha512 algorithms. With the updated key size, the default will work in all cases. --- ipaserver/plugins/otptoken.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipaserver/plugins/otptoken.py b/ipaserver/plugins/otptoken.py index 24815c108f..d94ae49fff 100644 --- a/ipaserver/plugins/otptoken.py +++ b/ipaserver/plugins/otptoken.py @@ -72,7 +72,7 @@ } # NOTE: For maximum compatibility, KEY_LENGTH % 5 == 0 -KEY_LENGTH = 20 +KEY_LENGTH = 35 class OTPTokenKey(Bytes): """A binary password type specified in base32.""" From 9b754396ce989006d4712d29bd06b78efb79732c Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum <npmccal...@redhat.com> Date: Thu, 22 Feb 2018 14:21:27 -0500 Subject: [PATCH 3/3] Add log message for OTP validation context When running in FIPS mode, NSS enforces key sizes on HMAC. If the input keys are too small, the creation of the context will fail. We don't want this failure to occur silently so that admins can see they need to increase their key sizes. --- daemons/ipa-slapi-plugins/libotp/hotp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/daemons/ipa-slapi-plugins/libotp/hotp.c b/daemons/ipa-slapi-plugins/libotp/hotp.c index 0c9de96d37..9875412661 100644 --- a/daemons/ipa-slapi-plugins/libotp/hotp.c +++ b/daemons/ipa-slapi-plugins/libotp/hotp.c @@ -45,6 +45,9 @@ #include "hotp.h" #include <time.h> +#include <slapi-plugin.h> +#include "../common/util.h" + #include <nss.h> #include <blapit.h> #include <pk11pub.h> @@ -139,8 +142,10 @@ static bool hmac(SECItem *key, CK_MECHANISM_TYPE mech, const SECItem *in, goto done; ctx = PK11_CreateContextBySymKey(mech, CKA_SIGN, symkey, ¶m); - if (ctx == NULL) + if (ctx == NULL) { + LOG_FATAL("Error creating OTP validation context (key too small?)!\n"); goto done; + } s = PK11_DigestBegin(ctx); if (s != SECSuccess)
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org