DESedeEngine.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
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        byte[]      key1 = new byte[8], key2 = new byte[8], key3 = new byte[8];
47
48        if (keyMaster.length > 24)
49        {
50            throw new IllegalArgumentException("key size greater than 24 bytes");
51        }
52
53        this.forEncryption = encrypting;
54
55        if (keyMaster.length == 24)
56        {
57            System.arraycopy(keyMaster, 0, key1, 0, key1.length);
58            System.arraycopy(keyMaster, 8, key2, 0, key2.length);
59            System.arraycopy(keyMaster, 16, key3, 0, key3.length);
60
61            workingKey1 = generateWorkingKey(encrypting, key1);
62            workingKey2 = generateWorkingKey(!encrypting, key2);
63            workingKey3 = generateWorkingKey(encrypting, key3);
64        }
65        else    // 16 byte key
66        {
67            System.arraycopy(keyMaster, 0, key1, 0, key1.length);
68            System.arraycopy(keyMaster, 8, key2, 0, key2.length);
69
70            workingKey1 = generateWorkingKey(encrypting, key1);
71            workingKey2 = generateWorkingKey(!encrypting, key2);
72            workingKey3 = workingKey1;
73        }
74    }
75
76    public String getAlgorithmName()
77    {
78        return "DESede";
79    }
80
81    public int getBlockSize()
82    {
83        return BLOCK_SIZE;
84    }
85
86    public int processBlock(
87        byte[] in,
88        int inOff,
89        byte[] out,
90        int outOff)
91    {
92        if (workingKey1 == null)
93        {
94            throw new IllegalStateException("DESede engine not initialised");
95        }
96
97        if ((inOff + BLOCK_SIZE) > in.length)
98        {
99            throw new DataLengthException("input buffer too short");
100        }
101
102        if ((outOff + BLOCK_SIZE) > out.length)
103        {
104            throw new DataLengthException("output buffer too short");
105        }
106
107        if (forEncryption)
108        {
109            desFunc(workingKey1, in, inOff, out, outOff);
110            desFunc(workingKey2, out, outOff, out, outOff);
111            desFunc(workingKey3, out, outOff, out, outOff);
112        }
113        else
114        {
115            desFunc(workingKey3, in, inOff, out, outOff);
116            desFunc(workingKey2, out, outOff, out, outOff);
117            desFunc(workingKey1, out, outOff, out, outOff);
118        }
119
120        return BLOCK_SIZE;
121    }
122
123    public void reset()
124    {
125    }
126}
127