Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/crypto/provider/DESCipher.java
38922 views
/*1* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.crypto.provider;2627import java.security.*;28import java.security.spec.*;29import javax.crypto.*;30import javax.crypto.spec.*;31import javax.crypto.BadPaddingException;3233/**34* This class implements the DES algorithm in its various modes35* (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>,36* <code>PCBC</code>) and padding schemes (<code>PKCS5Padding</code>,37* <code>NoPadding</code>, <code>ISO10126Padding</code>).38*39* @author Gigi Ankeny40* @author Jan Luehe41* @see DESCrypt42* @see CipherBlockChaining43* @see ElectronicCodeBook44* @see CipherFeedback45* @see OutputFeedback46*/4748public final class DESCipher extends CipherSpi {4950/*51* internal CipherCore object which does the real work.52*/53private CipherCore core = null;5455/**56* Creates an instance of DES cipher with default ECB mode and57* PKCS5Padding.58*/59public DESCipher() {60core = new CipherCore(new DESCrypt(), DESConstants.DES_BLOCK_SIZE);61}6263/**64* Sets the mode of this cipher.65*66* @param mode the cipher mode67*68* @exception NoSuchAlgorithmException if the requested cipher mode does69* not exist70*/71protected void engineSetMode(String mode)72throws NoSuchAlgorithmException {73core.setMode(mode);74}7576/**77* Sets the padding mechanism of this cipher.78*79* @param paddingScheme the padding mechanism80*81* @exception NoSuchPaddingException if the requested padding mechanism82* does not exist83*/84protected void engineSetPadding(String paddingScheme)85throws NoSuchPaddingException {86core.setPadding(paddingScheme);87}8889/**90* Returns the block size (in bytes).91*92* @return the block size (in bytes), or 0 if the underlying algorithm is93* not a block cipher94*/95protected int engineGetBlockSize() {96return DESConstants.DES_BLOCK_SIZE;97}9899/**100* Returns the length in bytes that an output buffer would need to be in101* order to hold the result of the next <code>update</code> or102* <code>doFinal</code> operation, given the input length103* <code>inputLen</code> (in bytes).104*105* <p>This call takes into account any unprocessed (buffered) data from a106* previous <code>update</code> call, and padding.107*108* <p>The actual output length of the next <code>update</code> or109* <code>doFinal</code> call may be smaller than the length returned by110* this method.111*112* @param inputLen the input length (in bytes)113*114* @return the required output buffer size (in bytes)115*/116protected int engineGetOutputSize(int inputLen) {117return core.getOutputSize(inputLen);118}119120/**121* Returns the initialization vector (IV) in a new buffer.122*123* <p>This is useful in the case where a random IV has been created124* (see <a href = "#init">init</a>),125* or in the context of password-based encryption or126* decryption, where the IV is derived from a user-provided password.127*128* @return the initialization vector in a new buffer, or null if the129* underlying algorithm does not use an IV, or if the IV has not yet130* been set.131*/132protected byte[] engineGetIV() {133return core.getIV();134}135136/**137* Returns the parameters used with this cipher.138*139* <p>The returned parameters may be the same that were used to initialize140* this cipher, or may contain the default set of parameters or a set of141* randomly generated parameters used by the underlying cipher142* implementation (provided that the underlying cipher implementation143* uses a default set of parameters or creates new parameters if it needs144* parameters but was not initialized with any).145*146* @return the parameters used with this cipher, or null if this cipher147* does not use any parameters.148*/149protected AlgorithmParameters engineGetParameters() {150return core.getParameters("DES");151}152153/**154* Initializes this cipher with a key and a source of randomness.155*156* <p>The cipher is initialized for one of the following four operations:157* encryption, decryption, key wrapping or key unwrapping, depending on158* the value of <code>opmode</code>.159*160* <p>If this cipher requires an initialization vector (IV), it will get161* it from <code>random</code>.162* This behaviour should only be used in encryption or key wrapping163* mode, however.164* When initializing a cipher that requires an IV for decryption or165* key unwrapping, the IV166* (same IV that was used for encryption or key wrapping) must be provided167* explicitly as a168* parameter, in order to get the correct result.169*170* <p>This method also cleans existing buffer and other related state171* information.172*173* @param opmode the operation mode of this cipher (this is one of174* the following:175* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,176* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)177* @param key the secret key178* @param random the source of randomness179*180* @exception InvalidKeyException if the given key is inappropriate for181* initializing this cipher182*/183protected void engineInit(int opmode, Key key, SecureRandom random)184throws InvalidKeyException {185core.init(opmode, key, random);186}187188/**189* Initializes this cipher with a key, a set of190* algorithm parameters, and a source of randomness.191*192* <p>The cipher is initialized for one of the following four operations:193* encryption, decryption, key wrapping or key unwrapping, depending on194* the value of <code>opmode</code>.195*196* <p>If this cipher (including its underlying feedback or padding scheme)197* requires any random bytes, it will get them from <code>random</code>.198*199* @param opmode the operation mode of this cipher (this is one of200* the following:201* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,202* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)203* @param key the encryption key204* @param params the algorithm parameters205* @param random the source of randomness206*207* @exception InvalidKeyException if the given key is inappropriate for208* initializing this cipher209* @exception InvalidAlgorithmParameterException if the given algorithm210* parameters are inappropriate for this cipher211*/212protected void engineInit(int opmode, Key key,213AlgorithmParameterSpec params,214SecureRandom random)215throws InvalidKeyException, InvalidAlgorithmParameterException {216core.init(opmode, key, params, random);217}218219protected void engineInit(int opmode, Key key,220AlgorithmParameters params,221SecureRandom random)222throws InvalidKeyException, InvalidAlgorithmParameterException {223core.init(opmode, key, params, random);224}225226/**227* Continues a multiple-part encryption or decryption operation228* (depending on how this cipher was initialized), processing another data229* part.230*231* <p>The first <code>inputLen</code> bytes in the <code>input</code>232* buffer, starting at <code>inputOffset</code>, are processed, and the233* result is stored in a new buffer.234*235* @param input the input buffer236* @param inputOffset the offset in <code>input</code> where the input237* starts238* @param inputLen the input length239*240* @return the new buffer with the result241*242* @exception IllegalStateException if this cipher is in a wrong state243* (e.g., has not been initialized)244*/245protected byte[] engineUpdate(byte[] input, int inputOffset,246int inputLen) {247return core.update(input, inputOffset, inputLen);248}249250/**251* Continues a multiple-part encryption or decryption operation252* (depending on how this cipher was initialized), processing another data253* part.254*255* <p>The first <code>inputLen</code> bytes in the <code>input</code>256* buffer, starting at <code>inputOffset</code>, are processed, and the257* result is stored in the <code>output</code> buffer, starting at258* <code>outputOffset</code>.259*260* @param input the input buffer261* @param inputOffset the offset in <code>input</code> where the input262* starts263* @param inputLen the input length264* @param output the buffer for the result265* @param outputOffset the offset in <code>output</code> where the result266* is stored267*268* @return the number of bytes stored in <code>output</code>269*270* @exception ShortBufferException if the given output buffer is too small271* to hold the result272*/273protected int engineUpdate(byte[] input, int inputOffset, int inputLen,274byte[] output, int outputOffset)275throws ShortBufferException {276return core.update(input, inputOffset, inputLen, output,277outputOffset);278}279280/**281* Encrypts or decrypts data in a single-part operation,282* or finishes a multiple-part operation.283* The data is encrypted or decrypted, depending on how this cipher was284* initialized.285*286* <p>The first <code>inputLen</code> bytes in the <code>input</code>287* buffer, starting at <code>inputOffset</code>, and any input bytes that288* may have been buffered during a previous <code>update</code> operation,289* are processed, with padding (if requested) being applied.290* The result is stored in a new buffer.291*292* <p>The cipher is reset to its initial state (uninitialized) after this293* call.294*295* @param input the input buffer296* @param inputOffset the offset in <code>input</code> where the input297* starts298* @param inputLen the input length299*300* @return the new buffer with the result301*302* @exception IllegalBlockSizeException if this cipher is a block cipher,303* no padding has been requested (only in encryption mode), and the total304* input length of the data processed by this cipher is not a multiple of305* block size306* @exception BadPaddingException if this cipher is in decryption mode,307* and (un)padding has been requested, but the decrypted data is not308* bounded by the appropriate padding bytes309*/310protected byte[] engineDoFinal(byte[] input, int inputOffset,311int inputLen)312throws IllegalBlockSizeException, BadPaddingException {313return core.doFinal(input, inputOffset, inputLen);314}315316/**317* Encrypts or decrypts data in a single-part operation,318* or finishes a multiple-part operation.319* The data is encrypted or decrypted, depending on how this cipher was320* initialized.321*322* <p>The first <code>inputLen</code> bytes in the <code>input</code>323* buffer, starting at <code>inputOffset</code>, and any input bytes that324* may have been buffered during a previous <code>update</code> operation,325* are processed, with padding (if requested) being applied.326* The result is stored in the <code>output</code> buffer, starting at327* <code>outputOffset</code>.328*329* <p>The cipher is reset to its initial state (uninitialized) after this330* call.331*332* @param input the input buffer333* @param inputOffset the offset in <code>input</code> where the input334* starts335* @param inputLen the input length336* @param output the buffer for the result337* @param outputOffset the offset in <code>output</code> where the result338* is stored339*340* @return the number of bytes stored in <code>output</code>341*342* @exception IllegalBlockSizeException if this cipher is a block cipher,343* no padding has been requested (only in encryption mode), and the total344* input length of the data processed by this cipher is not a multiple of345* block size346* @exception ShortBufferException if the given output buffer is too small347* to hold the result348* @exception BadPaddingException if this cipher is in decryption mode,349* and (un)padding has been requested, but the decrypted data is not350* bounded by the appropriate padding bytes351*/352protected int engineDoFinal(byte[] input, int inputOffset, int inputLen,353byte[] output, int outputOffset)354throws IllegalBlockSizeException, ShortBufferException,355BadPaddingException {356return core.doFinal(input, inputOffset, inputLen, output,357outputOffset);358}359360/**361* Returns the key size of the given key object.362*363* @param key the key object.364*365* @return the key size of the given key object.366*367* @exception InvalidKeyException if <code>key</code> is invalid.368*/369protected int engineGetKeySize(Key key) throws InvalidKeyException {370byte[] encoded = key.getEncoded();371if (encoded.length != 8) {372throw new InvalidKeyException("Invalid key length: " +373encoded.length + " bytes");374}375return 56;376}377378/**379* Wrap a key.380*381* @param key the key to be wrapped.382*383* @return the wrapped key.384*385* @exception IllegalBlockSizeException if this cipher is a block386* cipher, no padding has been requested, and the length of the387* encoding of the key to be wrapped is not a388* multiple of the block size.389*390* @exception InvalidKeyException if it is impossible or unsafe to391* wrap the key with this cipher (e.g., a hardware protected key is392* being passed to a software only cipher).393*/394protected byte[] engineWrap(Key key)395throws IllegalBlockSizeException, InvalidKeyException {396return core.wrap(key);397}398399/**400* Unwrap a previously wrapped key.401*402* @param wrappedKey the key to be unwrapped.403*404* @param wrappedKeyAlgorithm the algorithm the wrapped key is for.405*406* @param wrappedKeyType the type of the wrapped key.407* This is one of <code>Cipher.SECRET_KEY</code>,408* <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.409*410* @return the unwrapped key.411*412* @exception NoSuchAlgorithmException if no installed providers413* can create keys of type <code>wrappedKeyType</code> for the414* <code>wrappedKeyAlgorithm</code>.415*416* @exception InvalidKeyException if <code>wrappedKey</code> does not417* represent a wrapped key of type <code>wrappedKeyType</code> for418* the <code>wrappedKeyAlgorithm</code>.419*/420protected Key engineUnwrap(byte[] wrappedKey,421String wrappedKeyAlgorithm,422int wrappedKeyType)423throws InvalidKeyException, NoSuchAlgorithmException {424return core.unwrap(wrappedKey, wrappedKeyAlgorithm,425wrappedKeyType);426}427}428429430