libcore: add tests to check behaviour for padding and decrypt mode

Bug: 19186852
Change-Id: Ife346931e4ba2c8e3a99e066caee91267b1d138f
diff --git a/luni/src/test/java/libcore/javax/crypto/CipherTest.java b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
index 73357c6..7b9e7ab 100644
--- a/luni/src/test/java/libcore/javax/crypto/CipherTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
@@ -504,14 +504,12 @@
         setExpectedOutputSize("PBEWITHSHAAND192BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
         setExpectedOutputSize("PBEWITHSHAAND256BITAES-CBC-BC", Cipher.DECRYPT_MODE, 0);
         // AndroidOpenSSL returns the block size for the block ciphers
-        setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
-        setExpectedOutputSize("AES/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
-        setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
-        setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 16);
-        setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
-        setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
-        setExpectedOutputSize("DESEDE/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
-        setExpectedOutputSize("DESEDE/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 8);
+        setExpectedOutputSize("AES/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("AES/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("AES/ECB/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("AES/ECB/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("DESEDE/CBC/PKCS5PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 0);
+        setExpectedOutputSize("DESEDE/CBC/PKCS7PADDING", Cipher.DECRYPT_MODE, "AndroidOpenSSL", 0);
 
         if (StandardNames.IS_RI) {
             setExpectedOutputSize("AESWRAP", Cipher.WRAP_MODE, 8);
@@ -3274,4 +3272,50 @@
             }
         }
     }
+
+    /**
+     * When in decrypt mode and using padding, the buffer shouldn't necessarily have room for an
+     * extra block when using padding.
+     * http://b/19186852
+     */
+    public void testDecryptBufferMultipleBlockSize_mustNotThrowException() throws Exception {
+        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
+        cipher.init(Cipher.DECRYPT_MODE,
+                new SecretKeySpec("0123456789012345".getBytes("US-ASCII"), "AES"));
+        byte[] buffer = new BigInteger("0fcaa168b215767e4982121367865661", 16).toByteArray();
+        int bytesProduced = cipher.doFinal(buffer, 0, buffer.length, buffer);
+        assertEquals("Hello, World!", new String(buffer, 0, bytesProduced, "US-ASCII"));
+    }
+
+    /**
+     * When using padding in decrypt mode, ensure that empty buffers decode to empty strings
+     * (no padding needed for the empty buffer).
+     * http://b/19186852
+     */
+    public void testDecryptBufferZeroSize_mustDecodeToEmptyString() throws Exception {
+        String[] androidOpenSSLCiphers = { "AES/CBC/PKCS5PADDING", "AES/CBC/PKCS7PADDING",
+                "AES/ECB/PKCS5PADDING", "AES/ECB/PKCS7PADDING", "DESEDE/CBC/PKCS5PADDING",
+                "DESEDE/CBC/PKCS7PADDING" };
+        for (String c : androidOpenSSLCiphers) {
+            Cipher cipher = Cipher.getInstance(c);
+            if (c.contains("/CBC/")) {
+                cipher.init(Cipher.DECRYPT_MODE,
+                        new SecretKeySpec("0123456789012345".getBytes("US-ASCII"),
+                                (c.startsWith("AES/")) ? "AES" : "DESEDE"),
+                        new IvParameterSpec(
+                                ("01234567" + ((c.startsWith("AES/")) ? "89012345" : ""))
+                                        .getBytes("US-ASCII")));
+            } else {
+                cipher.init(Cipher.DECRYPT_MODE,
+                        new SecretKeySpec("0123456789012345".getBytes("US-ASCII"),
+                                (c.startsWith("AES/")) ? "AES" : "DESEDE"));
+            }
+
+            byte[] buffer = new byte[0];
+            int bytesProduced = cipher.doFinal(buffer, 0, buffer.length, buffer);
+            assertEquals("", new String(buffer, 0, bytesProduced, "US-ASCII"));
+        }
+    }
+
+
 }