From 6ce5f1be416eddd6e8c354cf030d2af1a1a9d947 Mon Sep 17 00:00:00 2001 From: Francisco Ferrari Bihurriet Date: Sun, 8 May 2022 16:01:02 +0000 Subject: [PATCH 1/3] RH2048582: Support PKCS#12 keystores v16 Co-Authored-By: Martin Balao --- .../crypto/provider/HmacPKCS12PBECore.java | 81 +---- .../com/sun/crypto/provider/PBES2Core.java | 151 +-------- .../classes/sun/security/util/PBEUtil.java | 297 ++++++++++++++++++ .../classes/sun/security/pkcs11/P11Key.java | 4 +- .../classes/sun/security/pkcs11/P11Mac.java | 24 +- .../sun/security/pkcs11/P11PBECipher.java | 200 ++++++++++++ .../security/pkcs11/P11SecretKeyFactory.java | 129 ++++++++ .../classes/sun/security/pkcs11/P11Util.java | 100 ++++++ .../sun/security/pkcs11/SunPKCS11.java | 159 +++++++++- .../wrapper/CK_ECDH1_DERIVE_PARAMS.java | 4 +- .../security/pkcs11/wrapper/CK_MECHANISM.java | 12 + .../pkcs11/wrapper/CK_PBE_PARAMS.java | 24 +- .../pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java | 24 +- .../wrapper/CK_PKCS5_PBKD2_PARAMS2.java | 156 +++++++++ .../wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java | 4 +- .../sun/security/pkcs11/wrapper/PKCS11.java | 19 +- .../pkcs11/wrapper/PKCS11Constants.java | 34 +- .../share/native/libj2pkcs11/p11_convert.c | 108 +++++-- .../share/native/libj2pkcs11/p11_util.c | 43 ++- .../share/native/libj2pkcs11/pkcs11wrapper.h | 35 ++- .../sun/security/pkcs11/Cipher/PBECipher.java | 233 ++++++++++++++ .../pkcs11/KeyStore/ImportKeyToP12.java | 137 ++++++++ test/jdk/sun/security/pkcs11/Mac/PBAMac.java | 187 +++++++++++ .../pkcs11/SecretKeyFactory/TestPBKD.java | 296 +++++++++++++++++ 24 files changed, 2161 insertions(+), 300 deletions(-) create mode 100644 src/java.base/share/classes/sun/security/util/PBEUtil.java create mode 100644 src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PBECipher.java create mode 100644 src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS2.java create mode 100644 test/jdk/sun/security/pkcs11/Cipher/PBECipher.java create mode 100644 test/jdk/sun/security/pkcs11/KeyStore/ImportKeyToP12.java create mode 100644 test/jdk/sun/security/pkcs11/Mac/PBAMac.java create mode 100644 test/jdk/sun/security/pkcs11/SecretKeyFactory/TestPBKD.java diff --git a/src/java.base/share/classes/com/sun/crypto/provider/HmacPKCS12PBECore.java b/src/java.base/share/classes/com/sun/crypto/provider/HmacPKCS12PBECore.java index 1fd6230d83bf3..683e3dd3a8df7 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/HmacPKCS12PBECore.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/HmacPKCS12PBECore.java @@ -25,13 +25,12 @@ package com.sun.crypto.provider; -import java.util.Arrays; - import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; -import javax.crypto.spec.PBEParameterSpec; +import javax.crypto.spec.PBEKeySpec; import java.security.*; import java.security.spec.*; +import sun.security.util.PBEUtil; /** * This is an implementation of the HMAC algorithms as defined @@ -108,79 +107,15 @@ public HmacPKCS12PBECore(String algorithm, int bl) throws NoSuchAlgorithmExcepti */ protected void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { - char[] passwdChars; - byte[] salt = null; - int iCount = 0; - if (key instanceof javax.crypto.interfaces.PBEKey) { - javax.crypto.interfaces.PBEKey pbeKey = - (javax.crypto.interfaces.PBEKey) key; - passwdChars = pbeKey.getPassword(); - salt = pbeKey.getSalt(); // maybe null if unspecified - iCount = pbeKey.getIterationCount(); // maybe 0 if unspecified - } else if (key instanceof SecretKey) { - byte[] passwdBytes; - if (!(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3)) || - (passwdBytes = key.getEncoded()) == null) { - throw new InvalidKeyException("Missing password"); - } - passwdChars = new char[passwdBytes.length]; - for (int i=0; i [ 0x0061, 0x0000 ] + // / \ / \ + // Expansion => [0x0000, 0x0061, 0x0000, 0x0000] + // | | | | + // BMPString => [ 0x00, 0x61, 0x00, 0x00] + // + int inputLength = (password == null) ? 0 : password.length; + char[] expPassword = new char[inputLength * 2 + 2]; + for (int i = 0, j = 0; i < inputLength; i++, j += 2) { + expPassword[j] = (char) ((password[i] >>> 8) & 0xFF); + expPassword[j + 1] = (char) (password[i] & 0xFF); + } + password = expPassword; + } + ckMech = new CK_MECHANISM(kdfData.kdfMech, + new CK_PBE_PARAMS(password, salt, itCount)); + } + + long keyType = getKeyType(kdfData.keyAlgo); + CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[ + switch (kdfData.op) { + case ENCRYPTION, AUTHENTICATION -> 4; + case GENERIC -> 5; + }]; + attrs[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY); + attrs[1] = new CK_ATTRIBUTE(CKA_VALUE_LEN, keySize >> 3); + attrs[2] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType); + switch (kdfData.op) { + case ENCRYPTION -> attrs[3] = CK_ATTRIBUTE.ENCRYPT_TRUE; + case AUTHENTICATION -> attrs[3] = CK_ATTRIBUTE.SIGN_TRUE; + case GENERIC -> { + attrs[3] = CK_ATTRIBUTE.ENCRYPT_TRUE; + attrs[4] = CK_ATTRIBUTE.SIGN_TRUE; + } + } + CK_ATTRIBUTE[] attr = token.getAttributes( + O_GENERATE, CKO_SECRET_KEY, keyType, attrs); + long keyID = token.p11.C_GenerateKey(session.id(), ckMech, attr); + return (P11Key)P11Key.secretKey( + session, keyID, kdfData.keyAlgo, keySize, attr); + } catch (PKCS11Exception e) { + throw new InvalidKeySpecException("Could not create key", e); + } finally { + token.releaseSession(session); + } + } + + static P11Key derivePBEKey(Token token, PBEKey key, String algo) + throws InvalidKeyException { + token.ensureValid(); + if (key == null) { + throw new InvalidKeyException("PBEKey must not be null"); + } + P11Key p11Key = token.secretCache.get(key); + if (p11Key != null) { + return p11Key; + } + try { + p11Key = derivePBEKey(token, new PBEKeySpec(key.getPassword(), + key.getSalt(), key.getIterationCount()), algo); + } catch (InvalidKeySpecException e) { + throw new InvalidKeyException(e); + } + token.secretCache.put(key, p11Key); + return p11Key; + } + static void fixDESParity(byte[] key, int offset) { for (int i = 0; i < 8; i++) { int b = key[offset] & 0xfe; @@ -319,6 +442,9 @@ protected SecretKey engineGenerateSecret(KeySpec keySpec) keySpec = new SecretKeySpec(keyBytes, "DESede"); return engineGenerateSecret(keySpec); } + } else if (keySpec instanceof PBEKeySpec) { + return (SecretKey)derivePBEKey(token, + (PBEKeySpec)keySpec, algorithm); } throw new InvalidKeySpecException ("Unsupported spec: " + keySpec.getClass().getName()); @@ -372,6 +498,9 @@ protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec) // see JCE spec protected SecretKey engineTranslateKey(SecretKey key) throws InvalidKeyException { + if (key instanceof PBEKey) { + return (SecretKey)derivePBEKey(token, (PBEKey)key, algorithm); + } return (SecretKey)convertKey(token, key, algorithm); } diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java index 262cfc062adae..72b64f72c0a8f 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java @@ -27,6 +27,10 @@ import java.math.BigInteger; import java.security.*; +import java.util.HashMap; +import java.util.Map; + +import static sun.security.pkcs11.wrapper.PKCS11Constants.*; /** * Collection of static utility methods. @@ -40,10 +44,106 @@ public final class P11Util { private static volatile Provider sun, sunRsaSign, sunJce; + // Used by PBE + static final class KDFData { + public enum Operation {ENCRYPTION, AUTHENTICATION, GENERIC} + public long kdfMech; + public long prfMech; + public String keyAlgo; + public int keyLen; + public Operation op; + KDFData(long kdfMech, long prfMech, String keyAlgo, + int keyLen, Operation op) { + this.kdfMech = kdfMech; + this.prfMech = prfMech; + this.keyAlgo = keyAlgo; + this.keyLen = keyLen; + this.op = op; + } + + public static void addPbkdf2Data(String algo, long kdfMech, + long prfMech) { + kdfDataMap.put(algo, new KDFData(kdfMech, prfMech, + "Generic", -1, Operation.GENERIC)); + } + + public static void addPbkdf2AesData(String algo, long kdfMech, + long prfMech, int keyLen) { + kdfDataMap.put(algo, new KDFData(kdfMech, prfMech, + "AES", keyLen, Operation.ENCRYPTION)); + } + + public static void addPkcs12KDData(String algo, long kdfMech, + int keyLen) { + kdfDataMap.put(algo, new KDFData(kdfMech, -1, + "Generic", keyLen, Operation.AUTHENTICATION)); + } + } + + static final Map kdfDataMap = new HashMap<>(); + + static { + KDFData.addPbkdf2AesData("PBEWithHmacSHA1AndAES_128", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA1, 128); + KDFData.addPbkdf2AesData("PBEWithHmacSHA224AndAES_128", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA224, 128); + KDFData.addPbkdf2AesData("PBEWithHmacSHA256AndAES_128", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA256, 128); + KDFData.addPbkdf2AesData("PBEWithHmacSHA384AndAES_128", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA384, 128); + KDFData.addPbkdf2AesData("PBEWithHmacSHA512AndAES_128", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA512, 128); + KDFData.addPbkdf2AesData("PBEWithHmacSHA1AndAES_256", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA1, 256); + KDFData.addPbkdf2AesData("PBEWithHmacSHA224AndAES_256", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA224, 256); + KDFData.addPbkdf2AesData("PBEWithHmacSHA256AndAES_256", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA256, 256); + KDFData.addPbkdf2AesData("PBEWithHmacSHA384AndAES_256", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA384, 256); + KDFData.addPbkdf2AesData("PBEWithHmacSHA512AndAES_256", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA512, 256); + + KDFData.addPbkdf2Data("PBKDF2WithHmacSHA1", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA1); + KDFData.addPbkdf2Data("PBKDF2WithHmacSHA224", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA224); + KDFData.addPbkdf2Data("PBKDF2WithHmacSHA256", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA256); + KDFData.addPbkdf2Data("PBKDF2WithHmacSHA384", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA384); + KDFData.addPbkdf2Data("PBKDF2WithHmacSHA512", + CKM_PKCS5_PBKD2, CKP_PKCS5_PBKD2_HMAC_SHA512); + + KDFData.addPkcs12KDData("HmacPBESHA1", + CKM_PBA_SHA1_WITH_SHA1_HMAC, 160); + KDFData.addPkcs12KDData("HmacPBESHA224", + CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN, 224); + KDFData.addPkcs12KDData("HmacPBESHA256", + CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN, 256); + KDFData.addPkcs12KDData("HmacPBESHA384", + CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN, 384); + KDFData.addPkcs12KDData("HmacPBESHA512", + CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN, 512); + KDFData.addPkcs12KDData("HmacPBESHA512/224", + CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN, 512); + KDFData.addPkcs12KDData("HmacPBESHA512/256", + CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN, 512); + } + private P11Util() { // empty } + static boolean isNSS(Token token) { + char[] tokenLabel = token.tokenInfo.label; + if (tokenLabel != null && tokenLabel.length >= 3) { + return (tokenLabel[0] == 'N' && tokenLabel[1] == 'S' + && tokenLabel[2] == 'S'); + } + return false; + } + static Provider getSunProvider() { Provider p = sun; if (p == null) { diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java index 5549cd9ed4e71..5d371aab5ef8c 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -388,7 +388,7 @@ private static T checkNull(T obj) { } p11 = tmpPKCS11; - CK_INFO p11Info = p11.C_GetInfo(); + CK_INFO p11Info = p11.getInfo(); if (p11Info.cryptokiVersion.major < 2) { throw new ProviderException("Only PKCS#11 v2.0 and later " + "supported, library version is v" + p11Info.cryptokiVersion); @@ -480,14 +480,19 @@ private static final class Descriptor { final String className; final List aliases; final int[] mechanisms; + final int[] requiredMechs; + // mechanisms is a list of possible mechanisms that implement the + // algorithm, at least one of them must be available. requiredMechs + // is a list of auxiliary mechanisms, all of them must be available private Descriptor(String type, String algorithm, String className, - List aliases, int[] mechanisms) { + List aliases, int[] mechanisms, int[] requiredMechs) { this.type = type; this.algorithm = algorithm; this.className = className; this.aliases = aliases; this.mechanisms = mechanisms; + this.requiredMechs = requiredMechs; } private P11Service service(Token token, int mechanism) { return new P11Service @@ -521,18 +526,29 @@ private static int[] m(long m1, long m2, long m3, long m4) { private static void d(String type, String algorithm, String className, int[] m) { - register(new Descriptor(type, algorithm, className, null, m)); + register(new Descriptor(type, algorithm, className, null, m, null)); } private static void d(String type, String algorithm, String className, List aliases, int[] m) { - register(new Descriptor(type, algorithm, className, aliases, m)); + register(new Descriptor(type, algorithm, className, aliases, m, null)); + } + + private static void d(String type, String algorithm, String className, + int[] m, int[] requiredMechs) { + register(new Descriptor(type, algorithm, className, null, m, + requiredMechs)); + } + private static void dA(String type, String algorithm, String className, + int[] m, int[] requiredMechs) { + register(new Descriptor(type, algorithm, className, + getAliases(algorithm), m, requiredMechs)); } private static void dA(String type, String algorithm, String className, int[] m) { register(new Descriptor(type, algorithm, className, - getAliases(algorithm), m)); + getAliases(algorithm), m, null)); } private static void register(Descriptor d) { @@ -588,6 +604,7 @@ private static void register(Descriptor d) { String P11Cipher = "sun.security.pkcs11.P11Cipher"; String P11RSACipher = "sun.security.pkcs11.P11RSACipher"; String P11AEADCipher = "sun.security.pkcs11.P11AEADCipher"; + String P11PBECipher = "sun.security.pkcs11.P11PBECipher"; String P11Signature = "sun.security.pkcs11.P11Signature"; String P11PSSSignature = "sun.security.pkcs11.P11PSSSignature"; @@ -650,6 +667,28 @@ private static void register(Descriptor d) { d(MAC, "SslMacSHA1", P11Mac, m(CKM_SSL3_SHA1_MAC)); + /* + * PBA HMacs + * + * KeyDerivationMech must be supported + * for these services to be available. + * + */ + d(MAC, "HmacPBESHA1", P11Mac, m(CKM_SHA_1_HMAC), + m(CKM_PBA_SHA1_WITH_SHA1_HMAC)); + d(MAC, "HmacPBESHA224", P11Mac, m(CKM_SHA224_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN)); + d(MAC, "HmacPBESHA256", P11Mac, m(CKM_SHA256_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN)); + d(MAC, "HmacPBESHA384", P11Mac, m(CKM_SHA384_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN)); + d(MAC, "HmacPBESHA512", P11Mac, m(CKM_SHA512_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + d(MAC, "HmacPBESHA512/224", P11Mac, m(CKM_SHA512_224_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + d(MAC, "HmacPBESHA512/256", P11Mac, m(CKM_SHA512_256_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + d(KPG, "RSA", P11KeyPairGenerator, getAliases("PKCS1"), m(CKM_RSA_PKCS_KEY_PAIR_GEN)); @@ -748,6 +787,64 @@ private static void register(Descriptor d) { d(SKF, "ChaCha20", P11SecretKeyFactory, m(CKM_CHACHA20_POLY1305)); + /* + * PBE Secret Key Factories + * + * KeyDerivationPrf must be supported for these services + * to be available. + * + */ + d(SKF, "PBEWithHmacSHA1AndAES_128", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); + d(SKF, "PBEWithHmacSHA224AndAES_128", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); + d(SKF, "PBEWithHmacSHA256AndAES_128", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); + d(SKF, "PBEWithHmacSHA384AndAES_128", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); + d(SKF, "PBEWithHmacSHA512AndAES_128", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); + d(SKF, "PBEWithHmacSHA1AndAES_256", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); + d(SKF, "PBEWithHmacSHA224AndAES_256", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); + d(SKF, "PBEWithHmacSHA256AndAES_256", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); + d(SKF, "PBEWithHmacSHA384AndAES_256", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); + d(SKF, "PBEWithHmacSHA512AndAES_256", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); + /* + * PBA Secret Key Factories + */ + d(SKF, "HmacPBESHA1", P11SecretKeyFactory, + m(CKM_PBA_SHA1_WITH_SHA1_HMAC)); + d(SKF, "HmacPBESHA224", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN)); + d(SKF, "HmacPBESHA256", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN)); + d(SKF, "HmacPBESHA384", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN)); + d(SKF, "HmacPBESHA512", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + d(SKF, "HmacPBESHA512/224", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + d(SKF, "HmacPBESHA512/256", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + /* + * PBKDF2 Secret Key Factories + */ + dA(SKF, "PBKDF2WithHmacSHA1", P11SecretKeyFactory, + m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); + d(SKF, "PBKDF2WithHmacSHA224", P11SecretKeyFactory, + m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); + d(SKF, "PBKDF2WithHmacSHA256", P11SecretKeyFactory, + m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); + d(SKF, "PBKDF2WithHmacSHA384", P11SecretKeyFactory, + m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); + d(SKF, "PBKDF2WithHmacSHA512", P11SecretKeyFactory, + m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); + // XXX attributes for Ciphers (supported modes, padding) dA(CIP, "ARCFOUR", P11Cipher, m(CKM_RC4)); @@ -817,6 +914,44 @@ private static void register(Descriptor d) { d(CIP, "RSA/ECB/NoPadding", P11RSACipher, m(CKM_RSA_X_509)); + /* + * PBE Ciphers + * + * KeyDerivationMech and KeyDerivationPrf must be supported + * for these services to be available. + * + */ + d(CIP, "PBEWithHmacSHA1AndAES_128", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA_1_HMAC)); + d(CIP, "PBEWithHmacSHA224AndAES_128", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA224_HMAC)); + d(CIP, "PBEWithHmacSHA256AndAES_128", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA256_HMAC)); + d(CIP, "PBEWithHmacSHA384AndAES_128", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA384_HMAC)); + d(CIP, "PBEWithHmacSHA512AndAES_128", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA512_HMAC)); + d(CIP, "PBEWithHmacSHA1AndAES_256", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA_1_HMAC)); + d(CIP, "PBEWithHmacSHA224AndAES_256", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA224_HMAC)); + d(CIP, "PBEWithHmacSHA256AndAES_256", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA256_HMAC)); + d(CIP, "PBEWithHmacSHA384AndAES_256", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA384_HMAC)); + d(CIP, "PBEWithHmacSHA512AndAES_256", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA512_HMAC)); + d(SIG, "RawDSA", P11Signature, List.of("NONEwithDSA"), m(CKM_DSA)); @@ -1207,9 +1342,21 @@ private void initToken(CK_SLOT_INFO slotInfo) throws PKCS11Exception { if (ds == null) { continue; } + descLoop: for (Descriptor d : ds) { Integer oldMech = supportedAlgs.get(d); if (oldMech == null) { + if (d.requiredMechs != null) { + // Check that other mechanisms required for the + // service are supported before listing it as + // available for the first time. + for (int requiredMech : d.requiredMechs) { + if (token.getMechanismInfo( + requiredMech & 0xFFFFFFFFL) == null) { + continue descLoop; + } + } + } supportedAlgs.put(d, integerMech); continue; } @@ -1307,6 +1454,8 @@ public Object newInstance0(Object param) throws } else if (algorithm.endsWith("GCM/NoPadding") || algorithm.startsWith("ChaCha20-Poly1305")) { return new P11AEADCipher(token, algorithm, mechanism); + } else if (algorithm.startsWith("PBE")) { + return new P11PBECipher(token, algorithm, mechanism); } else { return new P11Cipher(token, algorithm, mechanism); } diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java index 88ff8a71fc300..47a2f97eddf20 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java @@ -100,9 +100,9 @@ public CK_ECDH1_DERIVE_PARAMS(long kdf, byte[] pSharedData, byte[] pPublicData) } /** - * Returns the string representation of CK_PKCS5_PBKD2_PARAMS. + * Returns the string representation of CK_ECDH1_DERIVE_PARAMS. * - * @return the string representation of CK_PKCS5_PBKD2_PARAMS + * @return the string representation of CK_ECDH1_DERIVE_PARAMS */ public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java index 0c9ebb289c159..b4b2448464d00 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java @@ -160,6 +160,18 @@ public CK_MECHANISM(long mechanism, init(mechanism, params); } + public CK_MECHANISM(long mechanism, CK_PBE_PARAMS params) { + init(mechanism, params); + } + + public CK_MECHANISM(long mechanism, CK_PKCS5_PBKD2_PARAMS params) { + init(mechanism, params); + } + + public CK_MECHANISM(long mechanism, CK_PKCS5_PBKD2_PARAMS2 params) { + init(mechanism, params); + } + // For PSS. the parameter may be set multiple times, use the // CK_MECHANISM(long) constructor and setParameter(CK_RSA_PKCS_PSS_PARAMS) // methods instead of creating yet another constructor diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java index e8b048869c4b3..a25fa1c39e5b7 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java @@ -50,15 +50,15 @@ /** - * class CK_PBE_PARAMS provides all of the necessary information required byte + * class CK_PBE_PARAMS provides all the necessary information required by * the CKM_PBE mechanisms and the CKM_PBA_SHA1_WITH_SHA1_HMAC mechanism.

