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