summaryrefslogtreecommitdiff
path: root/bcprov/src/main/java/org/bouncycastle/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/crypto')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java32
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithID.java28
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java15
3 files changed, 73 insertions, 2 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 54e54cec..1ba5ebb1 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
@@ -37,6 +37,7 @@ public class GCMBlockCipher
// These fields are set by init and not modified by processing
private boolean forEncryption;
+ private boolean initialised;
private int macSize;
private byte[] lastKey;
private byte[] nonce;
@@ -99,6 +100,7 @@ public class GCMBlockCipher
{
this.forEncryption = forEncryption;
this.macBlock = null;
+ this.initialised = true;
KeyParameter keyParam;
byte[] newNonce = null;
@@ -260,6 +262,7 @@ public class GCMBlockCipher
public void processAADByte(byte in)
{
+ checkStatus();
// BEGIN android-added
if (getTotalInputSizeAfterNewInput(1) > MAX_INPUT_SIZE) {
throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes");
@@ -319,11 +322,13 @@ public class GCMBlockCipher
public int processByte(byte in, byte[] out, int outOff)
throws DataLengthException
{
+ checkStatus();
// 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)
{
@@ -336,11 +341,13 @@ public class GCMBlockCipher
public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff)
throws DataLengthException
{
+ checkStatus();
// BEGIN android-added
if (getTotalInputSizeAfterNewInput(len) > MAX_INPUT_SIZE) {
throw new DataLengthException("Input exceeded " + MAX_INPUT_SIZE + " bytes");
}
// END android-added
+
if (in.length < (inOff + len))
{
throw new DataLengthException("Input buffer too short");
@@ -385,6 +392,8 @@ public class GCMBlockCipher
public int doFinal(byte[] out, int outOff)
throws IllegalStateException, InvalidCipherTextException
{
+ checkStatus();
+
if (totalLength == 0)
{
initCipher();
@@ -534,9 +543,16 @@ public class GCMBlockCipher
macBlock = null;
}
- if (initialAssociatedText != null)
+ if (forEncryption)
{
- processAADBytes(initialAssociatedText, 0, initialAssociatedText.length);
+ initialised = false;
+ }
+ else
+ {
+ if (initialAssociatedText != null)
+ {
+ processAADBytes(initialAssociatedText, 0, initialAssociatedText.length);
+ }
}
}
@@ -604,4 +620,16 @@ public class GCMBlockCipher
cipher.processBlock(counter, 0, tmp, 0);
return tmp;
}
+
+ private void checkStatus()
+ {
+ if (!initialised)
+ {
+ if (forEncryption)
+ {
+ throw new IllegalStateException("GCM cipher cannot be reused for encryption");
+ }
+ throw new IllegalStateException("GCM cipher needs to be initialised");
+ }
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithID.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithID.java
new file mode 100644
index 00000000..e942a5a8
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/ParametersWithID.java
@@ -0,0 +1,28 @@
+package org.bouncycastle.crypto.params;
+
+import org.bouncycastle.crypto.CipherParameters;
+
+public class ParametersWithID
+ implements CipherParameters
+{
+ private CipherParameters parameters;
+ private byte[] id;
+
+ public ParametersWithID(
+ CipherParameters parameters,
+ byte[] id)
+ {
+ this.parameters = parameters;
+ this.id = id;
+ }
+
+ public byte[] getID()
+ {
+ return id;
+ }
+
+ public CipherParameters getParameters()
+ {
+ return parameters;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java b/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java
new file mode 100644
index 00000000..a5c583b0
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/tls/TlsNoCloseNotifyException.java
@@ -0,0 +1,15 @@
+package org.bouncycastle.crypto.tls;
+
+import java.io.EOFException;
+
+/**
+ * This exception will be thrown (only) when the connection is closed by the peer without sending a
+ * {@link AlertDescription#close_notify close_notify} warning alert. If this happens, the TLS
+ * protocol cannot rule out truncation of the connection data (potentially malicious). It may be
+ * possible to check for truncation via some property of a higher level protocol built upon TLS,
+ * e.g. the Content-Length header for HTTPS.
+ */
+public class TlsNoCloseNotifyException
+ extends EOFException
+{
+}