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