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