Skip to content
Permalink
Browse files

DO NOT MERGE bouncycastle: limit input length as specified by the NIS…

…T spec

Bug: 24106146

Adapted from commit 9462245630b2913830b63310aa0d40a0901ccae5

Change-Id: Ic3cb8d87ac86700cab15c553e9cc638b55d92df4
(cherry picked from commit 08e455b)
  • Loading branch information...
Sergio Giro authored and andi34 committed Nov 12, 2015
1 parent f1d6765 commit 19dac08256aeeb2089f7a8567d237dcceb3fe219
Showing with 180 additions and 69 deletions.
  1. +33 −0 bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
  2. +147 −69 patches/bcprov.patch
@@ -22,6 +22,11 @@
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 int getOutputSize(int len)
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 int getUpdateOutputSize(int len)

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 void processAADByte(byte in)

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 @@ private void initCipher()
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 int processByte(byte in, byte[] out, int outOff)
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)

0 comments on commit 19dac08

Please sign in to comment.
You can’t perform that action at this time.