Showing the changes to java/pkg/com/sun/crypto/provider/DESCipher.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,428 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 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 javax.crypto.*; | ||
| 31 | import javax.crypto.spec.*; | ||
| 32 | import javax.crypto.BadPaddingException; | ||
| 33 | |||
| 34 | /** | ||
| 35 | * This class implements the DES algorithm in its various modes | ||
| 36 | * (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>, | ||
| 37 | * <code>PCBC</code>) and padding schemes (<code>PKCS5Padding</code>, | ||
| 38 | * <code>NoPadding</code>, <code>ISO10126Padding</code>). | ||
| 39 | * | ||
| 40 | * @author Gigi Ankeny | ||
| 41 | * @author Jan Luehe | ||
| 42 | * @see DESCrypt | ||
| 43 | * @see CipherBlockChaining | ||
| 44 | * @see ElectronicCodeBook | ||
| 45 | * @see CipherFeedback | ||
| 46 | * @see OutputFeedback | ||
| 47 | */ | ||
| 48 | |||
| 49 | public final class DESCipher extends CipherSpi { | ||
| 50 | |||
| 51 | /* | ||
| 52 | * internal CipherCore object which does the real work. | ||
| 53 | */ | ||
| 54 | private CipherCore core = null; | ||
| 55 | |||
| 56 | /** | ||
| 57 | * Creates an instance of DES cipher with default ECB mode and | ||
| 58 | * PKCS5Padding. | ||
| 59 | */ | ||
| 60 | public DESCipher() { | ||
| 61 | core = new CipherCore(new DESCrypt(), DESConstants.DES_BLOCK_SIZE); | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Sets the mode of this cipher. | ||
| 66 | * | ||
| 67 | * @param mode the cipher mode | ||
| 68 | * | ||
| 69 | * @exception NoSuchAlgorithmException if the requested cipher mode does | ||
| 70 | * not exist | ||
| 71 | */ | ||
| 72 | protected void engineSetMode(String mode) | ||
| 73 | throws NoSuchAlgorithmException { | ||
| 74 | core.setMode(mode); | ||
| 75 | } | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Sets the padding mechanism of this cipher. | ||
| 79 | * | ||
| 80 | * @param padding the padding mechanism | ||
| 81 | * | ||
| 82 | * @exception NoSuchPaddingException if the requested padding mechanism | ||
| 83 | * does not exist | ||
| 84 | */ | ||
| 85 | protected void engineSetPadding(String paddingScheme) | ||
| 86 | throws NoSuchPaddingException { | ||
| 87 | core.setPadding(paddingScheme); | ||
| 88 | } | ||
| 89 | |||
| 90 | /** | ||
| 91 | * Returns the block size (in bytes). | ||
| 92 | * | ||
| 93 | * @return the block size (in bytes), or 0 if the underlying algorithm is | ||
| 94 | * not a block cipher | ||
| 95 | */ | ||
| 96 | protected int engineGetBlockSize() { | ||
| 97 | return DESConstants.DES_BLOCK_SIZE; | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Returns the length in bytes that an output buffer would need to be in | ||
| 102 | * order to hold the result of the next <code>update</code> or | ||
| 103 | * <code>doFinal</code> operation, given the input length | ||
| 104 | * <code>inputLen</code> (in bytes). | ||
| 105 | * | ||
| 106 | * <p>This call takes into account any unprocessed (buffered) data from a | ||
| 107 | * previous <code>update</code> call, and padding. | ||
| 108 | * | ||
| 109 | * <p>The actual output length of the next <code>update</code> or | ||
| 110 | * <code>doFinal</code> call may be smaller than the length returned by | ||
| 111 | * this method. | ||
| 112 | * | ||
| 113 | * @param inputLen the input length (in bytes) | ||
| 114 | * | ||
| 115 | * @return the required output buffer size (in bytes) | ||
| 116 | */ | ||
| 117 | protected int engineGetOutputSize(int inputLen) { | ||
| 118 | return core.getOutputSize(inputLen); | ||
| 119 | } | ||
| 120 | |||
| 121 | /** | ||
| 122 | * Returns the initialization vector (IV) in a new buffer. | ||
| 123 | * | ||
| 124 | * <p>This is useful in the case where a random IV has been created | ||
| 125 | * (see <a href = "#init">init</a>), | ||
| 126 | * or in the context of password-based encryption or | ||
| 127 | * decryption, where the IV is derived from a user-provided password. | ||
| 128 | * | ||
| 129 | * @return the initialization vector in a new buffer, or null if the | ||
| 130 | * underlying algorithm does not use an IV, or if the IV has not yet | ||
| 131 | * been set. | ||
| 132 | */ | ||
| 133 | protected byte[] engineGetIV() { | ||
| 134 | return core.getIV(); | ||
| 135 | } | ||
| 136 | |||
| 137 | /** | ||
| 138 | * Returns the parameters used with this cipher. | ||
| 139 | * | ||
| 140 | * <p>The returned parameters may be the same that were used to initialize | ||
| 141 | * this cipher, or may contain the default set of parameters or a set of | ||
| 142 | * randomly generated parameters used by the underlying cipher | ||
| 143 | * implementation (provided that the underlying cipher implementation | ||
| 144 | * uses a default set of parameters or creates new parameters if it needs | ||
| 145 | * parameters but was not initialized with any). | ||
| 146 | * | ||
| 147 | * @return the parameters used with this cipher, or null if this cipher | ||
| 148 | * does not use any parameters. | ||
| 149 | */ | ||
| 150 | protected AlgorithmParameters engineGetParameters() { | ||
| 151 | return core.getParameters("DES"); | ||
| 152 | } | ||
| 153 | |||
| 154 | /** | ||
| 155 | * Initializes this cipher with a key and a source of randomness. | ||
| 156 | * | ||
| 157 | * <p>The cipher is initialized for one of the following four operations: | ||
| 158 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 159 | * the value of <code>opmode</code>. | ||
| 160 | * | ||
| 161 | * <p>If this cipher requires an initialization vector (IV), it will get | ||
| 162 | * it from <code>random</code>. | ||
| 163 | * This behaviour should only be used in encryption or key wrapping | ||
| 164 | * mode, however. | ||
| 165 | * When initializing a cipher that requires an IV for decryption or | ||
| 166 | * key unwrapping, the IV | ||
| 167 | * (same IV that was used for encryption or key wrapping) must be provided | ||
| 168 | * explicitly as a | ||
| 169 | * parameter, in order to get the correct result. | ||
| 170 | * | ||
| 171 | * <p>This method also cleans existing buffer and other related state | ||
| 172 | * information. | ||
| 173 | * | ||
| 174 | * @param opmode the operation mode of this cipher (this is one of | ||
| 175 | * the following: | ||
| 176 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 177 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 178 | * @param key the secret key | ||
| 179 | * @param random the source of randomness | ||
| 180 | * | ||
| 181 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 182 | * initializing this cipher | ||
| 183 | */ | ||
| 184 | protected void engineInit(int opmode, Key key, SecureRandom random) | ||
| 185 | throws InvalidKeyException { | ||
| 186 | core.init(opmode, key, random); | ||
| 187 | } | ||
| 188 | |||
| 189 | /** | ||
| 190 | * Initializes this cipher with a key, a set of | ||
| 191 | * algorithm parameters, and a source of randomness. | ||
| 192 | * | ||
| 193 | * <p>The cipher is initialized for one of the following four operations: | ||
| 194 | * encryption, decryption, key wrapping or key unwrapping, depending on | ||
| 195 | * the value of <code>opmode</code>. | ||
| 196 | * | ||
| 197 | * <p>If this cipher (including its underlying feedback or padding scheme) | ||
| 198 | * requires any random bytes, it will get them from <code>random</code>. | ||
| 199 | * | ||
| 200 | * @param opmode the operation mode of this cipher (this is one of | ||
| 201 | * the following: | ||
| 202 | * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, | ||
| 203 | * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) | ||
| 204 | * @param key the encryption key | ||
| 205 | * @param params the algorithm parameters | ||
| 206 | * @param random the source of randomness | ||
| 207 | * | ||
| 208 | * @exception InvalidKeyException if the given key is inappropriate for | ||
| 209 | * initializing this cipher | ||
| 210 | * @exception InvalidAlgorithmParameterException if the given algorithm | ||
| 211 | * parameters are inappropriate for this cipher | ||
| 212 | */ | ||
| 213 | protected void engineInit(int opmode, Key key, | ||
| 214 | AlgorithmParameterSpec params, | ||
| 215 | SecureRandom random) | ||
| 216 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 217 | core.init(opmode, key, params, random); | ||
| 218 | } | ||
| 219 | |||
| 220 | protected void engineInit(int opmode, Key key, | ||
| 221 | AlgorithmParameters params, | ||
| 222 | SecureRandom random) | ||
| 223 | throws InvalidKeyException, InvalidAlgorithmParameterException { | ||
| 224 | core.init(opmode, key, params, random); | ||
| 225 | } | ||
| 226 | |||
| 227 | /** | ||
| 228 | * Continues a multiple-part encryption or decryption operation | ||
| 229 | * (depending on how this cipher was initialized), processing another data | ||
| 230 | * part. | ||
| 231 | * | ||
| 232 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 233 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 234 | * result is stored in a new buffer. | ||
| 235 | * | ||
| 236 | * @param input the input buffer | ||
| 237 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 238 | * starts | ||
| 239 | * @param inputLen the input length | ||
| 240 | * | ||
| 241 | * @return the new buffer with the result | ||
| 242 | * | ||
| 243 | * @exception IllegalStateException if this cipher is in a wrong state | ||
| 244 | * (e.g., has not been initialized) | ||
| 245 | */ | ||
| 246 | protected byte[] engineUpdate(byte[] input, int inputOffset, | ||
| 247 | int inputLen) { | ||
| 248 | return core.update(input, inputOffset, inputLen); | ||
| 249 | } | ||
| 250 | |||
| 251 | /** | ||
| 252 | * Continues a multiple-part encryption or decryption operation | ||
| 253 | * (depending on how this cipher was initialized), processing another data | ||
| 254 | * part. | ||
| 255 | * | ||
| 256 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 257 | * buffer, starting at <code>inputOffset</code>, are processed, and the | ||
| 258 | * result is stored in the <code>output</code> buffer, starting at | ||
| 259 | * <code>outputOffset</code>. | ||
| 260 | * | ||
| 261 | * @param input the input buffer | ||
| 262 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 263 | * starts | ||
| 264 | * @param inputLen the input length | ||
| 265 | * @param output the buffer for the result | ||
| 266 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 267 | * is stored | ||
| 268 | * | ||
| 269 | * @return the number of bytes stored in <code>output</code> | ||
| 270 | * | ||
| 271 | * @exception ShortBufferException if the given output buffer is too small | ||
| 272 | * to hold the result | ||
| 273 | */ | ||
| 274 | protected int engineUpdate(byte[] input, int inputOffset, int inputLen, | ||
| 275 | byte[] output, int outputOffset) | ||
| 276 | throws ShortBufferException { | ||
| 277 | return core.update(input, inputOffset, inputLen, output, | ||
| 278 | outputOffset); | ||
| 279 | } | ||
| 280 | |||
| 281 | /** | ||
| 282 | * Encrypts or decrypts data in a single-part operation, | ||
| 283 | * or finishes a multiple-part operation. | ||
| 284 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 285 | * initialized. | ||
| 286 | * | ||
| 287 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 288 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 289 | * may have been buffered during a previous <code>update</code> operation, | ||
| 290 | * are processed, with padding (if requested) being applied. | ||
| 291 | * The result is stored in a new buffer. | ||
| 292 | * | ||
| 293 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 294 | * call. | ||
| 295 | * | ||
| 296 | * @param input the input buffer | ||
| 297 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 298 | * starts | ||
| 299 | * @param inputLen the input length | ||
| 300 | * | ||
| 301 | * @return the new buffer with the result | ||
| 302 | * | ||
| 303 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 304 | * no padding has been requested (only in encryption mode), and the total | ||
| 305 | * input length of the data processed by this cipher is not a multiple of | ||
| 306 | * block size | ||
| 307 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 308 | * and (un)padding has been requested, but the decrypted data is not | ||
| 309 | * bounded by the appropriate padding bytes | ||
| 310 | */ | ||
| 311 | protected byte[] engineDoFinal(byte[] input, int inputOffset, | ||
| 312 | int inputLen) | ||
| 313 | throws IllegalBlockSizeException, BadPaddingException { | ||
| 314 | return core.doFinal(input, inputOffset, inputLen); | ||
| 315 | } | ||
| 316 | |||
| 317 | /** | ||
| 318 | * Encrypts or decrypts data in a single-part operation, | ||
| 319 | * or finishes a multiple-part operation. | ||
| 320 | * The data is encrypted or decrypted, depending on how this cipher was | ||
| 321 | * initialized. | ||
| 322 | * | ||
| 323 | * <p>The first <code>inputLen</code> bytes in the <code>input</code> | ||
| 324 | * buffer, starting at <code>inputOffset</code>, and any input bytes that | ||
| 325 | * may have been buffered during a previous <code>update</code> operation, | ||
| 326 | * are processed, with padding (if requested) being applied. | ||
| 327 | * The result is stored in the <code>output</code> buffer, starting at | ||
| 328 | * <code>outputOffset</code>. | ||
| 329 | * | ||
| 330 | * <p>The cipher is reset to its initial state (uninitialized) after this | ||
| 331 | * call. | ||
| 332 | * | ||
| 333 | * @param input the input buffer | ||
| 334 | * @param inputOffset the offset in <code>input</code> where the input | ||
| 335 | * starts | ||
| 336 | * @param inputLen the input length | ||
| 337 | * @param output the buffer for the result | ||
| 338 | * @param outputOffset the offset in <code>output</code> where the result | ||
| 339 | * is stored | ||
| 340 | * | ||
| 341 | * @return the number of bytes stored in <code>output</code> | ||
| 342 | * | ||
| 343 | * @exception IllegalBlockSizeException if this cipher is a block cipher, | ||
| 344 | * no padding has been requested (only in encryption mode), and the total | ||
| 345 | * input length of the data processed by this cipher is not a multiple of | ||
| 346 | * block size | ||
| 347 | * @exception ShortBufferException if the given output buffer is too small | ||
| 348 | * to hold the result | ||
| 349 | * @exception BadPaddingException if this cipher is in decryption mode, | ||
| 350 | * and (un)padding has been requested, but the decrypted data is not | ||
| 351 | * bounded by the appropriate padding bytes | ||
| 352 | */ | ||
| 353 | protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, | ||
| 354 | byte[] output, int outputOffset) | ||
| 355 | throws IllegalBlockSizeException, ShortBufferException, | ||
| 356 | BadPaddingException { | ||
| 357 | return core.doFinal(input, inputOffset, inputLen, output, | ||
| 358 | outputOffset); | ||
| 359 | } | ||
| 360 | |||
| 361 | /** | ||
| 362 | * Returns the key size of the given key object. | ||
| 363 | * | ||
| 364 | * @param key the key object. | ||
| 365 | * | ||
| 366 | * @return the key size of the given key object. | ||
| 367 | * | ||
| 368 | * @exception InvalidKeyException if <code>key</code> is invalid. | ||
| 369 | */ | ||
| 370 | protected int engineGetKeySize(Key key) throws InvalidKeyException { | ||
| 371 | byte[] encoded = key.getEncoded(); | ||
| 372 | if (encoded.length != 8) { | ||
| 373 | throw new InvalidKeyException("Invalid key length: " + | ||
| 374 | encoded.length + " bytes"); | ||
| 375 | } | ||
| 376 | return 56; | ||
| 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 | } | ||