KIO
des.cpp
Go to the documentation of this file.
00001 /* 00002 * Sofware DES functions 00003 * 00004 * Copyright 1988-1991 Phil Karn <karn@ka9q.net> 00005 * Copyright 2003 Nikos Mavroyanopoulos <nmav@hellug.gr> 00006 * 00007 * Taken from libmcrypt (http://mcrypt.hellug.gr/lib/index.html). 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00021 * MA 02110-1301 USA 00022 */ 00023 00024 /* Sofware DES functions 00025 * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from 00026 * the 1977 public-domain program by Jim Gillogly 00027 * Modified for additional speed - 6 December 1988 Phil Karn 00028 * Modified for parameterized key schedules - Jan 1991 Phil Karn 00029 * Callers now allocate a key schedule as follows: 00030 * kn = (char (*)[8])malloc(sizeof(char) * 8 * 16); 00031 * or 00032 * char kn[16][8]; 00033 */ 00034 00035 /* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos 00036 * All modifications are placed under the license of libmcrypt. 00037 */ 00038 00039 00040 #include "des.h" 00041 00042 #include <string.h> 00043 #include <QtCore/qendian.h> 00044 00045 static void permute_ip (unsigned char *inblock, DES_KEY * key, unsigned char *outblock); 00046 static void permute_fp (unsigned char *inblock, DES_KEY * key, unsigned char *outblock); 00047 static void perminit_ip (DES_KEY * key); 00048 static void spinit (DES_KEY * key); 00049 static void perminit_fp (DES_KEY * key); 00050 static quint32 f (DES_KEY * key, quint32 r, char *subkey); 00051 00052 00053 /* Tables defined in the Data Encryption Standard documents */ 00054 00055 /* initial permutation IP */ 00056 static const char ip[] = { 00057 58, 50, 42, 34, 26, 18, 10, 2, 00058 60, 52, 44, 36, 28, 20, 12, 4, 00059 62, 54, 46, 38, 30, 22, 14, 6, 00060 64, 56, 48, 40, 32, 24, 16, 8, 00061 57, 49, 41, 33, 25, 17, 9, 1, 00062 59, 51, 43, 35, 27, 19, 11, 3, 00063 61, 53, 45, 37, 29, 21, 13, 5, 00064 63, 55, 47, 39, 31, 23, 15, 7 00065 }; 00066 00067 /* final permutation IP^-1 */ 00068 static const char fp[] = { 00069 40, 8, 48, 16, 56, 24, 64, 32, 00070 39, 7, 47, 15, 55, 23, 63, 31, 00071 38, 6, 46, 14, 54, 22, 62, 30, 00072 37, 5, 45, 13, 53, 21, 61, 29, 00073 36, 4, 44, 12, 52, 20, 60, 28, 00074 35, 3, 43, 11, 51, 19, 59, 27, 00075 34, 2, 42, 10, 50, 18, 58, 26, 00076 33, 1, 41, 9, 49, 17, 57, 25 00077 }; 00078 00079 /* expansion operation matrix 00080 * This is for reference only; it is unused in the code 00081 * as the f() function performs it implicitly for speed 00082 */ 00083 #ifdef notdef 00084 static const char ei[] = { 00085 32, 1, 2, 3, 4, 5, 00086 4, 5, 6, 7, 8, 9, 00087 8, 9, 10, 11, 12, 13, 00088 12, 13, 14, 15, 16, 17, 00089 16, 17, 18, 19, 20, 21, 00090 20, 21, 22, 23, 24, 25, 00091 24, 25, 26, 27, 28, 29, 00092 28, 29, 30, 31, 32, 1 00093 }; 00094 #endif 00095 00096 /* permuted choice table (key) */ 00097 static const char pc1[] = { 00098 57, 49, 41, 33, 25, 17, 9, 00099 1, 58, 50, 42, 34, 26, 18, 00100 10, 2, 59, 51, 43, 35, 27, 00101 19, 11, 3, 60, 52, 44, 36, 00102 00103 63, 55, 47, 39, 31, 23, 15, 00104 7, 62, 54, 46, 38, 30, 22, 00105 14, 6, 61, 53, 45, 37, 29, 00106 21, 13, 5, 28, 20, 12, 4 00107 }; 00108 00109 /* number left rotations of pc1 */ 00110 static const char totrot[] = { 00111 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 00112 }; 00113 00114 /* permuted choice key (table) */ 00115 static const char pc2[] = { 00116 14, 17, 11, 24, 1, 5, 00117 3, 28, 15, 6, 21, 10, 00118 23, 19, 12, 4, 26, 8, 00119 16, 7, 27, 20, 13, 2, 00120 41, 52, 31, 37, 47, 55, 00121 30, 40, 51, 45, 33, 48, 00122 44, 49, 39, 56, 34, 53, 00123 46, 42, 50, 36, 29, 32 00124 }; 00125 00126 /* The (in)famous S-boxes */ 00127 static const char si[8][64] = { 00128 /* S1 */ 00129 {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 00130 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 00131 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 00132 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, 00133 00134 /* S2 */ 00135 {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 00136 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 00137 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 00138 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, 00139 00140 /* S3 */ 00141 {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 00142 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 00143 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 00144 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, 00145 00146 /* S4 */ 00147 {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 00148 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 00149 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 00150 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, 00151 00152 /* S5 */ 00153 {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 00154 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 00155 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 00156 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, 00157 00158 /* S6 */ 00159 {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 00160 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 00161 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 00162 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, 00163 00164 /* S7 */ 00165 {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 00166 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 00167 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 00168 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, 00169 00170 /* S8 */ 00171 {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 00172 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 00173 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 00174 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}, 00175 00176 }; 00177 00178 /* 32-bit permutation function P used on the output of the S-boxes */ 00179 static const char p32i[] = { 00180 16, 7, 20, 21, 00181 29, 12, 28, 17, 00182 1, 15, 23, 26, 00183 5, 18, 31, 10, 00184 2, 8, 24, 14, 00185 32, 27, 3, 9, 00186 19, 13, 30, 6, 00187 22, 11, 4, 25 00188 }; 00189 00190 /* End of DES-defined tables */ 00191 00192 /* Lookup tables initialized once only at startup by desinit() */ 00193 00194 /* bit 0 is left-most in byte */ 00195 static const int bytebit[] = { 00196 0200, 0100, 040, 020, 010, 04, 02, 01 00197 }; 00198 00199 static const int nibblebit[] = { 00200 010, 04, 02, 01 00201 }; 00202 00203 /* Allocate space and initialize DES lookup arrays 00204 * mode == 0: standard Data Encryption Algorithm 00205 */ 00206 static int 00207 desinit (DES_KEY * key) 00208 { 00209 00210 spinit (key); 00211 perminit_ip (key); 00212 perminit_fp (key); 00213 00214 return 0; 00215 } 00216 00217 00218 /* Set key (initialize key schedule array) */ 00219 int 00220 ntlm_des_set_key (DES_KEY * dkey, char *user_key, int /*len*/) 00221 { 00222 char pc1m[56]; /* place to modify pc1 into */ 00223 char pcr[56]; /* place to rotate pc1 into */ 00224 int i, j, l; 00225 int m; 00226 00227 memset(dkey, 0, sizeof (DES_KEY)); 00228 desinit (dkey); 00229 00230 /* Clear key schedule */ 00231 00232 00233 for (j = 0; j < 56; ++j) 00234 { /* convert pc1 to bits of key */ 00235 l = pc1[j] - 1; /* integer bit location */ 00236 m = l & 07; /* find bit */ 00237 pc1m[j] = (user_key[l >> 3] & /* find which key byte l is in */ 00238 bytebit[m]) /* and which bit of that byte */ 00239 ? 1 : 0; /* and store 1-bit result */ 00240 00241 } 00242 for (i = 0; i < 16; ++i) 00243 { /* key chunk for each iteration */ 00244 for (j = 0; j < 56; ++j) /* rotate pc1 the right amount */ 00245 pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l - 28]; 00246 /* rotate left and right halves independently */ 00247 for (j = 0; j < 48; ++j) 00248 { /* select bits individually */ 00249 /* check bit that goes to kn[j] */ 00250 if (pcr[pc2[j] - 1]) 00251 { 00252 /* mask it in if it's there */ 00253 l = j % 6; 00254 dkey->kn[i][j / 6] |= bytebit[l] >> 2; 00255 } 00256 } 00257 } 00258 return 0; 00259 } 00260 00261 /* In-place encryption of 64-bit block */ 00262 static void 00263 ntlm_des_encrypt (DES_KEY * key, unsigned char *block) 00264 { 00265 quint32 left, right; 00266 char *knp; 00267 quint32 work[2]; /* Working data storage */ 00268 00269 permute_ip (block, key, (unsigned char *) work); /* Initial Permutation */ 00270 left = qFromBigEndian(work[0]); 00271 right = qFromBigEndian(work[1]); 00272 00273 /* Do the 16 rounds. 00274 * The rounds are numbered from 0 to 15. On even rounds 00275 * the right half is fed to f() and the result exclusive-ORs 00276 * the left half; on odd rounds the reverse is done. 00277 */ 00278 knp = &key->kn[0][0]; 00279 left ^= f (key, right, knp); 00280 knp += 8; 00281 right ^= f (key, left, knp); 00282 knp += 8; 00283 left ^= f (key, right, knp); 00284 knp += 8; 00285 right ^= f (key, left, knp); 00286 knp += 8; 00287 left ^= f (key, right, knp); 00288 knp += 8; 00289 right ^= f (key, left, knp); 00290 knp += 8; 00291 left ^= f (key, right, knp); 00292 knp += 8; 00293 right ^= f (key, left, knp); 00294 knp += 8; 00295 left ^= f (key, right, knp); 00296 knp += 8; 00297 right ^= f (key, left, knp); 00298 knp += 8; 00299 left ^= f (key, right, knp); 00300 knp += 8; 00301 right ^= f (key, left, knp); 00302 knp += 8; 00303 left ^= f (key, right, knp); 00304 knp += 8; 00305 right ^= f (key, left, knp); 00306 knp += 8; 00307 left ^= f (key, right, knp); 00308 knp += 8; 00309 right ^= f (key, left, knp); 00310 00311 /* Left/right half swap, plus byte swap if little-endian */ 00312 work[1] = qToBigEndian( left ); 00313 work[0] = qToBigEndian( right ); 00314 00315 permute_fp ((unsigned char *) work, key, block); /* Inverse initial permutation */ 00316 } 00317 00318 /* Permute inblock with perm */ 00319 static void 00320 permute_ip (unsigned char *inblock, DES_KEY * key, unsigned char *outblock) 00321 { 00322 unsigned char *ib, *ob; /* ptr to input or output block */ 00323 char *p, *q; 00324 int j; 00325 00326 /* Clear output block */ 00327 memset(outblock, 0, 8); 00328 00329 ib = inblock; 00330 for (j = 0; j < 16; j += 2, ++ib) 00331 { /* for each input nibble */ 00332 ob = outblock; 00333 p = key->iperm[j][(*ib >> 4) & 0xf]; 00334 q = key->iperm[j + 1][*ib & 0xf]; 00335 /* and each output byte, OR the masks together */ 00336 *ob++ |= *p++ | *q++; 00337 *ob++ |= *p++ | *q++; 00338 *ob++ |= *p++ | *q++; 00339 *ob++ |= *p++ | *q++; 00340 *ob++ |= *p++ | *q++; 00341 *ob++ |= *p++ | *q++; 00342 *ob++ |= *p++ | *q++; 00343 *ob++ |= *p++ | *q++; 00344 } 00345 } 00346 00347 /* Permute inblock with perm */ 00348 static void 00349 permute_fp (unsigned char *inblock, DES_KEY * key, unsigned char *outblock) 00350 { 00351 unsigned char *ib, *ob; /* ptr to input or output block */ 00352 char *p, *q; 00353 int j; 00354 00355 /* Clear output block */ 00356 memset(outblock, 0, 8); 00357 00358 ib = inblock; 00359 for (j = 0; j < 16; j += 2, ++ib) 00360 { /* for each input nibble */ 00361 ob = outblock; 00362 p = key->fperm[j][(*ib >> 4) & 0xf]; 00363 q = key->fperm[j + 1][*ib & 0xf]; 00364 /* and each output byte, OR the masks together */ 00365 *ob++ |= *p++ | *q++; 00366 *ob++ |= *p++ | *q++; 00367 *ob++ |= *p++ | *q++; 00368 *ob++ |= *p++ | *q++; 00369 *ob++ |= *p++ | *q++; 00370 *ob++ |= *p++ | *q++; 00371 *ob++ |= *p++ | *q++; 00372 *ob++ |= *p++ | *q++; 00373 } 00374 } 00375 00376 /* The nonlinear function f(r,k), the heart of DES */ 00377 static quint32 00378 f (DES_KEY * key, quint32 r, char *subkey) 00379 { 00380 quint32 *spp; 00381 quint32 rval, rt; 00382 int er; 00383 00384 #ifdef TRACE 00385 printf ("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ", 00386 r, 00387 subkey[0], subkey[1], subkey[2], 00388 subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]); 00389 #endif 00390 /* Run E(R) ^ K through the combined S & P boxes. 00391 * This code takes advantage of a convenient regularity in 00392 * E, namely that each group of 6 bits in E(R) feeding 00393 * a single S-box is a contiguous segment of R. 00394 */ 00395 subkey += 7; 00396 00397 /* Compute E(R) for each block of 6 bits, and run thru boxes */ 00398 er = ((int) r << 1) | ((r & 0x80000000) ? 1 : 0); 00399 spp = &key->sp[7][0]; 00400 rval = spp[(er ^ *subkey--) & 0x3f]; 00401 spp -= 64; 00402 rt = (quint32) r >> 3; 00403 rval |= spp[((int) rt ^ *subkey--) & 0x3f]; 00404 spp -= 64; 00405 rt >>= 4; 00406 rval |= spp[((int) rt ^ *subkey--) & 0x3f]; 00407 spp -= 64; 00408 rt >>= 4; 00409 rval |= spp[((int) rt ^ *subkey--) & 0x3f]; 00410 spp -= 64; 00411 rt >>= 4; 00412 rval |= spp[((int) rt ^ *subkey--) & 0x3f]; 00413 spp -= 64; 00414 rt >>= 4; 00415 rval |= spp[((int) rt ^ *subkey--) & 0x3f]; 00416 spp -= 64; 00417 rt >>= 4; 00418 rval |= spp[((int) rt ^ *subkey--) & 0x3f]; 00419 spp -= 64; 00420 rt >>= 4; 00421 rt |= (r & 1) << 5; 00422 rval |= spp[((int) rt ^ *subkey) & 0x3f]; 00423 #ifdef TRACE 00424 printf (" %08lx\n", rval); 00425 #endif 00426 return rval; 00427 } 00428 00429 /* initialize a perm array */ 00430 static void 00431 perminit_ip (DES_KEY * key) 00432 { 00433 int l, j, k; 00434 int i, m; 00435 00436 /* Clear the permutation array */ 00437 memset(key->iperm, 0, 16 * 16 * 8); 00438 00439 for (i = 0; i < 16; ++i) /* each input nibble position */ 00440 for (j = 0; j < 16; ++j) /* each possible input nibble */ 00441 for (k = 0; k < 64; ++k) 00442 { /* each output bit position */ 00443 l = ip[k] - 1; /* where does this bit come from */ 00444 if ((l >> 2) != i) /* does it come from input posn? */ 00445 continue; /* if not, bit k is 0 */ 00446 if (!(j & nibblebit[l & 3])) 00447 continue; /* any such bit in input? */ 00448 m = k & 07; /* which bit is this in the byte */ 00449 key->iperm[i][j][k >> 3] |= bytebit[m]; 00450 } 00451 } 00452 00453 static void 00454 perminit_fp (DES_KEY * key) 00455 { 00456 int l, j, k; 00457 int i, m; 00458 00459 /* Clear the permutation array */ 00460 memset(key->fperm, 0, 16 * 16 * 8); 00461 00462 for (i = 0; i < 16; ++i) /* each input nibble position */ 00463 for (j = 0; j < 16; ++j) /* each possible input nibble */ 00464 for (k = 0; k < 64; ++k) 00465 { /* each output bit position */ 00466 l = fp[k] - 1; /* where does this bit come from */ 00467 if ((l >> 2) != i) /* does it come from input posn? */ 00468 continue; /* if not, bit k is 0 */ 00469 if (!(j & nibblebit[l & 3])) 00470 continue; /* any such bit in input? */ 00471 m = k & 07; /* which bit is this in the byte */ 00472 key->fperm[i][j][k >> 3] |= bytebit[m]; 00473 } 00474 } 00475 00476 /* Initialize the lookup table for the combined S and P boxes */ 00477 static void 00478 spinit (DES_KEY * key) 00479 { 00480 char pbox[32]; 00481 int p, i, s, j, rowcol; 00482 quint32 val; 00483 00484 /* Compute pbox, the inverse of p32i. 00485 * This is easier to work with 00486 */ 00487 for (p = 0; p < 32; ++p) 00488 { 00489 for (i = 0; i < 32; ++i) 00490 { 00491 if (p32i[i] - 1 == p) 00492 { 00493 pbox[p] = i; 00494 break; 00495 } 00496 } 00497 } 00498 for (s = 0; s < 8; ++s) 00499 { /* For each S-box */ 00500 for (i = 0; i < 64; ++i) 00501 { /* For each possible input */ 00502 val = 0; 00503 /* The row number is formed from the first and last 00504 * bits; the column number is from the middle 4 00505 */ 00506 rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf); 00507 for (j = 0; j < 4; j++) 00508 { /* For each output bit */ 00509 if (si[s][rowcol] & (8 >> j)) 00510 { 00511 val |= 1L << (31 - pbox[4 * s + j]); 00512 } 00513 } 00514 key->sp[s][i] = val; 00515 } 00516 } 00517 } 00518 00519 int 00520 ntlm_des_ecb_encrypt (const void *plaintext, int len, DES_KEY * akey, 00521 unsigned char output[8]) 00522 { 00523 int j; 00524 const unsigned char *plain = (const unsigned char *) plaintext; 00525 00526 for (j = 0; j < len / 8; ++j) 00527 { 00528 memcpy (&output[j * 8], &plain[j * 8], 8); 00529 ntlm_des_encrypt (akey, &output[j * 8]); 00530 } 00531 00532 if (j == 0 && len != 0) 00533 return -1; /* no blocks were encrypted */ 00534 return 0; 00535 }
KDE 4.6 API Reference