diff options
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util')
6 files changed, 171 insertions, 86 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java index fd99c41e..59b715ad 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java @@ -78,6 +78,7 @@ import org.bouncycastle.crypto.params.RC2Parameters; // END android-removed import org.bouncycastle.jcajce.PKCS12Key; import org.bouncycastle.jcajce.PKCS12KeyWithParameters; +import org.bouncycastle.jcajce.spec.AEADParameterSpec; // BEGIN android-removed // import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec; // import org.bouncycastle.jcajce.spec.RepeatedSecretKeySpec; @@ -177,9 +178,9 @@ public class BaseBlockCipher protected BaseBlockCipher( AEADBlockCipher engine) { - baseEngine = engine.getUnderlyingCipher(); - ivLength = baseEngine.getBlockSize(); - cipher = new AEADGenericBlockCipher(engine); + this.baseEngine = engine.getUnderlyingCipher(); + this.ivLength = baseEngine.getBlockSize(); + this.cipher = new AEADGenericBlockCipher(engine); } protected BaseBlockCipher( @@ -256,6 +257,18 @@ public class BaseBlockCipher return null; } } + else if (aeadParams != null) + { + try + { + engineParams = createParametersInstance("GCM"); + engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded()); + } + catch (Exception e) + { + throw new RuntimeException(e.toString()); + } + } else if (ivParam != null) { String name = cipher.getUnderlyingCipher().getAlgorithmName(); @@ -275,18 +288,6 @@ public class BaseBlockCipher throw new RuntimeException(e.toString()); } } - else if (aeadParams != null) - { - try - { - engineParams = createParametersInstance("GCM"); - engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded()); - } - catch (Exception e) - { - throw new RuntimeException(e.toString()); - } - } } return engineParams; @@ -515,7 +516,7 @@ public class BaseBlockCipher // if (!(key instanceof SecretKey)) { - throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption."); + throw new InvalidKeyException("Key for algorithm " + ((key != null) ? key.getAlgorithm() : null) + " not suitable for symmetric enryption."); } // @@ -553,34 +554,29 @@ public class BaseBlockCipher if (k instanceof PBEKey && pbeSpec == null) { - // BEGIN android-added - if (((PBEKey)k).getSalt() == null) { - throw new InvalidAlgorithmParameterException("Parameters for the algorithm are null " - + "and the PBEKey has null salt"); + PBEKey pbeKey = (PBEKey)k; + if (pbeKey.getSalt() == null) + { + throw new InvalidAlgorithmParameterException("PBEKey requires parameters to specify salt"); } - // END android-added - pbeSpec = new PBEParameterSpec(((PBEKey)k).getSalt(), ((PBEKey)k).getIterationCount()); + pbeSpec = new PBEParameterSpec(pbeKey.getSalt(), pbeKey.getIterationCount()); } if (pbeSpec == null && !(k instanceof PBEKey)) { throw new InvalidKeyException("Algorithm requires a PBE key"); } + if (key instanceof BCPBEKey) { - // BEGIN android-changed - // Was: - // if (((BCPBEKey)key).getParam() != null) - // Change taken from: - // https://github.com/bcgit/bc-java/commit/fcba5c782188d772148ba168beae368d06646ee2 - // PKCS#12 sets an IV, if we get a key that doesn't have ParametersWithIV we need to forget about the fact - // it's a BCPBEKey - if (((BCPBEKey)key).getParam() != null && ((BCPBEKey)key).getParam() instanceof ParametersWithIV) - // END android-changed + // PKCS#12 sets an IV, if we get a key that doesn't have ParametersWithIV we need to reject it. If the + // key has no parameters it means it's an old-school JCE PBE Key - we use getEncoded() on it. + CipherParameters pbeKeyParam = ((BCPBEKey)key).getParam(); + if (pbeKeyParam instanceof ParametersWithIV) { - param = ((BCPBEKey)key).getParam(); + param = pbeKeyParam; } - else + else if (pbeKeyParam == null) { // BEGIN android-changed // Was: param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS12, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName()); @@ -590,6 +586,10 @@ public class BaseBlockCipher // END android-changed throw new IllegalStateException("Unreachable code"); } + else + { + throw new InvalidKeyException("Algorithm requires a PBE key suitable for PKCS12"); + } } else { @@ -696,7 +696,27 @@ public class BaseBlockCipher // } // END android-removed - if (params instanceof IvParameterSpec) + if (params instanceof AEADParameterSpec) + { + if (!isAEADModeName(modeName) && !(cipher instanceof AEADGenericBlockCipher)) + { + throw new InvalidAlgorithmParameterException("AEADParameterSpec can only be used with AEAD modes."); + } + + AEADParameterSpec aeadSpec = (AEADParameterSpec)params; + + KeyParameter keyParam; + if (param instanceof ParametersWithIV) + { + keyParam = (KeyParameter)((ParametersWithIV)param).getParameters(); + } + else + { + keyParam = (KeyParameter)param; + } + param = aeadParams = new AEADParameters(keyParam, aeadSpec.getMacSizeInBits(), aeadSpec.getNonce(), aeadSpec.getAssociatedData()); + } + else if (params instanceof IvParameterSpec) { if (ivLength != 0) { @@ -878,6 +898,8 @@ public class BaseBlockCipher } } + + if (random != null && padded) { param = new ParametersWithRandom(param, random); @@ -898,16 +920,17 @@ public class BaseBlockCipher default: throw new InvalidParameterException("unknown opmode " + opmode + " passed"); } + + if (cipher instanceof AEADGenericBlockCipher && aeadParams == null) + { + AEADBlockCipher aeadCipher = ((AEADGenericBlockCipher)cipher).cipher; + + aeadParams = new AEADParameters((KeyParameter)ivParam.getParameters(), aeadCipher.getMac().length * 8, ivParam.getIV()); + } } catch (final Exception e) { - throw new InvalidKeyException(e.getMessage()) - { - public Throwable getCause() - { - return e; - } - }; + throw new InvalidKeyOrParametersException(e.getMessage(), e); } } @@ -1393,4 +1416,21 @@ public class BaseBlockCipher } } } + + private static class InvalidKeyOrParametersException + extends InvalidKeyException + { + private final Throwable cause; + + InvalidKeyOrParametersException(String msg, Throwable cause) + { + super(msg); + this.cause = cause; + } + + public Throwable getCause() + { + return cause; + } + } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java index f6076170..51c29d96 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java @@ -1,5 +1,6 @@ package org.bouncycastle.jcajce.provider.symmetric.util; +import java.lang.reflect.Method; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; @@ -13,15 +14,19 @@ import javax.crypto.SecretKey; import javax.crypto.interfaces.PBEKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEParameterSpec; +import javax.crypto.spec.RC2ParameterSpec; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.Mac; +import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; // BEGIN android-removed +// import org.bouncycastle.crypto.params.RC2Parameters; // import org.bouncycastle.crypto.params.SkeinParameters; // END android-removed import org.bouncycastle.jcajce.PKCS12Key; +import org.bouncycastle.jcajce.spec.AEADParameterSpec; // BEGIN android-removed // import org.bouncycastle.jcajce.spec.SkeinParameterSpec; // END android-removed @@ -29,6 +34,8 @@ import org.bouncycastle.jcajce.PKCS12Key; public class BaseMac extends MacSpi implements PBE { + private static final Class gcmSpecClass = lookup("javax.crypto.spec.GCMParameterSpec"); + private Mac macEngine; private int scheme = PKCS12; @@ -129,26 +136,77 @@ public class BaseMac throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set."); } } + else + { + if (params instanceof PBEParameterSpec) + { + throw new InvalidAlgorithmParameterException("inappropriate parameter type: " + params.getClass().getName()); + } + param = new KeyParameter(key.getEncoded()); + } + + KeyParameter keyParam; + if (param instanceof ParametersWithIV) + { + keyParam = (KeyParameter)((ParametersWithIV)param).getParameters(); + } + else + { + keyParam = (KeyParameter)param; + } + + if (params instanceof AEADParameterSpec) + { + AEADParameterSpec aeadSpec = (AEADParameterSpec)params; + + param = new AEADParameters(keyParam, aeadSpec.getMacSizeInBits(), aeadSpec.getNonce(), aeadSpec.getAssociatedData()); + } else if (params instanceof IvParameterSpec) { - param = new ParametersWithIV(new KeyParameter(key.getEncoded()), ((IvParameterSpec)params).getIV()); + param = new ParametersWithIV(keyParam, ((IvParameterSpec)params).getIV()); } // BEGIN android-removed + // else if (params instanceof RC2ParameterSpec) + // { + // param = new ParametersWithIV(new RC2Parameters(keyParam.getKey(), ((RC2ParameterSpec)params).getEffectiveKeyBits()), ((RC2ParameterSpec)params).getIV()); + // } + // else if (params instanceof SkeinParameterSpec) // { - // param = new SkeinParameters.Builder(copyMap(((SkeinParameterSpec)params).getParameters())).setKey(key.getEncoded()).build(); + // param = new SkeinParameters.Builder(copyMap(((SkeinParameterSpec)params).getParameters())).setKey(keyParam.getKey()).build(); // } // END android-removed else if (params == null) { param = new KeyParameter(key.getEncoded()); } - else + else if (gcmSpecClass != null && gcmSpecClass.isAssignableFrom(params.getClass())) { - throw new InvalidAlgorithmParameterException("unknown parameter type."); + try + { + Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]); + Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]); + + param = new AEADParameters(keyParam, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0])); + } + catch (Exception e) + { + throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec."); + } + } + else if (!(params instanceof PBEParameterSpec)) + { + throw new InvalidAlgorithmParameterException("unknown parameter type: " + params.getClass().getName()); } - macEngine.init(param); + try + { + macEngine.init(param); + } + catch (Exception e) + { + throw new InvalidAlgorithmParameterException("cannot initialize MAC: " + e.getMessage()); + } } protected int engineGetMacLength() @@ -197,4 +255,18 @@ public class BaseMac return newTable; } + + private static Class lookup(String className) + { + try + { + Class def = BaseBlockCipher.class.getClassLoader().loadClass(className); + + return def; + } + catch (Exception e) + { + return null; + } + } } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java index 31896cd2..9e798428 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java @@ -32,7 +32,7 @@ public class BaseSecretKeyFactory { if (keySpec instanceof SecretKeySpec) { - return (SecretKey)keySpec; + return new SecretKeySpec(((SecretKeySpec)keySpec).getEncoded(), algName); } throw new InvalidKeySpecException("Invalid KeySpec"); diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java index ece0d146..e2c86766 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java @@ -102,7 +102,7 @@ public abstract class BaseWrapCipher protected int engineGetKeySize( Key key) { - return key.getEncoded().length; + return key.getEncoded().length * 8; } protected int engineGetOutputSize( diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java index b5a95526..84da1003 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java @@ -43,7 +43,7 @@ public class IvAlgorithmParameters Class paramSpec) throws InvalidParameterSpecException { - if (paramSpec == IvParameterSpec.class) + if (paramSpec == IvParameterSpec.class || paramSpec == AlgorithmParameterSpec.class) { return new IvParameterSpec(iv); } diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java index be131f4e..2e4f96b5 100644 --- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java +++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java @@ -13,18 +13,15 @@ import javax.crypto.spec.PBEParameterSpec; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.PBEParametersGenerator; +// BEGIN android-added +import org.bouncycastle.crypto.digests.AndroidDigestFactory; +// END android-added // BEGIN android-removed // import org.bouncycastle.crypto.digests.GOST3411Digest; // import org.bouncycastle.crypto.digests.MD2Digest; -// import org.bouncycastle.crypto.digests.MD5Digest; // import org.bouncycastle.crypto.digests.RIPEMD160Digest; -// import org.bouncycastle.crypto.digests.SHA1Digest; -// import org.bouncycastle.crypto.digests.SHA256Digest; // import org.bouncycastle.crypto.digests.TigerDigest; // END android-removed -// BEGIN android-added -import org.bouncycastle.crypto.digests.AndroidDigestFactory; -// END android-added import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator; @@ -32,6 +29,9 @@ import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.params.DESParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; +// BEGIN android-removed +// import org.bouncycastle.crypto.util.DigestFactory; +// END android-removed public interface PBE { @@ -49,6 +49,9 @@ public interface PBE // static final int MD2 = 5; // static final int GOST3411 = 6; // END android-removed + static final int SHA224 = 7; + static final int SHA384 = 8; + static final int SHA512 = 9; static final int PKCS5S1 = 0; static final int PKCS5S2 = 1; @@ -56,11 +59,6 @@ public interface PBE static final int OPENSSL = 3; static final int PKCS5S1_UTF8 = 4; static final int PKCS5S2_UTF8 = 5; - // BEGIN android-added - static final int SHA224 = 6; - static final int SHA384 = 7; - static final int SHA512 = 8; - // END android-added /** @@ -111,6 +109,7 @@ public interface PBE generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getMD5()); // END android-changed break; + case SHA1: // BEGIN android-changed generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA1()); @@ -142,11 +141,6 @@ public interface PBE generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA512()); break; // END android-added - // BEGIN android-removed - // case GOST3411: - // generator = new PKCS5S2ParametersGenerator(new GOST3411Digest()); - // break; - // END android-removed default: throw new IllegalStateException("unknown digest scheme for PBE PKCS5S2 encryption."); } @@ -195,12 +189,6 @@ public interface PBE case SHA512: generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA512()); break; - // END android-added - // BEGIN android-removed - // case GOST3411: - // generator = new PKCS12ParametersGenerator(new GOST3411Digest()); - // break; - // END android-removed default: throw new IllegalStateException("unknown digest scheme for PBE encryption."); } @@ -284,11 +272,6 @@ public interface PBE } } - for (int i = 0; i != key.length; i++) - { - key[i] = 0; - } - return param; } @@ -358,11 +341,6 @@ public interface PBE } } - for (int i = 0; i != key.length; i++) - { - key[i] = 0; - } - return param; } @@ -388,11 +366,6 @@ public interface PBE generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount()); param = generator.generateDerivedMacParameters(pbeKey.getKeySize()); - - for (int i = 0; i != key.length; i++) - { - key[i] = 0; - } return param; } |