From fa447efe142a8ac666db2b83474ad1260d5caddb Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Tue, 23 Dec 2014 02:58:15 +0000 Subject: [PATCH] 8049312: AES/CICO test failed with on several modes Fixed error in calculating data sizes when using feedback modes Reviewed-by: xuelei --- .../crypto/provider/CipherBlockChaining.java | 40 ++-- .../com/sun/crypto/provider/CipherCore.java | 5 +- .../sun/crypto/provider/CipherFeedback.java | 210 +++++++++--------- .../com/sun/crypto/provider/CounterMode.java | 36 +-- .../crypto/provider/ElectronicCodeBook.java | 49 ++-- .../crypto/provider/GaloisCounterMode.java | 33 ++- .../sun/crypto/provider/OutputFeedback.java | 140 ++++++------ .../classes/com/sun/crypto/provider/PCBC.java | 46 ++-- jdk/test/ProblemList.txt | 3 - 9 files changed, 255 insertions(+), 307 deletions(-) diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java index 51d95c12e14..515478821d3 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java @@ -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 @@ class CipherBlockChaining extends FeedbackCipher { * *

The input plain text plain, starting at * plainOffset and ending at - * (plainOffset + len - 1), is encrypted. + * (plainOffset + plainLen - 1), is encrypted. * The result is stored in cipher, starting at * cipherOffset. * - *

It is the application's responsibility to make sure that - * plainLen 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 plain * @param plainLen the length of the input data * @param cipher the buffer for the result * @param cipherOffset the offset in cipher + * @exception ProviderException if len 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; iThe input cipher text cipher, starting at * cipherOffset and ending at - * (cipherOffset + len - 1), is decrypted. + * (cipherOffset + cipherLen - 1), is decrypted. * The result is stored in plain, starting at * plainOffset. * - *

It is the application's responsibility to make sure that - * cipherLen is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * *

It is also the application's responsibility to make sure that * init has been called before this method is called. * (This check is omitted here, to avoid double checking.) @@ -176,23 +174,23 @@ class CipherBlockChaining extends FeedbackCipher { * @param cipherLen the length of the input data * @param plain the buffer for the result * @param plainOffset the offset in plain + * @exception ProviderException if len 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); } diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java index 6b5eea85d6d..96a624391f0 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java @@ -708,7 +708,7 @@ final class CipherCore { 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 @@ final class CipherCore { 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; diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherFeedback.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherFeedback.java index f8e6115c98f..84b527efe5b 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherFeedback.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherFeedback.java @@ -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 @@ final class CipherFeedback extends FeedbackCipher { * *

The input plain text plain, starting at * plainOffset and ending at - * (plainOffset + len - 1), is encrypted. + * (plainOffset + plainLen - 1), is encrypted. * The result is stored in cipher, starting at * cipherOffset. * - *

It is the application's responsibility to make sure that - * plainLen is a multiple of the stream unit size - * numBytes, as any excess bytes are ignored. - * - *

It is also the application's responsibility to make sure that - * init 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 plain * @param plainLen the length of the input data * @param cipher the buffer for the result * @param cipherOffset the offset in cipher + * @exception ProviderException if plainLen is not + * a multiple of the numBytes * @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; + + 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]); + } + } + return plainLen; + } + + /** + * Performs the last encryption operation. + * + *

The input plain text plain, starting at + * plainOffset and ending at + * (plainOffset + plainLen - 1), is encrypted. + * The result is stored in cipher, starting at + * cipherOffset. + * + * @param plain the buffer with the input data to be encrypted + * @param plainOffset the offset in plain + * @param plainLen the length of the input data + * @param cipher the buffer for the result + * @param cipherOffset the offset in cipher + * @return the number of bytes placed into cipher + */ + int encryptFinal(byte[] plain, int plainOffset, int plainLen, + byte[] cipher, int cipherOffset) { + 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]); - } - if (oddBytes > 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i 0 ; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - System.arraycopy(register, numBytes, register, 0, len); - for (i=0; iThe input cipher text cipher, starting at * cipherOffset and ending at - * (cipherOffset + len - 1), is decrypted. + * (cipherOffset + cipherLen - 1), is decrypted. * The result is stored in plain, starting at * plainOffset. * - *

It is the application's responsibility to make sure that - * cipherLen is a multiple of the stream unit size - * numBytes, as any excess bytes are ignored. + * @param cipher the buffer with the input data to be decrypted + * @param cipherOffset the offset in cipherOffset + * @param cipherLen the length of the input data + * @param plain the buffer for the result + * @param plainOffset the offset in plain + * @exception ProviderException if cipherLen is not + * a multiple of the numBytes + * @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. * - *

It is also the application's responsibility to make sure that - * init has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + *

The input cipher text cipher, starting at + * cipherOffset and ending at + * (cipherOffset + cipherLen - 1), is decrypted. + * The result is stored in plain, starting at + * plainOffset. * * @param cipher the buffer with the input data to be decrypted * @param cipherOffset the offset in cipherOffset @@ -222,53 +264,19 @@ final class CipherFeedback extends FeedbackCipher { * @param plainOffset the offset in plain * @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 0; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - System.arraycopy(register, numBytes, register, 0, len); - for (i=0; icipher, starting at * cipherOffset. * - *

It is the application's responsibility to make sure that - * plainLen is a multiple of the embedded cipher's block size, - * as any excess bytes are ignored. - * - *

It is also the application's responsibility to make sure that - * init 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 plain * @param len the length of the input data @@ -155,30 +148,7 @@ final class CounterMode extends FeedbackCipher { return crypt(in, inOff, len, out, outOff); } - /** - * Performs decryption operation. - * - *

The input cipher text cipher, starting at - * cipherOffset and ending at - * (cipherOffset + len - 1), is decrypted. - * The result is stored in plain, starting at - * plainOffset. - * - *

It is the application's responsibility to make sure that - * cipherLen is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - *

It is also the application's responsibility to make sure that - * init 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 cipherOffset - * @param len the length of the input data - * @param out the buffer for the result - * @param outOff the offset in plain - * @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); } diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java index a407b6a50c0..334e4245e27 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java @@ -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 @@ final class ElectronicCodeBook extends FeedbackCipher { /** * Performs encryption operation. * - *

The input plain text plain, starting at - * plainOffset and ending at - * (plainOffset + len - 1), is encrypted. - * The result is stored in cipher, starting at - * cipherOffset. - * - *

It is the application's responsibility to make sure that - * plainLen is a multiple of the embedded cipher's block size, - * as any excess bytes are ignored. - * - *

It is also the application's responsibility to make sure that - * init has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + *

The input plain text in, starting at + * inOff and ending at * (inOff + len - 1), + * is encrypted. The result is stored in out, starting at + * outOff. * * @param in the buffer with the input data to be encrypted - * @param inOffset the offset in plain + * @param inOff the offset in plain * @param len the length of the input data * @param out the buffer for the result * @param outOff the offset in cipher + * @exception ProviderException if len 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 @@ final class ElectronicCodeBook extends FeedbackCipher { /** * Performs decryption operation. * - *

The input cipher text cipher, starting at - * cipherOffset and ending at - * (cipherOffset + len - 1), is decrypted. - * The result is stored in plain, starting at - * plainOffset. - * - *

It is the application's responsibility to make sure that - * cipherLen is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - *

It is also the application's responsibility to make sure that - * init has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + *

The input cipher text in, starting at + * inOff and ending at * (inOff + len - 1), + * is decrypted.The result is stored in out, starting at + * outOff. * * @param in the buffer with the input data to be decrypted * @param inOff the offset in cipherOffset * @param len the length of the input data * @param out the buffer for the result * @param outOff the offset in plain + * @exception ProviderException if len 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; diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java index 37bf6f41433..9f8f54a1823 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java @@ -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 @@ final class GaloisCounterMode extends FeedbackCipher { * and ending at (inOff + len - 1), is encrypted. The result * is stored in out, starting at outOfs. * - *

It is the application's responsibility to make sure that - * len is a multiple of the embedded cipher's block size, - * otherwise, a ProviderException will be thrown. - * - *

It is also the application's responsibility to make sure that - * init 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 in * @param len the length of the input data * @param out the buffer for the result * @param outOfs the offset in out + * @exception ProviderException if len is not + * a multiple of the block size + * @return the number of bytes placed into the out 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 @@ final class GaloisCounterMode extends FeedbackCipher { /** * Performs encryption operation for the last time. * - *

NOTE: len 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 in * @param len the length of the input data @@ -439,21 +434,19 @@ final class GaloisCounterMode extends FeedbackCipher { * is decrypted. The result is stored in out, starting at * outOfs. * - *

It is the application's responsibility to make sure that - * len is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - *

It is also the application's responsibility to make sure that - * init 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 in * @param len the length of the input data * @param out the buffer for the result * @param outOfs the offset in out + * @exception ProviderException if len is not + * a multiple of the block size + * @return the number of bytes placed into the out 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) { diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java index ea5890db2e5..250e60e343a 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java @@ -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 @@ final class OutputFeedback extends FeedbackCipher { * *

The input plain text plain, starting at * plainOffset and ending at - * (plainOffset + len - 1), is encrypted. + * (plainOffset + plainLen - 1), is encrypted. * The result is stored in cipher, starting at * cipherOffset. * - *

It is the application's responsibility to make sure that - * plainLen is a multiple of the stream unit size - * numBytes, as any excess bytes are ignored. + * @param plain the buffer with the input data to be encrypted + * @param plainOffset the offset in plain + * @param plainLen the length of the input data + * @param cipher the buffer for the result + * @param cipherOffset the offset in cipher + * @exception ProviderException if plainLen is not + * a multiple of the numBytes + * @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. * - *

It is also the application's responsibility to make sure that - * init has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + *

The input plain text plain, starting at + * plainOffset and ending at + * (plainOffset + plainLen - 1), is encrypted. + * The result is stored in cipher, starting at + * cipherOffset. * * @param plain the buffer with the input data to be encrypted * @param plainOffset the offset in plain @@ -151,82 +187,34 @@ final class OutputFeedback extends FeedbackCipher { * @param cipherOffset the offset in cipher * @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 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i 0; - plainOffset += numBytes, cipherOffset += numBytes, - loopCount--) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; i 0) { - embeddedCipher.encryptBlock(register, 0, k, 0); - for (i=0; iThe input cipher text cipher, starting at - * cipherOffset and ending at - * (cipherOffset + len - 1), is decrypted. - * The result is stored in plain, starting at - * plainOffset. - * - *

It is the application's responsibility to make sure that - * cipherLen is a multiple of the stream unit size - * numBytes, as any excess bytes are ignored. - * - *

It is also the application's responsibility to make sure that - * init 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 cipherOffset - * @param cipherLen the length of the input data - * @param plain the buffer for the result - * @param plainOffset the offset in plain - * @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); + } } diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/PCBC.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/PCBC.java index aefc45e697d..fd99bb0cbd5 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/PCBC.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/PCBC.java @@ -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 @@ final class PCBC extends FeedbackCipher { * *

The input plain text plain, starting at * plainOffset and ending at - * (plainOffset + len - 1), is encrypted. + * (plainOffset + plainLen - 1), is encrypted. * The result is stored in cipher, starting at * cipherOffset. * - *

It is the application's responsibility to make sure that - * plainLen is a multiple of the embedded cipher's block size, - * as any excess bytes are ignored. - * - *

It is also the application's responsibility to make sure that - * init 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 plain * @param plainLen the length of the input data * @param cipher the buffer for the result * @param cipherOffset the offset in cipher + * @exception ProviderException if plainLen 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; iThe input cipher text cipher, starting at * cipherOffset and ending at - * (cipherOffset + len - 1), is decrypted. + * (cipherOffset + cipherLen - 1), is decrypted. * The result is stored in plain, starting at * plainOffset. * - *

It is the application's responsibility to make sure that - * cipherLen is a multiple of the embedded cipher's block - * size, as any excess bytes are ignored. - * - *

It is also the application's responsibility to make sure that - * init 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 cipherOffset * @param cipherLen the length of the input data * @param plain the buffer for the result * @param plainOffset the offset in plain + * @exception ProviderException if cipherLen 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 @@ final class PCBC extends FeedbackCipher { 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; diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index fd8fa56579b..8648fbd96eb 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -239,9 +239,6 @@ sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java solaris-all 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