1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * Portable C version of des() and des_key() functions. 31 * This version is very similar to that in Part V of Applied Cryptography 32 * by Bruce Schneier. 33 * 34 * This information is in the public domain 12/15/95 P. Karn 35 */ 36 37 #include <sys/types.h> 38 #include <sys/sysmacros.h> 39 #if defined(_KERNEL) && !defined(_BOOT) 40 #include <sys/systm.h> 41 #else 42 #include <strings.h> 43 #endif 44 45 #include "des.h" 46 47 /* 48 * Combined SP lookup table, linked in 49 * For best results, ensure that this is aligned on a 32-bit boundary; 50 */ 51 static uint32_t Spbox[8][64] = { 52 0x01010400U, 0x00000000U, 0x00010000U, 0x01010404U, 53 0x01010004U, 0x00010404U, 0x00000004U, 0x00010000U, 54 0x00000400U, 0x01010400U, 0x01010404U, 0x00000400U, 55 0x01000404U, 0x01010004U, 0x01000000U, 0x00000004U, 56 0x00000404U, 0x01000400U, 0x01000400U, 0x00010400U, 57 0x00010400U, 0x01010000U, 0x01010000U, 0x01000404U, 58 0x00010004U, 0x01000004U, 0x01000004U, 0x00010004U, 59 0x00000000U, 0x00000404U, 0x00010404U, 0x01000000U, 60 0x00010000U, 0x01010404U, 0x00000004U, 0x01010000U, 61 0x01010400U, 0x01000000U, 0x01000000U, 0x00000400U, 62 0x01010004U, 0x00010000U, 0x00010400U, 0x01000004U, 63 0x00000400U, 0x00000004U, 0x01000404U, 0x00010404U, 64 0x01010404U, 0x00010004U, 0x01010000U, 0x01000404U, 65 0x01000004U, 0x00000404U, 0x00010404U, 0x01010400U, 66 0x00000404U, 0x01000400U, 0x01000400U, 0x00000000U, 67 0x00010004U, 0x00010400U, 0x00000000U, 0x01010004U, 68 0x80108020U, 0x80008000U, 0x00008000U, 0x00108020U, 69 0x00100000U, 0x00000020U, 0x80100020U, 0x80008020U, 70 0x80000020U, 0x80108020U, 0x80108000U, 0x80000000U, 71 0x80008000U, 0x00100000U, 0x00000020U, 0x80100020U, 72 0x00108000U, 0x00100020U, 0x80008020U, 0x00000000U, 73 0x80000000U, 0x00008000U, 0x00108020U, 0x80100000U, 74 0x00100020U, 0x80000020U, 0x00000000U, 0x00108000U, 75 0x00008020U, 0x80108000U, 0x80100000U, 0x00008020U, 76 0x00000000U, 0x00108020U, 0x80100020U, 0x00100000U, 77 0x80008020U, 0x80100000U, 0x80108000U, 0x00008000U, 78 0x80100000U, 0x80008000U, 0x00000020U, 0x80108020U, 79 0x00108020U, 0x00000020U, 0x00008000U, 0x80000000U, 80 0x00008020U, 0x80108000U, 0x00100000U, 0x80000020U, 81 0x00100020U, 0x80008020U, 0x80000020U, 0x00100020U, 82 0x00108000U, 0x00000000U, 0x80008000U, 0x00008020U, 83 0x80000000U, 0x80100020U, 0x80108020U, 0x00108000U, 84 0x00000208U, 0x08020200U, 0x00000000U, 0x08020008U, 85 0x08000200U, 0x00000000U, 0x00020208U, 0x08000200U, 86 0x00020008U, 0x08000008U, 0x08000008U, 0x00020000U, 87 0x08020208U, 0x00020008U, 0x08020000U, 0x00000208U, 88 0x08000000U, 0x00000008U, 0x08020200U, 0x00000200U, 89 0x00020200U, 0x08020000U, 0x08020008U, 0x00020208U, 90 0x08000208U, 0x00020200U, 0x00020000U, 0x08000208U, 91 0x00000008U, 0x08020208U, 0x00000200U, 0x08000000U, 92 0x08020200U, 0x08000000U, 0x00020008U, 0x00000208U, 93 0x00020000U, 0x08020200U, 0x08000200U, 0x00000000U, 94 0x00000200U, 0x00020008U, 0x08020208U, 0x08000200U, 95 0x08000008U, 0x00000200U, 0x00000000U, 0x08020008U, 96 0x08000208U, 0x00020000U, 0x08000000U, 0x08020208U, 97 0x00000008U, 0x00020208U, 0x00020200U, 0x08000008U, 98 0x08020000U, 0x08000208U, 0x00000208U, 0x08020000U, 99 0x00020208U, 0x00000008U, 0x08020008U, 0x00020200U, 100 0x00802001U, 0x00002081U, 0x00002081U, 0x00000080U, 101 0x00802080U, 0x00800081U, 0x00800001U, 0x00002001U, 102 0x00000000U, 0x00802000U, 0x00802000U, 0x00802081U, 103 0x00000081U, 0x00000000U, 0x00800080U, 0x00800001U, 104 0x00000001U, 0x00002000U, 0x00800000U, 0x00802001U, 105 0x00000080U, 0x00800000U, 0x00002001U, 0x00002080U, 106 0x00800081U, 0x00000001U, 0x00002080U, 0x00800080U, 107 0x00002000U, 0x00802080U, 0x00802081U, 0x00000081U, 108 0x00800080U, 0x00800001U, 0x00802000U, 0x00802081U, 109 0x00000081U, 0x00000000U, 0x00000000U, 0x00802000U, 110 0x00002080U, 0x00800080U, 0x00800081U, 0x00000001U, 111 0x00802001U, 0x00002081U, 0x00002081U, 0x00000080U, 112 0x00802081U, 0x00000081U, 0x00000001U, 0x00002000U, 113 0x00800001U, 0x00002001U, 0x00802080U, 0x00800081U, 114 0x00002001U, 0x00002080U, 0x00800000U, 0x00802001U, 115 0x00000080U, 0x00800000U, 0x00002000U, 0x00802080U, 116 0x00000100U, 0x02080100U, 0x02080000U, 0x42000100U, 117 0x00080000U, 0x00000100U, 0x40000000U, 0x02080000U, 118 0x40080100U, 0x00080000U, 0x02000100U, 0x40080100U, 119 0x42000100U, 0x42080000U, 0x00080100U, 0x40000000U, 120 0x02000000U, 0x40080000U, 0x40080000U, 0x00000000U, 121 0x40000100U, 0x42080100U, 0x42080100U, 0x02000100U, 122 0x42080000U, 0x40000100U, 0x00000000U, 0x42000000U, 123 0x02080100U, 0x02000000U, 0x42000000U, 0x00080100U, 124 0x00080000U, 0x42000100U, 0x00000100U, 0x02000000U, 125 0x40000000U, 0x02080000U, 0x42000100U, 0x40080100U, 126 0x02000100U, 0x40000000U, 0x42080000U, 0x02080100U, 127 0x40080100U, 0x00000100U, 0x02000000U, 0x42080000U, 128 0x42080100U, 0x00080100U, 0x42000000U, 0x42080100U, 129 0x02080000U, 0x00000000U, 0x40080000U, 0x42000000U, 130 0x00080100U, 0x02000100U, 0x40000100U, 0x00080000U, 131 0x00000000U, 0x40080000U, 0x02080100U, 0x40000100U, 132 0x20000010U, 0x20400000U, 0x00004000U, 0x20404010U, 133 0x20400000U, 0x00000010U, 0x20404010U, 0x00400000U, 134 0x20004000U, 0x00404010U, 0x00400000U, 0x20000010U, 135 0x00400010U, 0x20004000U, 0x20000000U, 0x00004010U, 136 0x00000000U, 0x00400010U, 0x20004010U, 0x00004000U, 137 0x00404000U, 0x20004010U, 0x00000010U, 0x20400010U, 138 0x20400010U, 0x00000000U, 0x00404010U, 0x20404000U, 139 0x00004010U, 0x00404000U, 0x20404000U, 0x20000000U, 140 0x20004000U, 0x00000010U, 0x20400010U, 0x00404000U, 141 0x20404010U, 0x00400000U, 0x00004010U, 0x20000010U, 142 0x00400000U, 0x20004000U, 0x20000000U, 0x00004010U, 143 0x20000010U, 0x20404010U, 0x00404000U, 0x20400000U, 144 0x00404010U, 0x20404000U, 0x00000000U, 0x20400010U, 145 0x00000010U, 0x00004000U, 0x20400000U, 0x00404010U, 146 0x00004000U, 0x00400010U, 0x20004010U, 0x00000000U, 147 0x20404000U, 0x20000000U, 0x00400010U, 0x20004010U, 148 0x00200000U, 0x04200002U, 0x04000802U, 0x00000000U, 149 0x00000800U, 0x04000802U, 0x00200802U, 0x04200800U, 150 0x04200802U, 0x00200000U, 0x00000000U, 0x04000002U, 151 0x00000002U, 0x04000000U, 0x04200002U, 0x00000802U, 152 0x04000800U, 0x00200802U, 0x00200002U, 0x04000800U, 153 0x04000002U, 0x04200000U, 0x04200800U, 0x00200002U, 154 0x04200000U, 0x00000800U, 0x00000802U, 0x04200802U, 155 0x00200800U, 0x00000002U, 0x04000000U, 0x00200800U, 156 0x04000000U, 0x00200800U, 0x00200000U, 0x04000802U, 157 0x04000802U, 0x04200002U, 0x04200002U, 0x00000002U, 158 0x00200002U, 0x04000000U, 0x04000800U, 0x00200000U, 159 0x04200800U, 0x00000802U, 0x00200802U, 0x04200800U, 160 0x00000802U, 0x04000002U, 0x04200802U, 0x04200000U, 161 0x00200800U, 0x00000000U, 0x00000002U, 0x04200802U, 162 0x00000000U, 0x00200802U, 0x04200000U, 0x00000800U, 163 0x04000002U, 0x04000800U, 0x00000800U, 0x00200002U, 164 0x10001040U, 0x00001000U, 0x00040000U, 0x10041040U, 165 0x10000000U, 0x10001040U, 0x00000040U, 0x10000000U, 166 0x00040040U, 0x10040000U, 0x10041040U, 0x00041000U, 167 0x10041000U, 0x00041040U, 0x00001000U, 0x00000040U, 168 0x10040000U, 0x10000040U, 0x10001000U, 0x00001040U, 169 0x00041000U, 0x00040040U, 0x10040040U, 0x10041000U, 170 0x00001040U, 0x00000000U, 0x00000000U, 0x10040040U, 171 0x10000040U, 0x10001000U, 0x00041040U, 0x00040000U, 172 0x00041040U, 0x00040000U, 0x10041000U, 0x00001000U, 173 0x00000040U, 0x10040040U, 0x00001000U, 0x00041040U, 174 0x10001000U, 0x00000040U, 0x10000040U, 0x10040000U, 175 0x10040040U, 0x10000000U, 0x00040000U, 0x10001040U, 176 0x00000000U, 0x10041040U, 0x00040040U, 0x10000040U, 177 0x10040000U, 0x10001000U, 0x10001040U, 0x00000000U, 178 0x10041040U, 0x00041000U, 0x00041000U, 0x00001040U, 179 0x00001040U, 0x00040040U, 0x10000000U, 0x10041000U, 180 }; 181 182 /* 183 * Primitive function F. 184 * Input is r, subkey array in keys, output is XORed into l. 185 * Each round consumes eight 6-bit subkeys, one for 186 * each of the 8 S-boxes, 2 longs for each round. 187 * Each long contains four 6-bit subkeys, each taking up a byte. 188 * The first long contains, from high to low end, the subkeys for 189 * S-boxes 1, 3, 5 & 7; the second contains the subkeys for S-boxes 190 * 2, 4, 6 & 8 (using the origin-1 S-box numbering in the standard, 191 * not the origin-0 numbering used elsewhere in this code) 192 * See comments elsewhere about the pre-rotated values of r and Spbox. 193 */ 194 #define F(l, r, key) {\ 195 work = ((r >> 4) | (r << 28)) ^ (key)[0];\ 196 l ^= Spbox[6][work & 0x3f];\ 197 l ^= Spbox[4][(work >> 8) & 0x3f];\ 198 l ^= Spbox[2][(work >> 16) & 0x3f];\ 199 l ^= Spbox[0][(work >> 24) & 0x3f];\ 200 work = r ^ (key)[1];\ 201 l ^= Spbox[7][work & 0x3f];\ 202 l ^= Spbox[5][(work >> 8) & 0x3f];\ 203 l ^= Spbox[3][(work >> 16) & 0x3f];\ 204 l ^= Spbox[1][(work >> 24) & 0x3f];\ 205 } 206 207 /* Encrypt or decrypt a block of data in ECB mode */ 208 void 209 des(void *cookie, uint8_t *block) 210 { 211 uint32_t *ks = (uint32_t *)cookie; 212 uint32_t left; 213 uint32_t right; 214 uint32_t work; 215 216 /* Read input block and place in left/right in big-endian order */ 217 left = ((uint32_t)block[0] << 24) | 218 ((uint32_t)block[1] << 16) | 219 ((uint32_t)block[2] << 8) | 220 (uint32_t)block[3]; 221 right = ((uint32_t)block[4] << 24) | 222 ((uint32_t)block[5] << 16) | 223 ((uint32_t)block[6] << 8) | 224 (uint32_t)block[7]; 225 226 /* 227 * Hoey's clever initial permutation algorithm, from Outerbridge 228 * (see Schneier p 478) 229 * 230 * The convention here is the same as Outerbridge: rotate each 231 * register left by 1 bit, i.e., so that "left" contains permuted 232 * input bits 2, 3, 4, ... 1 and "right" contains 33, 34, 35, ... 32 233 * (using origin-1 numbering as in the FIPS). This allows us to avoid 234 * one of the two rotates that would otherwise be required in each of 235 * the 16 rounds. 236 */ 237 work = ((left >> 4) ^ right) & 0x0f0f0f0f; 238 right ^= work; 239 left ^= work << 4; 240 work = ((left >> 16) ^ right) & 0xffff; 241 right ^= work; 242 left ^= work << 16; 243 work = ((right >> 2) ^ left) & 0x33333333; 244 left ^= work; 245 right ^= (work << 2); 246 work = ((right >> 8) ^ left) & 0xff00ff; 247 left ^= work; 248 right ^= (work << 8); 249 right = (right << 1) | (right >> 31); 250 work = (left ^ right) & 0xaaaaaaaa; 251 left ^= work; 252 right ^= work; 253 left = (left << 1) | (left >> 31); 254 255 /* First key */ 256 F(left, right, ks); 257 F(right, left, ks + 2); 258 F(left, right, ks + 4); 259 F(right, left, ks + 6); 260 F(left, right, ks + 8); 261 F(right, left, ks + 10); 262 F(left, right, ks + 12); 263 F(right, left, ks + 14); 264 F(left, right, ks + 16); 265 F(right, left, ks + 18); 266 F(left, right, ks + 20); 267 F(right, left, ks + 22); 268 F(left, right, ks + 24); 269 F(right, left, ks + 26); 270 F(left, right, ks + 28); 271 F(right, left, ks + 30); 272 273 /* Inverse permutation, also from Hoey via Outerbridge and Schneier */ 274 right = (right << 31) | (right >> 1); 275 work = (left ^ right) & 0xaaaaaaaa; 276 left ^= work; 277 right ^= work; 278 left = (left >> 1) | (left << 31); 279 work = ((left >> 8) ^ right) & 0xff00ff; 280 right ^= work; 281 left ^= work << 8; 282 work = ((left >> 2) ^ right) & 0x33333333; 283 right ^= work; 284 left ^= work << 2; 285 work = ((right >> 16) ^ left) & 0xffff; 286 left ^= work; 287 right ^= work << 16; 288 work = ((right >> 4) ^ left) & 0x0f0f0f0f; 289 left ^= work; 290 right ^= work << 4; 291 292 /* Put the block back into the user's buffer with final swap */ 293 block[0] = right >> 24; 294 block[1] = right >> 16; 295 block[2] = right >> 8; 296 block[3] = right; 297 block[4] = left >> 24; 298 block[5] = left >> 16; 299 block[6] = left >> 8; 300 block[7] = left; 301 } 302 303 /* Key schedule-related tables from FIPS-46 */ 304 305 /* permuted choice table (key) */ 306 static unsigned char pc1[] = { 307 57, 49, 41, 33, 25, 17, 9, 308 1, 58, 50, 42, 34, 26, 18, 309 10, 2, 59, 51, 43, 35, 27, 310 19, 11, 3, 60, 52, 44, 36, 311 63, 55, 47, 39, 31, 23, 15, 312 7, 62, 54, 46, 38, 30, 22, 313 14, 6, 61, 53, 45, 37, 29, 314 21, 13, 5, 28, 20, 12, 4 315 }; 316 317 /* number left rotations of pc1 */ 318 static unsigned char totrot[] = { 319 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 320 }; 321 322 /* permuted choice key (table) */ 323 static unsigned char pc2[] = { 324 14, 17, 11, 24, 1, 5, 325 3, 28, 15, 6, 21, 10, 326 23, 19, 12, 4, 26, 8, 327 16, 7, 27, 20, 13, 2, 328 41, 52, 31, 37, 47, 55, 329 30, 40, 51, 45, 33, 48, 330 44, 49, 39, 56, 34, 53, 331 46, 42, 50, 36, 29, 32 332 }; 333 334 /* End of DES-defined tables */ 335 336 337 /* bit 0 is left-most in byte */ 338 static int bytebit[] = { 339 0200, 0100, 040, 020, 010, 04, 02, 01 340 }; 341 342 /* 343 * Generate key schedule for encryption or decryption 344 * depending on the value of "decrypt" 345 */ 346 void 347 des_key(DES_KS k, const unsigned char *key, int decrypt) 348 { 349 unsigned char pc1m[56]; /* place to modify pc1 into */ 350 unsigned char pcr[56]; /* place to rotate pc1 into */ 351 int i; 352 int j; 353 int l; 354 int m; 355 unsigned char ks[8]; 356 357 for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */ 358 l = pc1[j] - 1; /* integer bit location */ 359 m = l & 07; /* find bit */ 360 pc1m[j] = (key[l >>3 ] /* find which key byte l is in */ 361 & bytebit[m]) /* and which bit of that byte */ 362 ? 1 : 0; /* and store 1-bit result */ 363 } 364 for (i = 0; i < 16; i++) { /* key chunk for each iteration */ 365 bzero(ks, sizeof (ks)); /* Clear key schedule */ 366 for (j = 0; j < 56; j++) /* rotate pc1 the right amount */ 367 pcr[j] = pc1m[(l = j + totrot[decrypt ? 15 - i : i]) < 368 (j < 28 ? 28 : 56) ? l : l - 28]; 369 /* rotate left and right halves independently */ 370 for (j = 0; j < 48; j++) { /* select bits individually */ 371 /* check bit that goes to ks[j] */ 372 if (pcr[pc2[j] - 1]) { 373 /* mask it in if it's there */ 374 l = j % 6; 375 ks[j/6] |= bytebit[l] >> 2; 376 } 377 } 378 /* Now convert to packed odd/even interleaved form */ 379 k[i][0] = ((uint32_t)ks[0] << 24) | 380 ((uint32_t)ks[2] << 16) | 381 ((uint32_t)ks[4] << 8) | 382 ((uint32_t)ks[6]); 383 k[i][1] = ((uint32_t)ks[1] << 24) | 384 ((uint32_t)ks[3] << 16) | 385 ((uint32_t)ks[5] << 8) | 386 ((uint32_t)ks[7]); 387 } 388 } 389