Blame SOURCES/java-1.7.0-openjdk-aes-buffering.patch

d557d5
diff -up openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java.sav openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java
d557d5
--- openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java.sav	2012-02-14 16:12:51.000000000 -0500
d557d5
+++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java	2012-05-02 14:07:20.642722122 -0400
d557d5
@@ -160,10 +160,16 @@ final class P11Cipher extends CipherSpi
d557d5
     // original IV, if in MODE_CBC or MODE_CTR
d557d5
     private byte[] iv;
d557d5
 
d557d5
-    // number of bytes buffered internally by the native mechanism and padBuffer
d557d5
-    // if we do the padding
d557d5
+    // number of bytes buffered by the blockBuffer
d557d5
     private int bytesBuffered;
d557d5
 
d557d5
+    // number of bytes buffered internally
d557d5
+    private int bytesBufferedInt;
d557d5
+
d557d5
+    // bytes buffered from an incomplete block
d557d5
+    private byte[] blockBuffer;
d557d5
+    private int blockBufferLen;
d557d5
+
d557d5
     P11Cipher(Token token, String algorithm, long mechanism)
d557d5
             throws PKCS11Exception, NoSuchAlgorithmException {
d557d5
         super();
d557d5
@@ -194,6 +200,9 @@ final class P11Cipher extends CipherSpi
d557d5
             // should not happen
d557d5
             throw new ProviderException(nspe);
d557d5
         }
d557d5
+
d557d5
+	if (blockSize > 0)
d557d5
+	    blockBuffer = new byte[blockSize];
d557d5
     }
d557d5
 
d557d5
     protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
d557d5
@@ -435,7 +444,9 @@ final class P11Cipher extends CipherSpi
d557d5
             throw ex;
d557d5
         }
d557d5
         bytesBuffered = 0;
d557d5
+	bytesBufferedInt = 0;
d557d5
         padBufferLen = 0;
d557d5
+	blockBufferLen = 0;
d557d5
         initialized = true;
d557d5
     }
d557d5
 
d557d5
@@ -445,7 +456,7 @@ final class P11Cipher extends CipherSpi
d557d5
             return 0;
d557d5
         }
d557d5
 
d557d5
-        int result = inLen + bytesBuffered;
d557d5
+        int result = inLen + bytesBuffered + bytesBufferedInt;
d557d5
         if (blockSize != 0) {
d557d5
             // minus the number of bytes in the last incomplete block.
d557d5
             result -= (result & (blockSize - 1));
d557d5
@@ -459,7 +470,7 @@ final class P11Cipher extends CipherSpi
d557d5
             return 0;
d557d5
         }
d557d5
 
