the better slot?

17 views
Skip to first unread message

Andrew Cagney

unread,
May 27, 2026, 9:47:38 PM (7 days ago) May 27
to mozilla's crypto code discussion list
I think I've managed to track down why a machine was failing ML_KEM in
libreswan, but it brings up several questions.

First the libreswan bug:

- the IKE_SA_INIT exchange generates a KE DH secret
- this secret is fed into the KDF which returns keymat and a key D
with slot A (I'm not sure where that slot came from)
- the IKE_INTERMEDIATE exchange generates an ADDKE ML_KEM secret with
an ML_KEM slot
- D+ADDKE are then fed into the KDF (CKM_NSS_IKE_PRF_DERIVE) which
barfs (fails gracefully) because ADDKE (.hNewKey) isn't in D's slot

Presumably the fix is to get both D and ADDKE on the same slot:

Q.1 But which is the better slot? D or the one that was for ML_KEM?
Q.2 Why would we only encounter the problem on one machine?

More broadly:

Do slots have any (multi threaded) performance implications? For
instance, in the above, I've a suspicion that D's slot is being shared
across threads and is very long lived

Andrew

Andrew Cagney

unread,
May 29, 2026, 9:42:56 AM (5 days ago) May 29
to mozilla's crypto code discussion list
On Wed, 27 May 2026 at 21:47, Andrew Cagney <andrew...@gmail.com> wrote:
>
> I think I've managed to track down why a machine was failing ML_KEM in
> libreswan, but it brings up several questions.
>
> First the libreswan bug:
>
> - the IKE_SA_INIT exchange generates a KE DH secret
> - this secret is fed into the KDF which returns keymat and a key D
> with slot A (I'm not sure where that slot came from)
> - the IKE_INTERMEDIATE exchange generates an ADDKE ML_KEM secret with
> an ML_KEM slot
> - D+ADDKE are then fed into the KDF (CKM_NSS_IKE_PRF_DERIVE) which
> barfs (fails gracefully) because ADDKE (.hNewKey) isn't in D's slot

We've figured out it has something to do with the on-disk NSS DB -
copy one DB to a new machine and the problem appears there.

Andrew Cagney

unread,
May 29, 2026, 4:13:58 PM (5 days ago) May 29
to mozilla's crypto code discussion list
On Fri, 29 May 2026 at 09:42, Andrew Cagney <andrew...@gmail.com> wrote:

> > - the IKE_SA_INIT exchange generates a KE DH secret
> > - this secret is fed into the KDF which returns keymat and a key D
> > with slot A (I'm not sure where that slot came from)
> > - the IKE_INTERMEDIATE exchange generates an ADDKE ML_KEM secret with
> > an ML_KEM slot
> > - D+ADDKE are then fed into the KDF (CKM_NSS_IKE_PRF_DERIVE) which
> > barfs (fails gracefully) because ADDKE (.hNewKey) isn't in D's slot
>
> We've figured out it has something to do with the on-disk NSS DB -
> copy one DB to a new machine and the problem appears there.

Here are some notes.

- the first exchange gets an ECP slot
- the hack:
208 * The key returned above doesn't play well with PK11_Derive()
209 * - "softokn" fails to extract its value when trying to
210 * CKM_CONCATENATE_BASE_AND_KEY - work around this by
211 * returning a copy of the key.
may switch slots
- the second exchange gets an ML_KEM slot
- the ML_KEM slot and the hack don't agree

On a machine that "works":
- module load populates pk11_ecSlotList with NSS Internal
Cryptographic Services slot mechanism 4161 which I assume is something
like ECC in
Flags: RSA:ECC:EDDSA:DH:RC2:RC4:DES:AES:CAMELLIA:SEED:SHA1:SHA256:SHA512:MD5:MD2:SSL:TLS
- ECP uses the NSS Internal Cryptographic Services slot from pk11_ecSlotList
- the hack leaves things on that slot
- ML_KEM uses the NSS Internal Cryptographic Services slot from pk11_ecSlotList
-> no clash, no problem

On a machine that "doesn't work":
- pk11_ecSlotList is not populated during module load because NSS
Internal PKCS #11 Module only has:
Flags: RSA:DH:RC2:RC4:DES:AES:CAMELLIA:SEED:SHA1:SHA256:SHA512:MD5:MD2:SSL:TLS
- ECP gets back an empty pk11_ecSlotList so picks "NSS Certificate DB"
from the list (NSS Certificate DB, NSS Generic Crypto Services)
returned by PK11_GetAllTokens()
- the hack moves the ECP from "NSS Certificate DB" to "NSS Generic
Crypto Services"
- ML_KEM, like ECP, ends up with NSS Certificate DB
=> hence the clash

I guess this leaves the question:

Andrew Cagney

unread,
May 29, 2026, 9:10:25 PM (5 days ago) May 29
to mozilla's crypto code discussion list
Just a side note. It seems that there's a bug in libreswan's `ipsec
initnss` command
where it forgets to rebuild pkcs11.txt. As a consequence:

rm /var/lib/ipsec/*.db # not pkcs11.txt
ipsec initnss

will recreate the DB described in pkcs11.txt; or perhaps that's a feature.

Robert Relyea

unread,
Jun 1, 2026, 4:41:33 PM (2 days ago) Jun 1
to dev-tec...@mozilla.org
On 5/29/26 6:10 PM, Andrew Cagney wrote:
Just a side note.  It seems that there's a bug in libreswan's `ipsec
initnss` where it forgets to rebuild pkcs11.txt.  As a consequence:

rm /var/lib/ipsec/*.db # not pkcs11.txt
ipsec initnss

will recreate the DB described in pkcs11.txt; or perhaps that's a feature.

Unless you have some external tokens loaded, the typical choice is between the NSS Certificate DB module and the NSS Generic Crypto Services. Both can do all the crypto the other can do, only the NSS Certificate DB can store token objects, but may require a password before you access it (depending on if you have set a db password). NSS Generic Crypto Services does not require a password, and thus most operations use it. If you need to store a key, NSS can usually move it in this case. If you are in FIPS mode there is only one module, as you need to authenticate before you do any crypto operation.

So it looks like we are still using the ecSlotList for mlkem instead of adding a new mlkem slot list (sigh).

bob



Robert Relyea

unread,
Jun 1, 2026, 5:05:15 PM (2 days ago) Jun 1
to dev-tec...@mozilla.org
On 5/27/26 6:47 PM, Andrew Cagney wrote:
> I think I've managed to track down why a machine was failing ML_KEM in
> libreswan, but it brings up several questions.
>
> First the libreswan bug:
>
> - the IKE_SA_INIT exchange generates a KE DH secret
> - this secret is fed into the KDF which returns keymat and a key D
> with slot A (I'm not sure where that slot came from)
> - the IKE_INTERMEDIATE exchange generates an ADDKE ML_KEM secret with
> an ML_KEM slot
> - D+ADDKE are then fed into the KDF (CKM_NSS_IKE_PRF_DERIVE) which
> barfs (fails gracefully) because ADDKE (.hNewKey) isn't in D's slot
>
> Presumably the fix is to get both D and ADDKE on the same slot:
>
> Q.1 But which is the better slot? D or the one that was for ML_KEM?
> Q.2 Why would we only encounter the problem on one machine?
>
> More broadly:
>
> Do slots have any (multi threaded) performance implications?

There shouldn't be. Under the covers in softoken they share most of the
same data structures.

Most NSS functions will try to move operations with two different keys
into the same slot when they are involved in the same operation. This
usually applies to things like key wrap/unwrap. I suspect the derive
call doesn't do that because the other key is passed in as part of the
derive function's parameters. We have a function that should help


/*
 * To do joint operations, we often need two keys in the same slot.
 * Usually the PKCS #11 wrappers handle this correctly (like for
PK11_WrapKey),
 * but sometimes the wrappers don't know about mechanism specific keys in
 * the Mechanism params. This function makes sure the two keys are in the
 * same slot by copying one or both of the keys into a common slot. This
 * functions makes sure the slot can handle the target mechanism. If
the copy
 * is warranted, this function will prefer to move the movingKey first,
then
 * the preferedKey. If the keys are moved, the new keys are returned in
 * newMovingKey and/or newPreferedKey. The application is responsible
 * for freeing those keys once the operation is complete.
 */
SECStatus
PK11_SymKeysToSameSlot(CK_MECHANISM_TYPE mech,
                       CK_ATTRIBUTE_TYPE preferedOperation,
                       CK_ATTRIBUTE_TYPE movingOperation,
                       PK11SymKey *preferedKey, PK11SymKey *movingKey,
                       PK11SymKey **newPreferedKey, PK11SymKey
**newMovingKey)

Note, if the keys are not moved newPreferedKey and newMovingKey will be
NULL.
Reply all
Reply to author
Forward
0 new messages