Path: blob/master/src/java.base/share/classes/com/sun/crypto/provider/DESedeCrypt.java
41161 views
/*1* Copyright (c) 1997, 2007, 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.InvalidKeyException;2829/**30* This class implements the Triple DES algorithm (DES encryption, followed by31* DES decryption, followed by DES encryption) on a byte array of size32* <code>DES_BLOCK_SIZE</code>. Each DES operation has its own key.33*34* @author Gigi Ankeny35* @author Jan Luehe36*37*38* @see DESConstants39* @see DESCipher40*/4142final class DESedeCrypt extends DESCrypt implements DESConstants {4344/*45* the expanded key used in encrypt/decrypt/encrypt phase46*/47private byte[] key1 = null;48private byte[] key2 = null;49private byte[] key3 = null;50private byte[] buf1, buf2;5152/*53* constructor54*/55DESedeCrypt() {56buf1 = new byte[DES_BLOCK_SIZE];57buf2 = new byte[DES_BLOCK_SIZE];58}5960void init(boolean decrypting, String algorithm, byte[] keys)61throws InvalidKeyException {62if (!algorithm.equalsIgnoreCase("DESede")63&& !algorithm.equalsIgnoreCase("TripleDES")) {64throw new InvalidKeyException65("Wrong algorithm: DESede or TripleDES required");66}67if (keys.length != DES_BLOCK_SIZE * 3) {68throw new InvalidKeyException("Wrong key size");69}7071byte[] keybuf = new byte[DES_BLOCK_SIZE];7273// retrieve the first key74key1 = new byte[128];75System.arraycopy(keys, 0, keybuf, 0, DES_BLOCK_SIZE);76expandKey(keybuf);77System.arraycopy(expandedKey, 0, key1, 0, 128);7879// check if the third key is the same80if (keyEquals(keybuf, 0, keys, DES_BLOCK_SIZE*2, DES_BLOCK_SIZE)) {81key3 = key1;82} else {83key3 = new byte[128];84System.arraycopy(keys, DES_BLOCK_SIZE*2, keybuf, 0,85DES_BLOCK_SIZE);86expandKey(keybuf);87System.arraycopy(expandedKey, 0, key3, 0, 128);88}8990// retrieve the second key91key2 = new byte[128];92System.arraycopy(keys, DES_BLOCK_SIZE, keybuf, 0, DES_BLOCK_SIZE);93expandKey(keybuf);94System.arraycopy(expandedKey, 0, key2, 0, 128);9596}9798/**99* Performs encryption operation.100*101* <p>The input plain text <code>plain</code>, starting at102* <code>plainOffset</code> and ending at103* <code>(plainOffset + blockSize - 1)</code>, is encrypted.104* The result is stored in <code>cipher</code>, starting at105* <code>cipherOffset</code>.106*107* @param plain the buffer with the input data to be encrypted108* @param plainOffset the offset in <code>plain</code>109* @param cipher the buffer for the result110* @param cipherOffset the offset in <code>cipher</code>111*/112void encryptBlock(byte[] plain, int plainOffset,113byte[] cipher, int cipherOffset)114{115expandedKey = key1;116decrypting = false;117cipherBlock(plain, plainOffset, buf1, 0);118119expandedKey = key2;120decrypting = true;121cipherBlock(buf1, 0, buf2, 0);122123expandedKey = key3;124decrypting = false;125cipherBlock(buf2, 0, cipher, cipherOffset);126}127128/**129* Performs decryption operation.130*131* <p>The input cipher text <code>cipher</code>, starting at132* <code>cipherOffset</code> and ending at133* <code>(cipherOffset + blockSize - 1)</code>, is decrypted.134* The result is stored in <code>plain</code>, starting at135* <code>plainOffset</code>.136*137* @param cipher the buffer with the input data to be decrypted138* @param cipherOffset the offset in <code>cipherOffset</code>139* @param plain the buffer for the result140* @param plainOffset the offset in <code>plain</code>141*/142void decryptBlock(byte[] cipher, int cipherOffset,143byte[] plain, int plainOffset)144{145expandedKey = key3;146decrypting = true;147cipherBlock(cipher, cipherOffset, buf1, 0);148149expandedKey = key2;150decrypting = false;151cipherBlock(buf1, 0, buf2, 0);152153expandedKey = key1;154decrypting = true;155cipherBlock(buf2, 0, plain, plainOffset);156}157158private boolean keyEquals(byte[] key1, int off1,159byte[] key2, int off2, int len) {160161for (int i=0; i<len; i++) {162if (key1[i+off1] != key2[i+off2])163return false;164}165return true;166}167}168169170