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 >=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 >=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 >=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 >=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 }