security/nss/lib/freebl/des.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /*
     2  *  des.c
     3  *
     4  *  core source file for DES-150 library
     5  *  Make key schedule from DES key.
     6  *  Encrypt/Decrypt one 8-byte block.
     7  *
     8  * This Source Code Form is subject to the terms of the Mozilla Public
     9  * License, v. 2.0. If a copy of the MPL was not distributed with this
    10  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    12 #include "des.h"
    13 #include <stddef.h>	/* for ptrdiff_t */
    14 /* #define USE_INDEXING 1 */
    16 /*
    17  * The tables below are the 8 sbox functions, with the 6-bit input permutation 
    18  * and the 32-bit output permutation pre-computed.
    19  * They are shifted circularly to the left 3 bits, which removes 2 shifts
    20  * and an or from each round by reducing the number of sboxes whose
    21  * indices cross word broundaries from 2 to 1.  
    22  */
    24 static const HALF SP[8][64] = {
    25 /* Box S1 */ { 
    26 	0x04041000, 0x00000000, 0x00040000, 0x04041010, 
    27 	0x04040010, 0x00041010, 0x00000010, 0x00040000, 
    28 	0x00001000, 0x04041000, 0x04041010, 0x00001000, 
    29 	0x04001010, 0x04040010, 0x04000000, 0x00000010, 
    30 	0x00001010, 0x04001000, 0x04001000, 0x00041000, 
    31 	0x00041000, 0x04040000, 0x04040000, 0x04001010, 
    32 	0x00040010, 0x04000010, 0x04000010, 0x00040010, 
    33 	0x00000000, 0x00001010, 0x00041010, 0x04000000, 
    34 	0x00040000, 0x04041010, 0x00000010, 0x04040000, 
    35 	0x04041000, 0x04000000, 0x04000000, 0x00001000, 
    36 	0x04040010, 0x00040000, 0x00041000, 0x04000010, 
    37 	0x00001000, 0x00000010, 0x04001010, 0x00041010, 
    38 	0x04041010, 0x00040010, 0x04040000, 0x04001010, 
    39 	0x04000010, 0x00001010, 0x00041010, 0x04041000, 
    40 	0x00001010, 0x04001000, 0x04001000, 0x00000000, 
    41 	0x00040010, 0x00041000, 0x00000000, 0x04040010
    42     },
    43 /* Box S2 */ { 
    44 	0x00420082, 0x00020002, 0x00020000, 0x00420080, 
    45 	0x00400000, 0x00000080, 0x00400082, 0x00020082, 
    46 	0x00000082, 0x00420082, 0x00420002, 0x00000002, 
    47 	0x00020002, 0x00400000, 0x00000080, 0x00400082, 
    48 	0x00420000, 0x00400080, 0x00020082, 0x00000000, 
    49 	0x00000002, 0x00020000, 0x00420080, 0x00400002, 
    50 	0x00400080, 0x00000082, 0x00000000, 0x00420000, 
    51 	0x00020080, 0x00420002, 0x00400002, 0x00020080, 
    52 	0x00000000, 0x00420080, 0x00400082, 0x00400000, 
    53 	0x00020082, 0x00400002, 0x00420002, 0x00020000, 
    54 	0x00400002, 0x00020002, 0x00000080, 0x00420082, 
    55 	0x00420080, 0x00000080, 0x00020000, 0x00000002, 
    56 	0x00020080, 0x00420002, 0x00400000, 0x00000082, 
    57 	0x00400080, 0x00020082, 0x00000082, 0x00400080, 
    58 	0x00420000, 0x00000000, 0x00020002, 0x00020080, 
    59 	0x00000002, 0x00400082, 0x00420082, 0x00420000 
    60     },
    61 /* Box S3 */ { 
    62 	0x00000820, 0x20080800, 0x00000000, 0x20080020, 
    63 	0x20000800, 0x00000000, 0x00080820, 0x20000800, 
    64 	0x00080020, 0x20000020, 0x20000020, 0x00080000, 
    65 	0x20080820, 0x00080020, 0x20080000, 0x00000820, 
    66 	0x20000000, 0x00000020, 0x20080800, 0x00000800, 
    67 	0x00080800, 0x20080000, 0x20080020, 0x00080820, 
    68 	0x20000820, 0x00080800, 0x00080000, 0x20000820, 
    69 	0x00000020, 0x20080820, 0x00000800, 0x20000000, 
    70 	0x20080800, 0x20000000, 0x00080020, 0x00000820, 
    71 	0x00080000, 0x20080800, 0x20000800, 0x00000000, 
    72 	0x00000800, 0x00080020, 0x20080820, 0x20000800, 
    73 	0x20000020, 0x00000800, 0x00000000, 0x20080020, 
    74 	0x20000820, 0x00080000, 0x20000000, 0x20080820, 
    75 	0x00000020, 0x00080820, 0x00080800, 0x20000020, 
    76 	0x20080000, 0x20000820, 0x00000820, 0x20080000, 
    77 	0x00080820, 0x00000020, 0x20080020, 0x00080800 
    78     },
    79 /* Box S4 */ { 
    80 	0x02008004, 0x00008204, 0x00008204, 0x00000200, 
    81 	0x02008200, 0x02000204, 0x02000004, 0x00008004, 
    82 	0x00000000, 0x02008000, 0x02008000, 0x02008204, 
    83 	0x00000204, 0x00000000, 0x02000200, 0x02000004, 
    84 	0x00000004, 0x00008000, 0x02000000, 0x02008004, 
    85 	0x00000200, 0x02000000, 0x00008004, 0x00008200, 
    86 	0x02000204, 0x00000004, 0x00008200, 0x02000200, 
    87 	0x00008000, 0x02008200, 0x02008204, 0x00000204, 
    88 	0x02000200, 0x02000004, 0x02008000, 0x02008204, 
    89 	0x00000204, 0x00000000, 0x00000000, 0x02008000, 
    90 	0x00008200, 0x02000200, 0x02000204, 0x00000004, 
    91 	0x02008004, 0x00008204, 0x00008204, 0x00000200, 
    92 	0x02008204, 0x00000204, 0x00000004, 0x00008000, 
    93 	0x02000004, 0x00008004, 0x02008200, 0x02000204, 
    94 	0x00008004, 0x00008200, 0x02000000, 0x02008004, 
    95 	0x00000200, 0x02000000, 0x00008000, 0x02008200 
    96     },
    97 /* Box S5 */ { 
    98 	0x00000400, 0x08200400, 0x08200000, 0x08000401, 
    99 	0x00200000, 0x00000400, 0x00000001, 0x08200000, 
   100 	0x00200401, 0x00200000, 0x08000400, 0x00200401, 
   101 	0x08000401, 0x08200001, 0x00200400, 0x00000001, 
   102 	0x08000000, 0x00200001, 0x00200001, 0x00000000, 
   103 	0x00000401, 0x08200401, 0x08200401, 0x08000400, 
   104 	0x08200001, 0x00000401, 0x00000000, 0x08000001, 
   105 	0x08200400, 0x08000000, 0x08000001, 0x00200400, 
   106 	0x00200000, 0x08000401, 0x00000400, 0x08000000, 
   107 	0x00000001, 0x08200000, 0x08000401, 0x00200401, 
   108 	0x08000400, 0x00000001, 0x08200001, 0x08200400, 
   109 	0x00200401, 0x00000400, 0x08000000, 0x08200001, 
   110 	0x08200401, 0x00200400, 0x08000001, 0x08200401, 
   111 	0x08200000, 0x00000000, 0x00200001, 0x08000001, 
   112 	0x00200400, 0x08000400, 0x00000401, 0x00200000, 
   113 	0x00000000, 0x00200001, 0x08200400, 0x00000401
   114     },
   115 /* Box S6 */ { 
   116 	0x80000040, 0x81000000, 0x00010000, 0x81010040, 
   117 	0x81000000, 0x00000040, 0x81010040, 0x01000000, 
   118 	0x80010000, 0x01010040, 0x01000000, 0x80000040, 
   119 	0x01000040, 0x80010000, 0x80000000, 0x00010040, 
   120 	0x00000000, 0x01000040, 0x80010040, 0x00010000, 
   121 	0x01010000, 0x80010040, 0x00000040, 0x81000040, 
   122 	0x81000040, 0x00000000, 0x01010040, 0x81010000, 
   123 	0x00010040, 0x01010000, 0x81010000, 0x80000000, 
   124 	0x80010000, 0x00000040, 0x81000040, 0x01010000, 
   125 	0x81010040, 0x01000000, 0x00010040, 0x80000040, 
   126 	0x01000000, 0x80010000, 0x80000000, 0x00010040, 
   127 	0x80000040, 0x81010040, 0x01010000, 0x81000000, 
   128 	0x01010040, 0x81010000, 0x00000000, 0x81000040, 
   129 	0x00000040, 0x00010000, 0x81000000, 0x01010040, 
   130 	0x00010000, 0x01000040, 0x80010040, 0x00000000, 
   131 	0x81010000, 0x80000000, 0x01000040, 0x80010040 
   132     },
   133 /* Box S7 */ { 
   134 	0x00800000, 0x10800008, 0x10002008, 0x00000000, 
   135 	0x00002000, 0x10002008, 0x00802008, 0x10802000, 
   136 	0x10802008, 0x00800000, 0x00000000, 0x10000008, 
   137 	0x00000008, 0x10000000, 0x10800008, 0x00002008, 
   138 	0x10002000, 0x00802008, 0x00800008, 0x10002000, 
   139 	0x10000008, 0x10800000, 0x10802000, 0x00800008, 
   140 	0x10800000, 0x00002000, 0x00002008, 0x10802008, 
   141 	0x00802000, 0x00000008, 0x10000000, 0x00802000, 
   142 	0x10000000, 0x00802000, 0x00800000, 0x10002008, 
   143 	0x10002008, 0x10800008, 0x10800008, 0x00000008, 
   144 	0x00800008, 0x10000000, 0x10002000, 0x00800000, 
   145 	0x10802000, 0x00002008, 0x00802008, 0x10802000, 
   146 	0x00002008, 0x10000008, 0x10802008, 0x10800000, 
   147 	0x00802000, 0x00000000, 0x00000008, 0x10802008, 
   148 	0x00000000, 0x00802008, 0x10800000, 0x00002000, 
   149 	0x10000008, 0x10002000, 0x00002000, 0x00800008 
   150     },
   151 /* Box S8 */ { 
   152 	0x40004100, 0x00004000, 0x00100000, 0x40104100, 
   153 	0x40000000, 0x40004100, 0x00000100, 0x40000000, 
   154 	0x00100100, 0x40100000, 0x40104100, 0x00104000, 
   155 	0x40104000, 0x00104100, 0x00004000, 0x00000100, 
   156 	0x40100000, 0x40000100, 0x40004000, 0x00004100, 
   157 	0x00104000, 0x00100100, 0x40100100, 0x40104000, 
   158 	0x00004100, 0x00000000, 0x00000000, 0x40100100, 
   159 	0x40000100, 0x40004000, 0x00104100, 0x00100000, 
   160 	0x00104100, 0x00100000, 0x40104000, 0x00004000, 
   161 	0x00000100, 0x40100100, 0x00004000, 0x00104100, 
   162 	0x40004000, 0x00000100, 0x40000100, 0x40100000, 
   163 	0x40100100, 0x40000000, 0x00100000, 0x40004100, 
   164 	0x00000000, 0x40104100, 0x00100100, 0x40000100, 
   165 	0x40100000, 0x40004000, 0x40004100, 0x00000000, 
   166 	0x40104100, 0x00104000, 0x00104000, 0x00004100, 
   167 	0x00004100, 0x00100100, 0x40000000, 0x40104000 
   168     }
   169 };
   171 static const HALF PC2[8][64] = {
   172 /* table 0 */ {
   173     0x00000000, 0x00001000, 0x04000000, 0x04001000, 
   174     0x00100000, 0x00101000, 0x04100000, 0x04101000, 
   175     0x00008000, 0x00009000, 0x04008000, 0x04009000, 
   176     0x00108000, 0x00109000, 0x04108000, 0x04109000, 
   177     0x00000004, 0x00001004, 0x04000004, 0x04001004, 
   178     0x00100004, 0x00101004, 0x04100004, 0x04101004, 
   179     0x00008004, 0x00009004, 0x04008004, 0x04009004, 
   180     0x00108004, 0x00109004, 0x04108004, 0x04109004, 
   181     0x08000000, 0x08001000, 0x0c000000, 0x0c001000, 
   182     0x08100000, 0x08101000, 0x0c100000, 0x0c101000, 
   183     0x08008000, 0x08009000, 0x0c008000, 0x0c009000, 
   184     0x08108000, 0x08109000, 0x0c108000, 0x0c109000, 
   185     0x08000004, 0x08001004, 0x0c000004, 0x0c001004, 
   186     0x08100004, 0x08101004, 0x0c100004, 0x0c101004, 
   187     0x08008004, 0x08009004, 0x0c008004, 0x0c009004, 
   188     0x08108004, 0x08109004, 0x0c108004, 0x0c109004
   189   },
   190 /* table 1 */ {
   191     0x00000000, 0x00002000, 0x80000000, 0x80002000, 
   192     0x00000008, 0x00002008, 0x80000008, 0x80002008, 
   193     0x00200000, 0x00202000, 0x80200000, 0x80202000, 
   194     0x00200008, 0x00202008, 0x80200008, 0x80202008, 
   195     0x20000000, 0x20002000, 0xa0000000, 0xa0002000, 
   196     0x20000008, 0x20002008, 0xa0000008, 0xa0002008, 
   197     0x20200000, 0x20202000, 0xa0200000, 0xa0202000, 
   198     0x20200008, 0x20202008, 0xa0200008, 0xa0202008, 
   199     0x00000400, 0x00002400, 0x80000400, 0x80002400, 
   200     0x00000408, 0x00002408, 0x80000408, 0x80002408, 
   201     0x00200400, 0x00202400, 0x80200400, 0x80202400, 
   202     0x00200408, 0x00202408, 0x80200408, 0x80202408, 
   203     0x20000400, 0x20002400, 0xa0000400, 0xa0002400, 
   204     0x20000408, 0x20002408, 0xa0000408, 0xa0002408, 
   205     0x20200400, 0x20202400, 0xa0200400, 0xa0202400, 
   206     0x20200408, 0x20202408, 0xa0200408, 0xa0202408
   207   },
   208 /* table 2 */ {
   209     0x00000000, 0x00004000, 0x00000020, 0x00004020, 
   210     0x00080000, 0x00084000, 0x00080020, 0x00084020, 
   211     0x00000800, 0x00004800, 0x00000820, 0x00004820, 
   212     0x00080800, 0x00084800, 0x00080820, 0x00084820, 
   213     0x00000010, 0x00004010, 0x00000030, 0x00004030, 
   214     0x00080010, 0x00084010, 0x00080030, 0x00084030, 
   215     0x00000810, 0x00004810, 0x00000830, 0x00004830, 
   216     0x00080810, 0x00084810, 0x00080830, 0x00084830, 
   217     0x00400000, 0x00404000, 0x00400020, 0x00404020, 
   218     0x00480000, 0x00484000, 0x00480020, 0x00484020, 
   219     0x00400800, 0x00404800, 0x00400820, 0x00404820, 
   220     0x00480800, 0x00484800, 0x00480820, 0x00484820, 
   221     0x00400010, 0x00404010, 0x00400030, 0x00404030, 
   222     0x00480010, 0x00484010, 0x00480030, 0x00484030, 
   223     0x00400810, 0x00404810, 0x00400830, 0x00404830, 
   224     0x00480810, 0x00484810, 0x00480830, 0x00484830 
   225   },
   226 /* table 3 */ {
   227     0x00000000, 0x40000000, 0x00000080, 0x40000080, 
   228     0x00040000, 0x40040000, 0x00040080, 0x40040080, 
   229     0x00000040, 0x40000040, 0x000000c0, 0x400000c0, 
   230     0x00040040, 0x40040040, 0x000400c0, 0x400400c0, 
   231     0x10000000, 0x50000000, 0x10000080, 0x50000080, 
   232     0x10040000, 0x50040000, 0x10040080, 0x50040080, 
   233     0x10000040, 0x50000040, 0x100000c0, 0x500000c0, 
   234     0x10040040, 0x50040040, 0x100400c0, 0x500400c0, 
   235     0x00800000, 0x40800000, 0x00800080, 0x40800080, 
   236     0x00840000, 0x40840000, 0x00840080, 0x40840080, 
   237     0x00800040, 0x40800040, 0x008000c0, 0x408000c0, 
   238     0x00840040, 0x40840040, 0x008400c0, 0x408400c0, 
   239     0x10800000, 0x50800000, 0x10800080, 0x50800080, 
   240     0x10840000, 0x50840000, 0x10840080, 0x50840080, 
   241     0x10800040, 0x50800040, 0x108000c0, 0x508000c0, 
   242     0x10840040, 0x50840040, 0x108400c0, 0x508400c0 
   243   },
   244 /* table 4 */ {
   245     0x00000000, 0x00000008, 0x08000000, 0x08000008, 
   246     0x00040000, 0x00040008, 0x08040000, 0x08040008, 
   247     0x00002000, 0x00002008, 0x08002000, 0x08002008, 
   248     0x00042000, 0x00042008, 0x08042000, 0x08042008, 
   249     0x80000000, 0x80000008, 0x88000000, 0x88000008, 
   250     0x80040000, 0x80040008, 0x88040000, 0x88040008, 
   251     0x80002000, 0x80002008, 0x88002000, 0x88002008, 
   252     0x80042000, 0x80042008, 0x88042000, 0x88042008, 
   253     0x00080000, 0x00080008, 0x08080000, 0x08080008, 
   254     0x000c0000, 0x000c0008, 0x080c0000, 0x080c0008, 
   255     0x00082000, 0x00082008, 0x08082000, 0x08082008, 
   256     0x000c2000, 0x000c2008, 0x080c2000, 0x080c2008, 
   257     0x80080000, 0x80080008, 0x88080000, 0x88080008, 
   258     0x800c0000, 0x800c0008, 0x880c0000, 0x880c0008, 
   259     0x80082000, 0x80082008, 0x88082000, 0x88082008, 
   260     0x800c2000, 0x800c2008, 0x880c2000, 0x880c2008 
   261   },
   262 /* table 5 */ {
   263     0x00000000, 0x00400000, 0x00008000, 0x00408000, 
   264     0x40000000, 0x40400000, 0x40008000, 0x40408000, 
   265     0x00000020, 0x00400020, 0x00008020, 0x00408020, 
   266     0x40000020, 0x40400020, 0x40008020, 0x40408020, 
   267     0x00001000, 0x00401000, 0x00009000, 0x00409000, 
   268     0x40001000, 0x40401000, 0x40009000, 0x40409000, 
   269     0x00001020, 0x00401020, 0x00009020, 0x00409020, 
   270     0x40001020, 0x40401020, 0x40009020, 0x40409020, 
   271     0x00100000, 0x00500000, 0x00108000, 0x00508000, 
   272     0x40100000, 0x40500000, 0x40108000, 0x40508000, 
   273     0x00100020, 0x00500020, 0x00108020, 0x00508020, 
   274     0x40100020, 0x40500020, 0x40108020, 0x40508020, 
   275     0x00101000, 0x00501000, 0x00109000, 0x00509000, 
   276     0x40101000, 0x40501000, 0x40109000, 0x40509000, 
   277     0x00101020, 0x00501020, 0x00109020, 0x00509020, 
   278     0x40101020, 0x40501020, 0x40109020, 0x40509020 
   279   },
   280 /* table 6 */ {
   281     0x00000000, 0x00000040, 0x04000000, 0x04000040, 
   282     0x00000800, 0x00000840, 0x04000800, 0x04000840, 
   283     0x00800000, 0x00800040, 0x04800000, 0x04800040, 
   284     0x00800800, 0x00800840, 0x04800800, 0x04800840, 
   285     0x10000000, 0x10000040, 0x14000000, 0x14000040, 
   286     0x10000800, 0x10000840, 0x14000800, 0x14000840, 
   287     0x10800000, 0x10800040, 0x14800000, 0x14800040, 
   288     0x10800800, 0x10800840, 0x14800800, 0x14800840, 
   289     0x00000080, 0x000000c0, 0x04000080, 0x040000c0, 
   290     0x00000880, 0x000008c0, 0x04000880, 0x040008c0, 
   291     0x00800080, 0x008000c0, 0x04800080, 0x048000c0, 
   292     0x00800880, 0x008008c0, 0x04800880, 0x048008c0, 
   293     0x10000080, 0x100000c0, 0x14000080, 0x140000c0, 
   294     0x10000880, 0x100008c0, 0x14000880, 0x140008c0, 
   295     0x10800080, 0x108000c0, 0x14800080, 0x148000c0, 
   296     0x10800880, 0x108008c0, 0x14800880, 0x148008c0 
   297   },
   298 /* table 7 */ {
   299     0x00000000, 0x00000010, 0x00000400, 0x00000410, 
   300     0x00000004, 0x00000014, 0x00000404, 0x00000414, 
   301     0x00004000, 0x00004010, 0x00004400, 0x00004410, 
   302     0x00004004, 0x00004014, 0x00004404, 0x00004414, 
   303     0x20000000, 0x20000010, 0x20000400, 0x20000410, 
   304     0x20000004, 0x20000014, 0x20000404, 0x20000414, 
   305     0x20004000, 0x20004010, 0x20004400, 0x20004410, 
   306     0x20004004, 0x20004014, 0x20004404, 0x20004414, 
   307     0x00200000, 0x00200010, 0x00200400, 0x00200410, 
   308     0x00200004, 0x00200014, 0x00200404, 0x00200414, 
   309     0x00204000, 0x00204010, 0x00204400, 0x00204410, 
   310     0x00204004, 0x00204014, 0x00204404, 0x00204414, 
   311     0x20200000, 0x20200010, 0x20200400, 0x20200410, 
   312     0x20200004, 0x20200014, 0x20200404, 0x20200414, 
   313     0x20204000, 0x20204010, 0x20204400, 0x20204410, 
   314     0x20204004, 0x20204014, 0x20204404, 0x20204414 
   315   }
   316 };
   318 /*
   319  * The PC-1 Permutation
   320  * If we number the bits of the 8 bytes of key input like this (in octal):
   321  *     00 01 02 03 04 05 06 07 
   322  *     10 11 12 13 14 15 16 17 
   323  *     20 21 22 23 24 25 26 27 
   324  *     30 31 32 33 34 35 36 37 
   325  *     40 41 42 43 44 45 46 47 
   326  *     50 51 52 53 54 55 56 57 
   327  *     60 61 62 63 64 65 66 67 
   328  *     70 71 72 73 74 75 76 77 
   329  * then after the PC-1 permutation, 
   330  * C0 is
   331  *     70 60 50 40 30 20 10 00 
   332  *     71 61 51 41 31 21 11 01 
   333  *     72 62 52 42 32 22 12 02 
   334  *     73 63 53 43 
   335  * D0 is
   336  *     76 66 56 46 36 26 16 06 
   337  *     75 65 55 45 35 25 15 05 
   338  *     74 64 54 44 34 24 14 04 
   339  *                 33 23 13 03 
   340  * and these parity bits have been discarded:
   341  *     77 67 57 47 37 27 17 07 
   342  * 
   343  * We achieve this by flipping the input matrix about the diagonal from 70-07,
   344  * getting left = 
   345  *     77 67 57 47 37 27 17 07 	(these are the parity bits)
   346  *     76 66 56 46 36 26 16 06 
   347  *     75 65 55 45 35 25 15 05 
   348  *     74 64 54 44 34 24 14 04 
   349  * right = 
   350  *     73 63 53 43 33 23 13 03 
   351  *     72 62 52 42 32 22 12 02 
   352  *     71 61 51 41 31 21 11 01 
   353  *     70 60 50 40 30 20 10 00 
   354  * then byte swap right, ala htonl() on a little endian machine.
   355  * right = 
   356  *     70 60 50 40 30 20 10 00 
   357  *     71 67 57 47 37 27 11 07 
   358  *     72 62 52 42 32 22 12 02 
   359  *     73 63 53 43 33 23 13 03 
   360  * then
   361  *     c0 = right >> 4;
   362  *     d0 = ((left & 0x00ffffff) << 4) | (right & 0xf);
   363 */
   365 #define FLIP_RIGHT_DIAGONAL(word, temp) \
   366     temp  = (word ^ (word >> 18)) & 0x00003333; \
   367     word ^=  temp | (temp << 18); \
   368     temp  = (word ^ (word >> 9)) & 0x00550055; \
   369     word ^=  temp | (temp << 9);
   371 #if defined(__GNUC__) && defined(NSS_X86_OR_X64)
   372 #define BYTESWAP(word, temp) \
   373     __asm("bswap	%0" : "+r" (word));
   374 #elif (_MSC_VER >= 1300) && defined(NSS_X86_OR_X64)
   375 #include <stdlib.h>
   376 #pragma intrinsic(_byteswap_ulong)
   377 #define BYTESWAP(word, temp) \
   378     word = _byteswap_ulong(word);
   379 #elif defined(__GNUC__) && (defined(__thumb2__) || \
   380       (!defined(__thumb__) && \
   381       (defined(__ARM_ARCH_6__) || \
   382        defined(__ARM_ARCH_6J__) || \
   383        defined(__ARM_ARCH_6K__) || \
   384        defined(__ARM_ARCH_6Z__) || \
   385        defined(__ARM_ARCH_6ZK__) || \
   386        defined(__ARM_ARCH_6T2__) || \
   387        defined(__ARM_ARCH_7__) || \
   388        defined(__ARM_ARCH_7A__) || \
   389        defined(__ARM_ARCH_7R__))))
   390 #define BYTESWAP(word, temp) \
   391     __asm("rev %0, %0" : "+r" (word));
   392 #else
   393 #define BYTESWAP(word, temp) \
   394     word = (word >> 16) | (word << 16); \
   395     temp = 0x00ff00ff; \
   396     word = ((word & temp) << 8) | ((word >> 8) & temp); 
   397 #endif
   399 #define PC1(left, right, c0, d0, temp) \
   400     right ^= temp = ((left >> 4) ^ right) & 0x0f0f0f0f; \
   401     left  ^= temp << 4; \
   402     FLIP_RIGHT_DIAGONAL(left, temp); \
   403     FLIP_RIGHT_DIAGONAL(right, temp); \
   404     BYTESWAP(right, temp); \
   405     c0 = right >> 4; \
   406     d0 = ((left & 0x00ffffff) << 4) | (right & 0xf); 
   408 #define LEFT_SHIFT_1( reg ) (((reg << 1) | (reg >> 27)) & 0x0FFFFFFF)
   409 #define LEFT_SHIFT_2( reg ) (((reg << 2) | (reg >> 26)) & 0x0FFFFFFF)
   411 /*
   412  *   setup key schedules from key
   413  */
   415 void 
   416 DES_MakeSchedule( HALF * ks, const BYTE * key,   DESDirection direction)
   417 {
   418     register HALF left, right;
   419     register HALF c0, d0;
   420     register HALF temp;
   421     int           delta;
   422     unsigned int  ls;
   424 #if defined(NSS_X86_OR_X64)
   425     left  = HALFPTR(key)[0]; 
   426     right = HALFPTR(key)[1]; 
   427     BYTESWAP(left, temp);
   428     BYTESWAP(right, temp);
   429 #else
   430     if (((ptrdiff_t)key & 0x03) == 0) {
   431 	left  = HALFPTR(key)[0]; 
   432 	right = HALFPTR(key)[1]; 
   433 #if defined(IS_LITTLE_ENDIAN)
   434 	BYTESWAP(left, temp);
   435 	BYTESWAP(right, temp);
   436 #endif
   437     } else {
   438 	left    = ((HALF)key[0] << 24) | ((HALF)key[1] << 16) | 
   439 		  ((HALF)key[2] << 8)  | key[3];
   440 	right   = ((HALF)key[4] << 24) | ((HALF)key[5] << 16) | 
   441 		  ((HALF)key[6] << 8)  | key[7];
   442     }
   443 #endif
   445     PC1(left, right, c0, d0, temp);
   447     if (direction == DES_ENCRYPT) {
   448 	delta = 2 * (int)sizeof(HALF);
   449     } else {
   450 	ks += 30;
   451 	delta = (-2) * (int)sizeof(HALF);
   452     }
   454     for (ls = 0x8103; ls; ls >>= 1) {
   455 	if ( ls & 1 ) {
   456 	    c0 = LEFT_SHIFT_1( c0 );
   457 	    d0 = LEFT_SHIFT_1( d0 );
   458 	} else {
   459 	    c0 = LEFT_SHIFT_2( c0 );
   460 	    d0 = LEFT_SHIFT_2( d0 );
   461 	}
   463 #ifdef USE_INDEXING
   464 #define PC2LOOKUP(b,c) PC2[b][c]
   466 	left   = PC2LOOKUP(0, ((c0 >> 22) & 0x3F) );
   467 	left  |= PC2LOOKUP(1, ((c0 >> 13) & 0x3F) );
   468 	left  |= PC2LOOKUP(2, ((c0 >>  4) & 0x38) | (c0 & 0x7) );
   469 	left  |= PC2LOOKUP(3, ((c0>>18)&0xC) | ((c0>>11)&0x3) | (c0&0x30));
   471 	right  = PC2LOOKUP(4, ((d0 >> 22) & 0x3F) );
   472 	right |= PC2LOOKUP(5, ((d0 >> 15) & 0x30) | ((d0 >> 14) & 0xf) );
   473 	right |= PC2LOOKUP(6, ((d0 >>  7) & 0x3F) );
   474 	right |= PC2LOOKUP(7, ((d0 >>  1) & 0x3C) | (d0 & 0x3));
   475 #else
   476 #define PC2LOOKUP(b,c) *(HALF *)((BYTE *)&PC2[b][0]+(c))
   478 	left   = PC2LOOKUP(0, ((c0 >> 20) & 0xFC) );
   479 	left  |= PC2LOOKUP(1, ((c0 >> 11) & 0xFC) );
   480 	left  |= PC2LOOKUP(2, ((c0 >>  2) & 0xE0) | ((c0 <<  2) & 0x1C) );
   481 	left  |= PC2LOOKUP(3, ((c0>>16)&0x30)|((c0>>9)&0xC)|((c0<<2)&0xC0));
   483 	right  = PC2LOOKUP(4, ((d0 >> 20) & 0xFC) );
   484 	right |= PC2LOOKUP(5, ((d0 >> 13) & 0xC0) | ((d0 >> 12) & 0x3C) );
   485 	right |= PC2LOOKUP(6, ((d0 >>  5) & 0xFC) );
   486 	right |= PC2LOOKUP(7, ((d0 <<  1) & 0xF0) | ((d0 << 2) & 0x0C));
   487 #endif
   488 	/* left  contains key bits for S1 S3 S2 S4 */
   489 	/* right contains key bits for S6 S8 S5 S7 */
   490 	temp = (left  << 16)        /* S2 S4 XX XX */
   491 	     | (right >> 16);       /* XX XX S6 S8 */
   492 	ks[0] = temp;
   494 	temp = (left  & 0xffff0000) /* S1 S3 XX XX */
   495 	     | (right & 0x0000ffff);/* XX XX S5 S7 */
   496 	ks[1] = temp;
   498 	ks = (HALF*)((BYTE *)ks + delta);
   499     }
   500 }
   502 /*
   503  * The DES Initial Permutation
   504  * if we number the bits of the 8 bytes of input like this (in octal):
   505  *     00 01 02 03 04 05 06 07 
   506  *     10 11 12 13 14 15 16 17 
   507  *     20 21 22 23 24 25 26 27 
   508  *     30 31 32 33 34 35 36 37 
   509  *     40 41 42 43 44 45 46 47 
   510  *     50 51 52 53 54 55 56 57 
   511  *     60 61 62 63 64 65 66 67 
   512  *     70 71 72 73 74 75 76 77 
   513  * then after the initial permutation, they will be in this order. 
   514  *     71 61 51 41 31 21 11 01 
   515  *     73 63 53 43 33 23 13 03 
   516  *     75 65 55 45 35 25 15 05 
   517  *     77 67 57 47 37 27 17 07 
   518  *     70 60 50 40 30 20 10 00 
   519  *     72 62 52 42 32 22 12 02 
   520  *     74 64 54 44 34 24 14 04 
   521  *     76 66 56 46 36 26 16 06 
   522  *
   523  * One way to do this is in two steps:
   524  * 1. Flip this matrix about the diagonal from 70-07 as done for PC1.
   525  * 2. Rearrange the bytes (rows in the matrix above) with the following code.
   526  *
   527  * #define swapHiLo(word, temp) \
   528  *   temp  = (word ^ (word >> 24)) & 0x000000ff; \
   529  *   word ^=  temp | (temp << 24); 
   530  *
   531  *   right ^= temp = ((left << 8) ^ right) & 0xff00ff00; 
   532  *   left  ^= temp >> 8; 
   533  *   swapHiLo(left, temp);
   534  *   swapHiLo(right,temp);
   535  *
   536  * However, the two steps can be combined, so that the rows are rearranged
   537  * while the matrix is being flipped, reducing the number of bit exchange
   538  * operations from 8 ot 5.  
   539  *
   540  * Initial Permutation */
   541 #define IP(left, right, temp) \
   542     right ^= temp = ((left >> 4) ^  right) & 0x0f0f0f0f; \
   543     left  ^= temp << 4; \
   544     right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \
   545     left  ^= temp << 16; \
   546     right ^= temp = ((left << 2) ^ right) & 0xcccccccc; \
   547     left  ^= temp >> 2; \
   548     right ^= temp = ((left << 8) ^ right) & 0xff00ff00; \
   549     left  ^= temp >> 8; \
   550     right ^= temp = ((left >> 1) ^ right) & 0x55555555; \
   551     left  ^= temp << 1; 
   553 /* The Final (Inverse Initial) permutation is done by reversing the 
   554 ** steps of the Initital Permutation 
   555 */
   557 #define FP(left, right, temp) \
   558     right ^= temp = ((left >> 1) ^ right) & 0x55555555; \
   559     left  ^= temp << 1; \
   560     right ^= temp = ((left << 8) ^ right) & 0xff00ff00; \
   561     left  ^= temp >> 8; \
   562     right ^= temp = ((left << 2) ^ right) & 0xcccccccc; \
   563     left  ^= temp >> 2; \
   564     right ^= temp = ((left >> 16) ^ right) & 0x0000ffff; \
   565     left  ^= temp << 16; \
   566     right ^= temp = ((left >> 4) ^  right) & 0x0f0f0f0f; \
   567     left  ^= temp << 4; 
   569 void 
   570 DES_Do1Block(HALF * ks, const BYTE * inbuf, BYTE * outbuf)
   571 {
   572     register HALF left, right;
   573     register HALF temp;
   575 #if defined(NSS_X86_OR_X64)
   576     left  = HALFPTR(inbuf)[0]; 
   577     right = HALFPTR(inbuf)[1]; 
   578     BYTESWAP(left, temp);
   579     BYTESWAP(right, temp);
   580 #else
   581     if (((ptrdiff_t)inbuf & 0x03) == 0) {
   582 	left  = HALFPTR(inbuf)[0]; 
   583 	right = HALFPTR(inbuf)[1]; 
   584 #if defined(IS_LITTLE_ENDIAN)
   585 	BYTESWAP(left, temp);
   586 	BYTESWAP(right, temp);
   587 #endif
   588     } else {
   589 	left    = ((HALF)inbuf[0] << 24) | ((HALF)inbuf[1] << 16) | 
   590 		  ((HALF)inbuf[2] << 8)  | inbuf[3];
   591 	right   = ((HALF)inbuf[4] << 24) | ((HALF)inbuf[5] << 16) | 
   592 		  ((HALF)inbuf[6] << 8)  | inbuf[7];
   593     }
   594 #endif
   596     IP(left, right, temp);
   598     /* shift the values left circularly 3 bits. */
   599     left  = (left  << 3) | (left  >> 29);
   600     right = (right << 3) | (right >> 29);
   602 #ifdef USE_INDEXING
   603 #define KSLOOKUP(s,b) SP[s][((temp >> (b+2)) & 0x3f)]
   604 #else
   605 #define KSLOOKUP(s,b) *(HALF*)((BYTE*)&SP[s][0]+((temp >> b) & 0xFC))
   606 #endif
   607 #define ROUND(out, in, r) \
   608     temp  = in ^ ks[2*r]; \
   609     out ^= KSLOOKUP( 1,  24 ); \
   610     out ^= KSLOOKUP( 3,  16 ); \
   611     out ^= KSLOOKUP( 5,   8 ); \
   612     out ^= KSLOOKUP( 7,   0 ); \
   613     temp  = ((in >> 4) | (in << 28)) ^ ks[2*r+1]; \
   614     out ^= KSLOOKUP( 0,  24 ); \
   615     out ^= KSLOOKUP( 2,  16 ); \
   616     out ^= KSLOOKUP( 4,   8 ); \
   617     out ^= KSLOOKUP( 6,   0 ); 
   619     /* Do the 16 Feistel rounds */
   620     ROUND(left, right, 0)
   621     ROUND(right, left, 1)
   622     ROUND(left, right, 2)
   623     ROUND(right, left, 3)
   624     ROUND(left, right, 4)
   625     ROUND(right, left, 5)
   626     ROUND(left, right, 6)
   627     ROUND(right, left, 7)
   628     ROUND(left, right, 8)
   629     ROUND(right, left, 9)
   630     ROUND(left, right, 10)
   631     ROUND(right, left, 11)
   632     ROUND(left, right, 12)
   633     ROUND(right, left, 13)
   634     ROUND(left, right, 14)
   635     ROUND(right, left, 15)
   637     /* now shift circularly right 3 bits to undo the shifting done 
   638     ** above.  switch left and right here. 
   639     */
   640     temp  = (left >> 3) | (left << 29); 
   641     left  = (right >> 3) | (right << 29); 
   642     right = temp;
   644     FP(left, right, temp);
   646 #if defined(NSS_X86_OR_X64)
   647     BYTESWAP(left, temp);
   648     BYTESWAP(right, temp);
   649     HALFPTR(outbuf)[0]  = left; 
   650     HALFPTR(outbuf)[1]  = right; 
   651 #else
   652     if (((ptrdiff_t)outbuf & 0x03) == 0) {
   653 #if defined(IS_LITTLE_ENDIAN)
   654 	BYTESWAP(left, temp);
   655 	BYTESWAP(right, temp);
   656 #endif
   657 	HALFPTR(outbuf)[0]  = left; 
   658 	HALFPTR(outbuf)[1]  = right; 
   659     } else {
   660 	outbuf[0] = (BYTE)(left >> 24);
   661 	outbuf[1] = (BYTE)(left >> 16);
   662 	outbuf[2] = (BYTE)(left >>  8);
   663 	outbuf[3] = (BYTE)(left      );
   665 	outbuf[4] = (BYTE)(right >> 24);
   666 	outbuf[5] = (BYTE)(right >> 16);
   667 	outbuf[6] = (BYTE)(right >>  8);
   668 	outbuf[7] = (BYTE)(right      );
   669     }
   670 #endif
   672 }
   674 /* Ackowledgements:
   675 ** Two ideas used in this implementation were shown to me by Dennis Ferguson 
   676 ** in 1990.  He credits them to Richard Outerbridge and Dan Hoey.  They were:
   677 ** 1. The method of computing the Initial and Final permutations.
   678 ** 2. Circularly rotating the SP tables and the initial values of left and 
   679 **	right to reduce the number of shifts required during the 16 rounds.
   680 */

mercurial