Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8368073

PKCS11 HKDF can't use byte array IKM in FIPS mode

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • 25, 26
    • security-libs
    • None

      Spotted while trying to run a TLS1.3 handshake with Sun PKCS11 + NSS in FIPS mode.

      The handshake fails with the following exception:
      javax.net.ssl.SSLException: (internal_error) Unhandled exception
      at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:132)
      at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:376)
      at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:319)
      at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1209)
      at FipsModeTLS12$testTLS12SunPKCS11Communication.runDelegatedTasks(FipsModeTLS12.java:381)
      at FipsModeTLS12$testTLS12SunPKCS11Communication.run(FipsModeTLS12.java:330)
      at FipsModeTLS12.main(FipsModeTLS12.java:105)
      at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
      at java.base/java.lang.reflect.Method.invoke(Method.java:565)
      at com.sun.javatest.regtest.agent.MainWrapper$MainTask.run(MainWrapper.java:138)
      at java.base/java.lang.Thread.run(Thread.java:1474)
      Caused by: java.security.ProviderException: IKM could not be converted to a token key for HKDF derivation.
      at jdk.crypto.cryptoki/sun.security.pkcs11.P11HKDF.convertKey(P11HKDF.java:307)
      at jdk.crypto.cryptoki/sun.security.pkcs11.P11HKDF.derive(P11HKDF.java:173)
      at jdk.crypto.cryptoki/sun.security.pkcs11.P11HKDF.engineDeriveKey(P11HKDF.java:109)
      at java.base/javax.crypto.KDF.deriveKey(KDF.java:544)
      at java.base/sun.security.ssl.KAKeyDerivation.t13DeriveKey(KAKeyDerivation.java:118)
      at java.base/sun.security.ssl.KAKeyDerivation.deriveKey(KAKeyDerivation.java:65)
      at java.base/sun.security.ssl.ServerHello$T13ServerHelloProducer.produce(ServerHello.java:592)
      at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:465)
      at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1247)
      at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1183)
      at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:841)
      at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:798)
      at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:421)
      at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:477)
      at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1207)
      ... 7 more
      Caused by: java.security.InvalidKeyException: Could not create key
      at jdk.crypto.cryptoki/sun.security.pkcs11.P11SecretKeyFactory.createKey(P11SecretKeyFactory.java:672)
      at jdk.crypto.cryptoki/sun.security.pkcs11.P11SecretKeyFactory.convertKey(P11SecretKeyFactory.java:476)
      at jdk.crypto.cryptoki/sun.security.pkcs11.P11SecretKeyFactory.convertKey(P11SecretKeyFactory.java:386)
      at jdk.crypto.cryptoki/sun.security.pkcs11.P11HKDF.convertKey(P11HKDF.java:304)
      ... 21 more
      Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_ATTRIBUTE_VALUE_INVALID
      at jdk.crypto.cryptoki/sun.security.pkcs11.wrapper.PKCS11.C_CreateObject(Native Method)
      at jdk.crypto.cryptoki/sun.security.pkcs11.P11SecretKeyFactory.createKey(P11SecretKeyFactory.java:667)
      ... 24 more

      That's because the HKDF mechanism expects the IKM to be a PKCS11 object, and we try to import the IKM to a CKO_SECRET_KEY. NSS in FIPS mode disallows importing secret keys.

      The PKCS11 standard [1] offers a workable alternative:
      > The input key must be of type CKK_HKDF or CKK_GENERIC_SECRET and the length must be the size of the underlying hash function specified in prfHashMechanism. The exception is a data object which has the same size as the underlying hash function, and which may be supplied as an input key. In this case bExtract should be true and non-null salt should be supplied.


      We should load the IKM to a CKO_DATA object, and use that object in the HKDF mechanism instead.

      [1] https://docs.oasis-open.org/pkcs11/pkcs11-curr/v3.0/os/pkcs11-curr-v3.0-os.html#_Toc30061600

            djelinski Daniel Jelinski
            djelinski Daniel Jelinski
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: