001: package org.bouncycastle.crypto.engines;
002:
003: import org.bouncycastle.crypto.CipherParameters;
004: import org.bouncycastle.crypto.DataLengthException;
005: import org.bouncycastle.crypto.params.KeyParameter;
006:
007: /**
008: * a class that provides a basic DESede (or Triple DES) engine.
009: */
010: public class DESedeEngine extends DESEngine {
011: protected static final int BLOCK_SIZE = 8;
012:
013: private int[] workingKey1 = null;
014: private int[] workingKey2 = null;
015: private int[] workingKey3 = null;
016:
017: private boolean forEncryption;
018:
019: /**
020: * standard constructor.
021: */
022: public DESedeEngine() {
023: }
024:
025: /**
026: * initialise a DESede cipher.
027: *
028: * @param encrypting whether or not we are for encryption.
029: * @param params the parameters required to set up the cipher.
030: * @exception IllegalArgumentException if the params argument is
031: * inappropriate.
032: */
033: public void init(boolean encrypting, CipherParameters params) {
034: if (!(params instanceof KeyParameter)) {
035: throw new IllegalArgumentException(
036: "invalid parameter passed to DESede init - "
037: + params.getClass().getName());
038: }
039:
040: byte[] keyMaster = ((KeyParameter) params).getKey();
041: byte[] key1 = new byte[8], key2 = new byte[8], key3 = new byte[8];
042:
043: if (keyMaster.length > 24) {
044: throw new IllegalArgumentException(
045: "key size greater than 24 bytes");
046: }
047:
048: this .forEncryption = encrypting;
049:
050: if (keyMaster.length == 24) {
051: System.arraycopy(keyMaster, 0, key1, 0, key1.length);
052: System.arraycopy(keyMaster, 8, key2, 0, key2.length);
053: System.arraycopy(keyMaster, 16, key3, 0, key3.length);
054:
055: workingKey1 = generateWorkingKey(encrypting, key1);
056: workingKey2 = generateWorkingKey(!encrypting, key2);
057: workingKey3 = generateWorkingKey(encrypting, key3);
058: } else // 16 byte key
059: {
060: System.arraycopy(keyMaster, 0, key1, 0, key1.length);
061: System.arraycopy(keyMaster, 8, key2, 0, key2.length);
062:
063: workingKey1 = generateWorkingKey(encrypting, key1);
064: workingKey2 = generateWorkingKey(!encrypting, key2);
065: workingKey3 = workingKey1;
066: }
067: }
068:
069: public String getAlgorithmName() {
070: return "DESede";
071: }
072:
073: public int getBlockSize() {
074: return BLOCK_SIZE;
075: }
076:
077: public int processBlock(byte[] in, int inOff, byte[] out, int outOff) {
078: if (workingKey1 == null) {
079: throw new IllegalStateException(
080: "DESede engine not initialised");
081: }
082:
083: if ((inOff + BLOCK_SIZE) > in.length) {
084: throw new DataLengthException("input buffer too short");
085: }
086:
087: if ((outOff + BLOCK_SIZE) > out.length) {
088: throw new DataLengthException("output buffer too short");
089: }
090:
091: if (forEncryption) {
092: desFunc(workingKey1, in, inOff, out, outOff);
093: desFunc(workingKey2, out, outOff, out, outOff);
094: desFunc(workingKey3, out, outOff, out, outOff);
095: } else {
096: desFunc(workingKey3, in, inOff, out, outOff);
097: desFunc(workingKey2, out, outOff, out, outOff);
098: desFunc(workingKey1, out, outOff, out, outOff);
099: }
100:
101: return BLOCK_SIZE;
102: }
103:
104: public void reset() {
105: }
106: }
|