CipherCore.java revision 0
1879N/A * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. Sun designates this 0N/A * particular file as subject to the "Classpath" exception as provided 0N/A * by Sun in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 1472N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1472N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 0N/A * CA 95054 USA or visit www.sun.com if you need additional information or 0N/A * have any questions. 0N/A * This class represents the symmetric algorithms in its various modes 0N/A * (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>, 0N/A * <code>PCBC</code>, <code>CTR</code>, and <code>CTS</code>) and 0N/A * padding schemes (<code>PKCS5Padding</code>, <code>NoPadding</code>, 0N/A * <code>ISO10126Padding</code>). 0N/A * @author Gigi Ankeny 0N/A * @see ElectronicCodeBook 0N/A * @see CipherFeedback 0N/A * @see OutputFeedback 0N/A * @see CipherBlockChaining 0N/A * @see CipherTextStealing 0N/A * unit size (number of input bytes that can be processed at a time) 0N/A * index of the content size left in the buffer 0N/A * minimum number of bytes in the buffer required for 0N/A * FeedbackCipher.encryptFinal()/decryptFinal() call. 0N/A * update() must buffer this many bytes before before starting 0N/A * currently, only CTS mode has a non-zero value due to its special 0N/A * handling on the last two blocks (the last one may be incomplete). 0N/A * number of bytes needed to make the total input length a multiple 0N/A * of the blocksize (this is used in feedback mode, when the number of 0N/A * input bytes that are processed at a time is different from the block 0N/A * internal cipher engine 0N/A * are we encrypting or decrypting? 0N/A * Block Mode constants * Creates an instance of CipherCore with default ECB mode and * The buffer should be usable for all cipher mode and padding * schemes. Thus, it has to be at least (blockSize+1) for CTS. * In decryption mode, it also hold the possible padding block. * Sets the mode of this cipher. * @param mode the cipher mode * @exception NoSuchAlgorithmException if the requested cipher mode does (
"Algorithm mode: " +
mode +
" not implemented");
(
"Invalid algorithm mode: " +
mode);
* Sets the padding mechanism of this cipher. * @param padding the padding mechanism * @exception NoSuchPaddingException if the requested padding mechanism " mode must be used with NoPadding");
* Returns the length in bytes that an output buffer would need to be in * order to hold the result of the next <code>update</code> or * <code>doFinal</code> operation, given the input length * <code>inputLen</code> (in bytes). * <p>This call takes into account any unprocessed (buffered) data from a * previous <code>update</code> call, and padding. * <p>The actual output length of the next <code>update</code> or * <code>doFinal</code> call may be smaller than the length returned by * @param inputLen the input length (in bytes) * @return the required output buffer size (in bytes) * Returns the initialization vector (IV) in a new buffer. * <p>This is useful in the case where a random IV has been created * (see <a href = "#init">init</a>), * or in the context of password-based encryption or * decryption, where the IV is derived from a user-provided password. * @return the initialization vector in a new buffer, or null if the * underlying algorithm does not use an IV, or if the IV has not yet * Returns the parameters used with this cipher. * <p>The returned parameters may be the same that were used to initialize * this cipher, or may contain the default set of parameters or a set of * randomly generated parameters used by the underlying cipher * implementation (provided that the underlying cipher implementation * uses a default set of parameters or creates new parameters if it needs * parameters but was not initialized with any). * @return the parameters used with this cipher, or null if this cipher * does not use any parameters. " AlgorithmParameters implementation in SunJCE provider");
* Initializes this cipher with a key and a source of randomness. * <p>The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending on * the value of <code>opmode</code>. * <p>If this cipher requires an initialization vector (IV), it will get * it from <code>random</code>. * This behaviour should only be used in encryption or key wrapping * When initializing a cipher that requires an IV for decryption or * (same IV that was used for encryption or key wrapping) must be provided * parameter, in order to get the correct result. * <p>This method also cleans existing buffer and other related state * @param opmode the operation mode of this cipher (this is one of * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) * @param key the secret key * @param random the source of randomness * @exception InvalidKeyException if the given key is inappropriate for * initializing this cipher * Initializes this cipher with a key, a set of * algorithm parameters, and a source of randomness. * <p>The cipher is initialized for one of the following four operations: * encryption, decryption, key wrapping or key unwrapping, depending on * the value of <code>opmode</code>. * <p>If this cipher (including its underlying feedback or padding scheme) * requires any random bytes, it will get them from <code>random</code>. * @param opmode the operation mode of this cipher (this is one of * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) * @param key the encryption key * @param params the algorithm parameters * @param random the source of randomness * @exception InvalidKeyException if the given key is inappropriate for * initializing this cipher * @exception InvalidAlgorithmParameterException if the given algorithm * parameters are inappropriate for this cipher (
"ECB mode cannot use IV");
* Return the key bytes of the specified key. Throw an InvalidKeyException * if the key is not usable. // note: key.getFormat() may return null * Continues a multiple-part encryption or decryption operation * (depending on how this cipher was initialized), processing another data * <p>The first <code>inputLen</code> bytes in the <code>input</code> * buffer, starting at <code>inputOffset</code>, are processed, and the * result is stored in a new buffer. * @param input the input buffer * @param inputOffset the offset in <code>input</code> where the input * @param inputLen the input length * @return the new buffer with the result * @exception IllegalStateException if this cipher is in a wrong state * (e.g., has not been initialized) * Continues a multiple-part encryption or decryption operation * (depending on how this cipher was initialized), processing another data * <p>The first <code>inputLen</code> bytes in the <code>input</code> * buffer, starting at <code>inputOffset</code>, are processed, and the * result is stored in the <code>output</code> buffer, starting at * <code>outputOffset</code>. * @param input the input buffer * @param inputOffset the offset in <code>input</code> where the input * @param inputLen the input length * @param output the buffer for the result * @param outputOffset the offset in <code>output</code> where the result * @return the number of bytes stored in <code>output</code> * @exception ShortBufferException if the given output buffer is too small // figure out how much can be sent to crypto function // do not include the padding bytes when decrypting // do not count the trailing bytes which do not make up a unit // check output buffer capacity // there is some work to do byte[]
in =
new byte[
len];
// Let's keep track of how many bytes are needed to make // the total input length a multiple of blocksize when * Encrypts or decrypts data in a single-part operation, * or finishes a multiple-part operation. * The data is encrypted or decrypted, depending on how this cipher was * <p>The first <code>inputLen</code> bytes in the <code>input</code> * buffer, starting at <code>inputOffset</code>, and any input bytes that * may have been buffered during a previous <code>update</code> operation, * are processed, with padding (if requested) being applied. * The result is stored in a new buffer. * <p>The cipher is reset to its initial state (uninitialized) after this * @param input the input buffer * @param inputOffset the offset in <code>input</code> where the input * @param inputLen the input length * @return the new buffer with the result * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes * Encrypts or decrypts data in a single-part operation, * or finishes a multiple-part operation. * The data is encrypted or decrypted, depending on how this cipher was * <p>The first <code>inputLen</code> bytes in the <code>input</code> * buffer, starting at <code>inputOffset</code>, and any input bytes that * may have been buffered during a previous <code>update</code> operation, * are processed, with padding (if requested) being applied. * The result is stored in the <code>output</code> buffer, starting at * <code>outputOffset</code>. * <p>The cipher is reset to its initial state (uninitialized) after this * @param input the input buffer * @param inputOffset the offset in <code>input</code> where the input * @param inputLen the input length * @param output the buffer for the result * @param outputOffset the offset in <code>output</code> where the result * @return the number of bytes stored in <code>output</code> * @exception IllegalBlockSizeException if this cipher is a block cipher, * no padding has been requested (only in encryption mode), and the total * input length of the data processed by this cipher is not a multiple of * @exception ShortBufferException if the given output buffer is too small * @exception BadPaddingException if this cipher is in decryption mode, * and (un)padding has been requested, but the decrypted data is not * bounded by the appropriate padding bytes // calculate the total input length // will the total input length be a multiple of blockSize? (
"Input length must be multiple of " +
blockSize +
" when decrypting with padded cipher");
// if encrypting and padding not null, add padding // check output buffer capacity. // if we are decrypting with padding applied, we can perform this // check only after we have determined how many padding bytes there // prepare the final input avoiding copying if possible // if the size of specified output buffer is less than // the length of the cipher text, then the current // content of cipher has to be preserved in order for // users to retry the call with a larger buffer in the // case of ShortBufferException. // create temporary output buffer so that only "real" // data bytes are passed to user's output buffer. // restore so users can retry with a larger buffer (
"Input length (with padding) not multiple of " +
// Note: Wrap() and Unwrap() are the same in // each of SunJCE CipherSpi implementation classes. // They are duplicated due to export control requirements: // All CipherSpi implementation must be final. * @param key the key to be wrapped. * @return the wrapped key. * @exception IllegalBlockSizeException if this cipher is a block * cipher, no padding has been requested, and the length of the * encoding of the key to be wrapped is not a * multiple of the block size. * @exception InvalidKeyException if it is impossible or unsafe to * wrap the key with this cipher (e.g., a hardware protected key is * being passed to a software only cipher). "the key to be wrapped");
* Unwrap a previously wrapped key. * @param wrappedKey the key to be unwrapped. * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. * @param wrappedKeyType the type of the wrapped key. * This is one of <code>Cipher.SECRET_KEY</code>, * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. * @return the unwrapped key. * @exception NoSuchAlgorithmException if no installed providers * can create keys of type <code>wrappedKeyType</code> for the * <code>wrappedKeyAlgorithm</code>. * @exception InvalidKeyException if <code>wrappedKey</code> does not * represent a wrapped key of type <code>wrappedKeyType</code> for * the <code>wrappedKeyAlgorithm</code>.