001    /*
002     * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org
003     * Copyright (C) 2011 NightLabs Consulting GmbH
004     *
005     * This program is free software: you can redistribute it and/or modify
006     * it under the terms of the GNU Affero General Public License as
007     * published by the Free Software Foundation, either version 3 of the
008     * License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013     * GNU Affero General Public License for more details.
014     *
015     * You should have received a copy of the GNU Affero General Public License
016     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017     */
018    package org.cumulus4j.crypto;
019    
020    import org.bouncycastle.crypto.CipherParameters;
021    import org.bouncycastle.crypto.CryptoException;
022    import org.bouncycastle.crypto.DataLengthException;
023    import org.bouncycastle.crypto.params.KeyParameter;
024    import org.bouncycastle.crypto.params.ParametersWithIV;
025    import org.bouncycastle.jce.provider.BouncyCastleProvider;
026    
027    /**
028     * <p>
029     * A cipher encrypts or decrypts data.
030     * </p>
031     * <p>
032     * This interface defines the algorithm-independent API contract to allow
033     * for encrypting and decrypting data. It has been introduced in analogy
034     * to {@link javax.crypto.Cipher} and with easy migration from JCE
035     * to this API in mind.
036     * </p>
037     * <p>
038     * <b>Important: <code>Cipher</code>s are not thread-safe!</b>
039     * </p>
040     * <p>
041     * Use {@link CryptoRegistry#createCipher(String)} to obtain a <code>Cipher</code> instance.
042     * </p>
043     * <p>
044     * This own API is used instead of the JCE, because of the following reasons:
045     * </p>
046     * <ul>
047     *  <li>The JCE has a key length constraint (maximum 128 bit) that requires manual modifications of
048     * the Java runtime environment (installing some files that are not included in the operating system's
049     * package management).</li>
050     *      <li>The {@link BouncyCastleProvider} was not correctly registered in the JCE when using One-JAR to
051     * package e.g. the <code>org.cumulus4j.keymanager.cli</code>. Probably because the signatures where not
052     * found when looking for the MANIFEST.MF (probably the wrong MANIFEST.MF was picked by the class loader).
053     *      </li>
054     * </ul>
055     * <p>
056     * Note: Implementors should subclass {@link AbstractCipher} instead of directly implementing this interface.
057     * </p>
058     * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de
059     */
060    public interface Cipher
061    {
062            /**
063             * <p>
064             * Initialise the cipher.
065             * </p><p>
066             * A cipher cannot be used, before this method was called.
067             * </p><p>
068             * A cipher can be re-initialised to modify only certain parameters (and keep the others). For example to modify
069             * the <a target="_blank" href="http://en.wikipedia.org/wiki/Initialisation_vector">IV</a> while keeping the key, a cipher can
070             * be re-initialised with an IV only (i.e. <code>null</code> is passed to
071             * {@link ParametersWithIV#ParametersWithIV(CipherParameters, byte[], int, int)} instead of a {@link KeyParameter}).
072             * This is useful for performance reasons, because modifying an IV is a very fast operation while changing the key is
073             * slow (especially <a target="_blank" href="http://en.wikipedia.org/wiki/Blowfish_%28cipher%29">Blowfish</a> is known for its very
074             * slow key initialisation).
075             * </p>
076             *
077             * @param mode the operation mode; must not be <code>null</code>.
078             * @param parameters the parameters; for example an instance of {@link ParametersWithIV} with a wrapped {@link KeyParameter}
079             * to pass IV and secret key.
080             * @throws IllegalArgumentException if the given arguments are invalid - for example if the given <code>parameters</code>
081             * are not understood by the implementation (parameters not compatible with the chosen algorithm).
082             */
083            void init(CipherOperationMode mode, CipherParameters parameters)
084            throws IllegalArgumentException;
085    
086            /**
087             * Get the mode of this cipher. This is <code>null</code>, before
088             * {@link #init(CipherOperationMode, CipherParameters)} was called the first
089             * time.
090             * @return the mode of this cipher.
091             */
092            CipherOperationMode getMode();
093    
094            /**
095             * Get the parameters of this cipher. This is <code>null</code>, before
096             * {@link #init(CipherOperationMode, CipherParameters)} was called the first
097             * time.
098             * @return the parameters of this cipher.
099             */
100            CipherParameters getParameters();
101    
102            /**
103             * Get the transformation that was passed to {@link CryptoRegistry#createCipher(String)}
104             * for obtaining this <code>Cipher</code>.
105             * @return the transformation (encryption algorithm, mode and padding) of this cipher.
106             */
107            String getTransformation();
108    
109            /**
110             * Reset this cipher. After resetting, the state is the same as if it was just freshly
111             * {@link #init(CipherOperationMode, CipherParameters) initialised}.
112             */
113            void reset();
114    
115            /**
116       * Get the input block size for this cipher (in bytes).
117       * If this is a symmetric cipher, this equals {@link #getOutputBlockSize()}.
118       *
119       * @return the input block size for this cipher in bytes.
120       */
121            int getInputBlockSize();
122    
123            /**
124       * Get the output block size for this cipher (in bytes).
125       * If this is a symmetric cipher, this equals {@link #getInputBlockSize()}.
126       *
127       * @return the output block size for this cipher in bytes.
128       */
129            int getOutputBlockSize();
130    
131            /**
132             * Return the size of the output buffer required for an {@link #update(byte[], int, int, byte[], int) update}
133             * of an input of <code>length</code> bytes.
134             * @param length the size of the input (in bytes) that is to be passed to {@link #update(byte[], int, int, byte[], int)}.
135             * @return the required length of the output buffer in bytes.
136             */
137            int getUpdateOutputSize(int length);
138    
139            /**
140             * Return the size of the output buffer required for an {@link #update(byte[], int, int, byte[], int) update} plus a
141             * {@link #doFinal(byte[], int) doFinal} with an input of <code>length</code> bytes.
142             * @param length the size of the input (in bytes) that is to be passed to {@link #update(byte[], int, int, byte[], int)}.
143             * @return the required length of the output buffer in bytes.
144             */
145            int getOutputSize(int length);
146    
147            /**
148             * <p>
149             * Update this cipher with a single byte. This is synonymous to calling {@link #update(byte[], int, int, byte[], int)}
150             * with an <code>in</code> byte array of length 1 and <code>inOff = 0</code> and <code>inLen = 1</code>.
151             * </p><p>
152             * Note that data might still be unprocessed in this cipher when this method returns. That is because many ciphers work
153             * with blocks and keep a block unprocessed until it is filled up. Call {@link #doFinal(byte[], int)} after you finished
154             * updating this cipher (i.e. all input was passed completely).
155             * </p>
156             *
157             * @param in the input to be encrypted or decrypted (or a part of the input).
158             * @param out the buffer receiving the output (data is written into this byte-array). Must not be <code>null</code>.
159             * @param outOff the array-index in <code>out</code> at which to start writing. Must be &gt;=0.
160             * @return the number of bytes written into <code>out</code>.
161             * @throws DataLengthException if the buffer <code>out</code> is insufficient.
162             * @throws IllegalStateException if this cipher has not yet been {@link #init(CipherOperationMode, CipherParameters) initialised}.
163             * @throws CryptoException if there is a cryptographic error happening while processing the input. For example when
164             * decrypting a padding might be wrong or an authenticating block mode (like GCM) might recognize that the ciphertext has
165             * been manipulated/corrupted.
166             * @see #update(byte[], int, int, byte[], int)
167             * @see #doFinal(byte[], int)
168             */
169            int update(byte in, byte[] out, int outOff) throws DataLengthException,
170                            IllegalStateException, CryptoException;
171    
172            /**
173             * <p>
174             * Update this cipher with multiple bytes.
175             * </p><p>
176             * Note that data might still be unprocessed in this cipher when this method returns. That is because many ciphers work
177             * with blocks and keep a block unprocessed until it is filled up. Call {@link #doFinal(byte[], int)} after you finished
178             * updating this cipher (i.e. all input was passed completely).
179             * </p>
180             *
181             * @param in the input to be encrypted or decrypted (or a part of the input). Must not be <code>null</code>.
182             * @param inOff the array-index in <code>in</code> at which to start reading. Must be &gt;=0.
183             * @param inLen the number of bytes that should be read from <code>in</code>.
184             * @param out the buffer receiving the output (data is written into this byte-array). Must not be <code>null</code>.
185             * @param outOff the array-index in <code>out</code> at which to start writing. Must be &gt;=0.
186             * @return the number of bytes written into <code>out</code>.
187             * @throws DataLengthException if the buffer <code>out</code> is insufficient or if <code>inOff + inLen</code> exceeds the
188             * input byte array.
189             * @throws IllegalStateException if this cipher has not yet been {@link #init(CipherOperationMode, CipherParameters) initialised}.
190             * @throws CryptoException if there is a cryptographic error happening while processing the input. For example when
191             * decrypting a padding might be wrong or an authenticating block mode (like GCM) might recognize that the ciphertext has
192             * been manipulated/corrupted.
193             * @see #update(byte, byte[], int)
194             * @see #doFinal(byte[], int)
195             */
196            int update(byte[] in, int inOff, int inLen, byte[] out, int outOff)
197                            throws DataLengthException, IllegalStateException, CryptoException;
198    
199            /**
200             * Process the last block in the buffer. After this call, no unprocessed data is left in this
201             * cipher and it is {@link #reset()} implicitly.
202             *
203             * @param out the buffer receiving the output (data is written into this byte-array). Must not be <code>null</code>.
204             * @param outOff the array-index in <code>out</code> at which to start writing. Must be &gt;=0.
205             * @return the number of bytes written into <code>out</code>.
206             * @throws DataLengthException if the buffer <code>out</code> is insufficient or if <code>inOff + inLen</code> exceeds the
207             * input byte array.
208             * @throws IllegalStateException if this cipher has not yet been {@link #init(CipherOperationMode, CipherParameters) initialised}.
209             * @throws CryptoException if there is a cryptographic error happening while processing the input. For example when
210             * decrypting a padding might be wrong or an authenticating block mode (like GCM) might recognize that the ciphertext has
211             * been manipulated/corrupted.
212             * @see #update(byte, byte[], int)
213             * @see #update(byte[], int, int, byte[], int)
214             * @see #doFinal(byte[])
215             */
216            int doFinal(byte[] out, int outOff) throws DataLengthException,
217                            IllegalStateException, CryptoException;
218    
219            /**
220             * Convenience method to encrypt/decrypt the complete input byte array at once. After this method was called,
221             * no unprocessed data is left in this cipher and it is {@link #reset()} implicitly.
222             *
223             * @param in the input to be encrypted or decrypted. Must not be <code>null</code>.
224             * @return the processed output.
225             * @throws IllegalStateException if the cipher isn't initialised.
226             * @throws CryptoException if padding is expected and not found or sth. else goes wrong while encrypting or decrypting.
227             */
228            byte[] doFinal(byte[] in)
229            throws IllegalStateException, CryptoException;
230    
231            /**
232             * Get the required size of the IV (in bytes). If a cipher supports multiple sizes, this is the optimal (most secure) IV size.
233             * If the cipher supports no IV, this is 0.
234             * @return the required size of the IV.
235             */
236            int getIVSize();
237    }