1package org.bouncycastle.crypto.engines; 2 3import org.bouncycastle.crypto.CipherParameters; 4import org.bouncycastle.crypto.DataLengthException; 5import org.bouncycastle.crypto.params.KeyParameter; 6 7/** 8 * a class that provides a basic DESede (or Triple DES) engine. 9 */ 10public class DESedeEngine 11 extends DESEngine 12{ 13 protected static final int BLOCK_SIZE = 8; 14 15 private int[] workingKey1 = null; 16 private int[] workingKey2 = null; 17 private int[] workingKey3 = null; 18 19 private boolean forEncryption; 20 21 /** 22 * standard constructor. 23 */ 24 public DESedeEngine() 25 { 26 } 27 28 /** 29 * initialise a DESede cipher. 30 * 31 * @param encrypting whether or not we are for encryption. 32 * @param params the parameters required to set up the cipher. 33 * @exception IllegalArgumentException if the params argument is 34 * inappropriate. 35 */ 36 public void init( 37 boolean encrypting, 38 CipherParameters params) 39 { 40 if (!(params instanceof KeyParameter)) 41 { 42 throw new IllegalArgumentException("invalid parameter passed to DESede init - " + params.getClass().getName()); 43 } 44 45 byte[] keyMaster = ((KeyParameter)params).getKey(); 46 47 if (keyMaster.length != 24 && keyMaster.length != 16) 48 { 49 throw new IllegalArgumentException("key size must be 16 or 24 bytes."); 50 } 51 52 this.forEncryption = encrypting; 53 54 byte[] key1 = new byte[8]; 55 System.arraycopy(keyMaster, 0, key1, 0, key1.length); 56 workingKey1 = generateWorkingKey(encrypting, key1); 57 58 byte[] key2 = new byte[8]; 59 System.arraycopy(keyMaster, 8, key2, 0, key2.length); 60 workingKey2 = generateWorkingKey(!encrypting, key2); 61 62 if (keyMaster.length == 24) 63 { 64 byte[] key3 = new byte[8]; 65 System.arraycopy(keyMaster, 16, key3, 0, key3.length); 66 workingKey3 = generateWorkingKey(encrypting, key3); 67 } 68 else // 16 byte key 69 { 70 workingKey3 = workingKey1; 71 } 72 } 73 74 public String getAlgorithmName() 75 { 76 return "DESede"; 77 } 78 79 public int getBlockSize() 80 { 81 return BLOCK_SIZE; 82 } 83 84 public int processBlock( 85 byte[] in, 86 int inOff, 87 byte[] out, 88 int outOff) 89 { 90 if (workingKey1 == null) 91 { 92 throw new IllegalStateException("DESede engine not initialised"); 93 } 94 95 if ((inOff + BLOCK_SIZE) > in.length) 96 { 97 throw new DataLengthException("input buffer too short"); 98 } 99 100 if ((outOff + BLOCK_SIZE) > out.length) 101 { 102 throw new DataLengthException("output buffer too short"); 103 } 104 105 byte[] temp = new byte[BLOCK_SIZE]; 106 107 if (forEncryption) 108 { 109 desFunc(workingKey1, in, inOff, temp, 0); 110 desFunc(workingKey2, temp, 0, temp, 0); 111 desFunc(workingKey3, temp, 0, out, outOff); 112 } 113 else 114 { 115 desFunc(workingKey3, in, inOff, temp, 0); 116 desFunc(workingKey2, temp, 0, temp, 0); 117 desFunc(workingKey1, temp, 0, out, outOff); 118 } 119 120 return BLOCK_SIZE; 121 } 122 123 public void reset() 124 { 125 } 126} 127