Home | History | Annotate | Download | only in engines
      1 package org.bouncycastle.crypto.engines;
      2 
      3 import org.bouncycastle.crypto.BlockCipher;
      4 import org.bouncycastle.crypto.CipherParameters;
      5 import org.bouncycastle.crypto.DataLengthException;
      6 import org.bouncycastle.crypto.OutputLengthException;
      7 import org.bouncycastle.crypto.params.KeyParameter;
      8 
      9 /**
     10  * a class that provides a basic DES engine.
     11  */
     12 public class DESEngine
     13     implements BlockCipher
     14 {
     15     protected static final int  BLOCK_SIZE = 8;
     16 
     17     private int[]               workingKey = null;
     18 
     19     /**
     20      * standard constructor.
     21      */
     22     public DESEngine()
     23     {
     24     }
     25 
     26     /**
     27      * initialise a DES cipher.
     28      *
     29      * @param encrypting whether or not we are for encryption.
     30      * @param params the parameters required to set up the cipher.
     31      * @exception IllegalArgumentException if the params argument is
     32      * inappropriate.
     33      */
     34     public void init(
     35         boolean           encrypting,
     36         CipherParameters  params)
     37     {
     38         if (params instanceof KeyParameter)
     39         {
     40             if (((KeyParameter)params).getKey().length > 8)
     41             {
     42                 throw new IllegalArgumentException("DES key too long - should be 8 bytes");
     43             }
     44 
     45             workingKey = generateWorkingKey(encrypting,
     46                                   ((KeyParameter)params).getKey());
     47 
     48             return;
     49         }
     50 
     51         throw new IllegalArgumentException("invalid parameter passed to DES init - " + params.getClass().getName());
     52     }
     53 
     54     public String getAlgorithmName()
     55     {
     56         return "DES";
     57     }
     58 
     59     public int getBlockSize()
     60     {
     61         return BLOCK_SIZE;
     62     }
     63 
     64     public int processBlock(
     65         byte[] in,
     66         int inOff,
     67         byte[] out,
     68         int outOff)
     69     {
     70         if (workingKey == null)
     71         {
     72             throw new IllegalStateException("DES engine not initialised");
     73         }
     74 
     75         if ((inOff + BLOCK_SIZE) > in.length)
     76         {
     77             throw new DataLengthException("input buffer too short");
     78         }
     79 
     80         if ((outOff + BLOCK_SIZE) > out.length)
     81         {
     82             throw new OutputLengthException("output buffer too short");
     83         }
     84 
     85         desFunc(workingKey, in, inOff, out, outOff);
     86 
     87         return BLOCK_SIZE;
     88     }
     89 
     90     public void reset()
     91     {
     92     }
     93 
     94     /**
     95      * what follows is mainly taken from "Applied Cryptography", by
     96      * Bruce Schneier, however it also bears great resemblance to Richard
     97      * Outerbridge's D3DES...
     98      */
     99 
    100 //    private static final short[]    Df_Key =
    101 //        {
    102 //            0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
    103 //            0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
    104 //            0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
    105 //        };
    106 
    107     private static final short[]    bytebit =
    108         {
    109             0200, 0100, 040, 020, 010, 04, 02, 01
    110         };
    111 
    112     private static final int[]    bigbyte =
    113         {
    114             0x800000, 0x400000, 0x200000, 0x100000,
    115             0x80000,  0x40000,  0x20000,  0x10000,
    116             0x8000,      0x4000,   0x2000,   0x1000,
    117             0x800,    0x400,    0x200,    0x100,
    118             0x80,      0x40,        0x20,     0x10,
    119             0x8,      0x4,      0x2,      0x1
    120         };
    121 
    122     /*
    123      * Use the key schedule specified in the Standard (ANSI X3.92-1981).
    124      */
    125 
    126     private static final byte[]    pc1 =
    127         {
    128             56, 48, 40, 32, 24, 16,  8,   0, 57, 49, 41, 33, 25, 17,
    129              9,  1, 58, 50, 42, 34, 26,  18, 10,  2, 59, 51, 43, 35,
    130             62, 54, 46, 38, 30, 22, 14,   6, 61, 53, 45, 37, 29, 21,
    131             13,  5, 60, 52, 44, 36, 28,  20, 12,  4, 27, 19, 11,  3
    132         };
    133 
    134     private static final byte[] totrot =
    135         {
    136             1, 2, 4, 6, 8, 10, 12, 14,
    137             15, 17, 19, 21, 23, 25, 27, 28
    138         };
    139 
    140     private static final byte[] pc2 =
    141         {
    142             13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
    143             22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
    144             40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
    145             43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
    146         };
    147 
    148     private static final int[] SP1 = {
    149         0x01010400, 0x00000000, 0x00010000, 0x01010404,
    150         0x01010004, 0x00010404, 0x00000004, 0x00010000,
    151         0x00000400, 0x01010400, 0x01010404, 0x00000400,
    152         0x01000404, 0x01010004, 0x01000000, 0x00000004,
    153         0x00000404, 0x01000400, 0x01000400, 0x00010400,
    154         0x00010400, 0x01010000, 0x01010000, 0x01000404,
    155         0x00010004, 0x01000004, 0x01000004, 0x00010004,
    156         0x00000000, 0x00000404, 0x00010404, 0x01000000,
    157         0x00010000, 0x01010404, 0x00000004, 0x01010000,
    158         0x01010400, 0x01000000, 0x01000000, 0x00000400,
    159         0x01010004, 0x00010000, 0x00010400, 0x01000004,
    160         0x00000400, 0x00000004, 0x01000404, 0x00010404,
    161         0x01010404, 0x00010004, 0x01010000, 0x01000404,
    162         0x01000004, 0x00000404, 0x00010404, 0x01010400,
    163         0x00000404, 0x01000400, 0x01000400, 0x00000000,
    164         0x00010004, 0x00010400, 0x00000000, 0x01010004
    165     };
    166 
    167     private static final int[] SP2 = {
    168         0x80108020, 0x80008000, 0x00008000, 0x00108020,
    169         0x00100000, 0x00000020, 0x80100020, 0x80008020,
    170         0x80000020, 0x80108020, 0x80108000, 0x80000000,
    171         0x80008000, 0x00100000, 0x00000020, 0x80100020,
    172         0x00108000, 0x00100020, 0x80008020, 0x00000000,
    173         0x80000000, 0x00008000, 0x00108020, 0x80100000,
    174         0x00100020, 0x80000020, 0x00000000, 0x00108000,
    175         0x00008020, 0x80108000, 0x80100000, 0x00008020,
    176         0x00000000, 0x00108020, 0x80100020, 0x00100000,
    177         0x80008020, 0x80100000, 0x80108000, 0x00008000,
    178         0x80100000, 0x80008000, 0x00000020, 0x80108020,
    179         0x00108020, 0x00000020, 0x00008000, 0x80000000,
    180         0x00008020, 0x80108000, 0x00100000, 0x80000020,
    181         0x00100020, 0x80008020, 0x80000020, 0x00100020,
    182         0x00108000, 0x00000000, 0x80008000, 0x00008020,
    183         0x80000000, 0x80100020, 0x80108020, 0x00108000
    184     };
    185 
    186     private static final int[] SP3 = {
    187         0x00000208, 0x08020200, 0x00000000, 0x08020008,
    188         0x08000200, 0x00000000, 0x00020208, 0x08000200,
    189         0x00020008, 0x08000008, 0x08000008, 0x00020000,
    190         0x08020208, 0x00020008, 0x08020000, 0x00000208,
    191         0x08000000, 0x00000008, 0x08020200, 0x00000200,
    192         0x00020200, 0x08020000, 0x08020008, 0x00020208,
    193         0x08000208, 0x00020200, 0x00020000, 0x08000208,
    194         0x00000008, 0x08020208, 0x00000200, 0x08000000,
    195         0x08020200, 0x08000000, 0x00020008, 0x00000208,
    196         0x00020000, 0x08020200, 0x08000200, 0x00000000,
    197         0x00000200, 0x00020008, 0x08020208, 0x08000200,
    198         0x08000008, 0x00000200, 0x00000000, 0x08020008,
    199         0x08000208, 0x00020000, 0x08000000, 0x08020208,
    200         0x00000008, 0x00020208, 0x00020200, 0x08000008,
    201         0x08020000, 0x08000208, 0x00000208, 0x08020000,
    202         0x00020208, 0x00000008, 0x08020008, 0x00020200
    203     };
    204 
    205     private static final int[] SP4 = {
    206         0x00802001, 0x00002081, 0x00002081, 0x00000080,
    207         0x00802080, 0x00800081, 0x00800001, 0x00002001,
    208         0x00000000, 0x00802000, 0x00802000, 0x00802081,
    209         0x00000081, 0x00000000, 0x00800080, 0x00800001,
    210         0x00000001, 0x00002000, 0x00800000, 0x00802001,
    211         0x00000080, 0x00800000, 0x00002001, 0x00002080,
    212         0x00800081, 0x00000001, 0x00002080, 0x00800080,
    213         0x00002000, 0x00802080, 0x00802081, 0x00000081,
    214         0x00800080, 0x00800001, 0x00802000, 0x00802081,
    215         0x00000081, 0x00000000, 0x00000000, 0x00802000,
    216         0x00002080, 0x00800080, 0x00800081, 0x00000001,
    217         0x00802001, 0x00002081, 0x00002081, 0x00000080,
    218         0x00802081, 0x00000081, 0x00000001, 0x00002000,
    219         0x00800001, 0x00002001, 0x00802080, 0x00800081,
    220         0x00002001, 0x00002080, 0x00800000, 0x00802001,
    221         0x00000080, 0x00800000, 0x00002000, 0x00802080
    222     };
    223 
    224     private static final int[] SP5 = {
    225         0x00000100, 0x02080100, 0x02080000, 0x42000100,
    226         0x00080000, 0x00000100, 0x40000000, 0x02080000,
    227         0x40080100, 0x00080000, 0x02000100, 0x40080100,
    228         0x42000100, 0x42080000, 0x00080100, 0x40000000,
    229         0x02000000, 0x40080000, 0x40080000, 0x00000000,
    230         0x40000100, 0x42080100, 0x42080100, 0x02000100,
    231         0x42080000, 0x40000100, 0x00000000, 0x42000000,
    232         0x02080100, 0x02000000, 0x42000000, 0x00080100,
    233         0x00080000, 0x42000100, 0x00000100, 0x02000000,
    234         0x40000000, 0x02080000, 0x42000100, 0x40080100,
    235         0x02000100, 0x40000000, 0x42080000, 0x02080100,
    236         0x40080100, 0x00000100, 0x02000000, 0x42080000,
    237         0x42080100, 0x00080100, 0x42000000, 0x42080100,
    238         0x02080000, 0x00000000, 0x40080000, 0x42000000,
    239         0x00080100, 0x02000100, 0x40000100, 0x00080000,
    240         0x00000000, 0x40080000, 0x02080100, 0x40000100
    241     };
    242 
    243     private static final int[] SP6 = {
    244         0x20000010, 0x20400000, 0x00004000, 0x20404010,
    245         0x20400000, 0x00000010, 0x20404010, 0x00400000,
    246         0x20004000, 0x00404010, 0x00400000, 0x20000010,
    247         0x00400010, 0x20004000, 0x20000000, 0x00004010,
    248         0x00000000, 0x00400010, 0x20004010, 0x00004000,
    249         0x00404000, 0x20004010, 0x00000010, 0x20400010,
    250         0x20400010, 0x00000000, 0x00404010, 0x20404000,
    251         0x00004010, 0x00404000, 0x20404000, 0x20000000,
    252         0x20004000, 0x00000010, 0x20400010, 0x00404000,
    253         0x20404010, 0x00400000, 0x00004010, 0x20000010,
    254         0x00400000, 0x20004000, 0x20000000, 0x00004010,
    255         0x20000010, 0x20404010, 0x00404000, 0x20400000,
    256         0x00404010, 0x20404000, 0x00000000, 0x20400010,
    257         0x00000010, 0x00004000, 0x20400000, 0x00404010,
    258         0x00004000, 0x00400010, 0x20004010, 0x00000000,
    259         0x20404000, 0x20000000, 0x00400010, 0x20004010
    260     };
    261 
    262     private static final int[] SP7 = {
    263         0x00200000, 0x04200002, 0x04000802, 0x00000000,
    264         0x00000800, 0x04000802, 0x00200802, 0x04200800,
    265         0x04200802, 0x00200000, 0x00000000, 0x04000002,
    266         0x00000002, 0x04000000, 0x04200002, 0x00000802,
    267         0x04000800, 0x00200802, 0x00200002, 0x04000800,
    268         0x04000002, 0x04200000, 0x04200800, 0x00200002,
    269         0x04200000, 0x00000800, 0x00000802, 0x04200802,
    270         0x00200800, 0x00000002, 0x04000000, 0x00200800,
    271         0x04000000, 0x00200800, 0x00200000, 0x04000802,
    272         0x04000802, 0x04200002, 0x04200002, 0x00000002,
    273         0x00200002, 0x04000000, 0x04000800, 0x00200000,
    274         0x04200800, 0x00000802, 0x00200802, 0x04200800,
    275         0x00000802, 0x04000002, 0x04200802, 0x04200000,
    276         0x00200800, 0x00000000, 0x00000002, 0x04200802,
    277         0x00000000, 0x00200802, 0x04200000, 0x00000800,
    278         0x04000002, 0x04000800, 0x00000800, 0x00200002
    279     };
    280 
    281     private static final int[] SP8 = {
    282         0x10001040, 0x00001000, 0x00040000, 0x10041040,
    283         0x10000000, 0x10001040, 0x00000040, 0x10000000,
    284         0x00040040, 0x10040000, 0x10041040, 0x00041000,
    285         0x10041000, 0x00041040, 0x00001000, 0x00000040,
    286         0x10040000, 0x10000040, 0x10001000, 0x00001040,
    287         0x00041000, 0x00040040, 0x10040040, 0x10041000,
    288         0x00001040, 0x00000000, 0x00000000, 0x10040040,
    289         0x10000040, 0x10001000, 0x00041040, 0x00040000,
    290         0x00041040, 0x00040000, 0x10041000, 0x00001000,
    291         0x00000040, 0x10040040, 0x00001000, 0x00041040,
    292         0x10001000, 0x00000040, 0x10000040, 0x10040000,
    293         0x10040040, 0x10000000, 0x00040000, 0x10001040,
    294         0x00000000, 0x10041040, 0x00040040, 0x10000040,
    295         0x10040000, 0x10001000, 0x10001040, 0x00000000,
    296         0x10041040, 0x00041000, 0x00041000, 0x00001040,
    297         0x00001040, 0x00040040, 0x10000000, 0x10041000
    298     };
    299 
    300     /**
    301      * generate an integer based working key based on our secret key
    302      * and what we processing we are planning to do.
    303      *
    304      * Acknowledgements for this routine go to James Gillogly & Phil Karn.
    305      *         (whoever, and wherever they are!).
    306      */
    307     protected int[] generateWorkingKey(
    308         boolean encrypting,
    309         byte[]  key)
    310     {
    311         int[]       newKey = new int[32];
    312         boolean[]   pc1m = new boolean[56],
    313                     pcr = new boolean[56];
    314 
    315         for (int j = 0; j < 56; j++)
    316         {
    317             int    l = pc1[j];
    318 
    319             pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0);
    320         }
    321 
    322         for (int i = 0; i < 16; i++)
    323         {
    324             int    l, m, n;
    325 
    326             if (encrypting)
    327             {
    328                 m = i << 1;
    329             }
    330             else
    331             {
    332                 m = (15 - i) << 1;
    333             }
    334 
    335             n = m + 1;
    336             newKey[m] = newKey[n] = 0;
    337 
    338             for (int j = 0; j < 28; j++)
    339             {
    340                 l = j + totrot[i];
    341                 if (l < 28)
    342                 {
    343                     pcr[j] = pc1m[l];
    344                 }
    345                 else
    346                 {
    347                     pcr[j] = pc1m[l - 28];
    348                 }
    349             }
    350 
    351             for (int j = 28; j < 56; j++)
    352             {
    353                 l = j + totrot[i];
    354                 if (l < 56)
    355                 {
    356                     pcr[j] = pc1m[l];
    357                 }
    358                 else
    359                 {
    360                     pcr[j] = pc1m[l - 28];
    361                 }
    362             }
    363 
    364             for (int j = 0; j < 24; j++)
    365             {
    366                 if (pcr[pc2[j]])
    367                 {
    368                     newKey[m] |= bigbyte[j];
    369                 }
    370 
    371                 if (pcr[pc2[j + 24]])
    372                 {
    373                     newKey[n] |= bigbyte[j];
    374                 }
    375             }
    376         }
    377 
    378         //
    379         // store the processed key
    380         //
    381         for (int i = 0; i != 32; i += 2)
    382         {
    383             int    i1, i2;
    384 
    385             i1 = newKey[i];
    386             i2 = newKey[i + 1];
    387 
    388             newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10)
    389                                    | ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6);
    390 
    391             newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16)
    392                                    | ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f);
    393         }
    394 
    395         return newKey;
    396     }
    397 
    398     /**
    399      * the DES engine.
    400      */
    401     protected void desFunc(
    402         int[]   wKey,
    403         byte[]  in,
    404         int     inOff,
    405         byte[]  out,
    406         int     outOff)
    407     {
    408         int     work, right, left;
    409 
    410         left     = (in[inOff + 0] & 0xff) << 24;
    411         left    |= (in[inOff + 1] & 0xff) << 16;
    412         left    |= (in[inOff + 2] & 0xff) << 8;
    413         left    |= (in[inOff + 3] & 0xff);
    414 
    415         right     = (in[inOff + 4] & 0xff) << 24;
    416         right    |= (in[inOff + 5] & 0xff) << 16;
    417         right    |= (in[inOff + 6] & 0xff) << 8;
    418         right    |= (in[inOff + 7] & 0xff);
    419 
    420         work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
    421         right ^= work;
    422         left ^= (work << 4);
    423         work = ((left >>> 16) ^ right) & 0x0000ffff;
    424         right ^= work;
    425         left ^= (work << 16);
    426         work = ((right >>> 2) ^ left) & 0x33333333;
    427         left ^= work;
    428         right ^= (work << 2);
    429         work = ((right >>> 8) ^ left) & 0x00ff00ff;
    430         left ^= work;
    431         right ^= (work << 8);
    432         right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
    433         work = (left ^ right) & 0xaaaaaaaa;
    434         left ^= work;
    435         right ^= work;
    436         left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
    437 
    438         for (int round = 0; round < 8; round++)
    439         {
    440             int     fval;
    441 
    442             work  = (right << 28) | (right >>> 4);
    443             work ^= wKey[round * 4 + 0];
    444             fval  = SP7[ work      & 0x3f];
    445             fval |= SP5[(work >>>  8) & 0x3f];
    446             fval |= SP3[(work >>> 16) & 0x3f];
    447             fval |= SP1[(work >>> 24) & 0x3f];
    448             work  = right ^ wKey[round * 4 + 1];
    449             fval |= SP8[ work      & 0x3f];
    450             fval |= SP6[(work >>>  8) & 0x3f];
    451             fval |= SP4[(work >>> 16) & 0x3f];
    452             fval |= SP2[(work >>> 24) & 0x3f];
    453             left ^= fval;
    454             work  = (left << 28) | (left >>> 4);
    455             work ^= wKey[round * 4 + 2];
    456             fval  = SP7[ work      & 0x3f];
    457             fval |= SP5[(work >>>  8) & 0x3f];
    458             fval |= SP3[(work >>> 16) & 0x3f];
    459             fval |= SP1[(work >>> 24) & 0x3f];
    460             work  = left ^ wKey[round * 4 + 3];
    461             fval |= SP8[ work      & 0x3f];
    462             fval |= SP6[(work >>>  8) & 0x3f];
    463             fval |= SP4[(work >>> 16) & 0x3f];
    464             fval |= SP2[(work >>> 24) & 0x3f];
    465             right ^= fval;
    466         }
    467 
    468         right = (right << 31) | (right >>> 1);
    469         work = (left ^ right) & 0xaaaaaaaa;
    470         left ^= work;
    471         right ^= work;
    472         left = (left << 31) | (left >>> 1);
    473         work = ((left >>> 8) ^ right) & 0x00ff00ff;
    474         right ^= work;
    475         left ^= (work << 8);
    476         work = ((left >>> 2) ^ right) & 0x33333333;
    477         right ^= work;
    478         left ^= (work << 2);
    479         work = ((right >>> 16) ^ left) & 0x0000ffff;
    480         left ^= work;
    481         right ^= (work << 16);
    482         work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
    483         left ^= work;
    484         right ^= (work << 4);
    485 
    486         out[outOff + 0] = (byte)((right >>> 24) & 0xff);
    487         out[outOff + 1] = (byte)((right >>> 16) & 0xff);
    488         out[outOff + 2] = (byte)((right >>>  8) & 0xff);
    489         out[outOff + 3] = (byte)(right         & 0xff);
    490         out[outOff + 4] = (byte)((left >>> 24) & 0xff);
    491         out[outOff + 5] = (byte)((left >>> 16) & 0xff);
    492         out[outOff + 6] = (byte)((left >>>  8) & 0xff);
    493         out[outOff + 7] = (byte)(left         & 0xff);
    494     }
    495 }
    496