summaryrefslogtreecommitdiff
path: root/bcprov
diff options
context:
space:
mode:
authorSergio Giro <sgiro@google.com>2015-11-12 22:10:47 +0000
committerSergio Giro <sgiro@google.com>2015-11-16 23:36:05 +0000
commit59d4ea83797f7712d75e8a54420804b9f6ffe309 (patch)
treeee14d9625f03f7a9042cbd4e9e76e47d336cc223 /bcprov
parent2a64eecc02ffb5b991fb5c367eab777b1325eef8 (diff)
downloadbouncycastle-59d4ea83797f7712d75e8a54420804b9f6ffe309.tar.gz
DO NOT MERGE bouncycastle: limit input length as specified by the NIST spec
Bug: 24106146 Adapted from commit 9462245630b2913830b63310aa0d40a0901ccae5 Change-Id: Ic3cb8d87ac86700cab15c553e9cc638b55d92df4
Diffstat (limited to 'bcprov')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java33
1 files changed, 33 insertions, 0 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
index 9e617ec9..031fe1b9 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
@@ -22,6 +22,11 @@ public class GCMBlockCipher
implements AEADBlockCipher
{
private static final int BLOCK_SIZE = 16;
+ // BEGIN android-added
+ // 2^36-32 : limitation imposed by NIST GCM as otherwise the counter is wrapped and it can leak
+ // plaintext and authentication key
+ private static final long MAX_INPUT_SIZE = 68719476704L;
+ // END android-added
// not final due to a compiler bug
private BlockCipher cipher;
@@ -194,6 +199,14 @@ public class GCMBlockCipher
return totalData < macSize ? 0 : totalData - macSize;
}
+ // BEGIN android-added
+ /** Helper used to ensure that {@link #MAX_INPUT_SIZE} is not exceeded. */
+ private long getTotalInputSizeAfterNewInput(int newInputLen)
+ {
+ return totalLength + newInputLen + bufOff;
+ }
+ // END android-added
+
public int getUpdateOutputSize(int len)
{
int totalData = len + bufOff;
@@ -210,6 +223,11 @@ public class GCMBlockCipher
public void processAADByte(byte in)
{
+ // BEGIN android-added
+ if (getTotalInputSizeAfterNewInput(1) > MAX_INPUT_SIZE) {
+ throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes");
+ }
+ // END android-added
atBlock[atBlockPos] = in;
if (++atBlockPos == BLOCK_SIZE)
{
@@ -222,6 +240,11 @@ public class GCMBlockCipher
public void processAADBytes(byte[] in, int inOff, int len)
{
+ // BEGIN android-added
+ if (getTotalInputSizeAfterNewInput(len) > MAX_INPUT_SIZE) {
+ throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes");
+ }
+ // END android-added
for (int i = 0; i < len; ++i)
{
atBlock[atBlockPos] = in[inOff + i];
@@ -259,6 +282,11 @@ public class GCMBlockCipher
public int processByte(byte in, byte[] out, int outOff)
throws DataLengthException
{
+ // BEGIN android-added
+ if (getTotalInputSizeAfterNewInput(1) > MAX_INPUT_SIZE) {
+ throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes");
+ }
+ // END android-added
bufBlock[bufOff] = in;
if (++bufOff == bufBlock.length)
{
@@ -271,6 +299,11 @@ public class GCMBlockCipher
public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
throws DataLengthException
{
+ // BEGIN android-added
+ if (getTotalInputSizeAfterNewInput(len) > MAX_INPUT_SIZE) {
+ throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes");
+ }
+ // END android-added
int resultLen = 0;
for (int i = 0; i < len; ++i)