1 /* 2 * Copyright 2004 Hans Leidekker 3 * Copyright 2006 Mike McCormack 4 * 5 * Based on DES.c from libcifs 6 * 7 * Copyright (C) 2003, 2004 by Christopher R. Hertel 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 22 */ 23 24 #ifdef __REACTOS__ 25 #include <advapi32.h> 26 #else 27 #include "windef.h" 28 #include "crypt.h" 29 #endif 30 31 static const unsigned char InitialPermuteMap[64] = 32 { 33 57, 49, 41, 33, 25, 17, 9, 1, 34 59, 51, 43, 35, 27, 19, 11, 3, 35 61, 53, 45, 37, 29, 21, 13, 5, 36 63, 55, 47, 39, 31, 23, 15, 7, 37 56, 48, 40, 32, 24, 16, 8, 0, 38 58, 50, 42, 34, 26, 18, 10, 2, 39 60, 52, 44, 36, 28, 20, 12, 4, 40 62, 54, 46, 38, 30, 22, 14, 6 41 }; 42 43 static const unsigned char KeyPermuteMap[56] = 44 { 45 49, 42, 35, 28, 21, 14, 7, 0, 46 50, 43, 36, 29, 22, 15, 8, 1, 47 51, 44, 37, 30, 23, 16, 9, 2, 48 52, 45, 38, 31, 55, 48, 41, 34, 49 27, 20, 13, 6, 54, 47, 40, 33, 50 26, 19, 12, 5, 53, 46, 39, 32, 51 25, 18, 11, 4, 24, 17, 10, 3, 52 }; 53 54 static const unsigned char KeyRotation[16] = 55 { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; 56 57 static const unsigned char KeyCompression[48] = 58 { 59 13, 16, 10, 23, 0, 4, 2, 27, 60 14, 5, 20, 9, 22, 18, 11, 3, 61 25, 7, 15, 6, 26, 19, 12, 1, 62 40, 51, 30, 36, 46, 54, 29, 39, 63 50, 44, 32, 47, 43, 48, 38, 55, 64 33, 52, 45, 41, 49, 35, 28, 31 65 }; 66 67 static const unsigned char DataExpansion[48] = 68 { 69 31, 0, 1, 2, 3, 4, 3, 4, 70 5, 6, 7, 8, 7, 8, 9, 10, 71 11, 12, 11, 12, 13, 14, 15, 16, 72 15, 16, 17, 18, 19, 20, 19, 20, 73 21, 22, 23, 24, 23, 24, 25, 26, 74 27, 28, 27, 28, 29, 30, 31, 0 75 }; 76 77 static const unsigned char SBox[8][64] = 78 { 79 { /* S0 */ 80 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1, 81 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8, 82 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7, 83 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13 84 }, 85 { /* S1 */ 86 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14, 87 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5, 88 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2, 89 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9 90 }, 91 { /* S2 */ 92 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10, 93 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1, 94 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7, 95 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12 96 }, 97 { /* S3 */ 98 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3, 99 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9, 100 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8, 101 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14 102 }, 103 { /* S4 */ 104 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1, 105 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6, 106 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13, 107 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3 108 }, 109 { /* S5 */ 110 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5, 111 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8, 112 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10, 113 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13 114 }, 115 { /* S6 */ 116 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10, 117 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6, 118 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7, 119 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12 120 }, 121 { /* S7 */ 122 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4, 123 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2, 124 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13, 125 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11 126 } 127 }; 128 129 static const unsigned char PBox[32] = 130 { 131 15, 6, 19, 20, 28, 11, 27, 16, 132 0, 14, 22, 25, 4, 17, 30, 9, 133 1, 7, 23, 13, 31, 26, 2, 8, 134 18, 12, 29, 5, 21, 10, 3, 24 135 }; 136 137 static const unsigned char FinalPermuteMap[64] = 138 { 139 7, 39, 15, 47, 23, 55, 31, 63, 140 6, 38, 14, 46, 22, 54, 30, 62, 141 5, 37, 13, 45, 21, 53, 29, 61, 142 4, 36, 12, 44, 20, 52, 28, 60, 143 3, 35, 11, 43, 19, 51, 27, 59, 144 2, 34, 10, 42, 18, 50, 26, 58, 145 1, 33, 9, 41, 17, 49, 25, 57, 146 0, 32, 8, 40, 16, 48, 24, 56 147 }; 148 149 #define CLRBIT( STR, IDX ) ( (STR)[(IDX)/8] &= ~(0x01 << (7 - ((IDX)%8))) ) 150 #define SETBIT( STR, IDX ) ( (STR)[(IDX)/8] |= (0x01 << (7 - ((IDX)%8))) ) 151 #define GETBIT( STR, IDX ) (( ((STR)[(IDX)/8]) >> (7 - ((IDX)%8)) ) & 0x01) 152 153 static void Permute( unsigned char *dst, const unsigned char *src, const unsigned char *map, const int mapsize ) 154 { 155 int bitcount, i; 156 157 for (i = 0; i < mapsize; i++) 158 dst[i] = 0; 159 160 bitcount = mapsize * 8; 161 162 for (i = 0; i < bitcount; i++) 163 { 164 if (GETBIT( src, map[i] )) 165 SETBIT( dst, i ); 166 } 167 } 168 169 static void KeyShiftLeft( unsigned char *key, const int numbits ) 170 { 171 int i; 172 unsigned char keep = key[0]; 173 174 for (i = 0; i < numbits; i++) 175 { 176 int j; 177 178 for (j = 0; j < 7; j++) 179 { 180 if (j && (key[j] & 0x80)) 181 key[j-1] |= 0x01; 182 key[j] <<= 1; 183 } 184 185 if (GETBIT( key, 27 )) 186 { 187 CLRBIT( key, 27 ); 188 SETBIT( key, 55 ); 189 } 190 191 if (keep & 0x80) 192 SETBIT( key, 27 ); 193 194 keep <<= 1; 195 } 196 } 197 198 static void KeyShiftRight( unsigned char *key, const int numbits ) 199 { 200 int i; 201 unsigned char keep = key[6]; 202 203 for (i = 0; i < numbits; i++) 204 { 205 int j; 206 207 for (j = 6; j >= 0; j--) 208 { 209 if (j!=6 && (key[j] & 0x01)) 210 key[j+1] |= 0x80; 211 key[j] >>= 1; 212 } 213 214 if (GETBIT( key, 28 )) 215 { 216 CLRBIT( key, 28 ); 217 SETBIT( key, 0 ); 218 } 219 220 if (keep & 0x01) 221 SETBIT( key, 28 ); 222 223 keep >>= 1; 224 } 225 } 226 227 static void sbox( unsigned char *dst, const unsigned char *src ) 228 { 229 int i; 230 231 for (i = 0; i < 4; i++) 232 dst[i] = 0; 233 234 for (i = 0; i < 8; i++) 235 { 236 int j, Snum, bitnum; 237 238 for (Snum = j = 0, bitnum = (i * 6); j < 6; j++, bitnum++) 239 { 240 Snum <<= 1; 241 Snum |= GETBIT( src, bitnum ); 242 } 243 244 if (0 == (i%2)) 245 dst[i/2] |= ((SBox[i][Snum]) << 4); 246 else 247 dst[i/2] |= SBox[i][Snum]; 248 } 249 } 250 251 static void xor( unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count ) 252 { 253 int i; 254 255 for (i = 0; i < count; i++) 256 dst[i] = a[i] ^ b[i]; 257 } 258 259 unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key, const unsigned char *src ) 260 { 261 int i; 262 unsigned char K[7]; 263 unsigned char D[8]; 264 265 Permute( K, key, KeyPermuteMap, 7 ); 266 Permute( D, src, InitialPermuteMap, 8 ); 267 268 for (i = 0; i < 16; i++) 269 { 270 int j; 271 unsigned char *L = D; 272 unsigned char *R = &(D[4]); 273 unsigned char Rexp[6]; 274 unsigned char Rn[4]; 275 unsigned char SubK[6]; 276 277 KeyShiftLeft( K, KeyRotation[i] ); 278 Permute( SubK, K, KeyCompression, 6 ); 279 280 Permute( Rexp, R, DataExpansion, 6 ); 281 xor( Rexp, Rexp, SubK, 6 ); 282 283 sbox( Rn, Rexp ); 284 Permute( Rexp, Rn, PBox, 4 ); 285 xor( Rn, L, Rexp, 4 ); 286 287 for (j = 0; j < 4; j++) 288 { 289 L[j] = R[j]; 290 R[j] = Rn[j]; 291 } 292 } 293 294 Permute( dst, D, FinalPermuteMap, 8 ); 295 296 return dst; 297 } 298 299 unsigned char *CRYPT_DESunhash( unsigned char *dst, const unsigned char *key, const unsigned char *src ) 300 { 301 int i; 302 unsigned char K[7]; 303 unsigned char D[8]; 304 305 Permute( K, key, KeyPermuteMap, 7 ); 306 Permute( D, src, InitialPermuteMap, 8 ); 307 308 for (i = 0; i < 16; i++) 309 { 310 int j; 311 unsigned char *L = D; 312 unsigned char *R = &(D[4]); 313 unsigned char Rexp[6]; 314 unsigned char Rn[4]; 315 unsigned char SubK[6]; 316 317 Permute( SubK, K, KeyCompression, 6 ); 318 319 Permute( Rexp, R, DataExpansion, 6 ); 320 xor( Rexp, Rexp, SubK, 6 ); 321 322 sbox( Rn, Rexp ); 323 Permute( Rexp, Rn, PBox, 4 ); 324 xor( Rn, L, Rexp, 4 ); 325 326 for (j = 0; j < 4; j++) 327 { 328 L[j] = R[j]; 329 R[j] = Rn[j]; 330 } 331 332 KeyShiftRight( K, KeyRotation[15 - i] ); 333 } 334 335 Permute( dst, D, FinalPermuteMap, 8 ); 336 337 return dst; 338 } 339