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