d557d5
-        int result = inLen + bytesBuffered;
d557d5
+        int result = inLen + bytesBuffered + bytesBufferedInt;
d557d5
         if (blockSize != 0 && encrypt && paddingType != PAD_NONE) {
d557d5
             // add the number of bytes to make the last block complete.
d557d5
             result += (blockSize - (result & (blockSize - 1)));
d557d5
@@ -471,7 +482,9 @@ final class P11Cipher extends CipherSpi
d557d5
     private void reset() {
d557d5
         initialized = false;
d557d5
         bytesBuffered = 0;
d557d5
+	bytesBufferedInt = 0;
d557d5
         padBufferLen = 0;
d557d5
+	blockBufferLen = 0;
d557d5
         if (session != null) {
d557d5
             session = token.releaseSession(session);
d557d5
         }
d557d5
@@ -547,48 +560,57 @@ final class P11Cipher extends CipherSpi
d557d5
         try {
d557d5
             ensureInitialized();
d557d5
             int k = 0;
d557d5
-            if (encrypt) {
d557d5
-                k = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs, inLen,
d557d5
-                        0, out, outOfs, outLen);
d557d5
-            } else {
d557d5
-                int newPadBufferLen = 0;
d557d5
-                if (paddingObj != null) {
d557d5
-                    if (padBufferLen != 0) {
d557d5
-                        // NSS throws up when called with data not in multiple
d557d5
-                        // of blocks. Try to work around this by holding the
d557d5
-                        // extra data in padBuffer.
d557d5
-                        if (padBufferLen != padBuffer.length) {
d557d5
-                            int bufCapacity = padBuffer.length - padBufferLen;
d557d5
-                            if (inLen > bufCapacity) {
d557d5
-                                bufferInputBytes(in, inOfs, bufCapacity);
d557d5
-                                inOfs += bufCapacity;
d557d5
-                                inLen -= bufCapacity;
d557d5
-                            } else {
d557d5
-                                bufferInputBytes(in, inOfs, inLen);
d557d5
-                                return 0;
d557d5
-                            }
d557d5
-                        }
d557d5
-                        k = token.p11.C_DecryptUpdate(session.id(),
d557d5
-                                0, padBuffer, 0, padBufferLen,
d557d5
-                                0, out, outOfs, outLen);
d557d5
-                        padBufferLen = 0;
d557d5
-                    }
d557d5
-                    newPadBufferLen = inLen & (blockSize - 1);
d557d5
-                    if (newPadBufferLen == 0) {
d557d5
-                        newPadBufferLen = padBuffer.length;
d557d5
-                    }
d557d5
-                    inLen -= newPadBufferLen;
d557d5
-                }
d557d5
-                if (inLen > 0) {
d557d5
-                    k += token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
d557d5
+	    int newBlockBufferLen = 0;
d557d5
+
d557d5
+	    // NSS throws up when called with data not in multiple
d557d5
+	    // of blocks. Try to work around this by holding the
d557d5
+	    // extra data in blockBuffer.
d557d5
+	    if (blockBufferLen != 0) {
d557d5
+		if (blockBufferLen != blockBuffer.length) {
d557d5
+		    int bufCapacity = blockBuffer.length - blockBufferLen;
d557d5
+		    if (inLen >= bufCapacity) {
d557d5
+			bufferInputBytes(in, inOfs, bufCapacity);
d557d5
+			inOfs += bufCapacity;
d557d5
+			inLen -= bufCapacity;
d557d5
+		    } else {
d557d5
+			bufferInputBytes(in, inOfs, inLen);
d557d5
+			return 0;
d557d5
+		    }
d557d5
+		}
d557d5
+		if (encrypt) {
d557d5
+		    k = token.p11.C_EncryptUpdate(session.id(), 0, blockBuffer, 0,
d557d5
+						  blockBufferLen, 0, out, outOfs,
d557d5
+						  outLen);
d557d5
+		} else {
d557d5
+		    k = token.p11.C_DecryptUpdate(session.id(), 0, blockBuffer, 0,
d557d5
+						  blockBufferLen, 0, out, outOfs,
d557d5
+						  outLen);
d557d5
+		}
d557d5
+		blockBufferLen = 0;
d557d5
+		bytesBuffered = 0;
d557d5
+	    }
d557d5
+
d557d5
+	    if (inLen == 0)
d557d5
+		return k;
d557d5
+
d557d5
+	    newBlockBufferLen = inLen & (blockSize - 1);
d557d5
+	    if (!encrypt && paddingObj != null && newBlockBufferLen == 0)
d557d5
+		// Hold the last block in the buffer if we need to unpad
d557d5
+		newBlockBufferLen = blockBuffer.length;
d557d5
+	    inLen -= newBlockBufferLen;
d557d5
+
d557d5
+	    if (inLen > 0) {
d557d5
+		if (encrypt) {
d557d5
+                    k = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs,
d557d5
                             inLen, 0, out, (outOfs + k), (outLen - k));
d557d5
-                }
d557d5
-                // update 'padBuffer' if using our own padding impl.
d557d5
-                if (paddingObj != null) {
d557d5
-                    bufferInputBytes(in, inOfs + inLen, newPadBufferLen);
d557d5
-                }
d557d5
-            }
d557d5
-            bytesBuffered += (inLen - k);
d557d5
+		} else {
d557d5
+                    k = token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
d557d5
+                            inLen, 0, out, (outOfs + k), (outLen - k));
d557d5
+		}
d557d5
+	    }
d557d5
+
d557d5
+	    bufferInputBytes(in, inOfs + inLen, newBlockBufferLen);
d557d5
+            bytesBufferedInt += (inLen - k);
d557d5
             return k;
d557d5
         } catch (PKCS11Exception e) {
d557d5
             if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
d557d5
@@ -643,62 +665,65 @@ final class P11Cipher extends CipherSpi
d557d5
             }
d557d5
 
