File indexing completed on 2024-04-28 11:41:49
0001 /* 0002 Software DES functions 0003 0004 SPDX-FileCopyrightText: 1988-1991 Phil Karn <karn@ka9q.net> 0005 SPDX-FileCopyrightText: 2003 Nikos Mavroyanopoulos <nmav@hellug.gr> 0006 0007 Taken from libmcrypt (http://mcrypt.hellug.gr/lib/index.html). 0008 0009 SPDX-License-Identifier: LGPL-2.1-only 0010 */ 0011 0012 /* Software DES functions 0013 * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from 0014 * the 1977 public-domain program by Jim Gillogly 0015 * Modified for additional speed - 6 December 1988 Phil Karn 0016 * Modified for parameterized key schedules - Jan 1991 Phil Karn 0017 * Callers now allocate a key schedule as follows: 0018 * kn = (char (*)[8])malloc(sizeof(char) * 8 * 16); 0019 * or 0020 * char kn[16][8]; 0021 */ 0022 0023 /* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos 0024 * All modifications are placed under the license of libmcrypt. 0025 */ 0026 0027 #include "des.h" 0028 0029 #include <limits> // This needs to be first with GCC 11 0030 0031 #include <qendian.h> 0032 #include <string.h> 0033 0034 static void permute_ip(unsigned char *inblock, DES_KEY *key, unsigned char *outblock); 0035 static void permute_fp(unsigned char *inblock, DES_KEY *key, unsigned char *outblock); 0036 static void perminit_ip(DES_KEY *key); 0037 static void spinit(DES_KEY *key); 0038 static void perminit_fp(DES_KEY *key); 0039 static quint32 f(DES_KEY *key, quint32 r, char *subkey); 0040 0041 /* Tables defined in the Data Encryption Standard documents */ 0042 0043 /* initial permutation IP */ 0044 static const char ip[] = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 0045 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7}; 0046 0047 /* final permutation IP^-1 */ 0048 static const char fp[] = {40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 0049 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25}; 0050 0051 /* expansion operation matrix 0052 * This is for reference only; it is unused in the code 0053 * as the f() function performs it implicitly for speed 0054 */ 0055 #ifdef notdef 0056 static const char ei[] = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 0057 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; 0058 #endif 0059 0060 /* permuted choice table (key) */ 0061 static const char pc1[] = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 0062 0063 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; 0064 0065 /* number left rotations of pc1 */ 0066 static const char totrot[] = {1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28}; 0067 0068 /* permuted choice key (table) */ 0069 static const char pc2[] = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 0070 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}; 0071 0072 /* The (in)famous S-boxes */ 0073 static const char si[8][64] = { 0074 /* S1 */ 0075 {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 0076 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, 0077 0078 /* S2 */ 0079 {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 0080 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, 0081 0082 /* S3 */ 0083 {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 0084 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, 0085 0086 /* S4 */ 0087 {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 0088 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, 0089 0090 /* S5 */ 0091 {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 0092 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, 0093 0094 /* S6 */ 0095 {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 0096 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, 0097 0098 /* S7 */ 0099 {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 0100 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, 0101 0102 /* S8 */ 0103 {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 0104 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}, 0105 0106 }; 0107 0108 /* 32-bit permutation function P used on the output of the S-boxes */ 0109 static const char p32i[] = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25}; 0110 0111 /* End of DES-defined tables */ 0112 0113 /* Lookup tables initialized once only at startup by desinit() */ 0114 0115 /* bit 0 is left-most in byte */ 0116 static const int bytebit[] = {0200, 0100, 040, 020, 010, 04, 02, 01}; 0117 0118 static const int nibblebit[] = {010, 04, 02, 01}; 0119 0120 /* Allocate space and initialize DES lookup arrays 0121 * mode == 0: standard Data Encryption Algorithm 0122 */ 0123 static int desinit(DES_KEY *key) 0124 { 0125 spinit(key); 0126 perminit_ip(key); 0127 perminit_fp(key); 0128 0129 return 0; 0130 } 0131 0132 /* Set key (initialize key schedule array) */ 0133 int ntlm_des_set_key(DES_KEY *dkey, char *user_key, int /*len*/) 0134 { 0135 char pc1m[56]; /* place to modify pc1 into */ 0136 char pcr[56]; /* place to rotate pc1 into */ 0137 int i; 0138 int j; 0139 int l; 0140 int m; 0141 0142 memset(dkey, 0, sizeof(DES_KEY)); 0143 desinit(dkey); 0144 0145 /* Clear key schedule */ 0146 0147 for (j = 0; j < 56; ++j) { 0148 /* convert pc1 to bits of key */ 0149 l = pc1[j] - 1; /* integer bit location */ 0150 m = l & 07; /* find bit */ 0151 pc1m[j] = (user_key[l >> 3] & /* find which key byte l is in */ 0152 bytebit[m]) /* and which bit of that byte */ 0153 ? 1 0154 : 0; /* and store 1-bit result */ 0155 } 0156 for (i = 0; i < 16; ++i) { 0157 /* key chunk for each iteration */ 0158 for (j = 0; j < 56; ++j) { /* rotate pc1 the right amount */ 0159 pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l - 28]; 0160 } 0161 /* rotate left and right halves independently */ 0162 for (j = 0; j < 48; ++j) { 0163 /* select bits individually */ 0164 /* check bit that goes to kn[j] */ 0165 if (pcr[pc2[j] - 1]) { 0166 /* mask it in if it's there */ 0167 l = j % 6; 0168 dkey->kn[i][j / 6] |= bytebit[l] >> 2; 0169 } 0170 } 0171 } 0172 return 0; 0173 } 0174 0175 /* In-place encryption of 64-bit block */ 0176 static void ntlm_des_encrypt(DES_KEY *key, unsigned char *block) 0177 { 0178 quint32 left; 0179 quint32 right; 0180 char *knp; 0181 quint32 work[2]; /* Working data storage */ 0182 0183 permute_ip(block, key, (unsigned char *)work); /* Initial Permutation */ 0184 left = qFromBigEndian(work[0]); 0185 right = qFromBigEndian(work[1]); 0186 0187 /* Do the 16 rounds. 0188 * The rounds are numbered from 0 to 15. On even rounds 0189 * the right half is fed to f() and the result exclusive-ORs 0190 * the left half; on odd rounds the reverse is done. 0191 */ 0192 knp = &key->kn[0][0]; 0193 left ^= f(key, right, knp); 0194 knp += 8; 0195 right ^= f(key, left, knp); 0196 knp += 8; 0197 left ^= f(key, right, knp); 0198 knp += 8; 0199 right ^= f(key, left, knp); 0200 knp += 8; 0201 left ^= f(key, right, knp); 0202 knp += 8; 0203 right ^= f(key, left, knp); 0204 knp += 8; 0205 left ^= f(key, right, knp); 0206 knp += 8; 0207 right ^= f(key, left, knp); 0208 knp += 8; 0209 left ^= f(key, right, knp); 0210 knp += 8; 0211 right ^= f(key, left, knp); 0212 knp += 8; 0213 left ^= f(key, right, knp); 0214 knp += 8; 0215 right ^= f(key, left, knp); 0216 knp += 8; 0217 left ^= f(key, right, knp); 0218 knp += 8; 0219 right ^= f(key, left, knp); 0220 knp += 8; 0221 left ^= f(key, right, knp); 0222 knp += 8; 0223 right ^= f(key, left, knp); 0224 0225 /* Left/right half swap, plus byte swap if little-endian */ 0226 work[1] = qToBigEndian(left); 0227 work[0] = qToBigEndian(right); 0228 0229 permute_fp((unsigned char *)work, key, block); /* Inverse initial permutation */ 0230 } 0231 0232 /* Permute inblock with perm */ 0233 static void permute_ip(unsigned char *inblock, DES_KEY *key, unsigned char *outblock) 0234 { 0235 unsigned char *ib; 0236 unsigned char *ob; /* ptr to input or output block */ 0237 char *p; 0238 char *q; 0239 int j; 0240 0241 /* Clear output block */ 0242 memset(outblock, 0, 8); 0243 0244 ib = inblock; 0245 for (j = 0; j < 16; j += 2, ++ib) { 0246 /* for each input nibble */ 0247 ob = outblock; 0248 p = key->iperm[j][(*ib >> 4) & 0xf]; 0249 q = key->iperm[j + 1][*ib & 0xf]; 0250 /* and each output byte, OR the masks together */ 0251 *ob++ |= *p++ | *q++; 0252 *ob++ |= *p++ | *q++; 0253 *ob++ |= *p++ | *q++; 0254 *ob++ |= *p++ | *q++; 0255 *ob++ |= *p++ | *q++; 0256 *ob++ |= *p++ | *q++; 0257 *ob++ |= *p++ | *q++; 0258 *ob++ |= *p++ | *q++; 0259 } 0260 } 0261 0262 /* Permute inblock with perm */ 0263 static void permute_fp(unsigned char *inblock, DES_KEY *key, unsigned char *outblock) 0264 { 0265 unsigned char *ib; 0266 unsigned char *ob; /* ptr to input or output block */ 0267 char *p; 0268 char *q; 0269 int j; 0270 0271 /* Clear output block */ 0272 memset(outblock, 0, 8); 0273 0274 ib = inblock; 0275 for (j = 0; j < 16; j += 2, ++ib) { 0276 /* for each input nibble */ 0277 ob = outblock; 0278 p = key->fperm[j][(*ib >> 4) & 0xf]; 0279 q = key->fperm[j + 1][*ib & 0xf]; 0280 /* and each output byte, OR the masks together */ 0281 *ob++ |= *p++ | *q++; 0282 *ob++ |= *p++ | *q++; 0283 *ob++ |= *p++ | *q++; 0284 *ob++ |= *p++ | *q++; 0285 *ob++ |= *p++ | *q++; 0286 *ob++ |= *p++ | *q++; 0287 *ob++ |= *p++ | *q++; 0288 *ob++ |= *p++ | *q++; 0289 } 0290 } 0291 0292 /* The nonlinear function f(r,k), the heart of DES */ 0293 static quint32 f(DES_KEY *key, quint32 r, char *subkey) 0294 { 0295 quint32 *spp; 0296 quint32 rval; 0297 quint32 rt; 0298 int er; 0299 0300 #ifdef TRACE 0301 printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ", r, subkey[0], subkey[1], subkey[2], subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]); 0302 #endif 0303 /* Run E(R) ^ K through the combined S & P boxes. 0304 * This code takes advantage of a convenient regularity in 0305 * E, namely that each group of 6 bits in E(R) feeding 0306 * a single S-box is a contiguous segment of R. 0307 */ 0308 subkey += 7; 0309 0310 /* Compute E(R) for each block of 6 bits, and run thru boxes */ 0311 er = ((int)r << 1) | ((r & 0x80000000) ? 1 : 0); 0312 spp = &key->sp[7][0]; 0313 rval = spp[(er ^ *subkey--) & 0x3f]; 0314 spp -= 64; 0315 rt = (quint32)r >> 3; 0316 rval |= spp[((int)rt ^ *subkey--) & 0x3f]; 0317 spp -= 64; 0318 rt >>= 4; 0319 rval |= spp[((int)rt ^ *subkey--) & 0x3f]; 0320 spp -= 64; 0321 rt >>= 4; 0322 rval |= spp[((int)rt ^ *subkey--) & 0x3f]; 0323 spp -= 64; 0324 rt >>= 4; 0325 rval |= spp[((int)rt ^ *subkey--) & 0x3f]; 0326 spp -= 64; 0327 rt >>= 4; 0328 rval |= spp[((int)rt ^ *subkey--) & 0x3f]; 0329 spp -= 64; 0330 rt >>= 4; 0331 rval |= spp[((int)rt ^ *subkey--) & 0x3f]; 0332 spp -= 64; 0333 rt >>= 4; 0334 rt |= (r & 1) << 5; 0335 rval |= spp[((int)rt ^ *subkey) & 0x3f]; 0336 #ifdef TRACE 0337 printf(" %08lx\n", rval); 0338 #endif 0339 return rval; 0340 } 0341 0342 /* initialize a perm array */ 0343 static void perminit_ip(DES_KEY *key) 0344 { 0345 int l; 0346 int j; 0347 int k; 0348 int i; 0349 int m; 0350 0351 /* Clear the permutation array */ 0352 memset(key->iperm, 0, 16 * 16 * 8); 0353 0354 for (i = 0; i < 16; ++i) { /* each input nibble position */ 0355 for (j = 0; j < 16; ++j) { /* each possible input nibble */ 0356 for (k = 0; k < 64; ++k) { 0357 /* each output bit position */ 0358 l = ip[k] - 1; /* where does this bit come from */ 0359 if ((l >> 2) != i) { /* does it come from input posn? */ 0360 continue; /* if not, bit k is 0 */ 0361 } 0362 if (!(j & nibblebit[l & 3])) { 0363 continue; /* any such bit in input? */ 0364 } 0365 m = k & 07; /* which bit is this in the byte */ 0366 key->iperm[i][j][k >> 3] |= bytebit[m]; 0367 } 0368 } 0369 } 0370 } 0371 0372 static void perminit_fp(DES_KEY *key) 0373 { 0374 int l; 0375 int j; 0376 int k; 0377 int i; 0378 int m; 0379 0380 /* Clear the permutation array */ 0381 memset(key->fperm, 0, 16 * 16 * 8); 0382 0383 for (i = 0; i < 16; ++i) { /* each input nibble position */ 0384 for (j = 0; j < 16; ++j) { /* each possible input nibble */ 0385 for (k = 0; k < 64; ++k) { 0386 /* each output bit position */ 0387 l = fp[k] - 1; /* where does this bit come from */ 0388 if ((l >> 2) != i) { /* does it come from input posn? */ 0389 continue; /* if not, bit k is 0 */ 0390 } 0391 if (!(j & nibblebit[l & 3])) { 0392 continue; /* any such bit in input? */ 0393 } 0394 m = k & 07; /* which bit is this in the byte */ 0395 key->fperm[i][j][k >> 3] |= bytebit[m]; 0396 } 0397 } 0398 } 0399 } 0400 0401 /* Initialize the lookup table for the combined S and P boxes */ 0402 static void spinit(DES_KEY *key) 0403 { 0404 char pbox[32]; 0405 int p; 0406 int i; 0407 int s; 0408 int j; 0409 int rowcol; 0410 quint32 val; 0411 0412 /* Compute pbox, the inverse of p32i. 0413 * This is easier to work with 0414 */ 0415 for (p = 0; p < 32; ++p) { 0416 for (i = 0; i < 32; ++i) { 0417 if (p32i[i] - 1 == p) { 0418 pbox[p] = i; 0419 break; 0420 } 0421 } 0422 } 0423 for (s = 0; s < 8; ++s) { 0424 /* For each S-box */ 0425 for (i = 0; i < 64; ++i) { 0426 /* For each possible input */ 0427 val = 0; 0428 /* The row number is formed from the first and last 0429 * bits; the column number is from the middle 4 0430 */ 0431 rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf); 0432 for (j = 0; j < 4; j++) { 0433 /* For each output bit */ 0434 if (si[s][rowcol] & (8 >> j)) { 0435 val |= 1L << (31 - pbox[4 * s + j]); 0436 } 0437 } 0438 key->sp[s][i] = val; 0439 } 0440 } 0441 } 0442 0443 int ntlm_des_ecb_encrypt(const void *plaintext, int len, DES_KEY *akey, unsigned char output[8]) 0444 { 0445 int j; 0446 const unsigned char *plain = (const unsigned char *)plaintext; 0447 0448 for (j = 0; j < len / 8; ++j) { 0449 memcpy(&output[j * 8], &plain[j * 8], 8); 0450 ntlm_des_encrypt(akey, &output[j * 8]); 0451 } 0452 0453 if (j == 0 && len != 0) { 0454 return -1; /* no blocks were encrypted */ 0455 } 0456 return 0; 0457 }