src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
changeset 51052 080776992b29
parent 49789 27b359322b1e
child 53721 f35a8aaabcb9
--- a/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Thu Jul 12 08:44:39 2018 +0800
+++ b/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Fri Jul 13 02:36:42 2018 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,8 @@
 import java.security.*;
 import javax.crypto.*;
 import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
+import sun.security.util.ArrayUtil;
+
 
 /**
  * This class represents ciphers in GaloisCounter (GCM) mode.
@@ -406,8 +408,8 @@
     /**
      * Performs encryption operation.
      *
-     * <p>The input plain text <code>in</code>, starting at <code>inOff</code>
-     * and ending at <code>(inOff + len - 1)</code>, is encrypted. The result
+     * <p>The input plain text <code>in</code>, starting at <code>inOfs</code>
+     * and ending at <code>(inOfs + len - 1)</code>, is encrypted. The result
      * is stored in <code>out</code>, starting at <code>outOfs</code>.
      *
      * @param in the buffer with the input data to be encrypted
@@ -420,18 +422,21 @@
      * @return the number of bytes placed into the <code>out</code> buffer
      */
     int encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
-        if ((len % blockSize) != 0) {
-             throw new ProviderException("Internal error in input buffering");
-        }
+        ArrayUtil.blockSizeCheck(len, blockSize);
 
         checkDataLength(processed, len);
 
         processAAD();
+
         if (len > 0) {
+            ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
+            ArrayUtil.nullAndBoundsCheck(out, outOfs, len);
+
             gctrPAndC.update(in, inOfs, len, out, outOfs);
             processed += len;
             ghashAllToS.update(out, outOfs, len);
         }
+
         return len;
     }
 
@@ -451,7 +456,10 @@
             throw new ShortBufferException
                 ("Can't fit both data and tag into one buffer");
         }
-        if (out.length - outOfs < (len + tagLenBytes)) {
+        try {
+            ArrayUtil.nullAndBoundsCheck(out, outOfs,
+                (len + tagLenBytes));
+        } catch (ArrayIndexOutOfBoundsException aiobe) {
             throw new ShortBufferException("Output buffer too small");
         }
 
@@ -459,6 +467,8 @@
 
         processAAD();
         if (len > 0) {
+            ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
+
             doLastBlock(in, inOfs, len, out, outOfs, true);
         }
 
@@ -492,9 +502,7 @@
      * @return the number of bytes placed into the <code>out</code> buffer
      */
     int decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
-        if ((len % blockSize) != 0) {
-             throw new ProviderException("Internal error in input buffering");
-        }
+        ArrayUtil.blockSizeCheck(len, blockSize);
 
         checkDataLength(ibuffer.size(), len);
 
@@ -504,6 +512,7 @@
             // store internally until decryptFinal is called because
             // spec mentioned that only return recovered data after tag
             // is successfully verified
+            ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
             ibuffer.write(in, inOfs, len);
         }
         return 0;
@@ -532,22 +541,28 @@
         if (len < tagLenBytes) {
             throw new AEADBadTagException("Input too short - need tag");
         }
+
         // do this check here can also catch the potential integer overflow
         // scenario for the subsequent output buffer capacity check.
         checkDataLength(ibuffer.size(), (len - tagLenBytes));
 
-        if (out.length - outOfs < ((ibuffer.size() + len) - tagLenBytes)) {
+        try {
+            ArrayUtil.nullAndBoundsCheck(out, outOfs,
+                (ibuffer.size() + len) - tagLenBytes);
+        } catch (ArrayIndexOutOfBoundsException aiobe) {
             throw new ShortBufferException("Output buffer too small");
         }
 
         processAAD();
 
+        ArrayUtil.nullAndBoundsCheck(in, inOfs, len);
+
         // get the trailing tag bytes from 'in'
         byte[] tag = new byte[tagLenBytes];
         System.arraycopy(in, inOfs + len - tagLenBytes, tag, 0, tagLenBytes);
         len -= tagLenBytes;
 
-        if (len != 0) {
+        if (len > 0) {
             ibuffer.write(in, inOfs, len);
         }