diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java index b7dbc2f203..8438ef42ee 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java @@ -577,7 +577,7 @@ else if (paddingName.equals("TBCPADDING")) protected void engineInit( int opmode, Key key, - final AlgorithmParameterSpec params, + final AlgorithmParameterSpec paramSpec, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { @@ -599,11 +599,16 @@ protected void engineInit( // // for RC5-64 we must have some default parameters // - if (params == null && (baseEngine != null && baseEngine.getAlgorithmName().startsWith("RC5-64"))) + if (paramSpec == null && (baseEngine != null && baseEngine.getAlgorithmName().startsWith("RC5-64"))) { throw new InvalidAlgorithmParameterException("RC5 requires an RC5ParametersSpec to be passed in."); } + if (paramSpec instanceof PBEParameterSpec) + { + pbeSpec = (PBEParameterSpec)paramSpec; + } + // // a note on iv's - if ivLength is zero the IV gets ignored (we don't use it). // @@ -619,9 +624,9 @@ protected void engineInit( throw new InvalidKeyException("PKCS12 requires a SecretKey/PBEKey"); } - if (params instanceof PBEParameterSpec) + if (paramSpec instanceof PBEParameterSpec) { - pbeSpec = (PBEParameterSpec)params; + pbeSpec = (PBEParameterSpec)paramSpec; } if (k instanceof PBEKey && pbeSpec == null) @@ -670,9 +675,9 @@ else if (key instanceof PBKDF1Key) { PBKDF1Key k = (PBKDF1Key)key; - if (params instanceof PBEParameterSpec) + if (paramSpec instanceof PBEParameterSpec) { - pbeSpec = (PBEParameterSpec)params; + pbeSpec = (PBEParameterSpec)paramSpec; } if (k instanceof PBKDF1KeyWithParameters && pbeSpec == null) { @@ -700,12 +705,12 @@ else if (key instanceof BCPBEKey) if (k.getParam() != null) { - param = adjustParameters(params, k.getParam()); + param = adjustParameters(paramSpec, k.getParam()); } - else if (params instanceof PBEParameterSpec) + else if (paramSpec instanceof PBEParameterSpec) { - pbeSpec = (PBEParameterSpec)params; - param = PBE.Util.makePBEParameters(k, params, cipher.getUnderlyingCipher().getAlgorithmName()); + pbeSpec = (PBEParameterSpec)paramSpec; + param = PBE.Util.makePBEParameters(k, paramSpec, cipher.getUnderlyingCipher().getAlgorithmName()); } else { @@ -720,7 +725,7 @@ else if (params instanceof PBEParameterSpec) else if (key instanceof PBEKey) { PBEKey k = (PBEKey)key; - pbeSpec = (PBEParameterSpec)params; + pbeSpec = (PBEParameterSpec)paramSpec; if (k instanceof PKCS12KeyWithParameters && pbeSpec == null) { pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount()); @@ -745,6 +750,16 @@ else if (!(key instanceof RepeatedSecretKeySpec)) param = null; } + AlgorithmParameterSpec params; + if (pbeSpec != null) + { + params = pbeSpec.getParameterSpec(); + } + else + { + params = paramSpec; + } + if (params instanceof AEADParameterSpec) { if (!isAEADModeName(modeName) && !(cipher instanceof AEADGenericBlockCipher)) diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/PBETest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/PBETest.java index 7a6791161f..a449a5e26f 100644 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/PBETest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/PBETest.java @@ -524,6 +524,43 @@ public void testNullSalt() } } + private void testExtendedPBEParameterSpec() + throws Exception + { + String keyAlgo = "PBKDF2WITHHMACSHA512"; + String cipherAlgo = "2.16.840.1.101.3.4.1.42"; + + SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); + + char[] password = "abcdefghijklmnop".toCharArray(); + PBEKeySpec pbeKeySpec = new PBEKeySpec(password); + + SecretKeyFactory factory = SecretKeyFactory.getInstance(keyAlgo, "BC"); + SecretKey key = factory.generateSecret(pbeKeySpec); + + byte[] salt = new byte[16]; + random.nextBytes(salt); + byte[] iv = new byte[16]; + random.nextBytes(iv); + + PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, 1000, new IvParameterSpec(iv)); + + Cipher encryptCipher = Cipher.getInstance(cipherAlgo, "BC"); + Cipher decryptCipher = Cipher.getInstance(cipherAlgo, "BC"); + + encryptCipher.init(Cipher.ENCRYPT_MODE, key, pbeParamSpec); + decryptCipher.init(Cipher.DECRYPT_MODE, key, pbeParamSpec); + + byte[] input = Strings.toByteArray("testing"); + byte[] encryptedBytes = encryptCipher.doFinal(input); + byte[] decryptedBytes = decryptCipher.doFinal(encryptedBytes); + + decryptCipher = Cipher.getInstance(cipherAlgo, "BC"); + decryptCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(Hex.decode("6162636465666768696a6b6c6d6e6f70"), "AES"), pbeParamSpec.getParameterSpec()); + decryptedBytes = decryptCipher.doFinal(encryptedBytes); + + isTrue(Arrays.areEqual(input, decryptedBytes)); + } public void performTest() throws Exception { @@ -668,6 +705,8 @@ public void performTest() openSSLTests[i].perform(); } + testExtendedPBEParameterSpec(); + testPKCS12Interop(); testPBEHMac("PBEWithHMacSHA1", hMac1);