Created
April 9, 2017 18:36
-
-
Save apoleon/f38f47fe05ee66efdfbd38ee60a57944 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From: Markus Koschany <apo@debian.org> | |
Date: Sun, 9 Apr 2017 20:16:02 +0200 | |
Subject: CVE-2015-6644 | |
--- | |
.../bouncycastle/crypto/modes/GCMBlockCipher.java | 38 ++++++++++++++-------- | |
1 file changed, 24 insertions(+), 14 deletions(-) | |
diff --git a/src/org/bouncycastle/crypto/modes/GCMBlockCipher.java b/src/org/bouncycastle/crypto/modes/GCMBlockCipher.java | |
index 8e7c315..73193bc 100644 | |
--- a/src/org/bouncycastle/crypto/modes/GCMBlockCipher.java | |
+++ b/src/org/bouncycastle/crypto/modes/GCMBlockCipher.java | |
@@ -41,6 +41,7 @@ public class GCMBlockCipher | |
private byte[] macBlock; | |
private byte[] S; | |
private byte[] counter; | |
+ private int blocksRemaining; | |
private int bufOff; | |
private long totalLength; | |
@@ -157,6 +158,7 @@ public class GCMBlockCipher | |
this.S = Arrays.clone(initS); | |
this.counter = Arrays.clone(J0); | |
+ this.blocksRemaining = -2; | |
this.bufOff = 0; | |
this.totalLength = 0; | |
} | |
@@ -307,6 +309,7 @@ public class GCMBlockCipher | |
{ | |
S = Arrays.clone(initS); | |
counter = Arrays.clone(J0); | |
+ blocksRemaining = -2; | |
bufOff = 0; | |
totalLength = 0; | |
@@ -325,20 +328,7 @@ public class GCMBlockCipher | |
private void gCTRBlock(byte[] buf, int bufCount, byte[] out, int outOff) | |
{ | |
-// inc(counter); | |
- for (int i = 15; i >= 12; --i) | |
- { | |
- byte b = (byte)((counter[i] + 1) & 0xff); | |
- counter[i] = b; | |
- | |
- if (b != 0) | |
- { | |
- break; | |
- } | |
- } | |
- | |
- byte[] tmp = new byte[BLOCK_SIZE]; | |
- cipher.processBlock(counter, 0, tmp, 0); | |
+ byte[] tmp = getNextCounterBlock(); | |
byte[] hashBytes; | |
if (forEncryption) | |
@@ -413,4 +403,24 @@ public class GCMBlockCipher | |
Pack.intToBigEndian((int)(count >>> 32), bs, off); | |
Pack.intToBigEndian((int)count, bs, off + 4); | |
} | |
+ | |
+ private byte[] getNextCounterBlock() | |
+ { | |
+ if (blocksRemaining == 0) | |
+ { | |
+ throw new IllegalStateException("Attempt to process too many blocks"); | |
+ } | |
+ blocksRemaining--; | |
+ | |
+ int c = 1; | |
+ c += counter[15] & 0xFF; counter[15] = (byte)c; c >>>= 8; | |
+ c += counter[14] & 0xFF; counter[14] = (byte)c; c >>>= 8; | |
+ c += counter[13] & 0xFF; counter[13] = (byte)c; c >>>= 8; | |
+ c += counter[12] & 0xFF; counter[12] = (byte)c; | |
+ | |
+ byte[] tmp = new byte[BLOCK_SIZE]; | |
+ // TODO Sure would be nice if ciphers could operate on int[] | |
+ cipher.processBlock(counter, 0, tmp, 0); | |
+ return tmp; | |
+ } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment