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