Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Whittington <bc@whittington.net.nz>2014-03-06 00:04:26 +0400
committerTim Whittington <bc@whittington.net.nz>2014-03-10 12:27:39 +0400
commit8eca220a9b2c68938b19ee6b88e0534d0a07c618 (patch)
treec86fc67b63b1e86101997475ef0f949d3d0890b1 /core/src/main/java/org/bouncycastle
parent089aec1b5ddcbd904ac057652c43c6f5b89d952d (diff)
Implement and test consistent use of DataLengthException and OutputLengthException in AEAD ciphers.
Diffstat (limited to 'core/src/main/java/org/bouncycastle')
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java39
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java18
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java23
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java18
4 files changed, 76 insertions, 22 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
index fef51fdb..7f870ca2 100644
--- a/core/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
+++ b/core/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
@@ -7,6 +7,7 @@ import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.Mac;
+import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.macs.CBCBlockCipherMac;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.ParametersWithIV;
@@ -42,7 +43,7 @@ public class CCMBlockCipher
this.cipher = c;
this.blockSize = c.getBlockSize();
this.macBlock = new byte[blockSize];
-
+
if (blockSize != 16)
{
throw new IllegalArgumentException("cipher required with a block size of 16.");
@@ -99,7 +100,7 @@ public class CCMBlockCipher
{
throw new IllegalArgumentException("nonce must have length from 7 to 13 octets");
}
-
+
reset();
}
@@ -130,6 +131,10 @@ public class CCMBlockCipher
public int processBytes(byte[] in, int inOff, int inLen, byte[] out, int outOff)
throws DataLengthException, IllegalStateException
{
+ if (in.length < (inOff + inLen))
+ {
+ throw new DataLengthException("Input buffer too short");
+ }
data.write(in, inOff, inLen);
return 0;
@@ -155,15 +160,15 @@ public class CCMBlockCipher
/**
* Returns a byte array containing the mac calculated as part of the
* last encrypt or decrypt operation.
- *
+ *
* @return the last mac calculated.
*/
public byte[] getMac()
{
byte[] mac = new byte[macSize];
-
+
System.arraycopy(macBlock, 0, mac, 0, mac.length);
-
+
return mac;
}
@@ -267,7 +272,7 @@ public class CCMBlockCipher
outputLen = inLen + macSize;
if (output.length < (outputLen + outOff))
{
- throw new DataLengthException("Output buffer too short.");
+ throw new OutputLengthException("Output buffer too short.");
}
calculateMac(in, inOff, inLen, macBlock);
@@ -300,7 +305,7 @@ public class CCMBlockCipher
outputLen = inLen - macSize;
if (output.length < (outputLen + outOff))
{
- throw new DataLengthException("Output buffer too short.");
+ throw new OutputLengthException("Output buffer too short.");
}
System.arraycopy(in, inOff + outputLen, macBlock, 0, macSize);
@@ -350,18 +355,18 @@ public class CCMBlockCipher
// build b0
//
byte[] b0 = new byte[16];
-
+
if (hasAssociatedText())
{
b0[0] |= 0x40;
}
-
+
b0[0] |= (((cMac.getMacSize() - 2) / 2) & 0x7) << 3;
b0[0] |= ((15 - nonce.length) - 1) & 0x7;
-
+
System.arraycopy(nonce, 0, b0, 1, nonce.length);
-
+
int q = dataLen;
int count = 1;
while (q > 0)
@@ -370,22 +375,22 @@ public class CCMBlockCipher
q >>>= 8;
count++;
}
-
+
cMac.update(b0, 0, b0.length);
-
+
//
// process associated text
//
if (hasAssociatedText())
{
int extra;
-
+
int textLength = getAssociatedTextLength();
if (textLength < ((1 << 16) - (1 << 8)))
{
cMac.update((byte)(textLength >> 8));
cMac.update((byte)textLength);
-
+
extra = 2;
}
else // can't go any higher than 2^32
@@ -396,7 +401,7 @@ public class CCMBlockCipher
cMac.update((byte)(textLength >> 16));
cMac.update((byte)(textLength >> 8));
cMac.update((byte)textLength);
-
+
extra = 6;
}
@@ -418,7 +423,7 @@ public class CCMBlockCipher
}
}
}
-
+
//
// add the text
//
diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java
index fbfe3727..209d5cdb 100644
--- a/core/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java
+++ b/core/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java
@@ -5,6 +5,7 @@ import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.Mac;
+import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.macs.CMac;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.ParametersWithIV;
@@ -219,6 +220,11 @@ public class EAXBlockCipher
{
initCipher();
+ if (in.length < (inOff + len))
+ {
+ throw new DataLengthException("Input buffer too short");
+ }
+
int resultLen = 0;
for (int i = 0; i != len; i++)
@@ -241,9 +247,9 @@ public class EAXBlockCipher
if (forEncryption)
{
- if (out.length < (outOff + extra))
+ if (out.length < (outOff + extra + macSize))
{
- throw new DataLengthException("Output buffer too short");
+ throw new OutputLengthException("Output buffer too short");
}
cipher.processBlock(bufBlock, 0, tmp, 0);
@@ -261,6 +267,10 @@ public class EAXBlockCipher
}
else
{
+ if (out.length < (outOff + extra - macSize))
+ {
+ throw new OutputLengthException("Output buffer too short");
+ }
if (extra < macSize)
{
throw new InvalidCipherTextException("data too short");
@@ -328,6 +338,10 @@ public class EAXBlockCipher
if (bufOff == bufBlock.length)
{
+ if (out.length < (outOff + blockSize))
+ {
+ throw new OutputLengthException("Output buffer is too short");
+ }
// TODO Could move the processByte(s) calls to here
// initCipher();
diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
index 9e617ec9..59c2eb36 100644
--- a/core/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
+++ b/core/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
@@ -4,6 +4,7 @@ import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.modes.gcm.GCMExponentiator;
import org.bouncycastle.crypto.modes.gcm.GCMMultiplier;
import org.bouncycastle.crypto.modes.gcm.Tables1kGCMExponentiator;
@@ -23,7 +24,7 @@ public class GCMBlockCipher
{
private static final int BLOCK_SIZE = 16;
- // not final due to a compiler bug
+ // not final due to a compiler bug
private BlockCipher cipher;
private GCMMultiplier multiplier;
private GCMExponentiator exp;
@@ -102,7 +103,7 @@ public class GCMBlockCipher
throw new IllegalArgumentException("Invalid value for MAC size: " + macSizeBits);
}
- macSize = macSizeBits / 8;
+ macSize = macSizeBits / 8;
keyParam = param.getKey();
}
else if (params instanceof ParametersWithIV)
@@ -119,7 +120,7 @@ public class GCMBlockCipher
throw new IllegalArgumentException("invalid parameters passed to GCM");
}
- int bufLength = forEncryption ? BLOCK_SIZE : (BLOCK_SIZE + macSize);
+ int bufLength = forEncryption ? BLOCK_SIZE : (BLOCK_SIZE + macSize);
this.bufBlock = new byte[bufLength];
if (nonce == null || nonce.length < 1)
@@ -271,6 +272,10 @@ public class GCMBlockCipher
public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
throws DataLengthException
{
+ if (in.length < (inOff + len))
+ {
+ throw new DataLengthException("Input buffer too short");
+ }
int resultLen = 0;
for (int i = 0; i < len; ++i)
@@ -288,6 +293,10 @@ public class GCMBlockCipher
private void outputBlock(byte[] output, int offset)
{
+ if (output.length < (offset + BLOCK_SIZE))
+ {
+ throw new OutputLengthException("Output buffer too short");
+ }
if (totalLength == 0)
{
initCipher();
@@ -324,6 +333,10 @@ public class GCMBlockCipher
if (extra > 0)
{
+ if (out.length < (outOff + extra))
+ {
+ throw new OutputLengthException("Output buffer too short");
+ }
gCTRPartial(bufBlock, 0, extra, out, outOff);
}
@@ -390,6 +403,10 @@ public class GCMBlockCipher
if (forEncryption)
{
+ if (out.length < (outOff + extra + macSize))
+ {
+ throw new OutputLengthException("Output buffer too short");
+ }
// Append T to the message
System.arraycopy(macBlock, 0, out, outOff + bufOff, macSize);
resultLen += macSize;
diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java
index d0345c4b..66db8beb 100644
--- a/core/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java
+++ b/core/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java
@@ -6,6 +6,7 @@ import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
@@ -317,6 +318,10 @@ public class OCBBlockCipher
public int processBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
throws DataLengthException
{
+ if (input.length < (inOff + len))
+ {
+ throw new DataLengthException("Input buffer too short");
+ }
int resultLen = 0;
for (int i = 0; i < len; ++i)
@@ -378,6 +383,10 @@ public class OCBBlockCipher
xor(mainBlock, Pad);
+ if (output.length < (outOff + mainBlockPos))
+ {
+ throw new OutputLengthException("Output buffer too short");
+ }
System.arraycopy(mainBlock, 0, output, outOff, mainBlockPos);
if (!forEncryption)
@@ -405,6 +414,10 @@ public class OCBBlockCipher
if (forEncryption)
{
+ if (output.length < (outOff + resultLen + macSize))
+ {
+ throw new OutputLengthException("Output buffer too short");
+ }
// Append tag to the message
System.arraycopy(macBlock, 0, output, outOff + resultLen, macSize);
resultLen += macSize;
@@ -456,6 +469,11 @@ public class OCBBlockCipher
protected void processMainBlock(byte[] output, int outOff)
{
+ if (output.length < (outOff + BLOCK_SIZE))
+ {
+ throw new OutputLengthException("Output buffer too short");
+ }
+
/*
* OCB-ENCRYPT/OCB-DECRYPT: Process any whole blocks
*/