--- old/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java 2018-11-19 12:13:25.846251400 -0800 +++ new/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java 2018-11-19 12:13:24.942161000 -0800 @@ -128,6 +128,8 @@ // hash subkey H; should not change after the object has been constructed private final long[] subkeyH; + // subkeyHtbl holds 2*9 powers of subkeyH computed using carry-less multiplication + private long[] subkeyHtbl; // buffer for storing hash private final long[] state; @@ -149,9 +151,16 @@ throw new ProviderException("Internal error"); } state = new long[2]; + subkeyHtbl = new long[2*9]; this.subkeyH = new long[2]; this.subkeyH[0] = getLong(subkeyH, 0); this.subkeyH[1] = getLong(subkeyH, 8); + subkeyHtbl[0] = this.subkeyH[0]; + subkeyHtbl[1] = this.subkeyH[1]; + for (int i = 1; i < 9 ; i++) { + subkeyHtbl[2*i] = 0; + subkeyHtbl[2*i+1] = 0; + } } /** @@ -194,11 +203,11 @@ if (inLen == 0) { return; } - ghashRangeCheck(in, inOfs, inLen, state, subkeyH); - processBlocks(in, inOfs, inLen/AES_BLOCK_SIZE, state, subkeyH); + ghashRangeCheck(in, inOfs, inLen, state, subkeyHtbl); + processBlocks(in, inOfs, inLen/AES_BLOCK_SIZE, state, subkeyHtbl); } - private static void ghashRangeCheck(byte[] in, int inOfs, int inLen, long[] st, long[] subH) { + private static void ghashRangeCheck(byte[] in, int inOfs, int inLen, long[] st, long[] subkeyHtbl) { if (inLen < 0) { throw new RuntimeException("invalid input length: " + inLen); } @@ -219,9 +228,9 @@ throw new RuntimeException("internal state has invalid length: " + st.length); } - if (subH.length != 2) { + if (subkeyHtbl.length != 18) { throw new RuntimeException("internal subkeyH has invalid length: " + - subH.length); + subkeyHtbl.length); } } /*