* PKCS#11 structure: *

  * typedef struct CK_PBE_PARAMS {
- *   CK_CHAR_PTR pInitVector;
- *   CK_CHAR_PTR pPassword;
+ *   CK_BYTE_PTR pInitVector;
+ *   CK_UTF8CHAR_PTR pPassword;
  *   CK_ULONG ulPasswordLen;
- *   CK_CHAR_PTR pSalt;
+ *   CK_BYTE_PTR pSalt;
  *   CK_ULONG ulSaltLen;
  *   CK_ULONG ulIteration;
  * } CK_PBE_PARAMS;
@@ -72,15 +72,15 @@ public class CK_PBE_PARAMS {
     /**
      * PKCS#11:
      * 
-     *   CK_CHAR_PTR pInitVector;
+     *   CK_BYTE_PTR pInitVector;
      * 
*/ - public char[] pInitVector; + public byte[] pInitVector; /** * PKCS#11: *
-     *   CK_CHAR_PTR pPassword;
+     *   CK_UTF8CHAR_PTR pPassword;
      *   CK_ULONG ulPasswordLen;
      * 
*/ @@ -89,11 +89,11 @@ public class CK_PBE_PARAMS { /** * PKCS#11: *
-     *   CK_CHAR_PTR pSalt
+     *   CK_BYTE_PTR pSalt
      *   CK_ULONG ulSaltLen;
      * 
*/ - public char[] pSalt; + public byte[] pSalt; /** * PKCS#11: @@ -103,6 +103,12 @@ public class CK_PBE_PARAMS { */ public long ulIteration; + public CK_PBE_PARAMS(char[] pPassword, byte[] pSalt, long ulIteration) { + this.pPassword = pPassword; + this.pSalt = pSalt; + this.ulIteration = ulIteration; + } + /** * Returns the string representation of CK_PBE_PARAMS. * diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java index fb90bfced27ff..a01beb0753a23 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java @@ -47,7 +47,7 @@ package sun.security.pkcs11.wrapper; - +import static sun.security.pkcs11.wrapper.PKCS11Constants.*; /** * class CK_PKCS5_PBKD2_PARAMS provides the parameters to the CKM_PKCS5_PBKD2 @@ -55,13 +55,15 @@ * PKCS#11 structure: *
  * typedef struct CK_PKCS5_PBKD2_PARAMS {
- *   CK_PKCS5_PBKD2_SALT_SOURCE_TYPE saltSource;
+ *   CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
  *   CK_VOID_PTR pSaltSourceData;
  *   CK_ULONG ulSaltSourceDataLen;
  *   CK_ULONG iterations;
  *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
  *   CK_VOID_PTR pPrfData;
  *   CK_ULONG ulPrfDataLen;
+ *   CK_UTF8CHAR_PTR pPassword;
+ *   CK_ULONG_PTR ulPasswordLen;
  * } CK_PKCS5_PBKD2_PARAMS;
  * 
* @@ -112,6 +114,24 @@ public class CK_PKCS5_PBKD2_PARAMS { */ public byte[] pPrfData; + /** + * PKCS#11: + *
+     *   CK_UTF8CHAR_PTR pPassword
+     *   CK_ULONG_PTR ulPasswordLen;
+     * 
+ */ + public char[] pPassword; + + public CK_PKCS5_PBKD2_PARAMS(char[] pPassword, byte[] pSalt, + long iterations, long prf) { + this.pPassword = pPassword; + this.pSaltSourceData = pSalt; + this.iterations = iterations; + this.prf = prf; + this.saltSource = CKZ_SALT_SPECIFIED; + } + /** * Returns the string representation of CK_PKCS5_PBKD2_PARAMS. * diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS2.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS2.java new file mode 100644 index 0000000000000..935db6566390c --- /dev/null +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS2.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.pkcs11.wrapper; + +import static sun.security.pkcs11.wrapper.PKCS11Constants.*; + +/** + * class CK_PKCS5_PBKD2_PARAMS2 provides the parameters to the CKM_PKCS5_PBKD2 + * mechanism.

+ * PKCS#11 structure: + *

+ * typedef struct CK_PKCS5_PBKD2_PARAMS2 {
+ *   CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+ *   CK_VOID_PTR pSaltSourceData;
+ *   CK_ULONG ulSaltSourceDataLen;
+ *   CK_ULONG iterations;
+ *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ *   CK_VOID_PTR pPrfData;
+ *   CK_ULONG ulPrfDataLen;
+ *   CK_UTF8CHAR_PTR pPassword;
+ *   CK_ULONG ulPasswordLen;
+ * } CK_PKCS5_PBKD2_PARAMS2;
+ * 
+ * + */ +public class CK_PKCS5_PBKD2_PARAMS2 { + + /** + * PKCS#11: + *
+     *   CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+     * 
+ */ + public long saltSource; + + /** + * PKCS#11: + *
+     *   CK_VOID_PTR pSaltSourceData;
+     *   CK_ULONG ulSaltSourceDataLen;
+     * 
+ */ + public byte[] pSaltSourceData; + + /** + * PKCS#11: + *
+     *   CK_ULONG iterations;
+     * 
+ */ + public long iterations; + + /** + * PKCS#11: + *
+     *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+     * 
+ */ + public long prf; + + /** + * PKCS#11: + *
+     *   CK_VOID_PTR pPrfData;
+     *   CK_ULONG ulPrfDataLen;
+     * 
+ */ + public byte[] pPrfData; + + /** + * PKCS#11: + *
+     *   CK_UTF8CHAR_PTR pPassword
+     *   CK_ULONG ulPasswordLen;
+     * 
+ */ + public char[] pPassword; + + public CK_PKCS5_PBKD2_PARAMS2(char[] pPassword, byte[] pSalt, + long iterations, long prf) { + this.pPassword = pPassword; + this.pSaltSourceData = pSalt; + this.iterations = iterations; + this.prf = prf; + this.saltSource = CKZ_SALT_SPECIFIED; + } + + /** + * Returns the string representation of CK_PKCS5_PBKD2_PARAMS2. + * + * @return the string representation of CK_PKCS5_PBKD2_PARAMS2 + */ + public String toString() { + StringBuilder sb = new StringBuilder(); + + sb.append(Constants.INDENT); + sb.append("saltSource: "); + sb.append(saltSource); + sb.append(Constants.NEWLINE); + + sb.append(Constants.INDENT); + sb.append("pSaltSourceData: "); + sb.append(Functions.toHexString(pSaltSourceData)); + sb.append(Constants.NEWLINE); + + sb.append(Constants.INDENT); + sb.append("ulSaltSourceDataLen: "); + sb.append(pSaltSourceData.length); + sb.append(Constants.NEWLINE); + + sb.append(Constants.INDENT); + sb.append("iterations: "); + sb.append(iterations); + sb.append(Constants.NEWLINE); + + sb.append(Constants.INDENT); + sb.append("prf: "); + sb.append(prf); + sb.append(Constants.NEWLINE); + + sb.append(Constants.INDENT); + sb.append("pPrfData: "); + sb.append(Functions.toHexString(pPrfData)); + sb.append(Constants.NEWLINE); + + sb.append(Constants.INDENT); + sb.append("ulPrfDataLen: "); + sb.append(pPrfData.length); + + return sb.toString(); + } + +} diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java index 1f9c4d39f5797..5e3c1b9d29f87 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java @@ -94,9 +94,9 @@ public class CK_X9_42_DH1_DERIVE_PARAMS { public byte[] pPublicData; /** - * Returns the string representation of CK_PKCS5_PBKD2_PARAMS. + * Returns the string representation of CK_X9_42_DH1_DERIVE_PARAMS. * - * @return the string representation of CK_PKCS5_PBKD2_PARAMS + * @return the string representation of CK_X9_42_DH1_DERIVE_PARAMS */ public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java index 1e98ce2e280b4..5fbf8addcba66 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java @@ -116,6 +116,8 @@ public static void loadNative() { private long pNativeData; + private CK_INFO pInfo; + /** * This method does the initialization of the native library. It is called * exactly once for this class. @@ -148,9 +150,10 @@ public static void loadNative() { * @postconditions */ PKCS11(String pkcs11ModulePath, String functionListName) - throws IOException { + throws IOException, PKCS11Exception { connect(pkcs11ModulePath, functionListName); this.pkcs11ModulePath = pkcs11ModulePath; + pInfo = C_GetInfo(); } /* @@ -207,6 +210,14 @@ public static synchronized PKCS11 getInstance(String pkcs11ModulePath, return pkcs11; } + /** + * Returns the CK_INFO structure fetched at initialization with + * C_GetInfo. This structure represent Cryptoki library information. + */ + public CK_INFO getInfo() { + return pInfo; + } + /** * Connects this object to the specified PKCS#11 library. This method is for * internal use only. @@ -1653,7 +1664,7 @@ protected void finalize() throws Throwable { static class SynchronizedPKCS11 extends PKCS11 { SynchronizedPKCS11(String pkcs11ModulePath, String functionListName) - throws IOException { + throws IOException, PKCS11Exception { super(pkcs11ModulePath, functionListName); } @@ -1949,7 +1960,7 @@ static class FIPSPKCS11 extends PKCS11 { private MethodHandle hC_GetAttributeValue; FIPSPKCS11(String pkcs11ModulePath, String functionListName, MethodHandle fipsKeyImporter, MethodHandle fipsKeyExporter) - throws IOException { + throws IOException, PKCS11Exception { super(pkcs11ModulePath, functionListName); this.fipsKeyImporter = fipsKeyImporter; this.fipsKeyExporter = fipsKeyExporter; @@ -2001,7 +2012,7 @@ static class SynchronizedFIPSPKCS11 extends SynchronizedPKCS11 { private MethodHandle hC_GetAttributeValue; SynchronizedFIPSPKCS11(String pkcs11ModulePath, String functionListName, MethodHandle fipsKeyImporter, MethodHandle fipsKeyExporter) - throws IOException { + throws IOException, PKCS11Exception { super(pkcs11ModulePath, functionListName); this.fipsKeyImporter = fipsKeyImporter; this.fipsKeyExporter = fipsKeyExporter; diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java index d22844cfba836..9e02958b4b062 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java @@ -1104,17 +1104,6 @@ public interface PKCS11Constants { public static final long CKD_BLAKE2B_384_KDF = 0x00000019L; public static final long CKD_BLAKE2B_512_KDF = 0x0000001aL; - public static final long CKP_PKCS5_PBKD2_HMAC_SHA1 = 0x00000001L; - public static final long CKP_PKCS5_PBKD2_HMAC_GOSTR3411 = 0x00000002L; - public static final long CKP_PKCS5_PBKD2_HMAC_SHA224 = 0x00000003L; - public static final long CKP_PKCS5_PBKD2_HMAC_SHA256 = 0x00000004L; - public static final long CKP_PKCS5_PBKD2_HMAC_SHA384 = 0x00000005L; - public static final long CKP_PKCS5_PBKD2_HMAC_SHA512 = 0x00000006L; - public static final long CKP_PKCS5_PBKD2_HMAC_SHA512_224 = 0x00000007L; - public static final long CKP_PKCS5_PBKD2_HMAC_SHA512_256 = 0x00000008L; - - public static final long CKZ_SALT_SPECIFIED = 0x00000001L; - public static final long CK_OTP_VALUE = 0x00000000L; public static final long CK_OTP_PIN = 0x00000001L; public static final long CK_OTP_CHALLENGE = 0x00000002L; @@ -1150,12 +1139,23 @@ public interface PKCS11Constants { public static final long CKF_HKDF_SALT_KEY = 0x00000004L; */ + // PBKDF2 support, used in P11Util + public static final long CKZ_SALT_SPECIFIED = 0x00000001L; + public static final long CKP_PKCS5_PBKD2_HMAC_SHA1 = 0x00000001L; + public static final long CKP_PKCS5_PBKD2_HMAC_GOSTR3411 = 0x00000002L; + public static final long CKP_PKCS5_PBKD2_HMAC_SHA224 = 0x00000003L; + public static final long CKP_PKCS5_PBKD2_HMAC_SHA256 = 0x00000004L; + public static final long CKP_PKCS5_PBKD2_HMAC_SHA384 = 0x00000005L; + public static final long CKP_PKCS5_PBKD2_HMAC_SHA512 = 0x00000006L; + public static final long CKP_PKCS5_PBKD2_HMAC_SHA512_224 = 0x00000007L; + public static final long CKP_PKCS5_PBKD2_HMAC_SHA512_256 = 0x00000008L; + // private NSS attribute (for DSA and DH private keys) public static final long CKA_NETSCAPE_DB = 0xD5A0DB00L; // base number of NSS private attributes public static final long CKA_NETSCAPE_BASE /*0x80000000L + 0x4E534350L*/ - = 0xCE534350L; + /* now known as CKM_NSS ^ */ = 0xCE534350L; // object type for NSS trust public static final long CKO_NETSCAPE_TRUST = 0xCE534353L; @@ -1180,4 +1180,14 @@ public interface PKCS11Constants { = 0xCE534355L; public static final long CKT_NETSCAPE_VALID = 0xCE53435AL; public static final long CKT_NETSCAPE_VALID_DELEGATOR = 0xCE53435BL; + + // Additional PKCS #12 PBE key derivation algorithms defined in NSS v3.29 + public static final long CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN + /* (CKM_NSS + 29) */ = 0xCE53436DL; + public static final long CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN + /* (CKM_NSS + 30) */ = 0xCE53436EL; + public static final long CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN + /* (CKM_NSS + 31) */ = 0xCE53436FL; + public static final long CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN + /* (CKM_NSS + 32) */ = 0xCE534370L; } diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c index 666c5eb9b3b33..5523dafcdb4f8 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c @@ -1515,6 +1515,10 @@ CK_VOID_PTR jMechParamToCKMechParamPtrSlow(JNIEnv *env, jobject jParam, case CKM_PBE_SHA1_DES3_EDE_CBC: case CKM_PBE_SHA1_DES2_EDE_CBC: case CKM_PBA_SHA1_WITH_SHA1_HMAC: + case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN: ckpParamPtr = jPbeParamToCKPbeParamPtr(env, jParam, ckpLength); break; case CKM_PKCS5_PBKD2: @@ -1658,13 +1662,13 @@ jPbeParamToCKPbeParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) // retrieve java values jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS); if (jPbeParamsClass == NULL) { return NULL; } - fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pInitVector", "[C"); + fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pInitVector", "[B"); if (fieldID == NULL) { return NULL; } jInitVector = (*env)->GetObjectField(env, jParam, fieldID); fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pPassword", "[C"); if (fieldID == NULL) { return NULL; } jPassword = (*env)->GetObjectField(env, jParam, fieldID); - fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pSalt", "[C"); + fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pSalt", "[B"); if (fieldID == NULL) { return NULL; } jSalt = (*env)->GetObjectField(env, jParam, fieldID); fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "ulIteration", "J"); @@ -1680,15 +1684,15 @@ jPbeParamToCKPbeParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) // populate using java values ckParamPtr->ulIteration = jLongToCKULong(jIteration); - jCharArrayToCKCharArray(env, jInitVector, &(ckParamPtr->pInitVector), &ckTemp); + jByteArrayToCKByteArray(env, jInitVector, &(ckParamPtr->pInitVector), &ckTemp); if ((*env)->ExceptionCheck(env)) { goto cleanup; } - jCharArrayToCKCharArray(env, jPassword, &(ckParamPtr->pPassword), &(ckParamPtr->ulPasswordLen)); + jCharArrayToCKUTF8CharArray(env, jPassword, &(ckParamPtr->pPassword), &(ckParamPtr->ulPasswordLen)); if ((*env)->ExceptionCheck(env)) { goto cleanup; } - jCharArrayToCKCharArray(env, jSalt, &(ckParamPtr->pSalt), &(ckParamPtr->ulSaltLen)); + jByteArrayToCKByteArray(env, jSalt, &(ckParamPtr->pSalt), &(ckParamPtr->ulSaltLen)); if ((*env)->ExceptionCheck(env)) { goto cleanup; } @@ -1767,31 +1771,59 @@ void copyBackPBEInitializationVector(JNIEnv *env, CK_MECHANISM *ckMechanism, job } } +#define PBKD2_PARAM_SET(member, value) \ + do { \ + if(ckParamPtr->version == PARAMS) { \ + ckParamPtr->params.v1.member = value; \ + } else { \ + ckParamPtr->params.v2.member = value; \ + } \ + } while(0) + +#define PBKD2_PARAM_ADDR(member) \ + ( \ + (ckParamPtr->version == PARAMS) ? \ + (void*) &ckParamPtr->params.v1.member : \ + (void*) &ckParamPtr->params.v2.member \ + ) + /* - * converts the Java CK_PKCS5_PBKD2_PARAMS object to a CK_PKCS5_PBKD2_PARAMS + * converts a Java CK_PKCS5_PBKD2_PARAMS object to a CK_PKCS5_PBKD2_PARAMS + * pointer, or a Java CK_PKCS5_PBKD2_PARAMS2 object to a CK_PKCS5_PBKD2_PARAMS2 * pointer * - * @param env - used to call JNI funktions to get the Java classes and objects - * @param jParam - the Java CK_PKCS5_PBKD2_PARAMS object to convert + * @param env - used to call JNI functions to get the Java classes and objects + * @param jParam - the Java object to convert * @param pLength - length of the allocated memory of the returned pointer - * @return pointer to the new CK_PKCS5_PBKD2_PARAMS structure + * @return pointer to the new structure */ -CK_PKCS5_PBKD2_PARAMS_PTR +CK_VOID_PTR jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength) { - CK_PKCS5_PBKD2_PARAMS_PTR ckParamPtr; + VersionedPbkd2ParamsPtr ckParamPtr; + ParamVersion paramVersion; + CK_ULONG_PTR pUlPasswordLen; jclass jPkcs5Pbkd2ParamsClass; jfieldID fieldID; jlong jSaltSource, jIteration, jPrf; - jobject jSaltSourceData, jPrfData; + jobject jSaltSourceData, jPrfData, jPassword; if (pLength != NULL) { *pLength = 0L; } // retrieve java values - jPkcs5Pbkd2ParamsClass = (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS); - if (jPkcs5Pbkd2ParamsClass == NULL) { return NULL; } + if ((jPkcs5Pbkd2ParamsClass = + (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS)) != NULL + && (*env)->IsInstanceOf(env, jParam, jPkcs5Pbkd2ParamsClass)) { + paramVersion = PARAMS; + } else if ((jPkcs5Pbkd2ParamsClass = + (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS2)) != NULL + && (*env)->IsInstanceOf(env, jParam, jPkcs5Pbkd2ParamsClass)) { + paramVersion = PARAMS2; + } else { + return NULL; + } fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "saltSource", "J"); if (fieldID == NULL) { return NULL; } jSaltSource = (*env)->GetLongField(env, jParam, fieldID); @@ -1807,36 +1839,60 @@ jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pL fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pPrfData", "[B"); if (fieldID == NULL) { return NULL; } jPrfData = (*env)->GetObjectField(env, jParam, fieldID); + fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pPassword", "[C"); + if (fieldID == NULL) { return NULL; } + jPassword = (*env)->GetObjectField(env, jParam, fieldID); - // allocate memory for CK_PKCS5_PBKD2_PARAMS pointer - ckParamPtr = calloc(1, sizeof(CK_PKCS5_PBKD2_PARAMS)); + // allocate memory for VersionedPbkd2Params and store the structure version + ckParamPtr = calloc(1, sizeof(VersionedPbkd2Params)); if (ckParamPtr == NULL) { throwOutOfMemoryError(env, 0); return NULL; } + ckParamPtr->version = paramVersion; // populate using java values - ckParamPtr->saltSource = jLongToCKULong(jSaltSource); - jByteArrayToCKByteArray(env, jSaltSourceData, (CK_BYTE_PTR *) - &(ckParamPtr->pSaltSourceData), &(ckParamPtr->ulSaltSourceDataLen)); + PBKD2_PARAM_SET(saltSource, jLongToCKULong(jSaltSource)); + jByteArrayToCKByteArray(env, jSaltSourceData, + (CK_BYTE_PTR *) PBKD2_PARAM_ADDR(pSaltSourceData), + PBKD2_PARAM_ADDR(ulSaltSourceDataLen)); if ((*env)->ExceptionCheck(env)) { goto cleanup; } - ckParamPtr->iterations = jLongToCKULong(jIteration); - ckParamPtr->prf = jLongToCKULong(jPrf); - jByteArrayToCKByteArray(env, jPrfData, (CK_BYTE_PTR *) - &(ckParamPtr->pPrfData), &(ckParamPtr->ulPrfDataLen)); + PBKD2_PARAM_SET(iterations, jLongToCKULong(jIteration)); + PBKD2_PARAM_SET(prf, jLongToCKULong(jPrf)); + jByteArrayToCKByteArray(env, jPrfData, + (CK_BYTE_PTR *) PBKD2_PARAM_ADDR(pPrfData), + PBKD2_PARAM_ADDR(ulPrfDataLen)); + if ((*env)->ExceptionCheck(env)) { + goto cleanup; + } + if (ckParamPtr->version == PARAMS) { + pUlPasswordLen = calloc(1, sizeof(CK_ULONG)); + if (pUlPasswordLen == NULL) { + throwOutOfMemoryError(env, 0); + goto cleanup; + } + ckParamPtr->params.v1.ulPasswordLen = pUlPasswordLen; + } else { + pUlPasswordLen = &ckParamPtr->params.v2.ulPasswordLen; + } + jCharArrayToCKUTF8CharArray(env, jPassword, + (CK_CHAR_PTR *) PBKD2_PARAM_ADDR(pPassword), + pUlPasswordLen); if ((*env)->ExceptionCheck(env)) { goto cleanup; } if (pLength != NULL) { - *pLength = sizeof(CK_PKCS5_PBKD2_PARAMS); + *pLength = (ckParamPtr->version == PARAMS ? + sizeof(ckParamPtr->params.v1) : + sizeof(ckParamPtr->params.v2)); } + // VersionedPbkd2ParamsPtr is equivalent to CK_PKCS5_PBKD2_PARAMS[2]_PTR return ckParamPtr; cleanup: - free(ckParamPtr->pSaltSourceData); - free(ckParamPtr->pPrfData); + FREE_VERSIONED_PBKD2_MEMBERS(ckParamPtr); free(ckParamPtr); return NULL; diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c index 520bd52a2cd6c..aa76945283d74 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c @@ -410,11 +410,27 @@ void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) { case CKM_CAMELLIA_CTR: // params do not contain pointers break; + case CKM_PKCS5_PBKD2: + // get the versioned structure from behind memory + TRACE0(((VersionedPbkd2ParamsPtr)tmp)->version == PARAMS ? + "[ CK_PKCS5_PBKD2_PARAMS ]\n" : + "[ CK_PKCS5_PBKD2_PARAMS2 ]\n"); + FREE_VERSIONED_PBKD2_MEMBERS((VersionedPbkd2ParamsPtr)tmp); + break; + case CKM_PBA_SHA1_WITH_SHA1_HMAC: + case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN: + free(((CK_PBE_PARAMS_PTR)tmp)->pInitVector); + free(((CK_PBE_PARAMS_PTR)tmp)->pPassword); + free(((CK_PBE_PARAMS_PTR)tmp)->pSalt); + break; default: // currently unsupported mechs by SunPKCS11 provider // CKM_RSA_PKCS_OAEP, CKM_ECMQV_DERIVE, // CKM_X9_42_*, CKM_KEA_DERIVE, CKM_RC2_*, CKM_RC5_*, - // CKM_SKIPJACK_*, CKM_KEY_WRAP_SET_OAEP, CKM_PKCS5_PBKD2, + // CKM_SKIPJACK_*, CKM_KEY_WRAP_SET_OAEP, // PBE mechs, WTLS mechs, CMS mechs, // CKM_EXTRACT_KEY_FROM_KEY, CKM_OTP, CKM_KIP, // CKM_DSA_PARAMETER_GEN?, CKM_GOSTR3410_* @@ -517,12 +533,11 @@ void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBO jboolean* jpTemp; CK_ULONG i; - if(jArray == NULL) { + *ckpLength = jArray == NULL ? 0L : (*env)->GetArrayLength(env, jArray); + if(*ckpLength == 0L) { *ckpArray = NULL_PTR; - *ckpLength = 0L; return; } - *ckpLength = (*env)->GetArrayLength(env, jArray); jpTemp = (jboolean*) calloc(*ckpLength, sizeof(jboolean)); if (jpTemp == NULL) { throwOutOfMemoryError(env, 0); @@ -559,12 +574,11 @@ void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR * jbyte* jpTemp; CK_ULONG i; - if(jArray == NULL) { + *ckpLength = jArray == NULL ? 0L : (*env)->GetArrayLength(env, jArray); + if(*ckpLength == 0L) { *ckpArray = NULL_PTR; - *ckpLength = 0L; return; } - *ckpLength = (*env)->GetArrayLength(env, jArray); jpTemp = (jbyte*) calloc(*ckpLength, sizeof(jbyte)); if (jpTemp == NULL) { throwOutOfMemoryError(env, 0); @@ -606,12 +620,11 @@ void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR jlong* jTemp; CK_ULONG i; - if(jArray == NULL) { + *ckpLength = jArray == NULL ? 0L : (*env)->GetArrayLength(env, jArray); + if(*ckpLength == 0L) { *ckpArray = NULL_PTR; - *ckpLength = 0L; return; } - *ckpLength = (*env)->GetArrayLength(env, jArray); jTemp = (jlong*) calloc(*ckpLength, sizeof(jlong)); if (jTemp == NULL) { throwOutOfMemoryError(env, 0); @@ -648,12 +661,11 @@ void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR * jchar* jpTemp; CK_ULONG i; - if(jArray == NULL) { + *ckpLength = jArray == NULL ? 0L : (*env)->GetArrayLength(env, jArray); + if(*ckpLength == 0L) { *ckpArray = NULL_PTR; - *ckpLength = 0L; return; } - *ckpLength = (*env)->GetArrayLength(env, jArray); jpTemp = (jchar*) calloc(*ckpLength, sizeof(jchar)); if (jpTemp == NULL) { throwOutOfMemoryError(env, 0); @@ -690,12 +702,11 @@ void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CH jchar* jTemp; CK_ULONG i; - if(jArray == NULL) { + *ckpLength = jArray == NULL ? 0L : (*env)->GetArrayLength(env, jArray); + if(*ckpLength == 0L) { *ckpArray = NULL_PTR; - *ckpLength = 0L; return; } - *ckpLength = (*env)->GetArrayLength(env, jArray); jTemp = (jchar*) calloc(*ckpLength, sizeof(jchar)); if (jTemp == NULL) { throwOutOfMemoryError(env, 0); diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h index eb6d01b9e47c8..450e4d27d62db 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h @@ -68,6 +68,7 @@ /* extra PKCS#11 constants not in the standard include files */ #define CKA_NETSCAPE_BASE (0x80000000 + 0x4E534350) +/* ^ now known as CKM_NSS (CKM_VENDOR_DEFINED | NSSCK_VENDOR_NSS) */ #define CKA_NETSCAPE_TRUST_BASE (CKA_NETSCAPE_BASE + 0x2000) #define CKA_NETSCAPE_TRUST_SERVER_AUTH (CKA_NETSCAPE_TRUST_BASE + 8) #define CKA_NETSCAPE_TRUST_CLIENT_AUTH (CKA_NETSCAPE_TRUST_BASE + 9) @@ -76,6 +77,12 @@ #define CKA_NETSCAPE_DB 0xD5A0DB00 #define CKM_NSS_TLS_PRF_GENERAL 0x80000373 +/* additional PKCS #12 PBE key derivation algorithms defined in NSS v3.29 */ +#define CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN (CKA_NETSCAPE_BASE + 29) +#define CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN (CKA_NETSCAPE_BASE + 30) +#define CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN (CKA_NETSCAPE_BASE + 31) +#define CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN (CKA_NETSCAPE_BASE + 32) + /* Define the PKCS#11 functions to include and exclude. Reduces the size @@ -265,6 +272,7 @@ void printDebug(const char *format, ...); #define CLASS_PBE_PARAMS "sun/security/pkcs11/wrapper/CK_PBE_PARAMS" #define PBE_INIT_VECTOR_SIZE 8 #define CLASS_PKCS5_PBKD2_PARAMS "sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS" +#define CLASS_PKCS5_PBKD2_PARAMS2 "sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS2" #define CLASS_EXTRACT_PARAMS "sun/security/pkcs11/wrapper/CK_EXTRACT_PARAMS" #define CLASS_ECDH1_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS" @@ -378,7 +386,7 @@ CK_VOID_PTR jMechParamToCKMechParamPtr(JNIEnv *env, jobject jParam, CK_MECHANISM CK_RSA_PKCS_OAEP_PARAMS_PTR jRsaPkcsOaepParamToCKRsaPkcsOaepParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); CK_PBE_PARAMS_PTR jPbeParamToCKPbeParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); -CK_PKCS5_PBKD2_PARAMS_PTR jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); +CK_VOID_PTR jPkcs5Pbkd2ParamToCKPkcs5Pbkd2ParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); CK_SSL3_KEY_MAT_PARAMS_PTR jSsl3KeyMatParamToCKSsl3KeyMatParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); CK_KEY_DERIVATION_STRING_DATA jKeyDerivationStringDataToCKKeyDerivationStringData(JNIEnv *env, jobject jParam); @@ -388,6 +396,31 @@ CK_ECDH2_DERIVE_PARAMS_PTR jEcdh2DeriveParamToCKEcdh2DeriveParamPtr(JNIEnv *env, CK_X9_42_DH1_DERIVE_PARAMS_PTR jX942Dh1DeriveParamToCKX942Dh1DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); CK_X9_42_DH2_DERIVE_PARAMS_PTR jX942Dh2DeriveParamToCKX942Dh2DeriveParamPtr(JNIEnv *env, jobject jParam, CK_ULONG* pLength); +/* handling of CK_PKCS5_PBKD2_PARAMS and CK_PKCS5_PBKD2_PARAMS2 */ +typedef enum {PARAMS=0, PARAMS2} ParamVersion; + +typedef struct { + union { + CK_PKCS5_PBKD2_PARAMS v1; + CK_PKCS5_PBKD2_PARAMS2 v2; + } params; + ParamVersion version; +} VersionedPbkd2Params, *VersionedPbkd2ParamsPtr; + +#define FREE_VERSIONED_PBKD2_MEMBERS(verParamsPtr) \ + do { \ + if ((verParamsPtr)->version == PARAMS) { \ + free((verParamsPtr)->params.v1.pSaltSourceData); \ + free((verParamsPtr)->params.v1.pPrfData); \ + free((verParamsPtr)->params.v1.pPassword); \ + free((verParamsPtr)->params.v1.ulPasswordLen); \ + } else { \ + free((verParamsPtr)->params.v2.pSaltSourceData); \ + free((verParamsPtr)->params.v2.pPrfData); \ + free((verParamsPtr)->params.v2.pPassword); \ + } \ + } while(0) + /* functions to copy the returned values inside CK-mechanism back to Java object */ void copyBackPBEInitializationVector(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism); diff --git a/test/jdk/sun/security/pkcs11/Cipher/PBECipher.java b/test/jdk/sun/security/pkcs11/Cipher/PBECipher.java new file mode 100644 index 0000000000000..a184a16973280 --- /dev/null +++ b/test/jdk/sun/security/pkcs11/Cipher/PBECipher.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.math.BigInteger; +import java.security.AlgorithmParameters; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Security; +import java.util.Map; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.interfaces.PBEKey; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; + +/* + * @test + * @bug 9999999 + * @summary test password based encryption on SunPKCS11's Cipher service + * @requires (jdk.version.major >= 8) + * @library /test/lib .. + * @run main/othervm/timeout=30 PBECipher + */ + +public final class PBECipher { + public static void main(String[] args) throws Exception { + java.security.Security.getProviders(); + PBECipher2.main(args); + } +} + +final class PBECipher2 extends PKCS11Test { + private static final char[] password = "123456".toCharArray(); + private static final byte[] salt = "abcdefgh".getBytes(); + private static final byte[] iv = new byte[16]; + private static final int iterations = 1000; + private static final String plainText = "This is a know plain text!"; + private static final String sep = + "========================================================================="; + + private static enum Configuration { + // Provide salt and iterations through a PBEParameterSpec instance + PBEParameterSpec, + + // Provide salt and iterations through a AlgorithmParameters instance + AlgorithmParameters, + + // Provide salt and iterations through an anonymous class implementing + // the javax.crypto.interfaces.PBEKey interface + AnonymousPBEKey, + } + + private static Provider sunJCE = Security.getProvider("SunJCE"); + + // Generated with SunJCE + private static final Map assertionData = Map.of( + "PBEWithHmacSHA1AndAES_128", new BigInteger("8eebe98a580fb09d026" + + "dbfe60b3733b079e0de9ea7b0b1ccba011a1652d1e257", 16), + "PBEWithHmacSHA224AndAES_128", new BigInteger("1cbabdeb5d483af4a" + + "841942f4b1095b7d6f60e46fabfd2609c015adc38cc227", 16), + "PBEWithHmacSHA256AndAES_128", new BigInteger("4d82f6591df3508d2" + + "4531f06cdc4f90f4bdab7aeb07fbb57a3712e999d5b6f59", 16), + "PBEWithHmacSHA384AndAES_128", new BigInteger("3a0ed0959d51f40b9" + + "ba9f506a5277f430521f2fbe1ba94bae368835f221b6cb9", 16), + "PBEWithHmacSHA512AndAES_128", new BigInteger("1388287a446009309" + + "1418f4eca3ba1735b1fa025423d74ced36ce578d8ebf9da", 16), + "PBEWithHmacSHA1AndAES_256", new BigInteger("80f8208daab27ed02dd" + + "8a354ef6f23ff7813c84dd1c8a1b081d6f4dee27182a2", 16), + "PBEWithHmacSHA224AndAES_256", new BigInteger("7e3b9ce20aec2e52f" + + "f6c781602d4f79a55a88495b5217f1e22e1a068268e6247", 16), + "PBEWithHmacSHA256AndAES_256", new BigInteger("9d6a8b6a351dfd0dd" + + "9e9f45924b2860dca7719c4c07e207a64ebc1acd16cc157", 16), + "PBEWithHmacSHA384AndAES_256", new BigInteger("6f1b386cee3a8e2d9" + + "8c2e81828da0467dec8b989d22258efeab5932580d01d53", 16), + "PBEWithHmacSHA512AndAES_256", new BigInteger("30aaa346b2edd394f" + + "50916187876ac32f1287b19d55c5eea6f7ef9b84aaf291e", 16) + ); + + private static final class NoRandom extends SecureRandom { + @Override + public void nextBytes(byte[] bytes) { + return; + } + } + + public void main(Provider sunPKCS11) throws Exception { + System.out.println("SunPKCS11: " + sunPKCS11.getName()); + for (Configuration conf : Configuration.values()) { + testWith(sunPKCS11, "PBEWithHmacSHA1AndAES_128", conf); + testWith(sunPKCS11, "PBEWithHmacSHA224AndAES_128", conf); + testWith(sunPKCS11, "PBEWithHmacSHA256AndAES_128", conf); + testWith(sunPKCS11, "PBEWithHmacSHA384AndAES_128", conf); + testWith(sunPKCS11, "PBEWithHmacSHA512AndAES_128", conf); + testWith(sunPKCS11, "PBEWithHmacSHA1AndAES_256", conf); + testWith(sunPKCS11, "PBEWithHmacSHA224AndAES_256", conf); + testWith(sunPKCS11, "PBEWithHmacSHA256AndAES_256", conf); + testWith(sunPKCS11, "PBEWithHmacSHA384AndAES_256", conf); + testWith(sunPKCS11, "PBEWithHmacSHA512AndAES_256", conf); + } + System.out.println("TEST PASS - OK"); + } + + private void testWith(Provider sunPKCS11, String algorithm, + Configuration conf) throws Exception { + System.out.println(sep + System.lineSeparator() + algorithm + + " (with " + conf.name() + ")"); + + Cipher pbeCipher = getCipher(sunPKCS11, algorithm, conf); + BigInteger cipherText = new BigInteger(1, pbeCipher.doFinal( + plainText.getBytes())); + printByteArray("Cipher Text", cipherText); + + BigInteger expectedCipherText = null; + if (sunJCE != null) { + Cipher c = getCipher(sunJCE, algorithm, conf); + if (c != null) { + expectedCipherText = new BigInteger(1, c.doFinal( + plainText.getBytes())); + } else { + // Move to assertionData as it's unlikely that any of + // the algorithms are available. + sunJCE = null; + } + } + if (expectedCipherText == null) { + // If SunJCE or the algorithm are not available, assertionData + // is used instead. + expectedCipherText = assertionData.get(algorithm); + } + + if (!cipherText.equals(expectedCipherText)) { + printByteArray("Expected Cipher Text", expectedCipherText); + throw new Exception("Expected Cipher Text did not match"); + } + } + + private Cipher getCipher(Provider p, String algorithm, + Configuration conf) throws Exception { + Cipher pbeCipher = null; + try { + pbeCipher = Cipher.getInstance(algorithm, p); + } catch (NoSuchAlgorithmException e) { + return null; + } + switch (conf) { + case PBEParameterSpec, AlgorithmParameters -> { + SecretKey key = getPasswordOnlyPBEKey(); + PBEParameterSpec paramSpec = new PBEParameterSpec( + salt, iterations, new IvParameterSpec(iv)); + switch (conf) { + case PBEParameterSpec -> { + pbeCipher.init(Cipher.ENCRYPT_MODE, key, paramSpec); + } + case AlgorithmParameters -> { + AlgorithmParameters algoParams = + AlgorithmParameters.getInstance("PBES2"); + algoParams.init(paramSpec); + pbeCipher.init(Cipher.ENCRYPT_MODE, key, algoParams); + } + } + } + case AnonymousPBEKey -> { + SecretKey key = getPasswordSaltIterationsPBEKey(); + pbeCipher.init(Cipher.ENCRYPT_MODE, key, new NoRandom()); + } + } + return pbeCipher; + } + + private static SecretKey getPasswordOnlyPBEKey() throws Exception { + PBEKeySpec keySpec = new PBEKeySpec(password); + SecretKeyFactory skFac = SecretKeyFactory.getInstance("PBE"); + SecretKey skey = skFac.generateSecret(keySpec); + keySpec.clearPassword(); + return skey; + } + + private static SecretKey getPasswordSaltIterationsPBEKey() { + return new PBEKey() { + public byte[] getSalt() { return salt.clone(); } + public int getIterationCount() { return iterations; } + public String getAlgorithm() { return "PBE"; } + public String getFormat() { return "RAW"; } + public char[] getPassword() { return null; } // unused in PBE Cipher + public byte[] getEncoded() { + byte[] passwdBytes = new byte[password.length]; + for (int i = 0; i < password.length; i++) + passwdBytes[i] = (byte) (password[i] & 0x7f); + return passwdBytes; + } + }; + } + + private static void printByteArray(String title, BigInteger b) { + String repr = (b == null) ? "buffer is null" : b.toString(16); + System.out.println(title + ": " + repr + System.lineSeparator()); + } + + public static void main(String[] args) throws Exception { + PBECipher2 test = new PBECipher2(); + Provider p = Security.getProvider("SunPKCS11-NSS-FIPS"); + if (p != null) { + test.main(p); + } else { + main(test); + } + } +} diff --git a/test/jdk/sun/security/pkcs11/KeyStore/ImportKeyToP12.java b/test/jdk/sun/security/pkcs11/KeyStore/ImportKeyToP12.java new file mode 100644 index 0000000000000..360e11c339d2a --- /dev/null +++ b/test/jdk/sun/security/pkcs11/KeyStore/ImportKeyToP12.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.security.Key; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.MessageDigest; +import java.security.Provider; +import java.security.Security; + +import javax.crypto.spec.SecretKeySpec; + +/* + * @test + * @bug 9999999 + * @summary test SunPKCS11's password based privacy and integrity + * applied to PKCS#12 keystores + * @requires (jdk.version.major >= 8) + * @library /test/lib .. + * @modules java.base/sun.security.util + * @run main/othervm/timeout=30 -Dcom.redhat.fips=false -DNO_DEFAULT=true ImportKeyToP12 + */ + +public final class ImportKeyToP12 { + public static void main(String[] args) throws Exception { + java.security.Security.getProviders(); + ImportKeyToP122.main(args); + } +} + +final class ImportKeyToP122 extends PKCS11Test { + private static final String alias = "alias"; + private static final char[] password = "123456".toCharArray(); + private static final Key key = new SecretKeySpec(new byte[] { + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }, "AES"); + private static final String[] pbeCipherAlgs = new String[] { + "PBEWithHmacSHA1AndAES_128", "PBEWithHmacSHA224AndAES_128", + "PBEWithHmacSHA256AndAES_128", "PBEWithHmacSHA384AndAES_128", + "PBEWithHmacSHA512AndAES_128", "PBEWithHmacSHA1AndAES_256", + "PBEWithHmacSHA224AndAES_256", "PBEWithHmacSHA256AndAES_256", + "PBEWithHmacSHA384AndAES_256", "PBEWithHmacSHA512AndAES_256" + }; + private static final String[] pbeMacAlgs = new String[] { + "HmacPBESHA1", "HmacPBESHA224", "HmacPBESHA256", + "HmacPBESHA384", "HmacPBESHA512" + }; + private static final KeyStore p12; + private static final String sep = + "========================================================================="; + + static { + KeyStore tP12 = null; + try { + tP12 = KeyStore.getInstance("PKCS12"); + } catch (KeyStoreException e) {} + p12 = tP12; + } + + public void main(Provider sunPKCS11) throws Exception { + System.out.println("SunPKCS11: " + sunPKCS11.getName()); + // Test all privacy PBE algorithms with an integrity algorithm fixed + for (String pbeCipherAlg : pbeCipherAlgs) { + testWith(sunPKCS11, pbeCipherAlg, pbeMacAlgs[0]); + } + // Test all integrity PBE algorithms with a privacy algorithm fixed + for (String pbeMacAlg : pbeMacAlgs) { + testWith(sunPKCS11, pbeCipherAlgs[0], pbeMacAlg); + } + System.out.println("TEST PASS - OK"); + } + + /* + * Consistency test: 1) store a secret key in a PKCS#12 keystore using + * PBE algorithms from SunPKCS11 and, 2) read the secret key from the + * PKCS#12 keystore using PBE algorithms from other security providers + * such as SunJCE. + */ + private void testWith(Provider sunPKCS11, String pbeCipherAlg, + String pbeMacAlg) throws Exception { + System.out.println(sep + System.lineSeparator() + + "Cipher PBE: " + pbeCipherAlg + System.lineSeparator() + + "Mac PBE: " + pbeMacAlg); + + System.setProperty("keystore.pkcs12.macAlgorithm", pbeMacAlg); + System.setProperty("keystore.pkcs12.keyProtectionAlgorithm", + pbeCipherAlg); + + // Create an empty PKCS#12 keystore + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + p12.load(null, password); + + // Use PBE privacy and integrity algorithms from SunPKCS11 to store + // the secret key + Security.insertProviderAt(sunPKCS11, 1); + p12.setKeyEntry(alias, key, password, null); + p12.store(baos, password); + + // Use PBE privacy and integrity algorithms from other security + // providers, such as SunJCE, to read the secret key + Security.removeProvider(sunPKCS11.getName()); + p12.load(new ByteArrayInputStream(baos.toByteArray()), password); + Key k = p12.getKey(alias, password); + + if (!MessageDigest.isEqual(key.getEncoded(), k.getEncoded())) { + throw new Exception("Keys differ. Consistency check failed."); + } + System.out.println("Secret key import successful" + System.lineSeparator() + sep); + } + + public static void main(String[] args) throws Exception { + main(new ImportKeyToP122()); + } +} diff --git a/test/jdk/sun/security/pkcs11/Mac/PBAMac.java b/test/jdk/sun/security/pkcs11/Mac/PBAMac.java new file mode 100644 index 0000000000000..6b5662f6b4cae --- /dev/null +++ b/test/jdk/sun/security/pkcs11/Mac/PBAMac.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.math.BigInteger; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; +import java.util.Map; + +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.interfaces.PBEKey; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; + +/* + * @test + * @bug 9999999 + * @summary test password based authentication on SunPKCS11's Mac service + * @requires (jdk.version.major >= 8) + * @library /test/lib .. + * @run main/othervm/timeout=30 PBAMac + */ + +public final class PBAMac { + public static void main(String[] args) throws Exception { + java.security.Security.getProviders(); + PBAMac2.main(args); + } +} + +final class PBAMac2 extends PKCS11Test { + private static final char[] password = "123456".toCharArray(); + private static final byte[] salt = "abcdefgh".getBytes(); + private static final int iterations = 1000; + private static final String plainText = "This is a know plain text!"; + private static final String sep = + "========================================================================="; + + private static enum Configuration { + // Provide salt & iterations through a PBEParameterSpec instance + PBEParameterSpec, + + // Provide salt & iterations through an anonymous class implementing + // the javax.crypto.interfaces.PBEKey interface + AnonymousPBEKey, + } + + // Generated with SunJCE + private static final Map assertionData = Map.of( + "HmacPBESHA1", new BigInteger("febd26da5d63ce819770a2af1fc2857e" + + "e2c9c41c", 16), + "HmacPBESHA224", new BigInteger("aa6a3a1c35a4b266fea62d1a871508" + + "bd45f8ec326bcf16e09699063", 16), + "HmacPBESHA256", new BigInteger("af4d71121fd4e9d52eb42944d99b77" + + "8ff64376fcf6af8d1dca3ec688dfada5c8", 16), + "HmacPBESHA384", new BigInteger("5d6d37764205985ffca7e4a6222752" + + "a8bbd0520858da08ecafdc57e6246894675e375b9ba084f9ce7142" + + "35f202cc3452", 16), + "HmacPBESHA512", new BigInteger("f586c2006cc2de73fd5743e5cca701" + + "c942d3741a7a54a2a649ea36898996cf3c483f2d734179b47751db" + + "e8373c980b4072136d2e2810f4e7276024a3e9081cc1", 16) + ); + + private static Provider sunJCE = Security.getProvider("SunJCE"); + + public void main(Provider sunPKCS11) throws Exception { + System.out.println("SunPKCS11: " + sunPKCS11.getName()); + for (Configuration conf : Configuration.values()) { + testWith(sunPKCS11, "HmacPBESHA1", conf); + testWith(sunPKCS11, "HmacPBESHA224", conf); + testWith(sunPKCS11, "HmacPBESHA256", conf); + testWith(sunPKCS11, "HmacPBESHA384", conf); + testWith(sunPKCS11, "HmacPBESHA512", conf); + } + System.out.println("TEST PASS - OK"); + } + + private void testWith(Provider sunPKCS11, String algorithm, + Configuration conf) throws Exception { + System.out.println(sep + System.lineSeparator() + algorithm + + " (with " + conf.name() + ")"); + + BigInteger macResult = computeMac(sunPKCS11, algorithm, conf); + printByteArray("HMAC Result", macResult); + + BigInteger expectedMacResult = computeExpectedMac(algorithm, conf); + + if (!macResult.equals(expectedMacResult)) { + printByteArray("Expected HMAC Result", expectedMacResult); + throw new Exception("Expected HMAC Result did not match"); + } + } + + private BigInteger computeMac(Provider p, String algorithm, + Configuration conf) throws Exception { + Mac pbaMac; + try { + pbaMac = Mac.getInstance(algorithm, p); + } catch (NoSuchAlgorithmException e) { + return null; + } + switch (conf) { + case PBEParameterSpec -> { + SecretKey key = getPasswordOnlyPBEKey(); + pbaMac.init(key, new PBEParameterSpec(salt, iterations)); + } + case AnonymousPBEKey -> { + SecretKey key = getPasswordSaltIterationsPBEKey(); + pbaMac.init(key); + } + } + return new BigInteger(1, pbaMac.doFinal(plainText.getBytes())); + } + + private BigInteger computeExpectedMac(String algorithm, Configuration conf) + throws Exception { + if (sunJCE != null) { + BigInteger macResult = computeMac(sunJCE, algorithm, conf); + if (macResult != null) { + return macResult; + } + // Move to assertionData as it's unlikely that any of + // the algorithms are available. + sunJCE = null; + } + // If SunJCE or the algorithm are not available, assertionData + // is used instead. + return assertionData.get(algorithm); + } + + private static SecretKey getPasswordOnlyPBEKey() throws Exception { + PBEKeySpec keySpec = new PBEKeySpec(password); + SecretKeyFactory skFac = SecretKeyFactory.getInstance("PBE"); + SecretKey skey = skFac.generateSecret(keySpec); + keySpec.clearPassword(); + return skey; + } + + private static SecretKey getPasswordSaltIterationsPBEKey() { + return new PBEKey() { + public byte[] getSalt() { return salt.clone(); } + public int getIterationCount() { return iterations; } + public String getAlgorithm() { return "PBE"; } + public String getFormat() { return "RAW"; } + public char[] getPassword() { return password.clone(); } + public byte[] getEncoded() { return null; } // unused in PBA Mac + }; + } + + private static void printByteArray(String title, BigInteger b) { + String repr = (b == null) ? "buffer is null" : b.toString(16); + System.out.println(title + ": " + repr + System.lineSeparator()); + } + + public static void main(String[] args) throws Exception { + PBAMac2 test = new PBAMac2(); + Provider p = Security.getProvider("SunPKCS11-NSS-FIPS"); + if (p != null) { + test.main(p); + } else { + main(test); + } + } +} diff --git a/test/jdk/sun/security/pkcs11/SecretKeyFactory/TestPBKD.java b/test/jdk/sun/security/pkcs11/SecretKeyFactory/TestPBKD.java new file mode 100644 index 0000000000000..67c3cee597081 --- /dev/null +++ b/test/jdk/sun/security/pkcs11/SecretKeyFactory/TestPBKD.java @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigInteger; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; +import java.util.HashMap; +import java.util.Map; + +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +/* + * @test + * @bug 9999999 + * @summary test key derivation on SunPKCS11's SecretKeyFactory service + * @requires (jdk.version.major >= 8) + * @library /test/lib .. + * @modules java.base/com.sun.crypto.provider:open + * @run main/othervm/timeout=30 TestPBKD + */ + +public final class TestPBKD { + public static void main(String[] args) throws Exception { + java.security.Security.getProviders(); + TestPBKD2.main(args); + } +} + +final class TestPBKD2 extends PKCS11Test { + private static final char[] password = "123456".toCharArray(); + private static final byte[] salt = "abcdefgh".getBytes(); + private static final int iterations = 1000; + private static final String sep = + "========================================================================="; + + private static Provider sunJCE = Security.getProvider("SunJCE"); + + // Generated with SunJCE + private static final Map assertionData = + new HashMap<>() {{ + put("HmacPBESHA1", new BigInteger("5f7d1c360d1703cede76f47db" + + "2fa3facc62e7694", 16)); + put("HmacPBESHA224", new BigInteger("289563f799b708f522ab2a3" + + "8d283d0afa8fc1d3d227fcb9236c3a035", 16)); + put("HmacPBESHA256", new BigInteger("888defcf4ef37eb0647014a" + + "d172dd6fa3b3e9d024b962dba47608eea9b9c4b79", 16)); + put("HmacPBESHA384", new BigInteger("f5464b34253fadab8838d0d" + + "b11980c1787a99bf6f6304f2d8c942e30bada523494f9d5a0f3" + + "741e411de21add8b5718a8", 16)); + put("HmacPBESHA512", new BigInteger("18ae94337b132c68c611bc2" + + "e723ac24dcd44a46d900dae2dd6170380d4c34f90fef7bdeb5f" + + "6fddeb0d2230003e329b7a7eefcd35810d364ba95d31b68bb61" + + "e52", 16)); + put("PBEWithHmacSHA1AndAES_128", new BigInteger("fdb3dcc2e81" + + "244d4d56bf7ec8dd61dd7", 16)); + put("PBEWithHmacSHA224AndAES_128", new BigInteger("5ef9e5c6f" + + "df7c355f3b424233a9f24c2", 16)); + put("PBEWithHmacSHA256AndAES_128", new BigInteger("c5af597b0" + + "1b4f6baac8f62ff6f22bfb1", 16)); + put("PBEWithHmacSHA384AndAES_128", new BigInteger("c3208ebc5" + + "d6db88858988ec00153847d", 16)); + put("PBEWithHmacSHA512AndAES_128", new BigInteger("b27e8f7fb" + + "6a4bd5ebea892cd9a7f5043", 16)); + put("PBEWithHmacSHA1AndAES_256", new BigInteger("fdb3dcc2e81" + + "244d4d56bf7ec8dd61dd78a1b6fb3ad11d9ebd7f62027a2ccde" + + "98", 16)); + put("PBEWithHmacSHA224AndAES_256", new BigInteger("5ef9e5c6f" + + "df7c355f3b424233a9f24c2c9c41793cb0948b8ea3aac240b8d" + + "f64d", 16)); + put("PBEWithHmacSHA256AndAES_256", new BigInteger("c5af597b0" + + "1b4f6baac8f62ff6f22bfb1f319c3278c8b31cc616294716d4e" + + "ab08", 16)); + put("PBEWithHmacSHA384AndAES_256", new BigInteger("c3208ebc5" + + "d6db88858988ec00153847d5b1b7a8723640a022dc332bcaefe" + + "b356", 16)); + put("PBEWithHmacSHA512AndAES_256", new BigInteger("b27e8f7fb" + + "6a4bd5ebea892cd9a7f5043cefff9c38b07e599721e8d116189" + + "5482", 16)); + put("PBKDF2WithHmacSHA1", new BigInteger("fdb3dcc2e81244d4d5" + + "6bf7ec8dd61dd78a1b6fb3ad11d9ebd7f62027a2cc", 16)); + put("PBKDF2WithHmacSHA224", new BigInteger("5ef9e5c6fdf7c355" + + "f3b424233a9f24c2c9c41793cb0948b8ea3aac240b8df64d1a0" + + "736ec1c69eef1c7b2", 16)); + put("PBKDF2WithHmacSHA256", new BigInteger("c5af597b01b4f6ba" + + "ac8f62ff6f22bfb1f319c3278c8b31cc616294716d4eab080b9" + + "add9db34a42ceb2fea8d27adc00f4", 16)); + put("PBKDF2WithHmacSHA384", new BigInteger("c3208ebc5d6db888" + + "58988ec00153847d5b1b7a8723640a022dc332bcaefeb356995" + + "d076a949d35c42c7e1e1ca936c12f8dc918e497edf279a522b7" + + "c99580e2613846b3919af637da", 16)); + put("PBKDF2WithHmacSHA512", new BigInteger("b27e8f7fb6a4bd5e" + + "bea892cd9a7f5043cefff9c38b07e599721e8d1161895482da2" + + "55746844cc1030be37ba1969df10ff59554d1ac5468fa9b7297" + + "7bb7fd52103a0a7b488cdb8957616c3e23a16bca92120982180" + + "c6c11a4f14649b50d0ade3a", 16)); + }}; + + static interface AssertData { + BigInteger derive(String pbAlgo, PBEKeySpec keySpec) throws Exception; + } + + static final class P12PBKDAssertData implements AssertData { + private final int outLen; + private final String kdfAlgo; + private final int blockLen; + + P12PBKDAssertData(int outLen, String kdfAlgo, int blockLen) { + this.outLen = outLen; + this.kdfAlgo = kdfAlgo; + this.blockLen = blockLen; + } + + @Override + public BigInteger derive(String pbAlgo, PBEKeySpec keySpec) + throws Exception { + // Since we need to access an internal SunJCE API, we use reflection + Class PKCS12PBECipherCore = Class.forName( + "com.sun.crypto.provider.PKCS12PBECipherCore"); + + Field macKeyField = PKCS12PBECipherCore.getDeclaredField("MAC_KEY"); + macKeyField.setAccessible(true); + int MAC_KEY = (int) macKeyField.get(null); + + Method deriveMethod = PKCS12PBECipherCore.getDeclaredMethod( + "derive", char[].class, byte[].class, int.class, + int.class, int.class, String.class, int.class); + deriveMethod.setAccessible(true); + + return new BigInteger(1, (byte[]) deriveMethod.invoke(null, + keySpec.getPassword(), keySpec.getSalt(), + keySpec.getIterationCount(), this.outLen, + MAC_KEY, this.kdfAlgo, this.blockLen)); + } + } + + static final class PBKD2AssertData implements AssertData { + private final String kdfAlgo; + private final int keyLen; + + PBKD2AssertData(String kdfAlgo, int keyLen) { + // Key length is pinned by the algorithm name (not kdfAlgo, + // but the algorithm under test: PBEWithHmacSHA*AndAES_*) + this.kdfAlgo = kdfAlgo; + this.keyLen = keyLen; + } + + PBKD2AssertData(String kdfAlgo) { + // Key length is variable for the algorithm under test + // (kdfAlgo is the algorithm under test: PBKDF2WithHmacSHA*) + this(kdfAlgo, -1); + } + + @Override + public BigInteger derive(String pbAlgo, PBEKeySpec keySpec) + throws Exception { + if (this.keyLen != -1) { + keySpec = new PBEKeySpec( + keySpec.getPassword(), keySpec.getSalt(), + keySpec.getIterationCount(), this.keyLen); + } + if (sunJCE != null) { + try { + return new BigInteger(1, SecretKeyFactory.getInstance( + this.kdfAlgo, sunJCE).generateSecret(keySpec) + .getEncoded()); + } catch (NoSuchAlgorithmException e) { + // Move to assertionData as it's unlikely that any of + // the algorithms are available. + sunJCE = null; + } + } + // If SunJCE or the algorithm are not available, assertionData + // is used instead. + return assertionData.get(pbAlgo); + } + } + + public void main(Provider sunPKCS11) throws Exception { + System.out.println("SunPKCS11: " + sunPKCS11.getName()); + testWith(sunPKCS11, "HmacPBESHA1", + new P12PBKDAssertData(20, "SHA-1", 64)); + testWith(sunPKCS11, "HmacPBESHA224", + new P12PBKDAssertData(28, "SHA-224", 64)); + testWith(sunPKCS11, "HmacPBESHA256", + new P12PBKDAssertData(32, "SHA-256", 64)); + testWith(sunPKCS11, "HmacPBESHA384", + new P12PBKDAssertData(48, "SHA-384", 128)); + testWith(sunPKCS11, "HmacPBESHA512", + new P12PBKDAssertData(64, "SHA-512", 128)); + + testWith(sunPKCS11, "PBEWithHmacSHA1AndAES_128", + new PBKD2AssertData("PBKDF2WithHmacSHA1", 128)); + testWith(sunPKCS11, "PBEWithHmacSHA224AndAES_128", + new PBKD2AssertData("PBKDF2WithHmacSHA224", 128)); + testWith(sunPKCS11, "PBEWithHmacSHA256AndAES_128", + new PBKD2AssertData("PBKDF2WithHmacSHA256", 128)); + testWith(sunPKCS11, "PBEWithHmacSHA384AndAES_128", + new PBKD2AssertData("PBKDF2WithHmacSHA384", 128)); + testWith(sunPKCS11, "PBEWithHmacSHA512AndAES_128", + new PBKD2AssertData("PBKDF2WithHmacSHA512", 128)); + testWith(sunPKCS11, "PBEWithHmacSHA1AndAES_256", + new PBKD2AssertData("PBKDF2WithHmacSHA1", 256)); + testWith(sunPKCS11, "PBEWithHmacSHA224AndAES_256", + new PBKD2AssertData("PBKDF2WithHmacSHA224", 256)); + testWith(sunPKCS11, "PBEWithHmacSHA256AndAES_256", + new PBKD2AssertData("PBKDF2WithHmacSHA256", 256)); + testWith(sunPKCS11, "PBEWithHmacSHA384AndAES_256", + new PBKD2AssertData("PBKDF2WithHmacSHA384", 256)); + testWith(sunPKCS11, "PBEWithHmacSHA512AndAES_256", + new PBKD2AssertData("PBKDF2WithHmacSHA512", 256)); + + // Use 1,5 * digest size as the testing derived key length (in bits) + testWith(sunPKCS11, "PBKDF2WithHmacSHA1", 240, + new PBKD2AssertData("PBKDF2WithHmacSHA1")); + testWith(sunPKCS11, "PBKDF2WithHmacSHA224", 336, + new PBKD2AssertData("PBKDF2WithHmacSHA224")); + testWith(sunPKCS11, "PBKDF2WithHmacSHA256", 384, + new PBKD2AssertData("PBKDF2WithHmacSHA256")); + testWith(sunPKCS11, "PBKDF2WithHmacSHA384", 576, + new PBKD2AssertData("PBKDF2WithHmacSHA384")); + testWith(sunPKCS11, "PBKDF2WithHmacSHA512", 768, + new PBKD2AssertData("PBKDF2WithHmacSHA512")); + + System.out.println("TEST PASS - OK"); + } + + private static void testWith(Provider sunPKCS11, String algorithm, + AssertData assertData) throws Exception { + PBEKeySpec keySpec = new PBEKeySpec(password, salt, iterations); + testWith(sunPKCS11, algorithm, keySpec, assertData); + } + + private static void testWith(Provider sunPKCS11, String algorithm, + int keyLen, AssertData assertData) throws Exception { + PBEKeySpec keySpec = new PBEKeySpec(password, salt, iterations, keyLen); + testWith(sunPKCS11, algorithm, keySpec, assertData); + } + + private static void testWith(Provider sunPKCS11, String algorithm, + PBEKeySpec keySpec, AssertData assertData) throws Exception { + System.out.println(sep + System.lineSeparator() + algorithm); + + SecretKeyFactory skFac = SecretKeyFactory.getInstance( + algorithm, sunPKCS11); + BigInteger derivedKey = new BigInteger(1, + skFac.generateSecret(keySpec).getEncoded()); + printByteArray("Derived Key", derivedKey); + + BigInteger expectedDerivedKey = assertData.derive(algorithm, keySpec); + + if (!derivedKey.equals(expectedDerivedKey)) { + printByteArray("Expected Derived Key", expectedDerivedKey); + throw new Exception("Expected Derived Key did not match"); + } + } + + private static void printByteArray(String title, BigInteger b) { + String repr = (b == null) ? "buffer is null" : b.toString(16); + System.out.println(title + ": " + repr + System.lineSeparator()); + } + + public static void main(String[] args) throws Exception { + TestPBKD2 test = new TestPBKD2(); + Provider p = Security.getProvider("SunPKCS11-NSS-FIPS"); + if (p != null) { + test.main(p); + } else { + main(test); + } + } +} From ec8294be863aaca4a27dba847d0f551b84107ff7 Mon Sep 17 00:00:00 2001 From: Francisco Ferrari Bihurriet Date: Wed, 8 Jun 2022 19:46:42 -0300 Subject: [PATCH 2/3] Change default keystore type for FIPS Align it with the non-FIPS keystore type (pkcs12) now that it is supported --- src/java.base/share/conf/security/java.security | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index adfaf57d29e82..f357b63046009 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -302,7 +302,7 @@ keystore.type=pkcs12 # # Default keystore type used when global crypto-policies are set to FIPS. # -fips.keystore.type=PKCS11 +fips.keystore.type=pkcs12 # # Controls compatibility mode for JKS and PKCS12 keystore types. From 0d966e0cbc35840f27eae8cb3cfc80e0766e6d06 Mon Sep 17 00:00:00 2001 From: Francisco Ferrari Bihurriet Date: Wed, 8 Jun 2022 19:51:51 -0300 Subject: [PATCH 3/3] Register new SunPKCS11 algorithms only for FIPS mode This is: RHEL is in FIPS mode (non default), and the OpenJDK has been configured to align with it (default) --- .../sun/security/pkcs11/SunPKCS11.java | 236 +++++++++--------- 1 file changed, 121 insertions(+), 115 deletions(-) diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java index 5d371aab5ef8c..3e170b4c115ab 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -667,27 +667,29 @@ private static void register(Descriptor d) { d(MAC, "SslMacSHA1", P11Mac, m(CKM_SSL3_SHA1_MAC)); - /* - * PBA HMacs - * - * KeyDerivationMech must be supported - * for these services to be available. - * - */ - d(MAC, "HmacPBESHA1", P11Mac, m(CKM_SHA_1_HMAC), - m(CKM_PBA_SHA1_WITH_SHA1_HMAC)); - d(MAC, "HmacPBESHA224", P11Mac, m(CKM_SHA224_HMAC), - m(CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN)); - d(MAC, "HmacPBESHA256", P11Mac, m(CKM_SHA256_HMAC), - m(CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN)); - d(MAC, "HmacPBESHA384", P11Mac, m(CKM_SHA384_HMAC), - m(CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN)); - d(MAC, "HmacPBESHA512", P11Mac, m(CKM_SHA512_HMAC), - m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); - d(MAC, "HmacPBESHA512/224", P11Mac, m(CKM_SHA512_224_HMAC), - m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); - d(MAC, "HmacPBESHA512/256", P11Mac, m(CKM_SHA512_256_HMAC), - m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + if (systemFipsEnabled) { + /* + * PBA HMacs + * + * KeyDerivationMech must be supported + * for these services to be available. + * + */ + d(MAC, "HmacPBESHA1", P11Mac, m(CKM_SHA_1_HMAC), + m(CKM_PBA_SHA1_WITH_SHA1_HMAC)); + d(MAC, "HmacPBESHA224", P11Mac, m(CKM_SHA224_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN)); + d(MAC, "HmacPBESHA256", P11Mac, m(CKM_SHA256_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN)); + d(MAC, "HmacPBESHA384", P11Mac, m(CKM_SHA384_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN)); + d(MAC, "HmacPBESHA512", P11Mac, m(CKM_SHA512_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + d(MAC, "HmacPBESHA512/224", P11Mac, m(CKM_SHA512_224_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + d(MAC, "HmacPBESHA512/256", P11Mac, m(CKM_SHA512_256_HMAC), + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + } d(KPG, "RSA", P11KeyPairGenerator, getAliases("PKCS1"), @@ -787,63 +789,65 @@ private static void register(Descriptor d) { d(SKF, "ChaCha20", P11SecretKeyFactory, m(CKM_CHACHA20_POLY1305)); - /* - * PBE Secret Key Factories - * - * KeyDerivationPrf must be supported for these services - * to be available. - * - */ - d(SKF, "PBEWithHmacSHA1AndAES_128", - P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); - d(SKF, "PBEWithHmacSHA224AndAES_128", - P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); - d(SKF, "PBEWithHmacSHA256AndAES_128", - P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); - d(SKF, "PBEWithHmacSHA384AndAES_128", - P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); - d(SKF, "PBEWithHmacSHA512AndAES_128", - P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); - d(SKF, "PBEWithHmacSHA1AndAES_256", - P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); - d(SKF, "PBEWithHmacSHA224AndAES_256", - P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); - d(SKF, "PBEWithHmacSHA256AndAES_256", - P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); - d(SKF, "PBEWithHmacSHA384AndAES_256", - P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); - d(SKF, "PBEWithHmacSHA512AndAES_256", - P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); - /* - * PBA Secret Key Factories - */ - d(SKF, "HmacPBESHA1", P11SecretKeyFactory, - m(CKM_PBA_SHA1_WITH_SHA1_HMAC)); - d(SKF, "HmacPBESHA224", P11SecretKeyFactory, - m(CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN)); - d(SKF, "HmacPBESHA256", P11SecretKeyFactory, - m(CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN)); - d(SKF, "HmacPBESHA384", P11SecretKeyFactory, - m(CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN)); - d(SKF, "HmacPBESHA512", P11SecretKeyFactory, - m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); - d(SKF, "HmacPBESHA512/224", P11SecretKeyFactory, - m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); - d(SKF, "HmacPBESHA512/256", P11SecretKeyFactory, - m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); - /* - * PBKDF2 Secret Key Factories - */ - dA(SKF, "PBKDF2WithHmacSHA1", P11SecretKeyFactory, - m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); - d(SKF, "PBKDF2WithHmacSHA224", P11SecretKeyFactory, - m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); - d(SKF, "PBKDF2WithHmacSHA256", P11SecretKeyFactory, - m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); - d(SKF, "PBKDF2WithHmacSHA384", P11SecretKeyFactory, - m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); - d(SKF, "PBKDF2WithHmacSHA512", P11SecretKeyFactory, - m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); + if (systemFipsEnabled) { + /* + * PBE Secret Key Factories + * + * KeyDerivationPrf must be supported for these services + * to be available. + * + */ + d(SKF, "PBEWithHmacSHA1AndAES_128", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); + d(SKF, "PBEWithHmacSHA224AndAES_128", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); + d(SKF, "PBEWithHmacSHA256AndAES_128", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); + d(SKF, "PBEWithHmacSHA384AndAES_128", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); + d(SKF, "PBEWithHmacSHA512AndAES_128", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); + d(SKF, "PBEWithHmacSHA1AndAES_256", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); + d(SKF, "PBEWithHmacSHA224AndAES_256", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); + d(SKF, "PBEWithHmacSHA256AndAES_256", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); + d(SKF, "PBEWithHmacSHA384AndAES_256", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); + d(SKF, "PBEWithHmacSHA512AndAES_256", + P11SecretKeyFactory, m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); + /* + * PBA Secret Key Factories + */ + d(SKF, "HmacPBESHA1", P11SecretKeyFactory, + m(CKM_PBA_SHA1_WITH_SHA1_HMAC)); + d(SKF, "HmacPBESHA224", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN)); + d(SKF, "HmacPBESHA256", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN)); + d(SKF, "HmacPBESHA384", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN)); + d(SKF, "HmacPBESHA512", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + d(SKF, "HmacPBESHA512/224", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + d(SKF, "HmacPBESHA512/256", P11SecretKeyFactory, + m(CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN)); + /* + * PBKDF2 Secret Key Factories + */ + dA(SKF, "PBKDF2WithHmacSHA1", P11SecretKeyFactory, + m(CKM_PKCS5_PBKD2), m(CKM_SHA_1_HMAC)); + d(SKF, "PBKDF2WithHmacSHA224", P11SecretKeyFactory, + m(CKM_PKCS5_PBKD2), m(CKM_SHA224_HMAC)); + d(SKF, "PBKDF2WithHmacSHA256", P11SecretKeyFactory, + m(CKM_PKCS5_PBKD2), m(CKM_SHA256_HMAC)); + d(SKF, "PBKDF2WithHmacSHA384", P11SecretKeyFactory, + m(CKM_PKCS5_PBKD2), m(CKM_SHA384_HMAC)); + d(SKF, "PBKDF2WithHmacSHA512", P11SecretKeyFactory, + m(CKM_PKCS5_PBKD2), m(CKM_SHA512_HMAC)); + } // XXX attributes for Ciphers (supported modes, padding) dA(CIP, "ARCFOUR", P11Cipher, @@ -914,43 +918,45 @@ private static void register(Descriptor d) { d(CIP, "RSA/ECB/NoPadding", P11RSACipher, m(CKM_RSA_X_509)); - /* - * PBE Ciphers - * - * KeyDerivationMech and KeyDerivationPrf must be supported - * for these services to be available. - * - */ - d(CIP, "PBEWithHmacSHA1AndAES_128", P11PBECipher, - m(CKM_AES_CBC_PAD, CKM_AES_CBC), - m(CKM_PKCS5_PBKD2, CKM_SHA_1_HMAC)); - d(CIP, "PBEWithHmacSHA224AndAES_128", P11PBECipher, - m(CKM_AES_CBC_PAD, CKM_AES_CBC), - m(CKM_PKCS5_PBKD2, CKM_SHA224_HMAC)); - d(CIP, "PBEWithHmacSHA256AndAES_128", P11PBECipher, - m(CKM_AES_CBC_PAD, CKM_AES_CBC), - m(CKM_PKCS5_PBKD2, CKM_SHA256_HMAC)); - d(CIP, "PBEWithHmacSHA384AndAES_128", P11PBECipher, - m(CKM_AES_CBC_PAD, CKM_AES_CBC), - m(CKM_PKCS5_PBKD2, CKM_SHA384_HMAC)); - d(CIP, "PBEWithHmacSHA512AndAES_128", P11PBECipher, - m(CKM_AES_CBC_PAD, CKM_AES_CBC), - m(CKM_PKCS5_PBKD2, CKM_SHA512_HMAC)); - d(CIP, "PBEWithHmacSHA1AndAES_256", P11PBECipher, - m(CKM_AES_CBC_PAD, CKM_AES_CBC), - m(CKM_PKCS5_PBKD2, CKM_SHA_1_HMAC)); - d(CIP, "PBEWithHmacSHA224AndAES_256", P11PBECipher, - m(CKM_AES_CBC_PAD, CKM_AES_CBC), - m(CKM_PKCS5_PBKD2, CKM_SHA224_HMAC)); - d(CIP, "PBEWithHmacSHA256AndAES_256", P11PBECipher, - m(CKM_AES_CBC_PAD, CKM_AES_CBC), - m(CKM_PKCS5_PBKD2, CKM_SHA256_HMAC)); - d(CIP, "PBEWithHmacSHA384AndAES_256", P11PBECipher, - m(CKM_AES_CBC_PAD, CKM_AES_CBC), - m(CKM_PKCS5_PBKD2, CKM_SHA384_HMAC)); - d(CIP, "PBEWithHmacSHA512AndAES_256", P11PBECipher, - m(CKM_AES_CBC_PAD, CKM_AES_CBC), - m(CKM_PKCS5_PBKD2, CKM_SHA512_HMAC)); + if (systemFipsEnabled) { + /* + * PBE Ciphers + * + * KeyDerivationMech and KeyDerivationPrf must be supported + * for these services to be available. + * + */ + d(CIP, "PBEWithHmacSHA1AndAES_128", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA_1_HMAC)); + d(CIP, "PBEWithHmacSHA224AndAES_128", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA224_HMAC)); + d(CIP, "PBEWithHmacSHA256AndAES_128", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA256_HMAC)); + d(CIP, "PBEWithHmacSHA384AndAES_128", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA384_HMAC)); + d(CIP, "PBEWithHmacSHA512AndAES_128", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA512_HMAC)); + d(CIP, "PBEWithHmacSHA1AndAES_256", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA_1_HMAC)); + d(CIP, "PBEWithHmacSHA224AndAES_256", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA224_HMAC)); + d(CIP, "PBEWithHmacSHA256AndAES_256", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA256_HMAC)); + d(CIP, "PBEWithHmacSHA384AndAES_256", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA384_HMAC)); + d(CIP, "PBEWithHmacSHA512AndAES_256", P11PBECipher, + m(CKM_AES_CBC_PAD, CKM_AES_CBC), + m(CKM_PKCS5_PBKD2, CKM_SHA512_HMAC)); + } d(SIG, "RawDSA", P11Signature, List.of("NONEwithDSA"),