<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hi</p>
<p>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:</p>
<p><font face="monospace"><br>
</font></p>
<p><font face="monospace">Provider CRYPTOKI_PROVIDER =
Security.getProvider("SunPKCS11");<br>
CRYPTOKI_PROVIDER =
CRYPTOKI_PROVIDER.configure(PKCS11_CFG_LOCATION);<br>
Security.addProvider(CRYPTOKI_PROVIDER);<br>
</font></p>
<p><font face="monospace">//Generate ephemeral EC key<br>
KeyPairGenerator kpgen =
KeyPairGenerator.getInstance("ECDH", BC_FIPS_PROVIDER);<br>
kpgen.initialize(new
ECGenParameterSpec("secp256r1"), FIPS_DRBG);<br>
KeyPair keyPair = kpgen.generateKeyPair();<br>
ECPublicKey epubKey = (ECPublicKey)
keyPair.getPublic();<br>
ECPrivateKey eprivKey = (ECPrivateKey)
keyPair.getPrivate();<br>
<br>
PublicKey pubkey = null;<br>
if (keystore.containsAlias("alias")) {<br>
pubkey =
keystore.getCertificate(mapkey).getPublicKey();<br>
}<br>
<br>
if (pubkey == null) {<br>
cryptoCommon.logp(Level.WARNING, classname,
"wrapSymmetricKey", "CRYPTO-ERR-1041", mapkey);<br>
throw new InvalidKeyException(mapkey);<br>
}<br>
<br>
KeyAgreement ka =
KeyAgreement.getInstance("ECDH", CRYPTOKI_PROVIDER);<br>
ka.init(eprivKey, CRYPTOKI_RNG);<br>
ka.doPhase(pubkey, true);<br>
byte[] Z = <b>ka.generateSecret();</b></font></p>
<p><br>
</p>
<p>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.</p>
<p>I was looking at some source code and found the code below in the
file <span
style="color: rgb(31, 35, 40); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 600; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(246, 248, 250); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;">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>)</span>:</p>
<p><font face="monospace">protected byte[] engineGenerateSecret()
throws IllegalStateException {<br>
if ((privateKey == null) || (publicValue == null)) {<br>
throw new IllegalStateException("Not initialized
correctly");<br>
}<br>
Session session = null;<br>
long privKeyID = privateKey.getKeyID();<br>
try {<br>
session = token.getOpSession();<br>
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {<br>
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),<br>
new CK_ATTRIBUTE(CKA_KEY_TYPE,
CKK_GENERIC_SECRET),<br>
};<br>
CK_ECDH1_DERIVE_PARAMS ckParams =<br>
new CK_ECDH1_DERIVE_PARAMS(<b>CKD_NULL</b>,
null, publicValue);<br>
attributes = token.getAttributes<br>
(O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET,
attributes);<br>
long keyID = token.p11.C_DeriveKey(session.id(),<br>
new CK_MECHANISM(mechanism, ckParams),
privKeyID,<br>
attributes);<br>
attributes = new CK_ATTRIBUTE[] {<br>
new CK_ATTRIBUTE(CKA_VALUE)<br>
};<br>
token.p11.C_GetAttributeValue(session.id(), keyID,
attributes);<br>
byte[] secret = attributes[0].getByteArray();<br>
token.p11.C_DestroyObject(session.id(), keyID);<br>
return secret;<br>
} catch (PKCS11Exception e) {<br>
throw new ProviderException("Could not derive key",
e);<br>
} finally {<br>
privateKey.releaseKeyID();<br>
publicValue = null;<br>
token.releaseSession(session);<br>
}<br>
}</font></p>
<p><br>
</p>
<p>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. <br>
</p>
<p>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?</p>
<p>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 <br>
</p>
<p>CK_ECDH1_DERIVE_PARAMS params<br>
= new
CK_ECDH1_DERIVE_PARAMS(KDF.CKD_SHA224_NIST_KDF,<br>
"",<br>
""<br>
);</p>
<p>in the sample code to change the params. But i was looking for a
way to do this with the java code i have.</p>
<p><br>
</p>
<p>Thank you<br>
Pushkar<br>
</p>
</body>
</html>