summaryrefslogtreecommitdiff
path: root/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util
diff options
context:
space:
mode:
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java122
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java82
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java47
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;
}