summaryrefslogtreecommitdiffstats
path: root/luni/src/main/java/javax/crypto/CipherSpi.java
diff options
context:
space:
mode:
Diffstat (limited to 'luni/src/main/java/javax/crypto/CipherSpi.java')
-rw-r--r--luni/src/main/java/javax/crypto/CipherSpi.java557
1 files changed, 557 insertions, 0 deletions
diff --git a/luni/src/main/java/javax/crypto/CipherSpi.java b/luni/src/main/java/javax/crypto/CipherSpi.java
new file mode 100644
index 0000000..50fdd49
--- /dev/null
+++ b/luni/src/main/java/javax/crypto/CipherSpi.java
@@ -0,0 +1,557 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.crypto;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+import java.nio.ByteBuffer;
+
+import org.apache.harmony.crypto.internal.nls.Messages;
+
+/**
+ * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for
+ * cryptographic ciphers.
+ * <p>
+ * Implementers of cryptographic ciphers must implement all the abstract methods
+ * for every cipher they implement. {@code CipherSpi} instances are created
+ * along with ciphers when the {@link Cipher#getInstance} method is called. A
+ * {@code Cipher} is referenced by a <i>transformation</i>, which is a string
+ * that describes the operation (or set of operations), always consisting of the
+ * cipher's name and optionally followed by a mode and a padding, in the form:
+ * <ul>
+ * <li>"algorithm"</li>or
+ * <li>"algorithm/mode/padding"</li>
+ * </ul>
+ * The following behavior should be implemented for obtaining {@code Cipher}
+ * instances.
+ * <p>
+ * When one of the {@link Cipher#getInstance} factory methods is called with a
+ * <i>transformation</i> that is only an <i>algorithm</i>, check if the provider
+ * defines a {@code CipherSpi} for "algorithm", if so: return it, otherwise
+ * throw a {@link NoSuchAlgorithmException}.
+ * <p>
+ * The following rules apply when a <i>transformation</i> is of the form
+ * "algorithm/mode/padding":
+ * <ul>
+ * 1. The Provider has a {@code CipherSpi} subclass registered for
+ * "algorithm/mode/padding": return it, otherwise go to step 2.
+ * </ul>
+ * <ul>
+ * 2. The Provider has a {@code CipherSpi} subclass registered for
+ * "algorithm/mode": instantiate it, call
+ * {@link CipherSpi#engineSetPadding(String) engineSetPadding(String)} for the
+ * padding name and return it, otherwise go to step 3.
+ * </ul>
+ * <ul>
+ * 3. The Provider has a {@code CipherSpi} subclass registered for
+ * "algorithm//padding": instantiate it, call
+ * {@link CipherSpi#engineSetMode(String) engineSetMode(String)} for the mode
+ * name and return it, otherwise go to step 4.
+ * </ul>
+ * <ul>
+ * 4. The Provider has a {@code CipherSpi} subclass registered for "algorithm":
+ * instantiate it, call {@link CipherSpi#engineSetMode(String)
+ * engineSetMode(String)} for the mode name , call
+ * {@link CipherSpi#engineSetPadding(String) engineSetPadding(String)} for the
+ * padding name and return it, otherwise throw a
+ * {@link NoSuchAlgorithmException}.
+ * </ul>
+ *
+ * @see Cipher
+ */
+public abstract class CipherSpi {
+
+ /**
+ * Creates a new {@code CipherSpi} instance.
+ */
+ public CipherSpi() {
+ }
+
+ /**
+ * Sets the mode for this cipher.
+ *
+ * @param mode
+ * the name of the cipher mode.
+ * @throws NoSuchAlgorithmException
+ * if the specified cipher mode is not supported by this
+ * provider.
+ */
+ protected abstract void engineSetMode(String mode)
+ throws NoSuchAlgorithmException;
+
+ /**
+ * Sets the padding method for this cipher.
+ *
+ * @param padding
+ * the name of the padding method.
+ * @throws NoSuchPaddingException
+ * if the specified padding method is not supported by this
+ * cipher.
+ */
+ protected abstract void engineSetPadding(String padding)
+ throws NoSuchPaddingException;
+
+ /**
+ * Returns the block size of this cipher (in bytes)
+ *
+ * @return the block size of this cipher, or zero if this cipher is not a
+ * block cipher.
+ */
+ protected abstract int engineGetBlockSize();
+
+ /**
+ * Returns the size for a buffer (in bytes), that the next call to {@code
+ * update} of {@code doFinal} would return, taking into account any buffered
+ * data from previous {@code update} calls and padding.
+ * <p>
+ * The actual output length of the next call to {@code update} or {@code
+ * doFinal} may be smaller than the length returned by this method.
+ *
+ * @param inputLen
+ * the length of the input (in bytes).
+ * @return the size for a buffer (in bytes).
+ */
+ protected abstract int engineGetOutputSize(int inputLen);
+
+ /**
+ * Returns the Initialization Vector (IV) that was used to initialize this
+ * cipher or {@code null} if none was used.
+ *
+ * @return the Initialization Vector (IV), or {@code null} if none was used.
+ */
+ protected abstract byte[] engineGetIV();
+
+ /**
+ * Returns the parameters that where used to create this cipher instance.
+ * <p>
+ * These may be a the same parameters that were used to create this cipher
+ * instance, or may be a combination of default and random parameters,
+ * depending on the underlying cipher implementation.
+ *
+ * @return the parameters that where used to create this cipher instance, or
+ * {@code null} if this cipher instance does not have any parameters
+ * at all.
+ */
+ protected abstract AlgorithmParameters engineGetParameters();
+
+ /**
+ * Initializes this cipher instance with the specified key and a source of
+ * randomness.
+ * <p>
+ * The cipher will be initialized for the specified operation (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * <p>
+ * If this cipher instance needs any algorithm parameters or random values
+ * that the specified key cannot provide, the underlying implementation of
+ * this cipher is supposed to generate the required parameters (using its
+ * provider or random values). Random values will be generated using {@code
+ * random};
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, means it is
+ * equivalent to creating a new instance and calling it {@code init} method.
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @param random
+ * the source of randomness to use.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this cipher
+ * instance.
+ */
+ protected abstract void engineInit(int opmode, Key key, SecureRandom random)
+ throws InvalidKeyException;
+
+ /**
+ * Initializes this cipher instance with the specified key, algorithm
+ * parameters and a source of randomness.
+ * <p>
+ * The cipher will be initialized for the specified operation (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * <p>
+ * If this cipher instance needs any algorithm parameters and {@code params}
+ * is {@code null}, the underlying implementation of this cipher is supposed
+ * to generate the required parameters (using its provider or random
+ * values). Random values are generated using {@code random}.
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, means it is
+ * equivalent to creating a new instance and calling it {@code init} method.
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @param params
+ * the algorithm parameters.
+ * @param random
+ * the source of randomness to use.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this cipher
+ * instance.
+ * @throws InvalidAlgorithmParameterException
+ * it the specified parameters are inappropriate for this
+ * cipher.
+ */
+ protected abstract void engineInit(int opmode, Key key,
+ AlgorithmParameterSpec params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
+
+ /**
+ * Initializes this cipher instance with the specified key, algorithm
+ * parameters and a source of randomness.
+ * <p>
+ * The cipher will be initialized for the specified operation (one of:
+ * encryption, decryption, key wrapping or key unwrapping) depending on
+ * {@code opmode}.
+ * <p>
+ * If this cipher instance needs any algorithm parameters and {@code params}
+ * is {@code null}, the underlying implementation of this cipher is supposed
+ * to generate the required parameters (using its provider or random
+ * values). Random values are generated using {@code random}.
+ * <p>
+ * When a cipher instance is initialized by a call to any of the {@code
+ * init} methods, the state of the instance is overridden, means it is
+ * equivalent to creating a new instance and calling it {@code init} method.
+ *
+ * @param opmode
+ * the operation this cipher instance should be initialized for
+ * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
+ * WRAP_MODE} or {@code UNWRAP_MODE}).
+ * @param key
+ * the input key for the operation.
+ * @param params
+ * the algorithm parameters.
+ * @param random
+ * the source of randomness to use.
+ * @throws InvalidKeyException
+ * if the specified key cannot be used to initialize this cipher
+ * instance.
+ * @throws InvalidAlgorithmParameterException
+ * if the specified parameters are inappropriate for this
+ * cipher.
+ */
+ protected abstract void engineInit(int opmode, Key key,
+ AlgorithmParameters params, SecureRandom random)
+ throws InvalidKeyException, InvalidAlgorithmParameterException;
+
+ /**
+ * Continues a multi-part transformation (encryption or decryption). The
+ * transformed bytes are returned.
+ *
+ * @param input
+ * the input bytes to transform.
+ * @param inputOffset
+ * the offset in the input to start.
+ * @param inputLen
+ * the length of the input to transform.
+ * @return the transformed bytes in a new buffer, or {@code null} if the
+ * input has zero length.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ * @throws IllegalArgumentException
+ * if the input is null, or if {@code inputOffset} and {@code
+ * inputLen} do not specify a valid chunk in the input buffer.
+ */
+ protected abstract byte[] engineUpdate(byte[] input, int inputOffset,
+ int inputLen);
+
+ /**
+ * Continues a multi-part transformation (encryption or decryption). The
+ * transformed bytes are stored in the {@code output} buffer.
+ * <p>
+ * If the size of the {@code output} buffer is too small to hold the result,
+ * a {@code ShortBufferException} is thrown. Use
+ * {@link Cipher#getOutputSize getOutputSize} to check for the size of the
+ * output buffer.
+ *
+ * @param input
+ * the input bytes to transform.
+ * @param inputOffset
+ * the offset in the input to start.
+ * @param inputLen
+ * the length of the input to transform.
+ * @param output
+ * the output buffer.
+ * @param outputOffset
+ * the offset in the output buffer.
+ * @return the number of bytes placed in output.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ */
+ protected abstract int engineUpdate(byte[] input, int inputOffset,
+ int inputLen, byte[] output, int outputOffset)
+ throws ShortBufferException;
+
+ /**
+ * Continues a multi-part transformation (encryption or decryption). The
+ * {@code input.remaining()} bytes starting at {@code input.position()} are
+ * transformed and stored in the {@code output} buffer.
+ * <p>
+ * If the {@code output.remaining()} is too small to hold the transformed
+ * bytes a {@code ShortBufferException} is thrown. Use
+ * {@link Cipher#getOutputSize getOutputSize} to check for the size of the
+ * output buffer.
+ *
+ * @param input
+ * the input buffer to transform.
+ * @param output
+ * the output buffer to store the result within.
+ * @return the number of bytes stored in the output buffer.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ */
+ protected int engineUpdate(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException {
+ if (input == null) {
+ throw new NullPointerException(Messages.getString("crypto.0C")); //$NON-NLS-1$
+ }
+ if (output == null) {
+ throw new NullPointerException(Messages.getString("crypto.0D")); //$NON-NLS-1$
+ }
+ int position = input.position();
+ int limit = input.limit();
+ if ((limit - position) <= 0) {
+ return 0;
+ }
+ byte[] bInput;
+ byte[] bOutput;
+ if (input.hasArray()) {
+ bInput = input.array();
+ int offset = input.arrayOffset();
+ bOutput = engineUpdate(bInput, offset + position, limit - position);
+ input.position(limit);
+ } else {
+ bInput = new byte[limit - position];
+ input.get(bInput);
+ bOutput = engineUpdate(bInput, 0, limit - position);
+ }
+ if (output.remaining() < bOutput.length) {
+ throw new ShortBufferException(Messages.getString("crypto.0E")); //$NON-NLS-1$
+ }
+ try {
+ output.put(bOutput);
+ } catch (java.nio.BufferOverflowException e) {
+ throw new ShortBufferException(Messages.getString("crypto.0F", e)); //$NON-NLS-1$
+ }
+ return bOutput.length;
+ }
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes the {@code inputLen} bytes in {@code input} buffer at {@code
+ * inputOffset}, and any bytes that have been buffered in previous {@code
+ * update} calls.
+ *
+ * @param input
+ * the input buffer.
+ * @param inputOffset
+ * the offset in the input buffer.
+ * @param inputLen
+ * the length of the input.
+ * @return the final bytes from the transformation.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ */
+ protected abstract byte[] engineDoFinal(byte[] input, int inputOffset,
+ int inputLen) throws IllegalBlockSizeException, BadPaddingException;
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes the {@code inputLen} bytes in {@code input} buffer at
+ * {@code inputOffset}, and any bytes that have been buffered in previous
+ * {@code update} calls.
+ *
+ * @param input
+ * the input buffer.
+ * @param inputOffset
+ * the offset in the input buffer.
+ * @param inputLen
+ * the length of the input.
+ * @param output
+ * the output buffer for the transformed bytes.
+ * @param outputOffset
+ * the offset in the output buffer.
+ * @return the number of bytes placed in the output buffer.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ */
+ protected abstract int engineDoFinal(byte[] input, int inputOffset,
+ int inputLen, byte[] output, int outputOffset)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException;
+
+ /**
+ * Finishes a multi-part transformation (encryption or decryption).
+ * <p>
+ * Processes the {@code input.remaining()} bytes in {@code input} buffer at
+ * {@code input.position()}, and any bytes that have been buffered in
+ * previous {@code update} calls. The transformed bytes are placed into
+ * {@code output} buffer.
+ *
+ * @param input
+ * the input buffer.
+ * @param output
+ * the output buffer.
+ * @return the number of bytes placed into the output buffer.
+ * @throws ShortBufferException
+ * if the size of the {@code output} buffer is too small.
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws BadPaddingException
+ * if the padding of the data does not match the padding scheme.
+ * @throws IllegalArgumentException
+ * if the input buffer and the output buffer are the same
+ * object.
+ * @throws IllegalStateException
+ * if this cipher instance is not initialized for encryption or
+ * decryption.
+ */
+ protected int engineDoFinal(ByteBuffer input, ByteBuffer output)
+ throws ShortBufferException, IllegalBlockSizeException,
+ BadPaddingException {
+ if (input == null) {
+ throw new NullPointerException(Messages.getString("crypto.0C")); //$NON-NLS-1$
+ }
+ if (output == null) {
+ throw new NullPointerException(Messages.getString("crypto.0D")); //$NON-NLS-1$
+ }
+ int position = input.position();
+ int limit = input.limit();
+
+ if ((limit - position) <= 0) {
+ return 0;
+ }
+ byte[] bInput;
+ byte[] bOutput;
+
+ if (input.hasArray()) {
+ bInput = input.array();
+ int offset = input.arrayOffset();
+ bOutput = engineDoFinal(bInput, offset + position, limit - position);
+ input.position(limit);
+ } else {
+ bInput = new byte[limit - position];
+ input.get(bInput);
+ bOutput = engineDoFinal(bInput, 0, limit - position);
+ }
+ if (output.remaining() < bOutput.length) {
+ throw new ShortBufferException(Messages.getString("crypto.0E")); //$NON-NLS-1$
+ }
+ try {
+ output.put(bOutput);
+ } catch (java.nio.BufferOverflowException e) {
+ throw new ShortBufferException(Messages.getString("crypto.0F", e)); //$NON-NLS-1$
+ }
+ return bOutput.length;
+ }
+
+ /**
+ * Wraps a key using this cipher instance. This method has been added to
+ * this class (for backwards compatibility, it cannot be abstract). If this
+ * method is not overridden, it throws an {@code
+ * UnsupportedOperationException}.
+ *
+ * @param key
+ * the key to wrap.
+ * @return the wrapped key
+ * @throws IllegalBlockSizeException
+ * if the size of the resulting bytes is not a multiple of the
+ * cipher block size.
+ * @throws InvalidKeyException
+ * if this cipher instance cannot wrap this key.
+ */
+ protected byte[] engineWrap(Key key) throws IllegalBlockSizeException,
+ InvalidKeyException {
+ throw new UnsupportedOperationException(
+ Messages.getString("crypto.10")); //$NON-NLS-1$
+ }
+
+ /**
+ * Unwraps a key using this cipher instance.
+ * <p>
+ * This method has been added to this class (for backwards compatibility, it
+ * cannot be abstract). If this method is not overridden, it throws an
+ * {@code UnsupportedOperationException}.
+ *
+ * @param wrappedKey
+ * the wrapped key to unwrap.
+ * @param wrappedKeyAlgorithm
+ * the algorithm for the wrapped key.
+ * @param wrappedKeyType
+ * the type of the wrapped key (one of: {@code SECRET_KEY},
+ * {@code PRIVATE_KEY} or {@code PUBLIC_KEY})
+ * @return the unwrapped key.
+ * @throws InvalidKeyException
+ * if the {@code wrappedKey} cannot be unwrapped to a key of
+ * type {@code wrappedKeyType} for the {@code
+ * wrappedKeyAlgorithm}.
+ * @throws NoSuchAlgorithmException
+ * if no provider can be found that can create a key of type
+ * {@code wrappedKeyType} for the {@code wrappedKeyAlgorithm}.
+ */
+ protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
+ int wrappedKeyType) throws InvalidKeyException,
+ NoSuchAlgorithmException {
+ throw new UnsupportedOperationException(
+ Messages.getString("crypto.11")); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the size of a specified key object in bits. This method has been
+ * added to this class (for backwards compatibility, it cannot be abstract).
+ * If this method is not overridden, it throws an {@code
+ * UnsupportedOperationException}.
+ *
+ * @param key
+ * the key to get the size for.
+ * @return the size of a specified key object in bits.
+ * @throws InvalidKeyException
+ * if the size of the key cannot be determined by this
+ * implementation.
+ */
+ protected int engineGetKeySize(Key key) throws InvalidKeyException {
+ throw new UnsupportedOperationException(
+ Messages.getString("crypto.12")); //$NON-NLS-1$
+ }
+} \ No newline at end of file