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 }