1 /* 2 * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.crypto.provider; 27 28 import java.security.*; 29 import java.security.spec.*; 30 import sun.security.util.*; 31 import javax.crypto.*; 32 import javax.crypto.spec.*; 33 import javax.crypto.BadPaddingException; 34 35 /** 36 * This class implements the Blowfish algorithm in its various modes 37 * (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>, 38 * <code>PCBC</code>) and padding schemes (<code>PKCS5Padding</code>, 39 * <code>NoPadding</code>, <code>ISO10126Padding</code>). 40 * 41 * <p> Blowfish is a 64-bit block cipher with a variable-length key. 42 * 43 * @author Jan Luehe 44 * 45 * 46 * @see BlowfishCrypt 47 * @see CipherBlockChaining 48 * @see ElectronicCodeBook 49 * @see CipherFeedback 50 * @see OutputFeedback 51 */ 52 53 public final class BlowfishCipher extends CipherSpi { 54 55 /* 56 * internal CipherCore object which does the real work. 57 */ 58 private CipherCore core = null; 59 60 /** 61 * Creates an instance of Blowfish cipher with default ECB mode and 62 * PKCS5Padding. 63 */ 64 public BlowfishCipher() { 65 core = new CipherCore(new BlowfishCrypt(), 66 BlowfishConstants.BLOWFISH_BLOCK_SIZE); 67 } 68 69 /** 70 * Sets the mode of this cipher. 71 * 72 * @param mode the cipher mode 73 * 74 * @exception NoSuchAlgorithmException if the requested cipher mode does 75 * not exist 76 */ 77 protected void engineSetMode(String mode) 78 throws NoSuchAlgorithmException { 79 core.setMode(mode); 80 } 81 82 /** 83 * Sets the padding mechanism of this cipher. 84 * 85 * @param padding the padding mechanism 86 * 87 * @exception NoSuchPaddingException if the requested padding mechanism 88 * does not exist 89 */ 90 protected void engineSetPadding(String paddingScheme) 91 throws NoSuchPaddingException { 92 core.setPadding(paddingScheme); 93 } 94 95 /** 96 * Returns the block size (in bytes). 97 * 98 * @return the block size (in bytes), or 0 if the underlying algorithm is 99 * not a block cipher 100 */ 101 protected int engineGetBlockSize() { 102 return BlowfishConstants.BLOWFISH_BLOCK_SIZE; 103 } 104 105 /** 106 * Returns the length in bytes that an output buffer would need to be in 107 * order to hold the result of the next <code>update</code> or 108 * <code>doFinal</code> operation, given the input length 109 * <code>inputLen</code> (in bytes). 110 * 111 * <p>This call takes into account any unprocessed (buffered) data from a 112 * previous <code>update</code> call, and padding. 113 * 114 * <p>The actual output length of the next <code>update</code> or 115 * <code>doFinal</code> call may be smaller than the length returned by 116 * this method. 117 * 118 * @param inputLen the input length (in bytes) 119 * 120 * @return the required output buffer size (in bytes) 121 */ 122 protected int engineGetOutputSize(int inputLen) { 123 return core.getOutputSize(inputLen); 124 } 125 126 /** 127 * Returns the initialization vector (IV) in a new buffer. 128 * 129 * <p>This is useful in the case where a random IV has been created 130 * (see <a href = "#init">init</a>), 131 * or in the context of password-based encryption or 132 * decryption, where the IV is derived from a user-supplied password. 133 * 134 * @return the initialization vector in a new buffer, or null if the 135 * underlying algorithm does not use an IV, or if the IV has not yet 136 * been set. 137 */ 138 protected byte[] engineGetIV() { 139 return core.getIV(); 140 } 141 142 /** 143 * Returns the parameters used with this cipher. 144 * 145 * <p>The returned parameters may be the same that were used to initialize 146 * this cipher, or may contain the default set of parameters or a set of 147 * randomly generated parameters used by the underlying cipher 148 * implementation (provided that the underlying cipher implementation 149 * uses a default set of parameters or creates new parameters if it needs 150 * parameters but was not initialized with any). 151 * 152 * @return the parameters used with this cipher, or null if this cipher 153 * does not use any parameters. 154 */ 155 protected AlgorithmParameters engineGetParameters() { 156 return core.getParameters("Blowfish"); 157 } 158 159 /** 160 * Initializes this cipher with a key and a source of randomness. 161 * 162 * <p>The cipher is initialized for one of the following four operations: 163 * encryption, decryption, key wrapping or key unwrapping, depending on 164 * the value of <code>opmode</code>. 165 * 166 * <p>If this cipher requires an initialization vector (IV), it will get 167 * it from <code>random</code>. 168 * This behaviour should only be used in encryption or key wrapping 169 * mode, however. 170 * When initializing a cipher that requires an IV for decryption or 171 * key unwrapping, the IV 172 * (same IV that was used for encryption or key wrapping) must be provided 173 * explicitly as a 174 * parameter, in order to get the correct result. 175 * 176 * <p>This method also cleans existing buffer and other related state 177 * information. 178 * 179 * @param opmode the operation mode of this cipher (this is one of 180 * the following: 181 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, 182 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) 183 * @param key the secret key 184 * @param random the source of randomness 185 * 186 * @exception InvalidKeyException if the given key is inappropriate for 187 * initializing this cipher 188 */ 189 protected void engineInit(int opmode, Key key, SecureRandom random) 190 throws InvalidKeyException { 191 core.init(opmode, key, random); 192 } 193 194 /** 195 * Initializes this cipher with a key, a set of 196 * algorithm parameters, and a source of randomness. 197 * 198 * <p>The cipher is initialized for one of the following four operations: 199 * encryption, decryption, key wrapping or key unwrapping, depending on 200 * the value of <code>opmode</code>. 201 * 202 * <p>If this cipher (including its underlying feedback or padding scheme) 203 * requires any random bytes, it will get them from <code>random</code>. 204 * 205 * @param opmode the operation mode of this cipher (this is one of 206 * the following: 207 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, 208 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) 209 * @param key the encryption key 210 * @param params the algorithm parameters 211 * @param random the source of randomness 212 * 213 * @exception InvalidKeyException if the given key is inappropriate for 214 * initializing this cipher 215 * @exception InvalidAlgorithmParameterException if the given algorithm 216 * parameters are inappropriate for this cipher 217 */ 218 protected void engineInit(int opmode, Key key, 219 AlgorithmParameterSpec params, 220 SecureRandom random) 221 throws InvalidKeyException, InvalidAlgorithmParameterException { 222 core.init(opmode, key, params, random); 223 } 224 225 protected void engineInit(int opmode, Key key, 226 AlgorithmParameters params, 227 SecureRandom random) 228 throws InvalidKeyException, InvalidAlgorithmParameterException { 229 core.init(opmode, key, params, random); 230 } 231 232 /** 233 * Continues a multiple-part encryption or decryption operation 234 * (depending on how this cipher was initialized), processing another data 235 * part. 236 * 237 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 238 * buffer, starting at <code>inputOffset</code>, are processed, and the 239 * result is stored in a new buffer. 240 * 241 * @param input the input buffer 242 * @param inputOffset the offset in <code>input</code> where the input 243 * starts 244 * @param inputLen the input length 245 * 246 * @return the new buffer with the result 247 * 248 * @exception IllegalStateException if this cipher is in a wrong state 249 * (e.g., has not been initialized) 250 */ 251 protected byte[] engineUpdate(byte[] input, int inputOffset, 252 int inputLen) { 253 return core.update(input, inputOffset, inputLen); 254 } 255 256 /** 257 * Continues a multiple-part encryption or decryption operation 258 * (depending on how this cipher was initialized), processing another data 259 * part. 260 * 261 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 262 * buffer, starting at <code>inputOffset</code>, are processed, and the 263 * result is stored in the <code>output</code> buffer, starting at 264 * <code>outputOffset</code>. 265 * 266 * @param input the input buffer 267 * @param inputOffset the offset in <code>input</code> where the input 268 * starts 269 * @param inputLen the input length 270 * @param output the buffer for the result 271 * @param outputOffset the offset in <code>output</code> where the result 272 * is stored 273 * 274 * @return the number of bytes stored in <code>output</code> 275 * 276 * @exception ShortBufferException if the given output buffer is too small 277 * to hold the result 278 */ 279 protected int engineUpdate(byte[] input, int inputOffset, int inputLen, 280 byte[] output, int outputOffset) 281 throws ShortBufferException { 282 return core.update(input, inputOffset, inputLen, output, 283 outputOffset); 284 } 285 286 /** 287 * Encrypts or decrypts data in a single-part operation, 288 * or finishes a multiple-part operation. 289 * The data is encrypted or decrypted, depending on how this cipher was 290 * initialized. 291 * 292 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 293 * buffer, starting at <code>inputOffset</code>, and any input bytes that 294 * may have been buffered during a previous <code>update</code> operation, 295 * are processed, with padding (if requested) being applied. 296 * The result is stored in a new buffer. 297 * 298 * <p>The cipher is reset to its initial state (uninitialized) after this 299 * call. 300 * 301 * @param input the input buffer 302 * @param inputOffset the offset in <code>input</code> where the input 303 * starts 304 * @param inputLen the input length 305 * 306 * @return the new buffer with the result 307 * 308 * @exception IllegalBlockSizeException if this cipher is a block cipher, 309 * no padding has been requested (only in encryption mode), and the total 310 * input length of the data processed by this cipher is not a multiple of 311 * block size 312 * @exception BadPaddingException if this cipher is in decryption mode, 313 * and (un)padding has been requested, but the decrypted data is not 314 * bounded by the appropriate padding bytes 315 */ 316 protected byte[] engineDoFinal(byte[] input, int inputOffset, 317 int inputLen) 318 throws IllegalBlockSizeException, BadPaddingException { 319 return core.doFinal(input, inputOffset, inputLen); 320 } 321 322 /** 323 * Encrypts or decrypts data in a single-part operation, 324 * or finishes a multiple-part operation. 325 * The data is encrypted or decrypted, depending on how this cipher was 326 * initialized. 327 * 328 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 329 * buffer, starting at <code>inputOffset</code>, and any input bytes that 330 * may have been buffered during a previous <code>update</code> operation, 331 * are processed, with padding (if requested) being applied. 332 * The result is stored in the <code>output</code> buffer, starting at 333 * <code>outputOffset</code>. 334 * 335 * <p>The cipher is reset to its initial state (uninitialized) after this 336 * call. 337 * 338 * @param input the input buffer 339 * @param inputOffset the offset in <code>input</code> where the input 340 * starts 341 * @param inputLen the input length 342 * @param output the buffer for the result 343 * @param outputOffset the offset in <code>output</code> where the result 344 * is stored 345 * 346 * @return the number of bytes stored in <code>output</code> 347 * 348 * @exception IllegalBlockSizeException if this cipher is a block cipher, 349 * no padding has been requested (only in encryption mode), and the total 350 * input length of the data processed by this cipher is not a multiple of 351 * block size 352 * @exception ShortBufferException if the given output buffer is too small 353 * to hold the result 354 * @exception BadPaddingException if this cipher is in decryption mode, 355 * and (un)padding has been requested, but the decrypted data is not 356 * bounded by the appropriate padding bytes 357 */ 358 protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, 359 byte[] output, int outputOffset) 360 throws IllegalBlockSizeException, ShortBufferException, 361 BadPaddingException { 362 return core.doFinal(input, inputOffset, inputLen, output, 363 outputOffset); 364 } 365 366 /** 367 * Returns the key size of the given key object. 368 * 369 * @param key the key object. 370 * 371 * @return the key size of the given key object. 372 * 373 * @exception InvalidKeyException if <code>key</code> is invalid. 374 */ 375 protected int engineGetKeySize(Key key) throws InvalidKeyException { 376 return (key.getEncoded().length * 8); 377 } 378 379 /** 380 * Wrap a key. 381 * 382 * @param key the key to be wrapped. 383 * 384 * @return the wrapped key. 385 * 386 * @exception IllegalBlockSizeException if this cipher is a block 387 * cipher, no padding has been requested, and the length of the 388 * encoding of the key to be wrapped is not a 389 * multiple of the block size. 390 * 391 * @exception InvalidKeyException if it is impossible or unsafe to 392 * wrap the key with this cipher (e.g., a hardware protected key is 393 * being passed to a software only cipher). 394 */ 395 protected byte[] engineWrap(Key key) 396 throws IllegalBlockSizeException, InvalidKeyException { 397 return core.wrap(key); 398 } 399 400 /** 401 * Unwrap a previously wrapped key. 402 * 403 * @param wrappedKey the key to be unwrapped. 404 * 405 * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. 406 * 407 * @param wrappedKeyType the type of the wrapped key. 408 * This is one of <code>Cipher.SECRET_KEY</code>, 409 * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. 410 * 411 * @return the unwrapped key. 412 * 413 * @exception NoSuchAlgorithmException if no installed providers 414 * can create keys of type <code>wrappedKeyType</code> for the 415 * <code>wrappedKeyAlgorithm</code>. 416 * 417 * @exception InvalidKeyException if <code>wrappedKey</code> does not 418 * represent a wrapped key of type <code>wrappedKeyType</code> for 419 * the <code>wrappedKeyAlgorithm</code>. 420 */ 421 protected Key engineUnwrap(byte[] wrappedKey, 422 String wrappedKeyAlgorithm, 423 int wrappedKeyType) 424 throws InvalidKeyException, NoSuchAlgorithmException { 425 return core.unwrap(wrappedKey, wrappedKeyAlgorithm, 426 wrappedKeyType); 427 } 428 }