<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Thank you for that information but the problem is that the HSM
provider has documented that the CKD_NULL is not allowed in FIPS
mode and when i try either</p>
<pre class="moz-quote-pre" wrap="">byte[] Z = ka.generateSecret();
</pre>
<b>or</b><br>
<p></p>
<pre class="moz-quote-pre" wrap="">SecretKey Z = ka.generateSecret("TlsPremasterSecret");</pre>
<p></p>
<p>the error is the same:</p>
<p>Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: <b>CKR_MECHANISM_PARAM_INVALID</b></p>
<p>I get the same error if I use the wrapper provided by the
manufacturer but then in their code i modified the value for <br>
</p>
<p>"CK_EC_KDF_TYPE kdf" from "CKD_NULL" (default) to
"CKD_SHA224_NIST_KDF" then only it works but I could not get it
working with what i sent before.</p>
<p>And there is no shared data used.<br>
</p>
<div class="moz-cite-prefix">On 8/19/24 11:06, Valerie Peng wrote:<br>
</div>
<blockquote type="cite"
cite="mid:SN7PR10MB6364E57039271A105D959D63F18C2@SN7PR10MB6364.namprd10.prod.outlook.com">
<pre class="moz-quote-pre" wrap="">Yes, key value extraction is disallowed for PKCS11 provider in FIPS mode.
When you call KeyAgreement.generateSecret(), a native key is generated and its key value would be extracted and return which would be rejected for provider in FIPS mode. Please try the KeyAgreement.generateSecret(String) call which would not extract the key value and return the generated key which you'd use with the same provider afterwards.
Valerie
-----Original Message-----
From: security-dev <a class="moz-txt-link-rfc2396E" href="mailto:security-dev-retn@openjdk.org"><security-dev-retn@openjdk.org></a> On Behalf Of Daniel Jelinski
Sent: Sunday, August 18, 2024 10:52 PM
To: Pushkar Marathe <a class="moz-txt-link-rfc2396E" href="mailto:pushkar.marathe@strongkey.com"><pushkar.marathe@strongkey.com></a>
Cc: <a class="moz-txt-link-abbreviated" href="mailto:security-dev@openjdk.org">security-dev@openjdk.org</a>
Subject: Re: Jdk 21 PKCS11 ECDH Key agreement failing
Hi Pushkar,
The failure is not unexpected. In FIPS mode you are not allowed to extract secret keys, and ka.generateSecret() does just that.
Try:
SecretKey Z = ka.generateSecret("TlsPremasterSecret");
it should work even in FIPS mode.
CKD_NULL is valid when shared data is null, and I don't see why it would be disallowed in FIPS mode.
Regards,
Daniel
wt., 13 sie 2024 o 23:02 Pushkar Marathe <a class="moz-txt-link-rfc2396E" href="mailto:pushkar.marathe@strongkey.com"><pushkar.marathe@strongkey.com></a> napisaĆ(a):
</pre>
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">
Hi
I have some java code written using javax.crypto package which does a derivation using ht ECDH algorithm. This code is run against a HSM card and uses key pair on the hsm. Example code below:
Provider CRYPTOKI_PROVIDER = Security.getProvider("SunPKCS11");
CRYPTOKI_PROVIDER = CRYPTOKI_PROVIDER.configure(PKCS11_CFG_LOCATION);
Security.addProvider(CRYPTOKI_PROVIDER);
//Generate ephemeral EC key
KeyPairGenerator kpgen = KeyPairGenerator.getInstance("ECDH", BC_FIPS_PROVIDER);
kpgen.initialize(new ECGenParameterSpec("secp256r1"), FIPS_DRBG);
KeyPair keyPair = kpgen.generateKeyPair();
ECPublicKey epubKey = (ECPublicKey) keyPair.getPublic();
ECPrivateKey eprivKey = (ECPrivateKey)
keyPair.getPrivate();
PublicKey pubkey = null;
if (keystore.containsAlias("alias")) {
pubkey = keystore.getCertificate(mapkey).getPublicKey();
}
if (pubkey == null) {
cryptoCommon.logp(Level.WARNING, classname, "wrapSymmetricKey", "CRYPTO-ERR-1041", mapkey);
throw new InvalidKeyException(mapkey);
}
KeyAgreement ka = KeyAgreement.getInstance("ECDH", CRYPTOKI_PROVIDER);
ka.init(eprivKey, CRYPTOKI_RNG);
ka.doPhase(pubkey, true);
byte[] Z = ka.generateSecret();
Now when the HSM has FIPS mode turned on, the same code above starts failing at the highlighted line above. I believe this is because of the ECDH1_DERIVE_PARAMS because the default KDF used which is CKD_NULL is not allowed in FIPS mode. I couldnt find a way to change that to a FIPS approved param and make the code work.
I was looking at some source code and found the code below in the file P11ECDHKeyAgreement.java (<a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/blob/master/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECDHKeyAgreement.java">https://github.com/openjdk/jdk/blob/master/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECDHKeyAgreement.java</a>):
protected byte[] engineGenerateSecret() throws IllegalStateException {
if ((privateKey == null) || (publicValue == null)) {
throw new IllegalStateException("Not initialized correctly");
}
Session session = null;
long privKeyID = privateKey.getKeyID();
try {
session = token.getOpSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET),
};
CK_ECDH1_DERIVE_PARAMS ckParams =
new CK_ECDH1_DERIVE_PARAMS(CKD_NULL, null, publicValue);
attributes = token.getAttributes
(O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
long keyID = token.p11.C_DeriveKey(session.id(),
new CK_MECHANISM(mechanism, ckParams), privKeyID,
attributes);
attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_VALUE)
};
token.p11.C_GetAttributeValue(session.id(), keyID, attributes);
byte[] secret = attributes[0].getByteArray();
token.p11.C_DestroyObject(session.id(), keyID);
return secret;
} catch (PKCS11Exception e) {
throw new ProviderException("Could not derive key", e);
} finally {
privateKey.releaseKeyID();
publicValue = null;
token.releaseSession(session);
}
}
As we see here that the Params is taking CKD_NULL as the first param as highlighted below and i dont see code that lets me change that.
Is there an approach i could take to make the above code work with HSM in FIPS mode and with the ability to change the params?
There are some examples from the hsm provider which i was able to
modify to make it work but its not using javax.crypto but their
CRYPTOKI implementation. The way i made it work was to specify
CK_ECDH1_DERIVE_PARAMS params
= new CK_ECDH1_DERIVE_PARAMS(KDF.CKD_SHA224_NIST_KDF,
"",
""
);
in the sample code to change the params. But i was looking for a way to do this with the java code i have.
Thank you
Pushkar
</pre>
</blockquote>
</blockquote>
</body>
</html>