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