001: // CbcBlockCipher - use a block cipher in CBC mode
002: //
003: // Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
004: //
005: // Redistribution and use in source and binary forms, with or without
006: // modification, are permitted provided that the following conditions
007: // are met:
008: // 1. Redistributions of source code must retain the above copyright
009: // notice, this list of conditions and the following disclaimer.
010: // 2. Redistributions in binary form must reproduce the above copyright
011: // notice, this list of conditions and the following disclaimer in the
012: // documentation and/or other materials provided with the distribution.
013: //
014: // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
015: // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
016: // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
017: // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
018: // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
019: // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
020: // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
021: // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
022: // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
023: // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
024: // SUCH DAMAGE.
025: //
026: // Visit the ACME Labs Java page for up-to-date versions of this and other
027: // fine Java utilities: http://www.acme.com/java/
028:
029: package Acme.Crypto;
030:
031: import java.io.*;
032:
033: /// Use a block cipher in CBC mode.
034: // <P>
035: // A plain old block cipher, key and cleartext-block in, ciphertext-block
036: // out, is said to be in Electronic Code Book (ECB) mode. A given block
037: // of plaintext always encrypts to the same block of ciphertext. This
038: // makes it somewhat vulnerable to known plaintext attacks, block replay
039: // attacks, etc.
040: // <P>
041: // A fairly cheap alternative is to use it in Cipher Block Chaining (CBC)
042: // mode. All this does is XOR each plaintext block with the previous
043: // ciphertext block before encryption. For the first block, where there
044: // is no previous ciphertext block, a caller-specified Initialization
045: // Vector (IV) is used for the XOR. This makes each block's encryption
046: // depend on all the previous blocks
047: // <P>
048: // This class lets you use any given block cipher in CBC mode.
049: // <P>
050: // <A HREF="/resources/classes/Acme/Crypto/CbcBlockCipher.java">Fetch the software.</A><BR>
051: // <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
052: // <P>
053: // @see Cipher
054: // @see BlockCipher
055: // @see StreamCipher
056: // @see EncryptedOutputStream
057: // @see EncryptedInputStream
058:
059: public class CbcBlockCipher extends BlockCipher {
060:
061: private BlockCipher blockCipher;
062: private byte[] iv;
063: private byte[] temp;
064:
065: /// Constructor.
066: public CbcBlockCipher(BlockCipher blockCipher) {
067: super (blockCipher.keySize(), blockCipher.blockSize());
068: this .blockCipher = blockCipher;
069: iv = new byte[blockSize()];
070: zeroBlock(iv);
071: temp = new byte[blockSize()];
072: }
073:
074: // Key routines.
075:
076: // Set the key.
077: public void setKey(byte[] key) {
078: blockCipher.setKey(key);
079: }
080:
081: // IV routines.
082:
083: /// Set the Initialization Vector.
084: public void setIv(byte[] iv) {
085: copyBlock(iv, this .iv);
086: }
087:
088: /// Set and return a random IV.
089: // In CBC mode, the IV does not have to be kept secret.
090: // Typical usage is for the caller to set a random IV and then transmit
091: // it as the first block of the message.
092: public byte[] setRandomIv() {
093: byte[] riv = new byte[blockSize()];
094: randomBlock(riv);
095: setIv(riv);
096: return riv;
097: }
098:
099: // Block encryption routines.
100:
101: /// Encrypt a block of bytes.
102: public void encrypt(byte[] clearText, int clearOff,
103: byte[] cipherText, int cipherOff) {
104: xorBlock(clearText, clearOff, iv, 0, temp, 0, blockSize);
105: blockCipher.encrypt(temp, 0, cipherText, cipherOff);
106: copyBlock(cipherText, cipherOff, iv, 0, blockSize);
107: }
108:
109: /// Decrypt a block of bytes.
110: public void decrypt(byte[] cipherText, int cipherOff,
111: byte[] clearText, int clearOff) {
112: blockCipher.decrypt(cipherText, cipherOff, temp, 0);
113: xorBlock(temp, 0, iv, 0, clearText, clearOff, blockSize);
114: copyBlock(cipherText, cipherOff, iv, 0, blockSize);
115: }
116:
117: }
|