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 <pushkar.mara...@strongkey.com> napisał(a): > > 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 > (https://github.com/openjdk/jdk/blob/master/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECDHKeyAgreement.java): > > 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