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