提交 7cd5961b 编写于 作者: A akosarev

8049312: AES/CICO test failed with on several modes

Summary: Fixed error in calculating data sizes when using feedback modes
Reviewed-by: xuelei
上级 c08a2e22
/*
* 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 {
*
* <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 @@ class CipherBlockChaining extends FeedbackCipher {
*
* <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 @@ class CipherBlockChaining extends FeedbackCipher {
* @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);
}
......
......@@ -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;
......
/*
* 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 {
*
* <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);
}
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]);
for (int i = 0; i < numBytes; i++) {
register[nShift + 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,72 +210,73 @@ final class CipherFeedback extends FeedbackCipher {
*
* <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.
*
* <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 <code>numBytes</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;
byte[] plain, int plainOffset) {
if ((cipherLen % numBytes) != 0) {
throw new ProviderException("Internal error in input buffering");
}
int nShift = blockSize - numBytes;
int loopCount = cipherLen / numBytes;
int oddBytes = cipherLen % 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];
plain[i+plainOffset]
= (byte)(cipher[i+cipherOffset] ^ k[i]);
}
for (; loopCount > 0;
plainOffset += numBytes, cipherOffset += numBytes,
loopCount--) {
embeddedCipher.encryptBlock(register, 0, k, 0);
if (nShift != 0) {
System.arraycopy(register, numBytes, register, 0, nShift);
}
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]);
}
for (int i = 0; i < numBytes; i++) {
register[i + nShift] = 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]);
}
}
return cipherLen;
}
/**
* Performs the last decryption operation.
*
* <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>
* @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
*/
int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
byte[] plain, int plainOffset) {
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;
......
/*
* 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 @@ package com.sun.crypto.provider;
import java.security.InvalidKeyException;
/**
* This class represents ciphers in counter (CTR) mode.
*
......@@ -136,14 +137,6 @@ final class CounterMode extends FeedbackCipher {
* 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 @@ final class CounterMode extends FeedbackCipher {
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);
}
......
/*
* 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.
*
* <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 @@ final class ElectronicCodeBook extends FeedbackCipher {
/**
* 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;
......
/*
* 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 <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 @@ final class GaloisCounterMode extends FeedbackCipher {
/**
* 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 @@ final class GaloisCounterMode extends FeedbackCipher {
* 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) {
......
/*
* 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,101 +133,88 @@ final class OutputFeedback extends FeedbackCipher {
*
* <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;
int 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<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);
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 decryption operation.
* Performs last encryption 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.)
* <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 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 plain the buffer with the input data to be encrypted
* @param plainOffset the offset in <code>plain</code>
* @return the length of the decrypted data
* @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 length of the encrypted data
*/
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;
}
// 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);
}
}
/*
* 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 {
*
* <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 @@ final class PCBC extends FeedbackCipher {
*
* <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 @@ 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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册