d557d5
             int k = 0;
d557d5
-            if (encrypt) {
d557d5
-                if (inAddr == 0 && inArray == null) {
d557d5
-                    inArray = new byte[inLen];
d557d5
-                    inBuffer.get(inArray);
d557d5
-                } else {
d557d5
-                    inBuffer.position(origPos + inLen);
d557d5
-                }
d557d5
-                k = token.p11.C_EncryptUpdate(session.id(),
d557d5
-                        inAddr, inArray, inOfs, inLen,
d557d5
-                        outAddr, outArray, outOfs, outLen);
d557d5
-            } else {
d557d5
-                int newPadBufferLen = 0;
d557d5
-                if (paddingObj != null) {
d557d5
-                    if (padBufferLen != 0) {
d557d5
-                        // NSS throws up when called with data not in multiple
d557d5
-                        // of blocks. Try to work around this by holding the
d557d5
-                        // extra data in padBuffer.
d557d5
-                        if (padBufferLen != padBuffer.length) {
d557d5
-                            int bufCapacity = padBuffer.length - padBufferLen;
d557d5
-                            if (inLen > bufCapacity) {
d557d5
-                                bufferInputBytes(inBuffer, bufCapacity);
d557d5
-                                inOfs += bufCapacity;
d557d5
-                                inLen -= bufCapacity;
d557d5
-                            } else {
d557d5
-                                bufferInputBytes(inBuffer, inLen);
d557d5
-                                return 0;
d557d5
-                            }
d557d5
-                        }
d557d5
-                        k = token.p11.C_DecryptUpdate(session.id(), 0,
d557d5
-                                padBuffer, 0, padBufferLen, outAddr, outArray,
d557d5
-                                outOfs, outLen);
d557d5
-                        padBufferLen = 0;
d557d5
-                    }
d557d5
-                    newPadBufferLen = inLen & (blockSize - 1);
d557d5
-                    if (newPadBufferLen == 0) {
d557d5
-                        newPadBufferLen = padBuffer.length;
d557d5
-                    }
d557d5
-                    inLen -= newPadBufferLen;
d557d5
-                }
d557d5
-                if (inLen > 0) {
d557d5
-                    if (inAddr == 0 && inArray == null) {
d557d5
-                        inArray = new byte[inLen];
d557d5
-                        inBuffer.get(inArray);
d557d5
-                    } else {
d557d5
-                        inBuffer.position(inBuffer.position() + inLen);
d557d5
-                    }
d557d5
-                    k += token.p11.C_DecryptUpdate(session.id(), inAddr,
d557d5
-                            inArray, inOfs, inLen, outAddr, outArray,
d557d5
-                            (outOfs + k), (outLen - k));
d557d5
-                }
d557d5
-                // update 'padBuffer' if using our own padding impl.
d557d5
-                if (paddingObj != null && newPadBufferLen != 0) {
d557d5
-                    bufferInputBytes(inBuffer, newPadBufferLen);
d557d5
-                }
d557d5
-            }
d557d5
-            bytesBuffered += (inLen - k);
d557d5
+	    int newBlockBufferLen = 0;
d557d5
+
d557d5
+	    // NSS throws up when called with data not in multiple
d557d5
+	    // of blocks. Try to work around this by holding the
d557d5
+	    // extra data in blockBuffer.
d557d5
+	    if (blockBufferLen != 0) {
d557d5
+		if (blockBufferLen != blockBuffer.length) {
d557d5
+		    int bufCapacity = blockBuffer.length - blockBufferLen;
d557d5
+		    if (inLen >= bufCapacity) {
d557d5
+			bufferInputBytes(inBuffer, bufCapacity);
d557d5
+			inOfs += bufCapacity;
d557d5
+			inLen -= bufCapacity;
d557d5
+		    } else {
d557d5
+			bufferInputBytes(inBuffer, inLen);
d557d5
+			return 0;
d557d5
+		    }
d557d5
+		}
d557d5
+		if (encrypt) {
d557d5
+		    k = token.p11.C_EncryptUpdate(session.id(), 0, blockBuffer, 0,
d557d5
+						  blockBufferLen, outAddr, outArray, outOfs,
d557d5
+						  outLen);
d557d5
+		} else {
d557d5
+		    k = token.p11.C_DecryptUpdate(session.id(), 0, blockBuffer, 0,
d557d5
+						  blockBufferLen, outAddr, outArray, outOfs,
d557d5
+						  outLen);
d557d5
+		}
d557d5
+		blockBufferLen = 0;
d557d5
+		bytesBuffered = 0;
d557d5
+	    }
d557d5
+
d557d5
+	    if (inLen == 0)
d557d5
+		return k;
d557d5
+
d557d5
+	    newBlockBufferLen = inLen & (blockSize - 1);
d557d5
+	    if (!encrypt && paddingObj != null && newBlockBufferLen == 0)
d557d5
+		// Hold the last block in the buffer if we need to unpad
d557d5
+		newBlockBufferLen = blockBuffer.length;
d557d5
+	    inLen -= newBlockBufferLen;
d557d5
+
d557d5
+	    if (inAddr == 0 && inArray == null) {
d557d5
+		inArray = new byte[inLen];
d557d5
+		inBuffer.get(inArray);
d557d5
+	    } else {
d557d5
+		inBuffer.position(inBuffer.position() + inLen);
d557d5
+	    }
d557d5
+
d557d5
+	    if (inLen > 0) {
d557d5
+		if (encrypt) {
d557d5
+                    k = token.p11.C_EncryptUpdate(session.id(), inAddr, inArray, inOfs,
d557d5
+                            inLen, outAddr, outArray, (outOfs + k), (outLen - k));
d557d5
+		} else {
d557d5
+                    k = token.p11.C_DecryptUpdate(session.id(), inAddr, inArray, inOfs,
d557d5
+                            inLen, outAddr, outArray, (outOfs + k), (outLen - k));
d557d5
+		}
d557d5
+	    }
d557d5
+
d557d5
+	    bufferInputBytes(inBuffer, newBlockBufferLen);
d557d5
+            bytesBufferedInt += (inLen - k);
d557d5
+
d557d5
             if (!(outBuffer instanceof DirectBuffer) &&
d557d5
                     !outBuffer.hasArray()) {
d557d5
                 outBuffer.put(outArray, outOfs, k);
d557d5
@@ -728,31 +753,42 @@ final class P11Cipher extends CipherSpi
d557d5
         try {
d557d5
             ensureInitialized();
d557d5
             int k = 0;
d557d5
+	    if (blockBufferLen != 0) {
d557d5
+		if (encrypt) {
d557d5
+                    k = token.p11.C_EncryptUpdate(session.id(),
d557d5
+						  0, blockBuffer, 0, blockBufferLen,
d557d5
+						  0, out, outOfs, outLen);
d557d5
+		} else {
d557d5
+		    if (paddingObj == null)
d557d5
+			k = token.p11.C_DecryptUpdate(session.id(), 0,
d557d5
+						      blockBuffer, 0, blockBufferLen, 0,
d557d5
+						      out, outOfs, outLen);
d557d5
+		    else
d557d5
+			k = token.p11.C_DecryptUpdate(session.id(), 0,
d557d5
+						      blockBuffer, 0, blockBufferLen, 0,
d557d5
+						      padBuffer, 0, padBuffer.length);
d557d5
+		}
d557d5
+	    }
d557d5
             if (encrypt) {
d557d5
                 if (paddingObj != null) {
d557d5
                     int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
d557d5
-                            requiredOutLen - bytesBuffered);
d557d5
-                    k = token.p11.C_EncryptUpdate(session.id(),
d557d5
-                            0, padBuffer, 0, actualPadLen,
d557d5
-                            0, out, outOfs, outLen);
d557d5
+                            requiredOutLen - bytesBufferedInt);
d557d5
+                    k += token.p11.C_EncryptUpdate(session.id(),
d557d5
+						   0, padBuffer, 0, actualPadLen,
d557d5
+						   0, out, (outOfs + k), (outLen - k));
d557d5
                 }
d557d5
                 k += token.p11.C_EncryptFinal(session.id(),
d557d5
                         0, out, (outOfs + k), (outLen - k));
d557d5
             } else {
d557d5
                 if (paddingObj != null) {
d557d5
-                    if (padBufferLen != 0) {
d557d5
-                        k = token.p11.C_DecryptUpdate(session.id(), 0,
d557d5
-                                padBuffer, 0, padBufferLen, 0, padBuffer, 0,
d557d5
-                                padBuffer.length);
d557d5
-                    }
d557d5
                     k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k,
d557d5
                             padBuffer.length - k);
d557d5
                     int actualPadLen = paddingObj.unpad(padBuffer, k);
d557d5
                     k -= actualPadLen;
d557d5
                     System.arraycopy(padBuffer, 0, out, outOfs, k);
d557d5
                 } else {
d557d5
-                    k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs,
d557d5
-                            outLen);
d557d5
+                    k += token.p11.C_DecryptFinal(session.id(), 0, out, (outOfs + k),
d557d5
+						  (outLen - k));
d557d5
                 }
