mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
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. https://pagure.io/freeipa/issue/7168 Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
committed by
Rob Crittenden
parent
9797309ef9
commit
c9c58f2d35
@@ -46,6 +46,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include <nss.h>
|
#include <nss.h>
|
||||||
|
#include <blapit.h>
|
||||||
#include <pk11pub.h>
|
#include <pk11pub.h>
|
||||||
#include <hasht.h>
|
#include <hasht.h>
|
||||||
#include <prnetdb.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:
|
* This code is mostly cargo-cult taken from here:
|
||||||
* http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn5.html
|
* 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,
|
symkey = import_key(slot, mech, key);
|
||||||
CKA_SIGN, key, NULL);
|
|
||||||
if (symkey == NULL)
|
if (symkey == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user