diff options
author | David Hook <dgh@cryptoworkshop.com> | 2013-11-01 05:50:33 +0400 |
---|---|---|
committer | David Hook <dgh@cryptoworkshop.com> | 2013-11-01 05:50:33 +0400 |
commit | e20133bcb6de917145184e70acc942ed260acee4 (patch) | |
tree | 53fbdde1b021e468677af69a7fb0c262b88cfffc /prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util | |
parent | 13902ddbbf44f1fa528b011ba5cb461a90631958 (diff) |
BJA-157 added support for new AEAD API to provider.
Diffstat (limited to 'prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util')
-rw-r--r-- | prov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java | 79 |
1 files changed, 77 insertions, 2 deletions
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 f73997fc..489cbb81 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 @@ -1,5 +1,7 @@ package org.bouncycastle.jcajce.provider.symmetric.util; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -47,6 +49,7 @@ import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.paddings.TBCPadding; import org.bouncycastle.crypto.paddings.X923Padding; import org.bouncycastle.crypto.paddings.ZeroBytePadding; +import org.bouncycastle.crypto.params.AEADParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.ParametersWithRandom; @@ -62,6 +65,8 @@ public class BaseBlockCipher extends BaseWrapCipher implements PBE { + private static final Class gcmSpecClass = lookup("javax.crypto.spec.GCMParameterSpec"); + // // specs we can handle. // @@ -71,7 +76,8 @@ public class BaseBlockCipher RC5ParameterSpec.class, IvParameterSpec.class, PBEParameterSpec.class, - GOST28147ParameterSpec.class + GOST28147ParameterSpec.class, + gcmSpecClass }; private BlockCipher baseEngine; @@ -88,6 +94,20 @@ public class BaseBlockCipher private String modeName = null; + private static Class lookup(String className) + { + try + { + Class def = BaseBlockCipher.class.getClassLoader().loadClass(className); + + return def; + } + catch (Exception e) + { + return null; + } + } + protected BaseBlockCipher( BlockCipher engine) { @@ -548,12 +568,38 @@ public class BaseBlockCipher ivParam = (ParametersWithIV)param; } } + else if (gcmSpecClass != null && gcmSpecClass.isInstance(params)) + { + if (!isAEADModeName(modeName)) + { + throw new InvalidAlgorithmParameterException("GCMParameterSpec can only be used with AEAD modes."); + } + + try + { + Method tLen = gcmSpecClass.getDeclaredMethod("getTLen"); + Method iv= gcmSpecClass.getDeclaredMethod("getIV"); + + if (key instanceof RepeatedSecretKeySpec) + { + param = new AEADParameters(null, ((Integer)tLen.invoke(params)).intValue(), (byte[])iv.invoke(params)); + } + else + { + param = new AEADParameters(new KeyParameter(key.getEncoded()), ((Integer)tLen.invoke(params)).intValue(), (byte[])iv.invoke(params)); + } + } + catch (Exception e) + { + throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec."); + } + } else { throw new InvalidAlgorithmParameterException("unknown parameter type."); } - if ((ivLength != 0) && !(param instanceof ParametersWithIV)) + if ((ivLength != 0) && !(param instanceof ParametersWithIV) && !(param instanceof AEADParameters)) { SecureRandom ivRandom = random; @@ -616,6 +662,11 @@ public class BaseBlockCipher { for (int i = 0; i != availableSpecs.length; i++) { + if (availableSpecs[i] == null) + { + continue; + } + try { paramSpec = params.getParameterSpec(availableSpecs[i]); @@ -654,6 +705,18 @@ public class BaseBlockCipher } } + protected void engineUpdateAAD(byte[] input, int offset, int length) + { + cipher.updateAAD(input, offset, length); + } + + protected void engineUpdateAAD(ByteBuffer bytebuffer) + { + int offset = bytebuffer.arrayOffset() + bytebuffer.position(); + int length = bytebuffer.limit() - bytebuffer.position(); + engineUpdateAAD(bytebuffer.array(), offset, length); + } + protected byte[] engineUpdate( byte[] input, int inputOffset, @@ -803,6 +866,8 @@ public class BaseBlockCipher public int getUpdateOutputSize(int len); + public void updateAAD(byte[] input, int offset, int length); + public int processByte(byte in, byte[] out, int outOff) throws DataLengthException; @@ -864,6 +929,11 @@ public class BaseBlockCipher return cipher.getUpdateOutputSize(len); } + public void updateAAD(byte[] input, int offset, int length) + { + throw new UnsupportedOperationException("AAD is not supported in the current mode."); + } + public int processByte(byte in, byte[] out, int outOff) throws DataLengthException { return cipher.processByte(in, out, outOff); @@ -921,6 +991,11 @@ public class BaseBlockCipher return cipher.getUpdateOutputSize(len); } + public void updateAAD(byte[] input, int offset, int length) + { + cipher.processAADBytes(input, offset, length); + } + public int processByte(byte in, byte[] out, int outOff) throws DataLengthException { return cipher.processByte(in, out, outOff); |