001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.midp.crypto;
028:
029: /**
030: * DES CBC Cipher algorithm.
031: */
032: public class DES_CBC extends DES_ECB {
033:
034: /** Internal data. */
035: private byte[] chainingBlock;
036:
037: /** Internal data. */
038: private byte[] storeBuffer;
039:
040: /** Saved state variable. */
041: private byte[] savedChainingBlock;
042:
043: /**
044: * Constructor.
045: *
046: * @param useTripleDes true if the class is being used for triple DES
047: *
048: */
049: public DES_CBC(boolean useTripleDes) {
050: super (useTripleDes);
051: chainingBlock = new byte[BLOCK_SIZE];
052: storeBuffer = new byte[BLOCK_SIZE];
053: }
054:
055: /**
056: * Initializes this cipher with a key and a set of algorithm
057: * parameters.
058: * @param mode the operation mode of this cipher
059: * @param key the encryption key
060: * @param params the algorithm parameters
061: * @exception java.security.InvalidKeyException if the given key
062: * is inappropriate for initializing this cipher
063: * @exception java.security.InvalidAlgorithmParameterException
064: * if the given algorithm parameters are inappropriate for this cipher
065: */
066: public void init(int mode, Key key, CryptoParameter params)
067: throws InvalidKeyException,
068: InvalidAlgorithmParameterException {
069:
070: doInit(mode, keyAlgorithm, key, true, params);
071: System.arraycopy(IV, 0, chainingBlock, 0, BLOCK_SIZE);
072: }
073:
074: /**
075: * Encrypts or decrypts data in a single-part operation, or finishes a
076: * multiple-part operation. The data is encrypted or decrypted,
077: * depending on how this cipher was initialized.
078: *
079: * @param inBuff the input buffer
080: * @param inOffset the offset in <code>input</code> where the input
081: * starts
082: * @param inLength the input length
083: * @param outBuff the buffer for the result
084: * @param outOffset the offset in <code>output</code> where the result
085: * is stored
086: *
087: * @return the number of bytes stored in <code>output</code>
088: *
089: * @exception IllegalStateException if this cipher is in a wrong state
090: * (e.g., has not been initialized)
091: * @exception javax.crypto.IllegalBlockSizeException if this cipher is
092: * a block cipher,
093: * no padding has been requested (only in encryption mode), and the total
094: * input length of the data processed by this cipher is not a multiple of
095: * block size
096: * @exception javax.crypto.ShortBufferException if the given output buffer
097: * is too small to hold the result
098: * @exception javax.crypto.BadPaddingException if this cipher is int
099: * decryption mode,
100: * and (un)padding has been requested, but the decrypted data is not
101: * bounded by the appropriate padding bytes
102: */
103: public int doFinal(byte inBuff[], int inOffset, int inLength,
104: byte outBuff[], int outOffset)
105: throws IllegalStateException, IllegalBlockSizeException,
106: ShortBufferException, BadPaddingException {
107: int result = super .doFinal(inBuff, inOffset, inLength, outBuff,
108: outOffset);
109: System.arraycopy(IV, 0, chainingBlock, 0, BLOCK_SIZE);
110: return result;
111: }
112:
113: /**
114: * Depending on the mode, either encrypts or decrypts data block.
115: * @param out will contain the result of encryption
116: * or decryption operation
117: * @param offset is the offset in out
118: */
119: protected void processBlock(byte[] out, int offset) {
120:
121: if (mode == Cipher.ENCRYPT_MODE) {
122: Util.xorArrays(holdData, chainingBlock);
123: super .processBlock(out, offset);
124: System.arraycopy(out, offset, chainingBlock, 0, BLOCK_SIZE);
125: } else {
126: System.arraycopy(holdData, 0, storeBuffer, 0, BLOCK_SIZE);
127: super .processBlock(out, offset);
128: for (int i = 0; i < BLOCK_SIZE; i++) {
129: out[offset + i] ^= chainingBlock[i];
130: }
131: System.arraycopy(storeBuffer, 0, chainingBlock, 0,
132: BLOCK_SIZE);
133: }
134: }
135:
136: /**
137: * Saves cipher state.
138: */
139: protected void saveState() {
140: super .saveState();
141: savedChainingBlock = Util.cloneArray(chainingBlock);
142: }
143:
144: /**
145: * Restores cipher state.
146: */
147: protected void restoreState() {
148: super.restoreState();
149: chainingBlock = savedChainingBlock;
150: }
151: }
|