<!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>