8049312: AES/CICO test failed with on several modes
Summary: Fixed error in calculating data sizes when using feedback modes
Reviewed-by: xuelei
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java Tue Dec 23 02:36:48 2014 +0000
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java Tue Dec 23 02:58:15 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -26,6 +26,8 @@
package com.sun.crypto.provider;
import java.security.InvalidKeyException;
+import java.security.ProviderException;
+
/**
* This class represents ciphers in cipher block chaining (CBC) mode.
@@ -122,31 +124,31 @@
*
* <p>The input plain text <code>plain</code>, starting at
* <code>plainOffset</code> and ending at
- * <code>(plainOffset + len - 1)</code>, is encrypted.
+ * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
* The result is stored in <code>cipher</code>, starting at
* <code>cipherOffset</code>.
*
- * <p>It is the application's responsibility to make sure that
- * <code>plainLen</code> is a multiple of the embedded cipher's block size,
- * as any excess bytes are ignored.
- *
* @param plain the buffer with the input data to be encrypted
* @param plainOffset the offset in <code>plain</code>
* @param plainLen the length of the input data
* @param cipher the buffer for the result
* @param cipherOffset the offset in <code>cipher</code>
+ * @exception ProviderException if <code>len</code> is not
+ * a multiple of the block size
* @return the length of the encrypted data
*/
int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset)
{
- int i;
+ if ((plainLen % blockSize) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
int endIndex = plainOffset + plainLen;
for (; plainOffset < endIndex;
plainOffset+=blockSize, cipherOffset += blockSize) {
- for (i=0; i<blockSize; i++) {
- k[i] = (byte)(plain[i+plainOffset] ^ r[i]);
+ for (int i = 0; i < blockSize; i++) {
+ k[i] = (byte)(plain[i + plainOffset] ^ r[i]);
}
embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset);
System.arraycopy(cipher, cipherOffset, r, 0, blockSize);
@@ -159,14 +161,10 @@
*
* <p>The input cipher text <code>cipher</code>, starting at
* <code>cipherOffset</code> and ending at
- * <code>(cipherOffset + len - 1)</code>, is decrypted.
+ * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
* The result is stored in <code>plain</code>, starting at
* <code>plainOffset</code>.
*
- * <p>It is the application's responsibility to make sure that
- * <code>cipherLen</code> is a multiple of the embedded cipher's block
- * size, as any excess bytes are ignored.
- *
* <p>It is also the application's responsibility to make sure that
* <code>init</code> has been called before this method is called.
* (This check is omitted here, to avoid double checking.)
@@ -176,23 +174,23 @@
* @param cipherLen the length of the input data
* @param plain the buffer for the result
* @param plainOffset the offset in <code>plain</code>
+ * @exception ProviderException if <code>len</code> is not
+ * a multiple of the block size
* @return the length of the decrypted data
- *
- * @exception IllegalBlockSizeException if input data whose length does
- * not correspond to the embedded cipher's block size is passed to the
- * embedded cipher
*/
int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset)
{
- int i;
+ if ((cipherLen % blockSize) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
int endIndex = cipherOffset + cipherLen;
for (; cipherOffset < endIndex;
cipherOffset += blockSize, plainOffset += blockSize) {
embeddedCipher.decryptBlock(cipher, cipherOffset, k, 0);
- for (i = 0; i < blockSize; i++) {
- plain[i+plainOffset] = (byte)(k[i] ^ r[i]);
+ for (int i = 0; i < blockSize; i++) {
+ plain[i + plainOffset] = (byte)(k[i] ^ r[i]);
}
System.arraycopy(cipher, cipherOffset, r, 0, blockSize);
}
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java Tue Dec 23 02:36:48 2014 +0000
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java Tue Dec 23 02:58:15 2014 +0000
@@ -708,7 +708,7 @@
len -= blockSize;
}
// do not count the trailing bytes which do not make up a unit
- len = (len > 0 ? (len - (len%unitBytes)) : 0);
+ len = (len > 0 ? (len - (len % unitBytes)) : 0);
// check output buffer capacity
if ((output == null) ||
@@ -747,6 +747,9 @@
int bufferCapacity = buffer.length - buffered;
if (bufferCapacity != 0) {
temp = Math.min(bufferCapacity, inputConsumed);
+ if (unitBytes != blockSize) {
+ temp -= ((buffered + temp) % unitBytes);
+ }
System.arraycopy(input, inputOffset, buffer, buffered, temp);
inputOffset += temp;
inputConsumed -= temp;
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherFeedback.java Tue Dec 23 02:36:48 2014 +0000
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherFeedback.java Tue Dec 23 02:58:15 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -26,6 +26,7 @@
package com.sun.crypto.provider;
import java.security.InvalidKeyException;
+import java.security.ProviderException;
/**
* This class represents ciphers in cipher-feedback (CFB) mode.
@@ -133,66 +134,72 @@
*
* <p>The input plain text <code>plain</code>, starting at
* <code>plainOffset</code> and ending at
- * <code>(plainOffset + len - 1)</code>, is encrypted.
+ * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
* The result is stored in <code>cipher</code>, starting at
* <code>cipherOffset</code>.
*
- * <p>It is the application's responsibility to make sure that
- * <code>plainLen</code> is a multiple of the stream unit size
- * <code>numBytes</code>, as any excess bytes are ignored.
- *
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
- *
* @param plain the buffer with the input data to be encrypted
* @param plainOffset the offset in <code>plain</code>
* @param plainLen the length of the input data
* @param cipher the buffer for the result
* @param cipherOffset the offset in <code>cipher</code>
+ * @exception ProviderException if <code>plainLen</code> is not
+ * a multiple of the <code>numBytes</code>
* @return the length of the encrypted data
*/
int encrypt(byte[] plain, int plainOffset, int plainLen,
- byte[] cipher, int cipherOffset)
- {
- int i, len;
- len = blockSize - numBytes;
+ byte[] cipher, int cipherOffset) {
+ if ((plainLen % numBytes) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
+
+ int nShift = blockSize - numBytes;
int loopCount = plainLen / numBytes;
- int oddBytes = plainLen % numBytes;
- if (len == 0) {
- for (; loopCount > 0 ;
- plainOffset += numBytes, cipherOffset += numBytes,
- loopCount--) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- for (i = 0; i < blockSize; i++)
- register[i] = cipher[i+cipherOffset] =
- (byte)(k[i] ^ plain[i+plainOffset]);
+ for (; loopCount > 0 ;
+ plainOffset += numBytes, cipherOffset += numBytes,
+ loopCount--) {
+ embeddedCipher.encryptBlock(register, 0, k, 0);
+ if (nShift != 0) {
+ System.arraycopy(register, numBytes, register, 0, nShift);
+ }
+ for (int i = 0; i < numBytes; i++) {
+ register[nShift + i] = cipher[i + cipherOffset] =
+ (byte)(k[i] ^ plain[i + plainOffset]);
}
- if (oddBytes > 0) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- for (i=0; i<oddBytes; i++)
- register[i] = cipher[i+cipherOffset] =
- (byte)(k[i] ^ plain[i+plainOffset]);
- }
- } else {
- for (; loopCount > 0 ;
- plainOffset += numBytes, cipherOffset += numBytes,
- loopCount--) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- System.arraycopy(register, numBytes, register, 0, len);
- for (i=0; i<numBytes; i++)
- register[i+len] = cipher[i+cipherOffset] =
- (byte)(k[i] ^ plain[i+plainOffset]);
+ }
+ return plainLen;
+ }
- }
- if (oddBytes != 0) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- System.arraycopy(register, numBytes, register, 0, len);
- for (i=0; i<oddBytes; i++) {
- register[i+len] = cipher[i+cipherOffset] =
- (byte)(k[i] ^ plain[i+plainOffset]);
- }
+ /**
+ * Performs the last encryption operation.
+ *
+ * <p>The input plain text <code>plain</code>, starting at
+ * <code>plainOffset</code> and ending at
+ * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
+ * The result is stored in <code>cipher</code>, starting at
+ * <code>cipherOffset</code>.
+ *
+ * @param plain the buffer with the input data to be encrypted
+ * @param plainOffset the offset in <code>plain</code>
+ * @param plainLen the length of the input data
+ * @param cipher the buffer for the result
+ * @param cipherOffset the offset in <code>cipher</code>
+ * @return the number of bytes placed into <code>cipher</code>
+ */
+ int encryptFinal(byte[] plain, int plainOffset, int plainLen,
+ byte[] cipher, int cipherOffset) {
+
+ int oddBytes = plainLen % numBytes;
+ int len = encrypt(plain, plainOffset, (plainLen - oddBytes),
+ cipher, cipherOffset);
+ plainOffset += len;
+ cipherOffset += len;
+ if (oddBytes != 0) {
+ embeddedCipher.encryptBlock(register, 0, k, 0);
+ for (int i = 0; i < oddBytes; i++) {
+ cipher[i + cipherOffset] =
+ (byte)(k[i] ^ plain[i + plainOffset]);
}
}
return plainLen;
@@ -203,17 +210,52 @@
*
* <p>The input cipher text <code>cipher</code>, starting at
* <code>cipherOffset</code> and ending at
- * <code>(cipherOffset + len - 1)</code>, is decrypted.
+ * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
* The result is stored in <code>plain</code>, starting at
* <code>plainOffset</code>.
*
- * <p>It is the application's responsibility to make sure that
- * <code>cipherLen</code> is a multiple of the stream unit size
- * <code>numBytes</code>, as any excess bytes are ignored.
+ * @param cipher the buffer with the input data to be decrypted
+ * @param cipherOffset the offset in <code>cipherOffset</code>
+ * @param cipherLen the length of the input data
+ * @param plain the buffer for the result
+ * @param plainOffset the offset in <code>plain</code>
+ * @exception ProviderException if <code>cipherLen</code> is not
+ * a multiple of the <code>numBytes</code>
+ * @return the length of the decrypted data
+ */
+ int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
+ byte[] plain, int plainOffset) {
+ if ((cipherLen % numBytes) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
+
+ int nShift = blockSize - numBytes;
+ int loopCount = cipherLen / numBytes;
+
+ for (; loopCount > 0;
+ plainOffset += numBytes, cipherOffset += numBytes,
+ loopCount--) {
+ embeddedCipher.encryptBlock(register, 0, k, 0);
+ if (nShift != 0) {
+ System.arraycopy(register, numBytes, register, 0, nShift);
+ }
+ for (int i = 0; i < numBytes; i++) {
+ register[i + nShift] = cipher[i + cipherOffset];
+ plain[i + plainOffset]
+ = (byte)(cipher[i + cipherOffset] ^ k[i]);
+ }
+ }
+ return cipherLen;
+ }
+
+ /**
+ * Performs the last decryption operation.
*
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
+ * <p>The input cipher text <code>cipher</code>, starting at
+ * <code>cipherOffset</code> and ending at
+ * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
+ * The result is stored in <code>plain</code>, starting at
+ * <code>plainOffset</code>.
*
* @param cipher the buffer with the input data to be decrypted
* @param cipherOffset the offset in <code>cipherOffset</code>
@@ -222,53 +264,19 @@
* @param plainOffset the offset in <code>plain</code>
* @return the length of the decrypted data
*/
- int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
- byte[] plain, int plainOffset)
- {
- int i, len;
- len = blockSize - numBytes;
- int loopCount = cipherLen / numBytes;
- int oddBytes = cipherLen % numBytes;
+ int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
+ byte[] plain, int plainOffset) {
- if (len == 0) {
- for (; loopCount > 0;
- plainOffset += numBytes, cipherOffset += numBytes,
- loopCount--) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- for (i = 0; i < blockSize; i++) {
- register[i] = cipher[i+cipherOffset];
- plain[i+plainOffset]
- = (byte)(cipher[i+cipherOffset] ^ k[i]);
- }
- }
- if (oddBytes > 0) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- for (i=0; i<oddBytes; i++) {
- register[i] = cipher[i+cipherOffset];
- plain[i+plainOffset]
- = (byte)(cipher[i+cipherOffset] ^ k[i]);
- }
- }
- } else {
- for (; loopCount > 0;
- plainOffset += numBytes, cipherOffset += numBytes,
- loopCount--) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- System.arraycopy(register, numBytes, register, 0, len);
- for (i=0; i<numBytes; i++) {
- register[i+len] = cipher[i+cipherOffset];
- plain[i+plainOffset]
- = (byte)(cipher[i+cipherOffset] ^ k[i]);
- }
- }
- if (oddBytes != 0) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- System.arraycopy(register, numBytes, register, 0, len);
- for (i=0; i<oddBytes; i++) {
- register[i+len] = cipher[i+cipherOffset];
- plain[i+plainOffset]
- = (byte)(cipher[i+cipherOffset] ^ k[i]);
- }
+ int oddBytes = cipherLen % numBytes;
+ int len = decrypt(cipher, cipherOffset, (cipherLen - oddBytes),
+ plain, plainOffset);
+ cipherOffset += len;
+ plainOffset += len;
+ if (oddBytes != 0) {
+ embeddedCipher.encryptBlock(register, 0, k, 0);
+ for (int i = 0; i < oddBytes; i++) {
+ plain[i + plainOffset]
+ = (byte)(cipher[i + cipherOffset] ^ k[i]);
}
}
return cipherLen;
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java Tue Dec 23 02:36:48 2014 +0000
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java Tue Dec 23 02:58:15 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 201313, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2014, 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
@@ -27,6 +27,7 @@
import java.security.InvalidKeyException;
+
/**
* This class represents ciphers in counter (CTR) mode.
*
@@ -136,14 +137,6 @@
* The result is stored in <code>cipher</code>, starting at
* <code>cipherOffset</code>.
*
- * <p>It is the application's responsibility to make sure that
- * <code>plainLen</code> is a multiple of the embedded cipher's block size,
- * as any excess bytes are ignored.
- *
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
- *
* @param in the buffer with the input data to be encrypted
* @param inOffset the offset in <code>plain</code>
* @param len the length of the input data
@@ -155,30 +148,7 @@
return crypt(in, inOff, len, out, outOff);
}
- /**
- * Performs decryption operation.
- *
- * <p>The input cipher text <code>cipher</code>, starting at
- * <code>cipherOffset</code> and ending at
- * <code>(cipherOffset + len - 1)</code>, is decrypted.
- * The result is stored in <code>plain</code>, starting at
- * <code>plainOffset</code>.
- *
- * <p>It is the application's responsibility to make sure that
- * <code>cipherLen</code> is a multiple of the embedded cipher's block
- * size, as any excess bytes are ignored.
- *
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
- *
- * @param in the buffer with the input data to be decrypted
- * @param inOff the offset in <code>cipherOffset</code>
- * @param len the length of the input data
- * @param out the buffer for the result
- * @param outOff the offset in <code>plain</code>
- * @return the length of the decrypted data
- */
+ // CTR encrypt and decrypt are identical
int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
return crypt(in, inOff, len, out, outOff);
}
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java Tue Dec 23 02:36:48 2014 +0000
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java Tue Dec 23 02:58:15 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -26,6 +26,7 @@
package com.sun.crypto.provider;
import java.security.InvalidKeyException;
+import java.security.ProviderException;
/**
* This class represents ciphers in electronic codebook (ECB) mode.
@@ -96,28 +97,24 @@
/**
* Performs encryption operation.
*
- * <p>The input plain text <code>plain</code>, starting at
- * <code>plainOffset</code> and ending at
- * <code>(plainOffset + len - 1)</code>, is encrypted.
- * The result is stored in <code>cipher</code>, starting at
- * <code>cipherOffset</code>.
- *
- * <p>It is the application's responsibility to make sure that
- * <code>plainLen</code> is a multiple of the embedded cipher's block size,
- * as any excess bytes are ignored.
- *
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
+ * <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 is stored in <code>out</code>, starting at
+ * <code>outOff</code>.
*
* @param in the buffer with the input data to be encrypted
- * @param inOffset the offset in <code>plain</code>
+ * @param inOff the offset in <code>plain</code>
* @param len the length of the input data
* @param out the buffer for the result
* @param outOff the offset in <code>cipher</code>
+ * @exception ProviderException if <code>len</code> is not
+ * a multiple of the block size
* @return the length of the encrypted data
*/
int encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
+ if ((len % blockSize) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
for (int i = len; i >= blockSize; i -= blockSize) {
embeddedCipher.encryptBlock(in, inOff, out, outOff);
inOff += blockSize;
@@ -129,28 +126,24 @@
/**
* Performs decryption operation.
*
- * <p>The input cipher text <code>cipher</code>, starting at
- * <code>cipherOffset</code> and ending at
- * <code>(cipherOffset + len - 1)</code>, is decrypted.
- * The result is stored in <code>plain</code>, starting at
- * <code>plainOffset</code>.
- *
- * <p>It is the application's responsibility to make sure that
- * <code>cipherLen</code> is a multiple of the embedded cipher's block
- * size, as any excess bytes are ignored.
- *
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
+ * <p>The input cipher text <code>in</code>, starting at
+ * <code>inOff</code> and ending at * <code>(inOff + len - 1)</code>,
+ * is decrypted.The result is stored in <code>out</code>, starting at
+ * <code>outOff</code>.
*
* @param in the buffer with the input data to be decrypted
* @param inOff the offset in <code>cipherOffset</code>
* @param len the length of the input data
* @param out the buffer for the result
* @param outOff the offset in <code>plain</code>
+ * @exception ProviderException if <code>len</code> is not
+ * a multiple of the block size
* @return the length of the decrypted data
*/
int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
+ if ((len % blockSize) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
for (int i = len; i >= blockSize; i -= blockSize) {
embeddedCipher.decryptBlock(in, inOff, out, outOff);
inOff += blockSize;
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java Tue Dec 23 02:36:48 2014 +0000
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java Tue Dec 23 02:58:15 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -371,21 +371,19 @@
* and ending at <code>(inOff + len - 1)</code>, is encrypted. The result
* is stored in <code>out</code>, starting at <code>outOfs</code>.
*
- * <p>It is the application's responsibility to make sure that
- * <code>len</code> is a multiple of the embedded cipher's block size,
- * otherwise, a ProviderException will be thrown.
- *
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
- *
* @param in the buffer with the input data to be encrypted
* @param inOfs the offset in <code>in</code>
* @param len the length of the input data
* @param out the buffer for the result
* @param outOfs the offset in <code>out</code>
+ * @exception ProviderException if <code>len</code> is not
+ * a multiple of the block size
+ * @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");
+ }
processAAD();
if (len > 0) {
gctrPAndC.update(in, inOfs, len, out, outOfs);
@@ -398,9 +396,6 @@
/**
* Performs encryption operation for the last time.
*
- * <p>NOTE: <code>len</code> may not be multiple of the embedded
- * cipher's block size for this call.
- *
* @param in the input buffer with the data to be encrypted
* @param inOfs the offset in <code>in</code>
* @param len the length of the input data
@@ -439,21 +434,19 @@
* is decrypted. The result is stored in <code>out</code>, starting at
* <code>outOfs</code>.
*
- * <p>It is the application's responsibility to make sure that
- * <code>len</code> is a multiple of the embedded cipher's block
- * size, as any excess bytes are ignored.
- *
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
- *
* @param in the buffer with the input data to be decrypted
* @param inOfs the offset in <code>in</code>
* @param len the length of the input data
* @param out the buffer for the result
* @param outOfs the offset in <code>out</code>
+ * @exception ProviderException if <code>len</code> is not
+ * a multiple of the block size
+ * @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");
+ }
processAAD();
if (len > 0) {
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java Tue Dec 23 02:36:48 2014 +0000
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java Tue Dec 23 02:58:15 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -26,6 +26,7 @@
package com.sun.crypto.provider;
import java.security.InvalidKeyException;
+import java.security.ProviderException;
/**
* This class represents ciphers in output-feedback (OFB) mode.
@@ -132,17 +133,52 @@
*
* <p>The input plain text <code>plain</code>, starting at
* <code>plainOffset</code> and ending at
- * <code>(plainOffset + len - 1)</code>, is encrypted.
+ * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
* The result is stored in <code>cipher</code>, starting at
* <code>cipherOffset</code>.
*
- * <p>It is the application's responsibility to make sure that
- * <code>plainLen</code> is a multiple of the stream unit size
- * <code>numBytes</code>, as any excess bytes are ignored.
+ * @param plain the buffer with the input data to be encrypted
+ * @param plainOffset the offset in <code>plain</code>
+ * @param plainLen the length of the input data
+ * @param cipher the buffer for the result
+ * @param cipherOffset the offset in <code>cipher</code>
+ * @exception ProviderException if <code>plainLen</code> is not
+ * a multiple of the <code>numBytes</code>
+ * @return the length of the encrypted data
+ */
+ int encrypt(byte[] plain, int plainOffset, int plainLen,
+ byte[] cipher, int cipherOffset) {
+
+ if ((plainLen % numBytes) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
+ int nShift = blockSize - numBytes;
+ int loopCount = plainLen / numBytes;
+
+ for (; loopCount > 0;
+ plainOffset += numBytes, cipherOffset += numBytes,
+ loopCount--) {
+ embeddedCipher.encryptBlock(register, 0, k, 0);
+ for (int i = 0; i < numBytes; i++) {
+ cipher[i + cipherOffset] =
+ (byte)(k[i] ^ plain[i + plainOffset]);
+ if (nShift != 0) {
+ System.arraycopy(register, numBytes, register, 0, nShift);
+ }
+ System.arraycopy(k, 0, register, nShift, numBytes);
+ }
+ }
+ return plainLen;
+ }
+
+ /**
+ * Performs last encryption operation.
*
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
+ * <p>The input plain text <code>plain</code>, starting at
+ * <code>plainOffset</code> and ending at
+ * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
+ * The result is stored in <code>cipher</code>, starting at
+ * <code>cipherOffset</code>.
*
* @param plain the buffer with the input data to be encrypted
* @param plainOffset the offset in <code>plain</code>
@@ -151,82 +187,34 @@
* @param cipherOffset the offset in <code>cipher</code>
* @return the length of the encrypted data
*/
- int encrypt(byte[] plain, int plainOffset, int plainLen,
- byte[] cipher, int cipherOffset)
- {
- int i;
- int len = blockSize - numBytes;
- int loopCount = plainLen / numBytes;
+ int encryptFinal(byte[] plain, int plainOffset, int plainLen,
+ byte[] cipher, int cipherOffset) {
int oddBytes = plainLen % numBytes;
+ int len = encrypt(plain, plainOffset, (plainLen - oddBytes),
+ cipher, cipherOffset);
+ plainOffset += len;
+ cipherOffset += len;
- if (len == 0) {
- for (; loopCount > 0;
- plainOffset += numBytes, cipherOffset += numBytes,
- loopCount--) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- for (i=0; i<numBytes; i++)
- cipher[i+cipherOffset] =
- (byte)(k[i] ^ plain[i+plainOffset]);
- System.arraycopy(k, 0, register, 0, numBytes);
- }
- if (oddBytes > 0) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- for (i=0; i<oddBytes; i++)
- cipher[i+cipherOffset] =
- (byte)(k[i] ^ plain[i+plainOffset]);
- System.arraycopy(k, 0, register, 0, numBytes);
- }
- } else {
- for (; loopCount > 0;
- plainOffset += numBytes, cipherOffset += numBytes,
- loopCount--) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- for (i=0; i<numBytes; i++)
- cipher[i+cipherOffset] =
- (byte)(k[i] ^ plain[i+plainOffset]);
- System.arraycopy(register, numBytes, register, 0, len);
- System.arraycopy(k, 0, register, len, numBytes);
- }
- if (oddBytes > 0) {
- embeddedCipher.encryptBlock(register, 0, k, 0);
- for (i=0; i<oddBytes; i++)
- cipher[i+cipherOffset] =
- (byte)(k[i] ^ plain[i+plainOffset]);
- System.arraycopy(register, numBytes, register, 0, len);
- System.arraycopy(k, 0, register, len, numBytes);
+ if (oddBytes != 0) {
+ embeddedCipher.encryptBlock(register, 0, k, 0);
+ for (int i = 0; i < oddBytes; i++) {
+ cipher[i + cipherOffset] =
+ (byte)(k[i] ^ plain[ i + plainOffset]);
}
}
return plainLen;
}
- /**
- * Performs decryption operation.
- *
- * <p>The input cipher text <code>cipher</code>, starting at
- * <code>cipherOffset</code> and ending at
- * <code>(cipherOffset + len - 1)</code>, is decrypted.
- * The result is stored in <code>plain</code>, starting at
- * <code>plainOffset</code>.
- *
- * <p>It is the application's responsibility to make sure that
- * <code>cipherLen</code> is a multiple of the stream unit size
- * <code>numBytes</code>, as any excess bytes are ignored.
- *
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
- *
- * @param cipher the buffer with the input data to be decrypted
- * @param cipherOffset the offset in <code>cipherOffset</code>
- * @param cipherLen the length of the input data
- * @param plain the buffer for the result
- * @param plainOffset the offset in <code>plain</code>
- * @return the length of the decrypted data
- */
+ // OFB encrypt and decrypt are identical
int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
- byte[] plain, int plainOffset)
- {
- // OFB encrypt and decrypt are identical
+ byte[] plain, int plainOffset) {
return encrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
}
+
+ // OFB encrypt and decrypt are identical
+ int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
+ byte[] plain, int plainOffset) {
+ // OFB encrypt and decrypt are identical
+ return encryptFinal(cipher, cipherOffset, cipherLen, plain, plainOffset);
+ }
}
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/PCBC.java Tue Dec 23 02:36:48 2014 +0000
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/PCBC.java Tue Dec 23 02:58:15 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -26,6 +26,8 @@
package com.sun.crypto.provider;
import java.security.InvalidKeyException;
+import java.security.ProviderException;
+
/**
* This class represents ciphers in Plaintext Cipher Block Chaining (PCBC)
@@ -118,38 +120,36 @@
*
* <p>The input plain text <code>plain</code>, starting at
* <code>plainOffset</code> and ending at
- * <code>(plainOffset + len - 1)</code>, is encrypted.
+ * <code>(plainOffset + plainLen - 1)</code>, is encrypted.
* The result is stored in <code>cipher</code>, starting at
* <code>cipherOffset</code>.
*
- * <p>It is the application's responsibility to make sure that
- * <code>plainLen</code> is a multiple of the embedded cipher's block size,
- * as any excess bytes are ignored.
- *
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
- *
* @param plain the buffer with the input data to be encrypted
* @param plainOffset the offset in <code>plain</code>
* @param plainLen the length of the input data
* @param cipher the buffer for the result
* @param cipherOffset the offset in <code>cipher</code>
+ * @exception ProviderException if <code>plainLen</code> is not
+ * a multiple of the block size
+ * @return the length of the encrypted data
*/
int encrypt(byte[] plain, int plainOffset, int plainLen,
byte[] cipher, int cipherOffset)
{
+ if ((plainLen % blockSize) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
int i;
int endIndex = plainOffset + plainLen;
for (; plainOffset < endIndex;
plainOffset += blockSize, cipherOffset += blockSize) {
- for (i=0; i<blockSize; i++) {
- k[i] ^= plain[i+plainOffset];
+ for (i = 0; i < blockSize; i++) {
+ k[i] ^= plain[i + plainOffset];
}
embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset);
for (i = 0; i < blockSize; i++) {
- k[i] = (byte)(plain[i+plainOffset] ^ cipher[i+cipherOffset]);
+ k[i] = (byte)(plain[i + plainOffset] ^ cipher[i + cipherOffset]);
}
}
return plainLen;
@@ -160,27 +160,25 @@
*
* <p>The input cipher text <code>cipher</code>, starting at
* <code>cipherOffset</code> and ending at
- * <code>(cipherOffset + len - 1)</code>, is decrypted.
+ * <code>(cipherOffset + cipherLen - 1)</code>, is decrypted.
* The result is stored in <code>plain</code>, starting at
* <code>plainOffset</code>.
*
- * <p>It is the application's responsibility to make sure that
- * <code>cipherLen</code> is a multiple of the embedded cipher's block
- * size, as any excess bytes are ignored.
- *
- * <p>It is also the application's responsibility to make sure that
- * <code>init</code> has been called before this method is called.
- * (This check is omitted here, to avoid double checking.)
- *
* @param cipher the buffer with the input data to be decrypted
* @param cipherOffset the offset in <code>cipherOffset</code>
* @param cipherLen the length of the input data
* @param plain the buffer for the result
* @param plainOffset the offset in <code>plain</code>
+ * @exception ProviderException if <code>cipherLen</code> is not
+ * a multiple of the block size
+ * @return the length of the decrypted data
*/
int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset)
{
+ if ((cipherLen % blockSize) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
int i;
int endIndex = cipherOffset + cipherLen;
@@ -189,10 +187,10 @@
embeddedCipher.decryptBlock(cipher, cipherOffset,
plain, plainOffset);
for (i = 0; i < blockSize; i++) {
- plain[i+plainOffset] ^= k[i];
+ plain[i + plainOffset] ^= k[i];
}
for (i = 0; i < blockSize; i++) {
- k[i] = (byte)(plain[i+plainOffset] ^ cipher[i+cipherOffset]);
+ k[i] = (byte)(plain[i + plainOffset] ^ cipher[i + cipherOffset]);
}
}
return cipherLen;
--- a/jdk/test/ProblemList.txt Tue Dec 23 02:36:48 2014 +0000
+++ b/jdk/test/ProblemList.txt Tue Dec 23 02:58:15 2014 +0000
@@ -239,9 +239,6 @@
java/security/KeyPairGenerator/SolarisShortDSA.java solaris-all
sun/security/tools/keytool/standard.sh solaris-all
-# 8049312
-com/sun/crypto/provider/Cipher/AES/CICO.java generic-all
-
# 8062758
java/security/Security/ClassLoaderDeadlock/Deadlock2.sh generic-all