116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropackage org.bouncycastle.crypto.generators;
216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.KeyGenerationParameters;
416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.DESedeParameters;
516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropublic class DESedeKeyGenerator
716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    extends DESKeyGenerator
816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro{
9bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro    private static final int MAX_IT = 20;
10bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro
1116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    /**
1216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * initialise the key generator - if strength is set to zero
1316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * the key generated will be 192 bits in size, otherwise
1416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * strength can be 128 or 192 (or 112 or 168 if you don't count
1516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * parity bits), depending on whether you wish to do 2-key or 3-key
1616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * triple DES.
1716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     *
1816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * @param param the parameters to be used for key generation
1916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     */
2016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public void init(
2116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        KeyGenerationParameters param)
2216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
2316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        this.random = param.getRandom();
2416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        this.strength = (param.getStrength() + 7) / 8;
2516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
2616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (strength == 0 || strength == (168 / 8))
2716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
2816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            strength = DESedeParameters.DES_EDE_KEY_LENGTH;
2916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
3016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        else if (strength == (112 / 8))
3116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
3216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            strength = 2 * DESedeParameters.DES_KEY_LENGTH;
3316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
3416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        else if (strength != DESedeParameters.DES_EDE_KEY_LENGTH
3516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                && strength != (2 * DESedeParameters.DES_KEY_LENGTH))
3616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
3716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            throw new IllegalArgumentException("DESede key must be "
3816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                + (DESedeParameters.DES_EDE_KEY_LENGTH * 8) + " or "
3916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                + (2 * 8 * DESedeParameters.DES_KEY_LENGTH)
4016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                + " bits long.");
4116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
4216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
4316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
4416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public byte[] generateKey()
4516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
4616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        byte[]  newKey = new byte[strength];
47bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro        int     count = 0;
4816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
4916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        do
5016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
5116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            random.nextBytes(newKey);
5216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
5316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            DESedeParameters.setOddParity(newKey);
5416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
55bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro        while (++count < MAX_IT && (DESedeParameters.isWeakKey(newKey, 0, newKey.length) || !DESedeParameters.isRealEDEKey(newKey, 0)));
56bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro
57bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro        if (DESedeParameters.isWeakKey(newKey, 0, newKey.length) || !DESedeParameters.isRealEDEKey(newKey, 0))
58bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro        {
59bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro            throw new IllegalStateException("Unable to generate DES-EDE key");
60bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro        }
6116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
6216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return newKey;
6316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
6416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro}
65