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