diff options
author | Sergio Giro <sgiro@google.com> | 2015-11-12 22:10:47 +0000 |
---|---|---|
committer | Sergio Giro <sgiro@google.com> | 2015-11-16 23:36:05 +0000 |
commit | 59d4ea83797f7712d75e8a54420804b9f6ffe309 (patch) | |
tree | ee14d9625f03f7a9042cbd4e9e76e47d336cc223 /bcprov | |
parent | 2a64eecc02ffb5b991fb5c367eab777b1325eef8 (diff) | |
download | bouncycastle-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.java | 33 |
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) |