00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "includes.h"
00018
00019 #include "common.h"
00020 #include "crypto.h"
00021 #include "des_i.h"
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00044 #define ROLc(x, y) \
00045 ((((unsigned long) (x) << (unsigned long) ((y) & 31)) | \
00046 (((unsigned long) (x) & 0xFFFFFFFFUL) >> \
00047 (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
00048 #define RORc(x, y) \
00049 (((((unsigned long) (x) & 0xFFFFFFFFUL) >> \
00050 (unsigned long) ((y) & 31)) | \
00051 ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & \
00052 0xFFFFFFFFUL)
00053
00054
00055 static const u32 bytebit[8] =
00056 {
00057 0200, 0100, 040, 020, 010, 04, 02, 01
00058 };
00059
00060 static const u32 bigbyte[24] =
00061 {
00062 0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL,
00063 0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL,
00064 0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL,
00065 0x800UL, 0x400UL, 0x200UL, 0x100UL,
00066 0x80UL, 0x40UL, 0x20UL, 0x10UL,
00067 0x8UL, 0x4UL, 0x2UL, 0x1L
00068 };
00069
00070
00071
00072 static const u8 pc1[56] = {
00073 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
00074 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
00075 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
00076 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
00077 };
00078
00079 static const u8 totrot[16] = {
00080 1, 2, 4, 6,
00081 8, 10, 12, 14,
00082 15, 17, 19, 21,
00083 23, 25, 27, 28
00084 };
00085
00086 static const u8 pc2[48] = {
00087 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
00088 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
00089 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
00090 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
00091 };
00092
00093
00094 static const u32 SP1[64] =
00095 {
00096 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL,
00097 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL,
00098 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL,
00099 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL,
00100 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL,
00101 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL,
00102 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL,
00103 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL,
00104 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL,
00105 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL,
00106 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL,
00107 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL,
00108 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL,
00109 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL,
00110 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL,
00111 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL
00112 };
00113
00114 static const u32 SP2[64] =
00115 {
00116 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL,
00117 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL,
00118 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL,
00119 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL,
00120 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL,
00121 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL,
00122 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL,
00123 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL,
00124 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL,
00125 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL,
00126 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL,
00127 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL,
00128 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL,
00129 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL,
00130 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL,
00131 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL
00132 };
00133
00134 static const u32 SP3[64] =
00135 {
00136 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL,
00137 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL,
00138 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL,
00139 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL,
00140 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL,
00141 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL,
00142 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL,
00143 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL,
00144 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL,
00145 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL,
00146 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL,
00147 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL,
00148 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL,
00149 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL,
00150 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL,
00151 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL
00152 };
00153
00154 static const u32 SP4[64] =
00155 {
00156 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
00157 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL,
00158 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL,
00159 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL,
00160 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL,
00161 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL,
00162 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL,
00163 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL,
00164 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL,
00165 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL,
00166 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL,
00167 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL,
00168 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL,
00169 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL,
00170 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL,
00171 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL
00172 };
00173
00174 static const u32 SP5[64] =
00175 {
00176 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL,
00177 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL,
00178 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL,
00179 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL,
00180 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL,
00181 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL,
00182 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL,
00183 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL,
00184 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL,
00185 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL,
00186 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL,
00187 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL,
00188 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL,
00189 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL,
00190 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL,
00191 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL
00192 };
00193
00194 static const u32 SP6[64] =
00195 {
00196 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL,
00197 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL,
00198 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL,
00199 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
00200 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL,
00201 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL,
00202 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL,
00203 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL,
00204 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL,
00205 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL,
00206 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL,
00207 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL,
00208 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL,
00209 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL,
00210 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL,
00211 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL
00212 };
00213
00214 static const u32 SP7[64] =
00215 {
00216 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL,
00217 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL,
00218 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL,
00219 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL,
00220 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL,
00221 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL,
00222 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL,
00223 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL,
00224 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL,
00225 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL,
00226 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL,
00227 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL,
00228 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL,
00229 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL,
00230 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL,
00231 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL
00232 };
00233
00234 static const u32 SP8[64] =
00235 {
00236 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL,
00237 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL,
00238 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL,
00239 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL,
00240 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL,
00241 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL,
00242 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL,
00243 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL,
00244 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL,
00245 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL,
00246 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL,
00247 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL,
00248 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL,
00249 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL,
00250 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL,
00251 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL
00252 };
00253
00254
00255 static void cookey(const u32 *raw1, u32 *keyout)
00256 {
00257 u32 *cook;
00258 const u32 *raw0;
00259 u32 dough[32];
00260 int i;
00261
00262 cook = dough;
00263 for (i = 0; i < 16; i++, raw1++) {
00264 raw0 = raw1++;
00265 *cook = (*raw0 & 0x00fc0000L) << 6;
00266 *cook |= (*raw0 & 0x00000fc0L) << 10;
00267 *cook |= (*raw1 & 0x00fc0000L) >> 10;
00268 *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
00269 *cook = (*raw0 & 0x0003f000L) << 12;
00270 *cook |= (*raw0 & 0x0000003fL) << 16;
00271 *cook |= (*raw1 & 0x0003f000L) >> 4;
00272 *cook++ |= (*raw1 & 0x0000003fL);
00273 }
00274
00275 os_memcpy(keyout, dough, sizeof(dough));
00276 }
00277
00278
00279 static void deskey(const u8 *key, int decrypt, u32 *keyout)
00280 {
00281 u32 i, j, l, m, n, kn[32];
00282 u8 pc1m[56], pcr[56];
00283
00284 for (j = 0; j < 56; j++) {
00285 l = (u32) pc1[j];
00286 m = l & 7;
00287 pc1m[j] = (u8)
00288 ((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0);
00289 }
00290
00291 for (i = 0; i < 16; i++) {
00292 if (decrypt)
00293 m = (15 - i) << 1;
00294 else
00295 m = i << 1;
00296 n = m + 1;
00297 kn[m] = kn[n] = 0L;
00298 for (j = 0; j < 28; j++) {
00299 l = j + (u32) totrot[i];
00300 if (l < 28)
00301 pcr[j] = pc1m[l];
00302 else
00303 pcr[j] = pc1m[l - 28];
00304 }
00305 for (; j < 56; j++) {
00306 l = j + (u32) totrot[i];
00307 if (l < 56)
00308 pcr[j] = pc1m[l];
00309 else
00310 pcr[j] = pc1m[l - 28];
00311 }
00312 for (j = 0; j < 24; j++) {
00313 if ((int) pcr[(int) pc2[j]] != 0)
00314 kn[m] |= bigbyte[j];
00315 if ((int) pcr[(int) pc2[j + 24]] != 0)
00316 kn[n] |= bigbyte[j];
00317 }
00318 }
00319
00320 cookey(kn, keyout);
00321 }
00322
00323
00324 static void desfunc(u32 *block, const u32 *keys)
00325 {
00326 u32 work, right, leftt;
00327 int cur_round;
00328
00329 leftt = block[0];
00330 right = block[1];
00331
00332 work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
00333 right ^= work;
00334 leftt ^= (work << 4);
00335
00336 work = ((leftt >> 16) ^ right) & 0x0000ffffL;
00337 right ^= work;
00338 leftt ^= (work << 16);
00339
00340 work = ((right >> 2) ^ leftt) & 0x33333333L;
00341 leftt ^= work;
00342 right ^= (work << 2);
00343
00344 work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
00345 leftt ^= work;
00346 right ^= (work << 8);
00347
00348 right = ROLc(right, 1);
00349 work = (leftt ^ right) & 0xaaaaaaaaL;
00350
00351 leftt ^= work;
00352 right ^= work;
00353 leftt = ROLc(leftt, 1);
00354
00355 for (cur_round = 0; cur_round < 8; cur_round++) {
00356 work = RORc(right, 4) ^ *keys++;
00357 leftt ^= SP7[work & 0x3fL]
00358 ^ SP5[(work >> 8) & 0x3fL]
00359 ^ SP3[(work >> 16) & 0x3fL]
00360 ^ SP1[(work >> 24) & 0x3fL];
00361 work = right ^ *keys++;
00362 leftt ^= SP8[ work & 0x3fL]
00363 ^ SP6[(work >> 8) & 0x3fL]
00364 ^ SP4[(work >> 16) & 0x3fL]
00365 ^ SP2[(work >> 24) & 0x3fL];
00366
00367 work = RORc(leftt, 4) ^ *keys++;
00368 right ^= SP7[ work & 0x3fL]
00369 ^ SP5[(work >> 8) & 0x3fL]
00370 ^ SP3[(work >> 16) & 0x3fL]
00371 ^ SP1[(work >> 24) & 0x3fL];
00372 work = leftt ^ *keys++;
00373 right ^= SP8[ work & 0x3fL]
00374 ^ SP6[(work >> 8) & 0x3fL]
00375 ^ SP4[(work >> 16) & 0x3fL]
00376 ^ SP2[(work >> 24) & 0x3fL];
00377 }
00378
00379 right = RORc(right, 1);
00380 work = (leftt ^ right) & 0xaaaaaaaaL;
00381 leftt ^= work;
00382 right ^= work;
00383 leftt = RORc(leftt, 1);
00384 work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
00385 right ^= work;
00386 leftt ^= (work << 8);
00387
00388 work = ((leftt >> 2) ^ right) & 0x33333333L;
00389 right ^= work;
00390 leftt ^= (work << 2);
00391 work = ((right >> 16) ^ leftt) & 0x0000ffffL;
00392 leftt ^= work;
00393 right ^= (work << 16);
00394 work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
00395 leftt ^= work;
00396 right ^= (work << 4);
00397
00398 block[0] = right;
00399 block[1] = leftt;
00400 }
00401
00402
00403
00404
00405 void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
00406 {
00407 u8 pkey[8], next, tmp;
00408 int i;
00409 u32 ek[32], work[2];
00410
00411
00412 next = 0;
00413 for (i = 0; i < 7; i++) {
00414 tmp = key[i];
00415 pkey[i] = (tmp >> i) | next | 1;
00416 next = tmp << (7 - i);
00417 }
00418 pkey[i] = next | 1;
00419
00420 deskey(pkey, 0, ek);
00421
00422 work[0] = WPA_GET_BE32(clear);
00423 work[1] = WPA_GET_BE32(clear + 4);
00424 desfunc(work, ek);
00425 WPA_PUT_BE32(cypher, work[0]);
00426 WPA_PUT_BE32(cypher + 4, work[1]);
00427
00428 os_memset(pkey, 0, sizeof(pkey));
00429 os_memset(ek, 0, sizeof(ek));
00430 }
00431
00432
00433 void des_key_setup(const u8 *key, u32 *ek, u32 *dk)
00434 {
00435 deskey(key, 0, ek);
00436 deskey(key, 1, dk);
00437 }
00438
00439
00440 void des_block_encrypt(const u8 *plain, const u32 *ek, u8 *crypt)
00441 {
00442 u32 work[2];
00443 work[0] = WPA_GET_BE32(plain);
00444 work[1] = WPA_GET_BE32(plain + 4);
00445 desfunc(work, ek);
00446 WPA_PUT_BE32(crypt, work[0]);
00447 WPA_PUT_BE32(crypt + 4, work[1]);
00448 }
00449
00450
00451 void des_block_decrypt(const u8 *crypt, const u32 *dk, u8 *plain)
00452 {
00453 u32 work[2];
00454 work[0] = WPA_GET_BE32(crypt);
00455 work[1] = WPA_GET_BE32(crypt + 4);
00456 desfunc(work, dk);
00457 WPA_PUT_BE32(plain, work[0]);
00458 WPA_PUT_BE32(plain + 4, work[1]);
00459 }
00460
00461
00462 void des3_key_setup(const u8 *key, struct des3_key_s *dkey)
00463 {
00464 deskey(key, 0, dkey->ek[0]);
00465 deskey(key + 8, 1, dkey->ek[1]);
00466 deskey(key + 16, 0, dkey->ek[2]);
00467
00468 deskey(key, 1, dkey->dk[2]);
00469 deskey(key + 8, 0, dkey->dk[1]);
00470 deskey(key + 16, 1, dkey->dk[0]);
00471 }
00472
00473
00474 void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt)
00475 {
00476 u32 work[2];
00477
00478 work[0] = WPA_GET_BE32(plain);
00479 work[1] = WPA_GET_BE32(plain + 4);
00480 desfunc(work, key->ek[0]);
00481 desfunc(work, key->ek[1]);
00482 desfunc(work, key->ek[2]);
00483 WPA_PUT_BE32(crypt, work[0]);
00484 WPA_PUT_BE32(crypt + 4, work[1]);
00485 }
00486
00487
00488 void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain)
00489 {
00490 u32 work[2];
00491
00492 work[0] = WPA_GET_BE32(crypt);
00493 work[1] = WPA_GET_BE32(crypt + 4);
00494 desfunc(work, key->dk[0]);
00495 desfunc(work, key->dk[1]);
00496 desfunc(work, key->dk[2]);
00497 WPA_PUT_BE32(plain, work[0]);
00498 WPA_PUT_BE32(plain + 4, work[1]);
00499 }