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