diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KDF.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KDF.java index 83eff1d3db707..76607583b851c 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KDF.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KDF.java @@ -43,6 +43,22 @@ final class P11KDF extends KDFSpi { private final Token token; private final P11SecretKeyFactory.HKDFKeyInfo svcKi; private final long hmacMechanism; + private final SecretKey EMPTY_KEY = new SecretKey() { + @Override + public String getAlgorithm() { + return "Generic"; + } + + @Override + public String getFormat() { + return "RAW"; + } + + @Override + public byte[] getEncoded() { + return new byte[0]; + } + }; private static KDFParameters requireNull(KDFParameters kdfParameters, String message) throws InvalidAlgorithmParameterException { @@ -139,7 +155,7 @@ private T derive(String alg, AlgorithmParameterSpec derivationSpec, if (salt instanceof SecretKeySpec) { saltType = CKF_HKDF_SALT_DATA; saltBytes = salt.getEncoded(); - } else if (salt != null) { + } else if (salt != EMPTY_KEY) { // consolidateKeyMaterial returns a salt from the token. saltType = CKF_HKDF_SALT_KEY; p11SaltKey = (P11Key.P11SecretKey) salt; @@ -185,8 +201,8 @@ private T derive(String alg, AlgorithmParameterSpec derivationSpec, token.p11.C_DestroyObject(session.id(), derivedObjectID); } } else { - ret = P11Key.secretKey(session, derivedObjectID, alg, outLen, - null); + ret = P11Key.secretKey(session, derivedObjectID, alg, + outLen * 8, null); } return retType.cast(ret); } catch (PKCS11Exception e) { @@ -243,7 +259,7 @@ protected final P11Key.P11SecretKey p11Merge( long derivedKeyID = token.p11.C_DeriveKey(session.id(), ckMech, baseKeyID, attrs); return (P11Key.P11SecretKey) P11Key.secretKey(session, - derivedKeyID, "Generic", derivedKeyLen, null); + derivedKeyID, "Generic", derivedKeyLen * 8, null); } catch (PKCS11Exception e) { throw new ProviderException("Failure when merging key " + "material.", e); @@ -265,7 +281,7 @@ protected KeyMaterialMerger merge(P11Key.P11SecretKey nextKeyMaterial) { } SecretKey getKeyMaterial() { - return null; + return EMPTY_KEY; } } diff --git a/test/jdk/sun/security/pkcs11/KDF/TestHKDF.java b/test/jdk/sun/security/pkcs11/KDF/TestHKDF.java index 98879c5efb33b..11cf37d66fc50 100644 --- a/test/jdk/sun/security/pkcs11/KDF/TestHKDF.java +++ b/test/jdk/sun/security/pkcs11/KDF/TestHKDF.java @@ -132,7 +132,7 @@ private static List generateKdfParamSpecs( if (baseKey instanceof SecretKeySpec) { addKeyMaterial(keyMaterialCombination, baseKey.getEncoded(), b::addIKM, b::addIKM); - } else { + } else if (baseKey != null) { b.addIKM(baseKey); } if (ctx.salt != null) { @@ -611,6 +611,21 @@ private static void test_AES_HKDFWithHmacSHA512() { "63fc"); } + private static void test_AES_HKDFWithHmacSHA256_EmptyBaseKey() { + executeTest("AES - HKDF-SHA256 (empty base key)", + "HKDF-SHA256", + "AES", + (SecretKey) null, + "101112131415161718191a1b1c1d1e1f", + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf", + "cc267bd9515c1eba2cf6aaa1fc8380677f4351fcbea6d70873df5a334efc" + + "ee0d", + "cf353a33460b146c0eae3f0788ee281e5a0be15280fbeba107472aa1cd58" + + "d111", + "326e9028f51c05c1919215bad6e35668c94c88040c3777e8e6f8b6acdece" + + "85fa"); + } + private static void test_HKDF_after_DH_HkdfSHA256() throws Exception { SecretKey tlsPremasterSecret = getTlsPremasterSecretWithDHExchange( "00bcb8fa0a6b569961782a394599a1a02a05532a836819908a9a9000ed",