< prev index next >

src/java.base/share/classes/com/sun/crypto/provider/GHASH.java

Print this page

        

@@ -126,10 +126,12 @@
 
     /* subkeyH and state are stored in long[] for GHASH intrinsic use */
 
     // 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;
 
     // variables for save/restore calls

@@ -147,13 +149,20 @@
     GHASH(byte[] subkeyH) throws ProviderException {
         if ((subkeyH == null) || subkeyH.length != AES_BLOCK_SIZE) {
             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;
+        }
     }
 
     /**
      * Resets the GHASH object to its original state, i.e. blank w/
      * the same subkey H. Used after digest() is called and to re-use

@@ -192,15 +201,15 @@
 
     void update(byte[] in, int inOfs, int inLen) {
         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);
         }
         if (inOfs < 0) {
             throw new RuntimeException("invalid offset: " + inOfs);

@@ -217,13 +226,13 @@
         // These two checks are for C2 checking
         if (st.length != 2) {
             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);
         }
     }
     /*
      * This is an intrinsified method.  The method's argument list must match
      * the hotspot signature.  This method and methods called by it, cannot
< prev index next >