d557d5
             }
d557d5
             return k;
d557d5
@@ -793,6 +829,23 @@ final class P11Cipher extends CipherSpi
d557d5
 
d557d5
             int k = 0;
d557d5
 
d557d5
+	    if (blockBufferLen != 0) {
d557d5
+		if (encrypt) {
d557d5
+                    k = token.p11.C_EncryptUpdate(session.id(),
d557d5
+						  0, blockBuffer, 0, blockBufferLen,
d557d5
+						  outAddr, outArray, outOfs, outLen);
d557d5
+		} else {
d557d5
+		    if (paddingObj == null)
d557d5
+			k = token.p11.C_DecryptUpdate(session.id(), 0,
d557d5
+						      blockBuffer, 0, blockBufferLen, outAddr,
d557d5
+						      outArray, outOfs, outLen);
d557d5
+		    else
d557d5
+			k = token.p11.C_DecryptUpdate(session.id(), 0,
d557d5
+						      blockBuffer, 0, blockBufferLen, 0,
d557d5
+						      padBuffer, 0, padBuffer.length);
d557d5
+		}
d557d5
+	    }
d557d5
+
d557d5
             if (encrypt) {
d557d5
                 if (paddingObj != null) {
d557d5
                     int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
d557d5
@@ -805,12 +858,6 @@ final class P11Cipher extends CipherSpi
d557d5
                         outAddr, outArray, (outOfs + k), (outLen - k));
d557d5
             } else {
d557d5
                 if (paddingObj != null) {
d557d5
-                    if (padBufferLen != 0) {
d557d5
-                        k = token.p11.C_DecryptUpdate(session.id(),
d557d5
-                                0, padBuffer, 0, padBufferLen,
d557d5
-                                0, padBuffer, 0, padBuffer.length);
d557d5
-                        padBufferLen = 0;
d557d5
-                    }
d557d5
                     k += token.p11.C_DecryptFinal(session.id(),
d557d5
                             0, padBuffer, k, padBuffer.length - k);
d557d5
                     int actualPadLen = paddingObj.unpad(padBuffer, k);
d557d5
@@ -819,7 +866,8 @@ final class P11Cipher extends CipherSpi
d557d5
                     outOfs = 0;
d557d5
                 } else {
d557d5
                     k = token.p11.C_DecryptFinal(session.id(),
d557d5
-                            outAddr, outArray, outOfs, outLen);
d557d5
+						 outAddr, outArray,
d557d5
+						 (outOfs + k), (outLen - k));
d557d5
                 }
d557d5
             }
d557d5
             if ((!encrypt && paddingObj != null) ||
d557d5
@@ -875,14 +923,14 @@ final class P11Cipher extends CipherSpi
d557d5
     }
d557d5
 
d557d5
     private final void bufferInputBytes(byte[] in, int inOfs, int len) {
d557d5
-        System.arraycopy(in, inOfs, padBuffer, padBufferLen, len);
d557d5
-        padBufferLen += len;
d557d5
+        System.arraycopy(in, inOfs, blockBuffer, blockBufferLen, len);
d557d5
+        blockBufferLen += len;
d557d5
         bytesBuffered += len;
d557d5
     }
d557d5
 
d557d5
     private final void bufferInputBytes(ByteBuffer inBuffer, int len) {
d557d5
-        inBuffer.get(padBuffer, padBufferLen, len);
d557d5
-        padBufferLen += len;
d557d5
+        inBuffer.get(blockBuffer, blockBufferLen, len);
d557d5
+        blockBufferLen += len;
d557d5
         bytesBuffered += len;
d557d5
     }
d557d5
 }