mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1841 lines
57 KiB
1841 lines
57 KiB
//************************************************************************
|
|
// Microsoft Corporation
|
|
// Copyright(c) Microsoft Corp., 1990-1992
|
|
//
|
|
//
|
|
// Revision history:
|
|
// 5/5/94 Created gurdeep
|
|
//
|
|
//************************************************************************
|
|
|
|
//#define COMP_12K
|
|
|
|
#include "wan.h"
|
|
|
|
#define __FILE_SIG__ COMPRESS_FILESIG
|
|
|
|
//#define DEBUG
|
|
CONST
|
|
unsigned long lookup_array1[256] = {
|
|
0, 10276755, 20553510, 30830265,
|
|
41107020, 51383775, 61660530, 71937285,
|
|
82214040, 92490795, 102767550, 113044305,
|
|
123321060, 133597815, 143874570, 154151325,
|
|
164428080, 174704835, 184981590, 195258345,
|
|
205535100, 215811855, 226088610, 236365365,
|
|
246642120, 256918875, 267195630, 277472385,
|
|
287749140, 298025895, 308302650, 318579405,
|
|
328856160, 339132915, 349409670, 359686425,
|
|
369963180, 380239935, 390516690, 400793445,
|
|
411070200, 421346955, 431623710, 441900465,
|
|
452177220, 462453975, 472730730, 483007485,
|
|
493284240, 503560995, 513837750, 524114505,
|
|
534391260, 544668015, 554944770, 565221525,
|
|
575498280, 585775035, 596051790, 606328545,
|
|
616605300, 626882055, 637158810, 647435565,
|
|
657712320, 667989075, 678265830, 688542585,
|
|
698819340, 709096095, 719372850, 729649605,
|
|
739926360, 750203115, 760479870, 770756625,
|
|
781033380, 791310135, 801586890, 811863645,
|
|
822140400, 832417155, 842693910, 852970665,
|
|
863247420, 873524175, 883800930, 894077685,
|
|
904354440, 914631195, 924907950, 935184705,
|
|
945461460, 955738215, 966014970, 976291725,
|
|
986568480, 996845235, 1007121990, 1017398745,
|
|
1027675500, 1037952255, 1048229010, 1058505765,
|
|
1068782520, 1079059275, 1089336030, 1099612785,
|
|
1109889540, 1120166295, 1130443050, 1140719805,
|
|
1150996560, 1161273315, 1171550070, 1181826825,
|
|
1192103580, 1202380335, 1212657090, 1222933845,
|
|
1233210600, 1243487355, 1253764110, 1264040865,
|
|
1274317620, 1284594375, 1294871130, 1305147885,
|
|
1315424640, 1325701395, 1335978150, 1346254905,
|
|
1356531660, 1366808415, 1377085170, 1387361925,
|
|
1397638680, 1407915435, 1418192190, 1428468945,
|
|
1438745700, 1449022455, 1459299210, 1469575965,
|
|
1479852720, 1490129475, 1500406230, 1510682985,
|
|
1520959740, 1531236495, 1541513250, 1551790005,
|
|
1562066760, 1572343515, 1582620270, 1592897025,
|
|
1603173780, 1613450535, 1623727290, 1634004045,
|
|
1644280800, 1654557555, 1664834310, 1675111065,
|
|
1685387820, 1695664575, 1705941330, 1716218085,
|
|
1726494840, 1736771595, 1747048350, 1757325105,
|
|
1767601860, 1777878615, 1788155370, 1798432125,
|
|
1808708880, 1818985635, 1829262390, 1839539145,
|
|
1849815900, 1860092655, 1870369410, 1880646165,
|
|
1890922920, 1901199675, 1911476430, 1921753185,
|
|
1932029940, 1942306695, 1952583450, 1962860205,
|
|
1973136960, 1983413715, 1993690470, 2003967225,
|
|
2014243980, 2024520735, 2034797490, 2045074245,
|
|
2055351000, 2065627755, 2075904510, 2086181265,
|
|
2096458020, 2106734775, 2117011530, 2127288285,
|
|
2137565040, 2147841795, 2158118550, 2168395305,
|
|
2178672060, 2188948815, 2199225570, 2209502325,
|
|
2219779080, 2230055835, 2240332590, 2250609345,
|
|
2260886100, 2271162855, 2281439610, 2291716365,
|
|
2301993120, 2312269875, 2322546630, 2332823385,
|
|
2343100140, 2353376895, 2363653650, 2373930405,
|
|
2384207160, 2394483915, 2404760670, 2415037425,
|
|
2425314180, 2435590935, 2445867690, 2456144445,
|
|
2466421200, 2476697955, 2486974710, 2497251465,
|
|
2507528220, 2517804975, 2528081730, 2538358485,
|
|
2548635240, 2558911995, 2569188750, 2579465505,
|
|
2589742260, 2600019015, 2610295770, 2620572525
|
|
};
|
|
|
|
/*
|
|
for i = 0 to 255,
|
|
lookup_array2[i] = lookup_array1[i] << 8;
|
|
*/
|
|
CONST
|
|
unsigned long lookup_array2[256] = {
|
|
0, 2630849280, 966731264, 3597580544,
|
|
1933462528, 269344512, 2900193792, 1236075776,
|
|
3866925056, 2202807040, 538689024, 3169538304,
|
|
1505420288, 4136269568, 2472151552, 808033536,
|
|
3438882816, 1774764800, 110646784, 2741496064,
|
|
1077378048, 3708227328, 2044109312, 379991296,
|
|
3010840576, 1346722560, 3977571840, 2313453824,
|
|
649335808, 3280185088, 1616067072, 4246916352,
|
|
2582798336, 918680320, 3549529600, 1885411584,
|
|
221293568, 2852142848, 1188024832, 3818874112,
|
|
2154756096, 490638080, 3121487360, 1457369344,
|
|
4088218624, 2424100608, 759982592, 3390831872,
|
|
1726713856, 62595840, 2693445120, 1029327104,
|
|
3660176384, 1996058368, 331940352, 2962789632,
|
|
1298671616, 3929520896, 2265402880, 601284864,
|
|
3232134144, 1568016128, 4198865408, 2534747392,
|
|
870629376, 3501478656, 1837360640, 173242624,
|
|
2804091904, 1139973888, 3770823168, 2106705152,
|
|
442587136, 3073436416, 1409318400, 4040167680,
|
|
2376049664, 711931648, 3342780928, 1678662912,
|
|
14544896, 2645394176, 981276160, 3612125440,
|
|
1948007424, 283889408, 2914738688, 1250620672,
|
|
3881469952, 2217351936, 553233920, 3184083200,
|
|
1519965184, 4150814464, 2486696448, 822578432,
|
|
3453427712, 1789309696, 125191680, 2756040960,
|
|
1091922944, 3722772224, 2058654208, 394536192,
|
|
3025385472, 1361267456, 3992116736, 2327998720,
|
|
663880704, 3294729984, 1630611968, 4261461248,
|
|
2597343232, 933225216, 3564074496, 1899956480,
|
|
235838464, 2866687744, 1202569728, 3833419008,
|
|
2169300992, 505182976, 3136032256, 1471914240,
|
|
4102763520, 2438645504, 774527488, 3405376768,
|
|
1741258752, 77140736, 2707990016, 1043872000,
|
|
3674721280, 2010603264, 346485248, 2977334528,
|
|
1313216512, 3944065792, 2279947776, 615829760,
|
|
3246679040, 1582561024, 4213410304, 2549292288,
|
|
885174272, 3516023552, 1851905536, 187787520,
|
|
2818636800, 1154518784, 3785368064, 2121250048,
|
|
457132032, 3087981312, 1423863296, 4054712576,
|
|
2390594560, 726476544, 3357325824, 1693207808,
|
|
29089792, 2659939072, 995821056, 3626670336,
|
|
1962552320, 298434304, 2929283584, 1265165568,
|
|
3896014848, 2231896832, 567778816, 3198628096,
|
|
1534510080, 4165359360, 2501241344, 837123328,
|
|
3467972608, 1803854592, 139736576, 2770585856,
|
|
1106467840, 3737317120, 2073199104, 409081088,
|
|
3039930368, 1375812352, 4006661632, 2342543616,
|
|
678425600, 3309274880, 1645156864, 4276006144,
|
|
2611888128, 947770112, 3578619392, 1914501376,
|
|
250383360, 2881232640, 1217114624, 3847963904,
|
|
2183845888, 519727872, 3150577152, 1486459136,
|
|
4117308416, 2453190400, 789072384, 3419921664,
|
|
1755803648, 91685632, 2722534912, 1058416896,
|
|
3689266176, 2025148160, 361030144, 2991879424,
|
|
1327761408, 3958610688, 2294492672, 630374656,
|
|
3261223936, 1597105920, 4227955200, 2563837184,
|
|
899719168, 3530568448, 1866450432, 202332416,
|
|
2833181696, 1169063680, 3799912960, 2135794944,
|
|
471676928, 3102526208, 1438408192, 4069257472,
|
|
2405139456, 741021440, 3371870720, 1707752704,
|
|
43634688, 2674483968, 1010365952, 3641215232,
|
|
1977097216, 312979200, 2943828480, 1279710464,
|
|
3910559744, 2246441728, 582323712, 3213172992,
|
|
1549054976, 4179904256, 2515786240, 851668224
|
|
};
|
|
|
|
/*
|
|
for i = 0 to 255,
|
|
lookup_array3[i] = lookup_array1[i] << 16;
|
|
*/
|
|
CONST
|
|
unsigned long lookup_array3[256] = {
|
|
0, 3482517504, 2670067712, 1857617920,
|
|
1045168128, 232718336, 3715235840, 2902786048,
|
|
2090336256, 1277886464, 465436672, 3947954176,
|
|
3135504384, 2323054592, 1510604800, 698155008,
|
|
4180672512, 3368222720, 2555772928, 1743323136,
|
|
930873344, 118423552, 3600941056, 2788491264,
|
|
1976041472, 1163591680, 351141888, 3833659392,
|
|
3021209600, 2208759808, 1396310016, 583860224,
|
|
4066377728, 3253927936, 2441478144, 1629028352,
|
|
816578560, 4128768, 3486646272, 2674196480,
|
|
1861746688, 1049296896, 236847104, 3719364608,
|
|
2906914816, 2094465024, 1282015232, 469565440,
|
|
3952082944, 3139633152, 2327183360, 1514733568,
|
|
702283776, 4184801280, 3372351488, 2559901696,
|
|
1747451904, 935002112, 122552320, 3605069824,
|
|
2792620032, 1980170240, 1167720448, 355270656,
|
|
3837788160, 3025338368, 2212888576, 1400438784,
|
|
587988992, 4070506496, 3258056704, 2445606912,
|
|
1633157120, 820707328, 8257536, 3490775040,
|
|
2678325248, 1865875456, 1053425664, 240975872,
|
|
3723493376, 2911043584, 2098593792, 1286144000,
|
|
473694208, 3956211712, 3143761920, 2331312128,
|
|
1518862336, 706412544, 4188930048, 3376480256,
|
|
2564030464, 1751580672, 939130880, 126681088,
|
|
3609198592, 2796748800, 1984299008, 1171849216,
|
|
359399424, 3841916928, 3029467136, 2217017344,
|
|
1404567552, 592117760, 4074635264, 3262185472,
|
|
2449735680, 1637285888, 824836096, 12386304,
|
|
3494903808, 2682454016, 1870004224, 1057554432,
|
|
245104640, 3727622144, 2915172352, 2102722560,
|
|
1290272768, 477822976, 3960340480, 3147890688,
|
|
2335440896, 1522991104, 710541312, 4193058816,
|
|
3380609024, 2568159232, 1755709440, 943259648,
|
|
130809856, 3613327360, 2800877568, 1988427776,
|
|
1175977984, 363528192, 3846045696, 3033595904,
|
|
2221146112, 1408696320, 596246528, 4078764032,
|
|
3266314240, 2453864448, 1641414656, 828964864,
|
|
16515072, 3499032576, 2686582784, 1874132992,
|
|
1061683200, 249233408, 3731750912, 2919301120,
|
|
2106851328, 1294401536, 481951744, 3964469248,
|
|
3152019456, 2339569664, 1527119872, 714670080,
|
|
4197187584, 3384737792, 2572288000, 1759838208,
|
|
947388416, 134938624, 3617456128, 2805006336,
|
|
1992556544, 1180106752, 367656960, 3850174464,
|
|
3037724672, 2225274880, 1412825088, 600375296,
|
|
4082892800, 3270443008, 2457993216, 1645543424,
|
|
833093632, 20643840, 3503161344, 2690711552,
|
|
1878261760, 1065811968, 253362176, 3735879680,
|
|
2923429888, 2110980096, 1298530304, 486080512,
|
|
3968598016, 3156148224, 2343698432, 1531248640,
|
|
718798848, 4201316352, 3388866560, 2576416768,
|
|
1763966976, 951517184, 139067392, 3621584896,
|
|
2809135104, 1996685312, 1184235520, 371785728,
|
|
3854303232, 3041853440, 2229403648, 1416953856,
|
|
604504064, 4087021568, 3274571776, 2462121984,
|
|
1649672192, 837222400, 24772608, 3507290112,
|
|
2694840320, 1882390528, 1069940736, 257490944,
|
|
3740008448, 2927558656, 2115108864, 1302659072,
|
|
490209280, 3972726784, 3160276992, 2347827200,
|
|
1535377408, 722927616, 4205445120, 3392995328,
|
|
2580545536, 1768095744, 955645952, 143196160,
|
|
3625713664, 2813263872, 2000814080, 1188364288,
|
|
375914496, 3858432000, 3045982208, 2233532416,
|
|
1421082624, 608632832, 4091150336, 3278700544
|
|
};
|
|
|
|
/*
|
|
The key for the multiplicative hash function consists of 3 unsigned
|
|
characters. They are composed (logically) by concatenating them i.e.
|
|
the composed key = 2^16*c2 + 2^8*c2 + c3 and fits in 24 bits. The
|
|
composed key is not actually computed here as we use the components
|
|
to directly compute the hash function.
|
|
|
|
The multiplicative hash function consists of taking the higher order
|
|
12 bits (2^12 = 4096) of the lower order 24 bits of the product
|
|
key * Multiplier where
|
|
Multiplier = floor(A * pow(2.0, (double) w));
|
|
double A = 0.6125423371; (chosen according to Knuth)
|
|
w = 24 (the key's width in bits)
|
|
The algorithm for this is in Cormen/Leiserson/Rivest.
|
|
|
|
To do the multplication efficiently, the product c*Multiplier is
|
|
precomputed and stored in lookup_array1 (for all 256 possible c's).
|
|
lookup_array2 and lookup_array3 contain the same data as lookup_array1
|
|
but shifted left 8 and 16 bits respectively.
|
|
|
|
MultHash1 is the mult hashing function. MultHash0 contains an older
|
|
(slower but less space-efficient) version of the same function.
|
|
*/
|
|
|
|
|
|
#define MULTHASH1(c1,c2,c3) \
|
|
((lookup_array1[c1]+ \
|
|
lookup_array2[c2]+ \
|
|
lookup_array3[c3] ) & 0x00fff000) >> 12
|
|
|
|
|
|
/*
|
|
USHORT xorlookup1 [256] = {
|
|
0x110, 0x120, 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, // 0-7
|
|
0x190, 0x1a0, 0x1b0, 0x1c0, 0x1d0, 0x1e0, 0x1f0, 0x100, // 8-15
|
|
0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270, 0x280, // 16-23
|
|
0x290, 0x2a0, 0x2b0, 0x2c0, 0x2d0, 0x2e0, 0x2f0, 0x200, // 24-31
|
|
0x310, 0x320, 0x330, 0x340, 0x350, 0x360, 0x370, 0x380, // 32-39
|
|
0x390, 0x3a0, 0x3b0, 0x3c0, 0x3d0, 0x3e0, 0x3f0, 0x300, // 40-47
|
|
0x410, 0x420, 0x430, 0x440, 0x450, 0x460, 0x470, 0x480, // 48-55
|
|
0x490, 0x4a0, 0x4b0, 0x4c0, 0x4d0, 0x4e0, 0x4f0, 0x400, // 56-63
|
|
0x510, 0x520, 0x530, 0x540, 0x550, 0x560, 0x570, 0x580, // 64-71
|
|
0x590, 0x5a0, 0x5b0, 0x5c0, 0x5d0, 0x5e0, 0x5f0, 0x500, // 72-79
|
|
0x610, 0x620, 0x630, 0x640, 0x650, 0x660, 0x670, 0x680, // 80-87
|
|
0x690, 0x6a0, 0x6b0, 0x6c0, 0x6d0, 0x6e0, 0x6f0, 0x600, // 88-95
|
|
0x710, 0x720, 0x730, 0x740, 0x750, 0x760, 0x770, 0x780, // 96-103
|
|
0x790, 0x7a0, 0x7b0, 0x7c0, 0x7d0, 0x7e0, 0x7f0, 0x700, // 104-111
|
|
0x810, 0x820, 0x830, 0x840, 0x850, 0x860, 0x870, 0x880, // 112-119
|
|
0x890, 0x8a0, 0x8b0, 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x800, // 120-127
|
|
0x910, 0x920, 0x930, 0x940, 0x950, 0x960, 0x970, 0x980, // 128-135
|
|
0x990, 0x9a0, 0x9b0, 0x9c0, 0x9d0, 0x9e0, 0x9f0, 0x900, // 136-143
|
|
0xa10, 0xa20, 0xa30, 0xa40, 0xa50, 0xa60, 0xa70, 0xa80, // 144-151
|
|
0xa90, 0xaa0, 0xab0, 0xac0, 0xad0, 0xae0, 0xaf0, 0xa00, // 152-159
|
|
0xb10, 0xb20, 0xb30, 0xb40, 0xb50, 0xb60, 0xb70, 0xb80, // 160-167
|
|
0xb90, 0xba0, 0xbb0, 0xbc0, 0xbd0, 0xbe0, 0xbf0, 0xb00, // 168-175
|
|
0xc10, 0xc20, 0xc30, 0xc40, 0xc50, 0xc60, 0xc70, 0xc80, // 176-183
|
|
0xc90, 0xca0, 0xcb0, 0xcc0, 0xcd0, 0xce0, 0xcf0, 0xc00, // 184-191
|
|
0xd10, 0xd20, 0xd30, 0xd40, 0xd50, 0xd60, 0xd70, 0xd80, // 192-199
|
|
0xd90, 0xda0, 0xdb0, 0xdc0, 0xdd0, 0xde0, 0xdf0, 0xd00, // 200-207
|
|
0xe10, 0xe20, 0xe30, 0xe40, 0xe50, 0xe60, 0xe70, 0xe80, // 208-215
|
|
0xe90, 0xea0, 0xeb0, 0xec0, 0xed0, 0xee0, 0xef0, 0xe00, // 216-223
|
|
0xf10, 0xf20, 0xf30, 0xf40, 0xf50, 0xf60, 0xf70, 0xf80, // 224-231
|
|
0xf90, 0xfa0, 0xfb0, 0xfc0, 0xfd0, 0xfe0, 0xff0, 0xf00, // 232-239
|
|
0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, // 240-247
|
|
0x090, 0x0a0, 0x0b0, 0x0c0, 0x0d0, 0x0e0, 0x0f0, 0x000 }; // 248-255
|
|
|
|
|
|
USHORT xorlookup2 [256] = {
|
|
0x101, 0x201, 0x301, 0x401, 0x501, 0x601, 0x701, 0x801, // 0-7
|
|
0x901, 0xa01, 0xb01, 0xc01, 0xd01, 0xe01, 0xf01, 0x001, // 8-15
|
|
0x102, 0x202, 0x302, 0x402, 0x502, 0x602, 0x702, 0x802, // 16-23
|
|
0x902, 0xa02, 0xb02, 0xc02, 0xd02, 0xe02, 0xf02, 0x002, // 24-31
|
|
0x103, 0x203, 0x303, 0x403, 0x503, 0x603, 0x703, 0x803, // 32-39
|
|
0x903, 0xa03, 0xb03, 0xc03, 0xd03, 0xe03, 0xf03, 0x003, // 40-47
|
|
0x104, 0x204, 0x304, 0x404, 0x504, 0x604, 0x704, 0x804, // 48-55
|
|
0x904, 0xa04, 0xb04, 0xc04, 0xd04, 0xe04, 0xf04, 0x004, // 56-63
|
|
0x105, 0x205, 0x305, 0x405, 0x505, 0x605, 0x705, 0x805, // 64-71
|
|
0x905, 0xa05, 0xb05, 0xc05, 0xd05, 0xe05, 0xf05, 0x005, // 72-79
|
|
0x106, 0x206, 0x306, 0x406, 0x506, 0x606, 0x706, 0x806, // 80-87
|
|
0x906, 0xa06, 0xb06, 0xc06, 0xd06, 0xe06, 0xf06, 0x006, // 88-95
|
|
0x107, 0x207, 0x307, 0x407, 0x507, 0x607, 0x707, 0x807, // 96-103
|
|
0x907, 0xa07, 0xb07, 0xc07, 0xd07, 0xe07, 0xf07, 0x007, // 104-111
|
|
0x108, 0x208, 0x308, 0x408, 0x508, 0x608, 0x708, 0x808, // 112-119
|
|
0x908, 0xa08, 0xb08, 0xc08, 0xd08, 0xe08, 0xf08, 0x008, // 120-127
|
|
0x109, 0x209, 0x309, 0x409, 0x509, 0x609, 0x709, 0x809, // 128-135
|
|
0x909, 0xa09, 0xb09, 0xc09, 0xd09, 0xe09, 0xf09, 0x009, // 136-143
|
|
0x10a, 0x20a, 0x30a, 0x40a, 0x50a, 0x60a, 0x70a, 0x80a, // 144-151
|
|
0x90a, 0xa0a, 0xb0a, 0xc0a, 0xd0a, 0xe0a, 0xf0a, 0x00a, // 152-159
|
|
0x10b, 0x20b, 0x30b, 0x40b, 0x50b, 0x60b, 0x70b, 0x80b, // 160-167
|
|
0x90b, 0xa0b, 0xb0b, 0xc0b, 0xd0b, 0xe0b, 0xf0b, 0x00b, // 168-175
|
|
0x10c, 0x20c, 0x30c, 0x40c, 0x50c, 0x60c, 0x70c, 0x80c, // 176-183
|
|
0x90c, 0xa0c, 0xb0c, 0xc0c, 0xd0c, 0xe0c, 0xf0c, 0x00c, // 184-191
|
|
0x10d, 0x20d, 0x30d, 0x40d, 0x50d, 0x60d, 0x70d, 0x80d, // 192-199
|
|
0x90d, 0xa0d, 0xb0d, 0xc0d, 0xd0d, 0xe0d, 0xf0d, 0x00d, // 200-207
|
|
0x10e, 0x20e, 0x30e, 0x40e, 0x50e, 0x60e, 0x70e, 0x80e, // 208-215
|
|
0x90e, 0xa0e, 0xb0e, 0xc0e, 0xd0e, 0xe0e, 0xf0e, 0x00e, // 216-223
|
|
0x10f, 0x20f, 0x30f, 0x40f, 0x50f, 0x60f, 0x70f, 0x80f, // 224-231
|
|
0x90f, 0xa0f, 0xb0f, 0xc0f, 0xd0f, 0xe0f, 0xf0f, 0x00f, // 232-239
|
|
0x000, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800, // 240-247
|
|
0x900, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00, 0xf00, 0x100 }; // 248-255
|
|
|
|
*/
|
|
|
|
/* Bitptrs point to the current byte. The current bit (i.e. next bit to be
|
|
* stored) is masked off by the bit entry. When this reaches zero, it is
|
|
* reset to 0x80 and the next byte is set up. The bytes are filled MSBit
|
|
* first. */
|
|
|
|
/* Starts and sets the first byte to zero for the bitptr. */
|
|
#define bitptr_init(s) pbyte = s; byte=0; bit = 16;
|
|
|
|
/* Sets up the byte part of the bitptr so that it is pointing to the byte after
|
|
* the byte which had the last bit put into it. */
|
|
#define bitptr_end() if (bit != 16) *pbyte++=(UCHAR)(byte >> 8);
|
|
|
|
/* Goes to the next bit, and byte if necessary. */
|
|
#define bitptr_next() \
|
|
if (bit < 10) { \
|
|
*pbyte++=(UCHAR)(byte >> 8); \
|
|
byte <<= 8; \
|
|
bit = 16; \
|
|
} else \
|
|
bit-- ;
|
|
|
|
/*
|
|
#define bitptr_next() \
|
|
bit--; \
|
|
if (bit < 9) { \
|
|
*pbyte++=(UCHAR)(byte >> 8); \
|
|
byte <<= 8; \
|
|
bit = 16; \
|
|
}
|
|
*/
|
|
|
|
|
|
/* Advances to the next bit, and byte if necessary, readjusting the bit. */
|
|
#define bitptr_advance() \
|
|
if (bit < 9) { \
|
|
*pbyte++=(UCHAR)(byte >> 8); \
|
|
bit+=8; \
|
|
byte <<= 8; \
|
|
}
|
|
|
|
|
|
/* BIT I/O FUNCTIONS *********************************************************/
|
|
|
|
/* These routines output most-significant-bit-first and the input will return
|
|
* them MSB first, too. */
|
|
|
|
/* Outputs a one bit in the bit stream. */
|
|
#define out_bit_1() bit--; byte |= (1 << bit); bitptr_advance();
|
|
#define out_bit_0() bitptr_next();
|
|
|
|
/* TestBit; output 1 if that bit is set */
|
|
//#define tb(b,w,n) if ((w) & (n)) *pbyte |= bit; bitptr_next(b);
|
|
|
|
#define out_bits_2(w) bit-=2; byte|=(w << bit); bitptr_advance();
|
|
#define out_bits_3(w) bit-=3; byte|=(w << bit); bitptr_advance();
|
|
#define out_bits_4(w) bit-=4; byte|=(w << bit); bitptr_advance();
|
|
#define out_bits_5(w) bit-=5; byte|=(w << bit); bitptr_advance();
|
|
#define out_bits_6(w) bit-=6; byte|=(w << bit); bitptr_advance();
|
|
#define out_bits_7(w) bit-=7; byte|=(w << bit); bitptr_advance();
|
|
|
|
// #define out_bits_8(w) bit-=8; byte|=(w << bit); bit+=8; *pbyte++=(UCHAR)(byte >> 8); byte <<= 8;
|
|
#define out_bits_8(w) byte|=(w << (bit-8)); *pbyte++=(UCHAR)(byte >> 8); byte <<= 8;
|
|
|
|
|
|
/*
|
|
#define out_bits_9(w) \
|
|
if (bit > 9) { \
|
|
bit-=9; byte|=(w << bit); \
|
|
*pbyte++=(UCHAR)(byte >> 8);\
|
|
bit+=8; \
|
|
byte <<= 8; \
|
|
} else { \
|
|
bit=16; byte |= w; \
|
|
*pbyte++=(UCHAR)(byte >> 8); *pbyte++=(UCHAR)(byte); byte=0; \
|
|
}
|
|
*/
|
|
|
|
#define out_bits_9(w) \
|
|
if (bit > 9) { \
|
|
byte|=(w << (bit-9)); \
|
|
*pbyte++=(UCHAR)(byte >> 8);\
|
|
bit--; \
|
|
byte <<= 8; \
|
|
} else { \
|
|
bit=16; byte |= w; \
|
|
*pbyte++=(UCHAR)(byte >> 8); *pbyte++=(UCHAR)(byte); byte=0; \
|
|
}
|
|
|
|
|
|
#define out_bits_10(w) \
|
|
if (bit > 10) { \
|
|
bit-=10; byte |= (w << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
|
|
} else { \
|
|
out_bits_2((w >> 8)); \
|
|
out_bits_8((w & 0xFF)); \
|
|
}
|
|
|
|
//
|
|
// Weird effect - if out_bits_9 used instead of out_bits_8,
|
|
// it's faster! if (bit == 11) is faster than if (bit != 11).
|
|
//
|
|
|
|
#define out_bits_11(w) \
|
|
if (bit > 11) { \
|
|
bit-=11; byte |= (w << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
|
|
} else { \
|
|
if (bit == 11) { \
|
|
bit=16; byte |= w; \
|
|
*pbyte++=(UCHAR)(byte >> 8); *pbyte++=(UCHAR)(byte); byte=0; \
|
|
} else { \
|
|
bit=11-bit; \
|
|
byte|=(w >> bit); \
|
|
*pbyte++=(UCHAR)(byte >> 8); *pbyte++=(UCHAR)(byte); \
|
|
bit=16-bit; \
|
|
byte=(w << bit); \
|
|
} \
|
|
}
|
|
|
|
|
|
#define out_bits_12(w) \
|
|
if (bit > 12) { \
|
|
bit-=12; byte |= (w << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
|
|
} else { \
|
|
out_bits_4((w >> 8)); \
|
|
out_bits_8((w & 0xFF)); \
|
|
}
|
|
|
|
#define out_bits_13(w) \
|
|
if (bit > 13) { \
|
|
bit-=13; byte |= (w << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
|
|
} else { \
|
|
out_bits_5((w >> 8)); \
|
|
out_bits_8((w & 0xFF)); \
|
|
}
|
|
|
|
#define out_bits_14(w) \
|
|
if (bit > 14) { \
|
|
bit-=14; byte |= (w << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
|
|
} else { \
|
|
out_bits_6((w >> 8)); \
|
|
out_bits_8((w & 0xFF)); \
|
|
}
|
|
|
|
|
|
#define out_reserve_4() \
|
|
bit-=4; bitptr_advance();
|
|
|
|
|
|
/* Starts the given bit pointer */
|
|
#define inbit_start(s) pbyte = s; bit = 16; byte=(*pbyte << 8) + *(pbyte+1); pbyte++;
|
|
#define inbit_end() if (bit != 16) pbyte++;
|
|
|
|
#define in_bit_next() if (bit < 9) { \
|
|
bit=16; \
|
|
byte <<=8; \
|
|
byte |= *(++pbyte); \
|
|
}
|
|
|
|
|
|
#define in_bit_advance() if (bit < 9) { \
|
|
bit+=8; \
|
|
byte <<=8; \
|
|
byte |= *(++pbyte); \
|
|
}
|
|
|
|
/* Returns non-zero in bitset if the next bit in the stream is a 1. */
|
|
#define in_bit() bit--; bitset = (byte >> bit) & 1; in_bit_next()
|
|
|
|
|
|
#define in_bits_2(w) bit-=2; w = (byte >> bit) & 0x03;\
|
|
in_bit_advance();
|
|
|
|
#define in_bits_3(w) bit-=3; w = (byte >> bit) & 0x07;\
|
|
in_bit_advance();
|
|
|
|
#define in_bits_4(w) bit-=4; w = (byte >> bit) & 0x0F;\
|
|
in_bit_advance();
|
|
|
|
#define in_bits_5(w) bit-=5; w = (byte >> bit) & 0x1F;\
|
|
in_bit_advance();
|
|
|
|
#define in_bits_6(w) bit-=6; w = (byte >> bit) & 0x3F;\
|
|
in_bit_advance();
|
|
|
|
#define in_bits_7(w) bit-=7; w = (byte >> bit) & 0x7F;\
|
|
in_bit_advance();
|
|
|
|
#define in_bits_8(w) bit-=8; w = (byte >> bit) & 0xFF;\
|
|
bit+=8; byte <<=8; byte |= *(++pbyte);
|
|
|
|
|
|
#define in_bits_9(w) bit-=9; w = (byte >> bit) & 0x1FF; \
|
|
bit+=8; byte <<=8; byte |= *(++pbyte); \
|
|
in_bit_advance();
|
|
|
|
#define in_bits_10(w) if (bit > 10) { \
|
|
bit-=10; w = (byte >> bit) & 0x3FF; \
|
|
bit+=8; byte <<=8; byte |= *(++pbyte); \
|
|
} else { \
|
|
in_bits_2(bitset); \
|
|
in_bits_8(w); \
|
|
w= w + (bitset << 8); \
|
|
}
|
|
|
|
#define in_bits_11(w) if (bit > 11) { \
|
|
bit-=11; w = (byte >> bit) & 0x7FF; \
|
|
bit+=8; byte <<=8; byte |= *(++pbyte); \
|
|
} else { \
|
|
in_bits_3(bitset); \
|
|
in_bits_8(w); \
|
|
w= w + (bitset << 8); \
|
|
}
|
|
|
|
|
|
#define in_bits_12(w) if (bit > 12) { \
|
|
bit-=12; w = (byte >> bit) & 0xFFF; \
|
|
bit+=8; byte <<=8; byte |= *(++pbyte); \
|
|
} else { \
|
|
in_bits_4(bitset); \
|
|
in_bits_8(w); \
|
|
w= w + (bitset << 8); \
|
|
}
|
|
|
|
|
|
|
|
#define in_bits_13(w)\
|
|
if (bit > 13) { \
|
|
bit-=13; w = (byte >> bit) & 0x1FFF; \
|
|
bit+=8; byte <<=8; byte |= *(++pbyte); \
|
|
} else { \
|
|
in_bits_5(bitset); \
|
|
in_bits_8(w); \
|
|
w=w + (bitset << 8); \
|
|
}
|
|
|
|
|
|
#define in_bits_14(w)\
|
|
if (bit > 14) { \
|
|
bit-=14; w = (byte >> bit) & 0x3FFF; \
|
|
bit+=8; byte <<=8; byte |= *(++pbyte); \
|
|
} else { \
|
|
in_bits_6(bitset); \
|
|
in_bits_8(w); \
|
|
w=w + (bitset << 8); \
|
|
}
|
|
|
|
|
|
|
|
UCHAR SHApad1[40] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
UCHAR SHApad2[40] = {0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
|
|
0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
|
|
0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
|
|
0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2};
|
|
|
|
PUCHAR ClntSSrvR = "On the client side, this is the send key; on the server side, it is the receive key.";
|
|
PUCHAR ClntRSrvS = "On the client side, this is the receive key; on the server side, it is the send key.";
|
|
#define ECP_STRING_LEN strlen(ClntSSrvR)
|
|
|
|
#ifdef DEBUG
|
|
char
|
|
ChPrint(UCHAR b)
|
|
{
|
|
if (isprint(b))
|
|
return (char)b;
|
|
else
|
|
return '.';
|
|
}
|
|
#endif
|
|
|
|
|
|
//* compress()
|
|
//
|
|
// Function: Main compression function.
|
|
//
|
|
// Parameters:
|
|
// IN CurrentBuffer -> points to NDIS_WAN_PACKET with data to compress
|
|
// OUT CompOutBuffer -> points to NDIS_WAN_PACKET to compress data to
|
|
// IN CurrentLength -> points to Length of data to compress
|
|
// IN context -> connection compress context
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// WARNING: CODE IS HIGHLY OPTIMIZED FOR TIME.
|
|
//
|
|
//
|
|
UCHAR
|
|
compress (UCHAR *CurrentBuffer, UCHAR *CompOutBuffer, ULONG *CurrentLength, SendContext *context)
|
|
{
|
|
int copylen ;
|
|
int bit;
|
|
int byte;
|
|
int backptr ;
|
|
int cbMatch;
|
|
int hashvalue ;
|
|
int lookup1 ;
|
|
UCHAR *matchptr ;
|
|
UCHAR *pbyte;
|
|
UCHAR *historyptr ;
|
|
UCHAR *currentptr ;
|
|
UCHAR *endptr ;
|
|
UCHAR hashchar1;
|
|
UCHAR hashchar2;
|
|
UCHAR hashchar3;
|
|
int literal ;
|
|
UCHAR status=0; // return flags
|
|
PUCHAR currentbuf ;
|
|
|
|
|
|
// Will this packet fit at the end of the history buffer?
|
|
//
|
|
if (((context->CurrentIndex + *CurrentLength) >= (HISTORY_MAX - 1 )) ||
|
|
(context->CurrentIndex == 0)) {
|
|
context->CurrentIndex = 0; // Index into the history
|
|
status |= PACKET_AT_FRONT;
|
|
}
|
|
|
|
//
|
|
// we no longer need to save the non compressed data - tonybe 01-12-95
|
|
//
|
|
// RtlMoveMemory(context->CompressBuffer, CurrentBuffer, *CurrentLength) ;
|
|
|
|
// Start out the bit pointing output
|
|
//
|
|
bitptr_init(CompOutBuffer);
|
|
|
|
//
|
|
// We are now compressing into an output buffer - tonybe 01-12-95
|
|
//
|
|
// bitptr_init(CurrentBuffer);
|
|
|
|
historyptr = context->History + context->CurrentIndex ;
|
|
|
|
currentptr = CurrentBuffer;
|
|
|
|
//
|
|
// we are now compressing from the currentbuffer - tonybe 01-12-95
|
|
//
|
|
// currentptr = context->CompressBuffer ;
|
|
|
|
endptr = currentptr + *CurrentLength - 1;
|
|
|
|
while (currentptr < (endptr-2)) {
|
|
|
|
*historyptr++ = hashchar1 = *currentptr++ ;
|
|
hashchar2 = *currentptr ;
|
|
hashchar3 = *(currentptr+1) ;
|
|
|
|
// "fast" hash function
|
|
// hashvalue = (int)hashchar1 ^ xorlookup1[hashchar2] ^ xorlookup2[hashchar3];
|
|
hashvalue = MULTHASH1(hashchar1, hashchar2, hashchar3) ;
|
|
|
|
matchptr = context->History + context->HashTable[hashvalue] ;
|
|
|
|
if (matchptr != (historyptr - 1))
|
|
context->HashTable[hashvalue] = (USHORT)(historyptr - context->History) ;
|
|
|
|
if (context->ValidHistory < historyptr)
|
|
context->ValidHistory = historyptr ;
|
|
|
|
if (matchptr != context->History &&
|
|
*(matchptr-1) == hashchar1 && *matchptr == hashchar2 &&
|
|
*(matchptr+1) == hashchar3 && matchptr != (historyptr - 1) &&
|
|
matchptr != historyptr && (matchptr+1) <= context->ValidHistory) {
|
|
|
|
backptr = ((int)(historyptr - matchptr)) & (HISTORY_SIZE - 1) ;
|
|
|
|
*historyptr++ = hashchar2 ; // copy the other 2 chars
|
|
*historyptr++ = hashchar3 ; // copy the other 2 chars
|
|
currentptr +=2 ;
|
|
cbMatch = 3 ; // length of match
|
|
matchptr +=2 ; // we have already matched 3
|
|
|
|
while ((*matchptr == *currentptr) && (currentptr < endptr) && (matchptr <= context->ValidHistory)) {
|
|
matchptr++ ;
|
|
*historyptr++ = *currentptr++ ;
|
|
cbMatch++ ;
|
|
}
|
|
|
|
// First output the backpointer
|
|
//
|
|
if (backptr >= 320) {
|
|
backptr -= 320 ;
|
|
out_bits_8((0xc000 + backptr) >> 8) ; // 110 + 13 bits
|
|
out_bits_8((backptr)) ;
|
|
} else if (backptr < 64) { // 1111 + 6 bits
|
|
backptr += 0x3c0 ;
|
|
out_bits_10(backptr);
|
|
} else {
|
|
backptr += (0xE00 - 64); // 1110 + 8 bits
|
|
out_bits_12(backptr);
|
|
}
|
|
|
|
// output the length of the match encoding
|
|
//
|
|
switch (cbMatch) {
|
|
|
|
case 3:
|
|
out_bit_0(); // length of 3 - most common
|
|
break;
|
|
|
|
case 4:
|
|
out_bits_4(8);
|
|
break;
|
|
|
|
case 5:
|
|
out_bits_4(9);
|
|
break;
|
|
|
|
case 6:
|
|
out_bits_4(10);
|
|
break;
|
|
|
|
case 7:
|
|
out_bits_4(11);
|
|
break;
|
|
|
|
case 8:
|
|
out_bits_6(48);
|
|
break;
|
|
|
|
case 9:
|
|
out_bits_6(49);
|
|
break;
|
|
|
|
case 10:
|
|
out_bits_6(50);
|
|
break;
|
|
|
|
case 11:
|
|
out_bits_6(51);
|
|
break;
|
|
|
|
case 12:
|
|
out_bits_6(52);
|
|
break;
|
|
|
|
case 13:
|
|
out_bits_6(53);
|
|
break;
|
|
|
|
case 14:
|
|
out_bits_6(54);
|
|
break;
|
|
|
|
case 15:
|
|
out_bits_6(55);
|
|
break;
|
|
|
|
case 16:
|
|
out_bits_8(0xe0);
|
|
break;
|
|
|
|
case 17:
|
|
out_bits_8(0xe1);
|
|
break;
|
|
|
|
case 18:
|
|
out_bits_8(0xe2);
|
|
break;
|
|
|
|
case 19:
|
|
out_bits_8(0xe3);
|
|
break;
|
|
|
|
case 20:
|
|
out_bits_8(0xe4);
|
|
break;
|
|
|
|
case 21:
|
|
out_bits_8(0xe5);
|
|
break;
|
|
|
|
case 22:
|
|
out_bits_8(0xe6);
|
|
break;
|
|
|
|
case 23:
|
|
out_bits_8(0xe7);
|
|
break;
|
|
|
|
case 24:
|
|
out_bits_8(0xe8);
|
|
break;
|
|
|
|
case 25:
|
|
out_bits_8(0xe9);
|
|
break;
|
|
|
|
case 26:
|
|
out_bits_8(0xea);
|
|
break;
|
|
|
|
case 27:
|
|
out_bits_8(0xeb);
|
|
break;
|
|
|
|
case 28:
|
|
out_bits_8(0xec);
|
|
break;
|
|
|
|
case 29:
|
|
out_bits_8(0xed);
|
|
break;
|
|
|
|
case 30:
|
|
out_bits_8(0xee);
|
|
break;
|
|
|
|
case 31:
|
|
out_bits_8(0xef);
|
|
break;
|
|
|
|
default:
|
|
if (cbMatch < 64) {
|
|
out_bits_4(0xF) ;
|
|
cbMatch -= 32 ;
|
|
out_bits_6(cbMatch) ;
|
|
}
|
|
else if (cbMatch < 128) {
|
|
out_bits_5(0x1F) ;
|
|
cbMatch -= 64 ;
|
|
out_bits_7(cbMatch) ;
|
|
}
|
|
else if (cbMatch < 256) {
|
|
out_bits_6(0x3F) ;
|
|
cbMatch -= 128 ;
|
|
out_bits_8(cbMatch) ;
|
|
}
|
|
else if (cbMatch < 512) {
|
|
out_bits_7(0x7F) ;
|
|
cbMatch -= 256 ;
|
|
out_bits_9(cbMatch) ;
|
|
}
|
|
else if (cbMatch < 1024) {
|
|
out_bits_8(0xFF) ;
|
|
cbMatch -= 512 ;
|
|
out_bits_10(cbMatch) ;
|
|
}
|
|
else if (cbMatch < 2048) {
|
|
out_bits_9(0x1FF) ;
|
|
cbMatch -= 1024 ;
|
|
out_bits_11(cbMatch) ;
|
|
}
|
|
else if (cbMatch < 4096) {
|
|
out_bits_10(0x3FF) ;
|
|
cbMatch -= 2048 ;
|
|
out_bits_12(cbMatch) ;
|
|
}
|
|
else if (cbMatch < 8192) {
|
|
out_bits_11(0x7FF) ;
|
|
cbMatch -= 4096 ;
|
|
out_bits_13(cbMatch) ;
|
|
}
|
|
else { // 8192 and greater
|
|
out_bits_12(0xFFF) ;
|
|
cbMatch -= 8192 ;
|
|
out_bits_14(cbMatch) ;
|
|
}
|
|
break ;
|
|
}
|
|
|
|
} else { // encode a literal
|
|
|
|
// temp=literallookup[context->History[i-1]] ;
|
|
literal= hashchar1 ;
|
|
|
|
if (literal & 0x80) {
|
|
literal += 0x80;
|
|
out_bits_9(literal) ;
|
|
} else {
|
|
out_bits_8(literal) ;
|
|
}
|
|
|
|
}
|
|
|
|
} // while
|
|
|
|
|
|
// get any remaining chars as literals
|
|
while (currentptr <= endptr) {
|
|
|
|
// temp=literallookup[context->History[i-1]] ;
|
|
literal=*currentptr ;
|
|
|
|
|
|
if (literal & 0x80) {
|
|
literal += 0x80;
|
|
out_bits_9(literal) ;
|
|
} else {
|
|
out_bits_8(literal) ;
|
|
}
|
|
|
|
*historyptr++ = *currentptr++ ;
|
|
}
|
|
|
|
|
|
bitptr_end() ;
|
|
|
|
|
|
// Check if we had expansion instead of compression
|
|
//
|
|
if ((ULONG)(pbyte - CompOutBuffer) > *CurrentLength) { // expansion.
|
|
|
|
//
|
|
// We don't need to do this copy since we can just signal the outside world
|
|
// that compression did not take place and the valid data is still in the
|
|
// current buffer
|
|
//
|
|
// RtlMoveMemory(CompOutBuffer, CurrentBuffer, *CurrentLength) ;
|
|
|
|
memset (context->History, 0, sizeof(context->History)) ;
|
|
memset (context->HashTable, 0, sizeof(context->HashTable)) ;
|
|
#ifdef COMP_12K
|
|
status = 0 ;
|
|
#else
|
|
status = PACKET_FLUSHED;
|
|
#endif
|
|
context->CurrentIndex = HISTORY_SIZE+1 ; // this forces a start over next time
|
|
|
|
} else { // compression successful
|
|
|
|
*CurrentLength = (ULONG)(pbyte - CompOutBuffer);
|
|
|
|
//
|
|
// the compressed data is now in CompOutBuffer - tonybe 01-12-95
|
|
//
|
|
// *CurrentLength = pbyte - CurrentBuffer ;
|
|
|
|
status |= PACKET_COMPRESSED ;
|
|
context->CurrentIndex = (int)(historyptr - context->History) ;
|
|
}
|
|
|
|
return(status);
|
|
}
|
|
|
|
|
|
|
|
//* getcontextsizes()
|
|
//
|
|
// Function: Returns size of send and receive context blocks
|
|
//
|
|
// Parameters: OUT send -> sizeof(SendContext)
|
|
// OUT recv -> sizeof(RecvContext)
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
//*
|
|
void
|
|
getcontextsizes (long *send, long *recv)
|
|
{
|
|
*send = sizeof(SendContext) ;
|
|
*recv = sizeof(RecvContext) ;
|
|
}
|
|
|
|
|
|
//* initsendcontext()
|
|
//
|
|
// Function: Initialize SendContext block
|
|
//
|
|
// Parameters: IN context -> connection compress context
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
//*
|
|
void
|
|
initsendcontext (SendContext *context)
|
|
{
|
|
context->CurrentIndex = 0; // Index into the history
|
|
context->ValidHistory = 0 ; // reset valid history
|
|
memset (context->HashTable, 0, sizeof(context->HashTable)) ;
|
|
memset (context->History, 0, sizeof(context->HashTable)) ;
|
|
}
|
|
|
|
|
|
|
|
//* initrecvcontext()
|
|
//
|
|
// Function: Initialize RecvContext block
|
|
//
|
|
// Parameters: IN context -> connection decompress context
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
//*
|
|
void
|
|
initrecvcontext (RecvContext *context)
|
|
{
|
|
context->CurrentPtr = context->History ;
|
|
|
|
#if DBG
|
|
context->DebugFence = DEBUG_FENCE_VALUE;
|
|
#endif
|
|
|
|
memset (context->History, 0, sizeof(context->History)) ;
|
|
}
|
|
|
|
|
|
|
|
//* decompress()
|
|
//
|
|
// Function: de-compression function.
|
|
//
|
|
// Parameters: IN inbuf -> points to data to be uncompressed
|
|
// IN inlen -> length of data
|
|
// IN start -> flag indicating whether to start with a clean history buffer
|
|
// OUT output-> decompressed data
|
|
// OUT outlen-> lenght of decompressed data
|
|
// IN context -> connection decompress context
|
|
//
|
|
// Returns: TRUE if decompress was successful
|
|
// FALSE if it wasnt
|
|
//
|
|
// WARNING: CODE IS HIGHLY OPTIMIZED FOR TIME.
|
|
//
|
|
//*
|
|
int
|
|
decompress(
|
|
UCHAR *inbuf,
|
|
int inlen,
|
|
int start,
|
|
UCHAR **output,
|
|
int *outlen,
|
|
RecvContext *context)
|
|
{
|
|
UCHAR *inend; // When we know we're done decompressing
|
|
UCHAR *outstart; // Remember where in dbuf we started
|
|
|
|
UCHAR *current;
|
|
|
|
int backptr; // Back pointer for copy items
|
|
int length; // Where to copy from in dbuf
|
|
|
|
UCHAR *s1, *s2;
|
|
|
|
int bitset;
|
|
int bit;
|
|
int byte;
|
|
UCHAR *pbyte;
|
|
UCHAR *historyend = context->History + HISTORY_SIZE ;
|
|
|
|
inend = inbuf + inlen ;
|
|
|
|
//
|
|
// Start out looking at the first bit
|
|
//
|
|
inbit_start(inbuf);
|
|
|
|
if (start) // start over clean?
|
|
context->CurrentPtr = current = context->History ;
|
|
else
|
|
current = context->CurrentPtr ;
|
|
|
|
//
|
|
// Save our starting position
|
|
//
|
|
outstart = current;
|
|
|
|
//
|
|
// Decompress until we run out of input
|
|
//
|
|
while (pbyte < inend) {
|
|
|
|
//
|
|
// Jump on what to do with these three bits.
|
|
//
|
|
in_bits_3(length);
|
|
|
|
switch (length) {
|
|
|
|
case 0:
|
|
in_bits_5(length) ;
|
|
goto LITERAL ;
|
|
|
|
case 1:
|
|
in_bits_5(length) ;
|
|
length += 32 ;
|
|
goto LITERAL ;
|
|
|
|
case 2:
|
|
in_bits_5(length) ;
|
|
length += 64 ;
|
|
goto LITERAL ;
|
|
|
|
case 3:
|
|
in_bits_5(length) ;
|
|
length += 96 ;
|
|
goto LITERAL ;
|
|
|
|
case 4:
|
|
in_bits_6(length) ;
|
|
length +=128 ;
|
|
goto LITERAL ;
|
|
|
|
case 5:
|
|
in_bits_6(length) ;
|
|
length +=192 ;
|
|
goto LITERAL ;
|
|
|
|
case 6:
|
|
in_bits_13 (backptr) ; // 110 - 14 bit offset
|
|
backptr+=320 ;
|
|
break ;
|
|
|
|
case 7:
|
|
in_bit() ;
|
|
if (bitset) {
|
|
in_bits_6(backptr) ;
|
|
} else {
|
|
in_bits_8(backptr) ;
|
|
backptr+=64 ;
|
|
}
|
|
break ;
|
|
}
|
|
|
|
//
|
|
// If we reach here, it's a copy item
|
|
//
|
|
|
|
//
|
|
// Now get the length
|
|
//
|
|
|
|
in_bit() ; // 1st length bit
|
|
if (!bitset) {
|
|
length = 3 ;
|
|
goto DONE ;
|
|
}
|
|
|
|
in_bit() ; // 2nd length bit
|
|
if (!bitset) {
|
|
in_bits_2 (length) ;
|
|
length += 4 ;
|
|
goto DONE ;
|
|
}
|
|
|
|
in_bit() ; // 3rd length bit
|
|
if (!bitset) {
|
|
in_bits_3 (length) ;
|
|
length += 8 ;
|
|
goto DONE ;
|
|
}
|
|
|
|
in_bit() ; // 4th length bit
|
|
if (!bitset) {
|
|
in_bits_4 (length) ;
|
|
length += 16 ;
|
|
goto DONE ;
|
|
}
|
|
|
|
in_bit() ; // 5th length bit
|
|
if (!bitset) {
|
|
in_bits_5 (length) ;
|
|
length += 32 ;
|
|
goto DONE ;
|
|
}
|
|
|
|
in_bit() ; // 6th length bit
|
|
if (!bitset) {
|
|
in_bits_6 (length) ;
|
|
length += 64 ;
|
|
goto DONE ;
|
|
}
|
|
|
|
in_bit() ; // 7th length bit
|
|
if (!bitset) {
|
|
in_bits_7 (length) ;
|
|
length += 128 ;
|
|
goto DONE ;
|
|
}
|
|
|
|
in_bit() ; // 8th length bit
|
|
if (!bitset) {
|
|
in_bits_8 (length) ;
|
|
length += 256 ;
|
|
goto DONE ;
|
|
}
|
|
|
|
in_bit() ; // 9th length bit
|
|
if (!bitset) {
|
|
in_bits_9 (length) ;
|
|
length += 512 ;
|
|
goto DONE ;
|
|
}
|
|
|
|
in_bit() ; // 10th length bit
|
|
if (!bitset) {
|
|
in_bits_10 (length) ;
|
|
length += 1024 ;
|
|
goto DONE ;
|
|
}
|
|
|
|
//
|
|
// length cannot be greater than max packets size which is 1500
|
|
//
|
|
#if DBG
|
|
DbgPrint("NDISWAN: RAS Decompressor problem1: Possible data corruption\n");
|
|
#endif
|
|
|
|
return FALSE ;
|
|
|
|
|
|
DONE:
|
|
//
|
|
// Turn the backptr into an index location
|
|
//
|
|
#ifdef COMP_12K
|
|
s2 = current - backptr ;
|
|
#else
|
|
s2 = context->History + (((current - context->History) - backptr) & (HISTORY_SIZE -1)) ;
|
|
#endif
|
|
|
|
s1 = current;
|
|
|
|
current += length;
|
|
|
|
// if we are past the end of the history this is a bad sign: abort decompression
|
|
//
|
|
if (current >= historyend) {
|
|
#if DBG
|
|
DbgPrint("NDISWAN: RAS Decompressor problem2: Possible data corruption\n");
|
|
#endif
|
|
return FALSE ;
|
|
}
|
|
|
|
// loop unrolled to handle lenght>backptr case
|
|
//
|
|
*s1=*s2;
|
|
*(s1+1)=*(s2+1);
|
|
s1+=2;
|
|
s2+=2;
|
|
length-=2;
|
|
|
|
//
|
|
// copy all the bytes
|
|
//
|
|
while (length) {
|
|
*s1++=*s2++;
|
|
length--;
|
|
}
|
|
|
|
//
|
|
// We have another copy item, and no literals
|
|
//
|
|
continue;
|
|
|
|
|
|
LITERAL:
|
|
|
|
//
|
|
// We have a literal
|
|
//
|
|
|
|
if (current >= historyend) {
|
|
#if DBG
|
|
DbgPrint("NDISWAN: RAS Decompressor problem3: Possible data corruption\n");
|
|
#endif
|
|
return FALSE ;
|
|
}
|
|
|
|
//*current++ = literallookup[length];
|
|
*current++ = (UCHAR)length;
|
|
|
|
} // while loop
|
|
|
|
|
|
// End case:
|
|
//
|
|
if (current >= historyend) {
|
|
#if DBG
|
|
DbgPrint("NDISWAN: RAS Decompressor problem4: Possible data corruption\n");
|
|
#endif
|
|
return FALSE ;
|
|
}
|
|
|
|
if ((bit == 16) && (pbyte == inend)) {
|
|
*current++ = *(pbyte -1) ;
|
|
}
|
|
|
|
#if DBG
|
|
if (context->DebugFence != DEBUG_FENCE_VALUE) {
|
|
DbgPrint("Decompression Error!\n");
|
|
DbgPrint("context %p, current %p, outstart %p\n", context, current, outstart);
|
|
DbgPrint("inbuf %p, inlength %d, start %p\n", inbuf, inlen, start);
|
|
DbgBreakPoint();
|
|
}
|
|
#endif
|
|
|
|
*outlen = (int)(current - outstart) ; // the length of decompressed data
|
|
|
|
*output = context->CurrentPtr ;
|
|
|
|
context->CurrentPtr = current ;
|
|
|
|
return TRUE ;
|
|
}
|
|
|
|
|
|
//
|
|
// This function uses the 16 byte user session key and the 8 byte
|
|
// challenge to create an intial 16 byte encryption session key.
|
|
//
|
|
VOID
|
|
GetStartKeyFromSHA(
|
|
PCRYPTO_INFO CryptoInfo,
|
|
PUCHAR Challenge
|
|
)
|
|
{
|
|
UCHAR Digest[A_SHA_DIGEST_LEN];
|
|
UCHAR SessionKeyChallenge[MAX_USERSESSIONKEY_SIZE + MAX_CHALLENGE_SIZE];
|
|
|
|
NdisZeroMemory(Digest, A_SHA_DIGEST_LEN);
|
|
|
|
//
|
|
// Copy the start session key
|
|
//
|
|
NdisMoveMemory(SessionKeyChallenge,
|
|
CryptoInfo->StartKey,
|
|
MAX_USERSESSIONKEY_SIZE);
|
|
|
|
//
|
|
// Append the challenge
|
|
//
|
|
NdisMoveMemory((PUCHAR)(SessionKeyChallenge + MAX_USERSESSIONKEY_SIZE),
|
|
Challenge,
|
|
MAX_CHALLENGE_SIZE);
|
|
|
|
//
|
|
// SHAInit(context)
|
|
// SHAUpdate(context, sessionkey, sessionkeylength)
|
|
// SHAUpdate(context, sessionkeychallenge, sessionkeylength + challengelength)
|
|
// SHAFinal(context, digest)
|
|
//
|
|
// Start key is the first 16 bytes of the digest.
|
|
//
|
|
A_SHAInit(CryptoInfo->Context);
|
|
|
|
A_SHAUpdate(CryptoInfo->Context,
|
|
CryptoInfo->StartKey,
|
|
MAX_USERSESSIONKEY_SIZE);
|
|
|
|
A_SHAUpdate(CryptoInfo->Context,
|
|
SessionKeyChallenge,
|
|
MAX_USERSESSIONKEY_SIZE + MAX_CHALLENGE_SIZE);
|
|
|
|
A_SHAFinal(CryptoInfo->Context,
|
|
Digest);
|
|
|
|
NdisMoveMemory(CryptoInfo->StartKey,
|
|
Digest,
|
|
CryptoInfo->SessionKeyLength);
|
|
|
|
NdisMoveMemory(CryptoInfo->SessionKey,
|
|
Digest,
|
|
CryptoInfo->SessionKeyLength);
|
|
}
|
|
|
|
VOID
|
|
GetNewKeyFromSHA(
|
|
PCRYPTO_INFO CryptoInfo
|
|
)
|
|
{
|
|
UCHAR Digest[A_SHA_DIGEST_LEN];
|
|
|
|
NdisZeroMemory(Digest, A_SHA_DIGEST_LEN);
|
|
|
|
A_SHAInit(CryptoInfo->Context);
|
|
A_SHAUpdate(CryptoInfo->Context,
|
|
CryptoInfo->StartKey,
|
|
CryptoInfo->SessionKeyLength);
|
|
A_SHAUpdate(CryptoInfo->Context,
|
|
SHApad1,
|
|
40);
|
|
A_SHAUpdate(CryptoInfo->Context,
|
|
CryptoInfo->SessionKey,
|
|
CryptoInfo->SessionKeyLength);
|
|
A_SHAUpdate(CryptoInfo->Context,
|
|
SHApad2,
|
|
40);
|
|
A_SHAFinal(CryptoInfo->Context,
|
|
Digest);
|
|
|
|
NdisMoveMemory(CryptoInfo->SessionKey,
|
|
Digest,
|
|
CryptoInfo->SessionKeyLength);
|
|
}
|
|
|
|
VOID
|
|
GetMasterKey(
|
|
PCRYPTO_INFO CryptoInfo,
|
|
PUCHAR NTResponse
|
|
)
|
|
{
|
|
UCHAR Digest[A_SHA_DIGEST_LEN];
|
|
PVOID Context;
|
|
|
|
NdisZeroMemory(Digest, A_SHA_DIGEST_LEN);
|
|
|
|
Context = CryptoInfo->Context;
|
|
|
|
A_SHAInit(Context);
|
|
|
|
#ifdef DEBUG_CCP
|
|
{
|
|
PUCHAR Key;
|
|
|
|
Key = CryptoInfo->StartKey;
|
|
|
|
DbgPrint("GMK-UserSessionKey: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
|
|
Key[0],Key[1],Key[2],Key[3],
|
|
Key[4],Key[5],Key[6],Key[7],
|
|
Key[8],Key[9],Key[10],Key[11],
|
|
Key[12],Key[13],Key[14],Key[15]);
|
|
|
|
Key = NTResponse;
|
|
|
|
DbgPrint("GMK-NTResponse: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
|
|
Key[0],Key[1],Key[2],Key[3],
|
|
Key[4],Key[5],Key[6],Key[7],
|
|
Key[8],Key[9],Key[10],Key[11],
|
|
Key[12],Key[13],Key[14],Key[15]);
|
|
|
|
DbgPrint(" %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
|
|
Key[16],Key[17],Key[18],Key[19],
|
|
Key[20],Key[21],Key[22],Key[23]);
|
|
}
|
|
#endif
|
|
|
|
A_SHAUpdate(Context,
|
|
CryptoInfo->StartKey,
|
|
MAX_USERSESSIONKEY_SIZE);
|
|
|
|
A_SHAUpdate(Context,
|
|
NTResponse,
|
|
MAX_NT_RESPONSE);
|
|
|
|
A_SHAUpdate(Context,
|
|
"This is the MPPE Master Key",
|
|
27);
|
|
|
|
A_SHAFinal(Context, Digest);
|
|
|
|
NdisMoveMemory(CryptoInfo->StartKey,
|
|
Digest,
|
|
MAX_USERSESSIONKEY_SIZE);
|
|
|
|
#ifdef DEBUG_CCP
|
|
{
|
|
PUCHAR Key;
|
|
|
|
Key = CryptoInfo->StartKey;
|
|
|
|
DbgPrint("MasterKey: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
|
|
Key[0],Key[1],Key[2],Key[3],
|
|
Key[4],Key[5],Key[6],Key[7],
|
|
Key[8],Key[9],Key[10],Key[11],
|
|
Key[12],Key[13],Key[14],Key[15]);
|
|
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
VOID
|
|
GetAsymetricStartKey(
|
|
PCRYPTO_INFO CryptoInfo,
|
|
BOOLEAN IsSend
|
|
)
|
|
{
|
|
UCHAR Digest[A_SHA_DIGEST_LEN];
|
|
PVOID Context;
|
|
PUCHAR s;
|
|
|
|
NdisZeroMemory(Digest, A_SHA_DIGEST_LEN);
|
|
|
|
Context = CryptoInfo->Context;
|
|
|
|
if (IsSend) {
|
|
if (CryptoInfo->Flags & CRYPTO_IS_SERVER) {
|
|
s = ClntRSrvS;
|
|
} else {
|
|
s = ClntSSrvR;
|
|
}
|
|
} else {
|
|
if (CryptoInfo->Flags & CRYPTO_IS_SERVER) {
|
|
s = ClntSSrvR;
|
|
} else {
|
|
s = ClntRSrvS;
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG_CCP
|
|
{
|
|
PUCHAR Key;
|
|
|
|
Key = CryptoInfo->StartKey;
|
|
|
|
DbgPrint("GASK-StartKey: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
|
|
Key[0],Key[1],Key[2],Key[3],
|
|
Key[4],Key[5],Key[6],Key[7],
|
|
Key[8],Key[9],Key[10],Key[11],
|
|
Key[12],Key[13],Key[14],Key[15]);
|
|
|
|
DbgPrint("GASK-String: %s\n", s);
|
|
}
|
|
#endif
|
|
|
|
A_SHAInit(Context);
|
|
|
|
A_SHAUpdate(Context,
|
|
CryptoInfo->StartKey,
|
|
MAX_USERSESSIONKEY_SIZE);
|
|
|
|
A_SHAUpdate(Context,SHApad1,40);
|
|
|
|
A_SHAUpdate(Context,s,strlen(s));
|
|
|
|
A_SHAUpdate(Context,SHApad2,40);
|
|
|
|
A_SHAFinal(Context,Digest);
|
|
|
|
NdisMoveMemory(CryptoInfo->StartKey,
|
|
Digest,
|
|
CryptoInfo->SessionKeyLength);
|
|
|
|
NdisMoveMemory(CryptoInfo->SessionKey,
|
|
Digest,
|
|
CryptoInfo->SessionKeyLength);
|
|
|
|
#ifdef DEBUG_CCP
|
|
{
|
|
PUCHAR Key;
|
|
|
|
Key = CryptoInfo->StartKey;
|
|
|
|
DbgPrint("%s %s AsymetricKey: %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n",
|
|
(CryptoInfo->Flags & CRYPTO_IS_SERVER) ? "Server" : "Client",
|
|
(IsSend) ? "Send" : "Recv",
|
|
Key[0],Key[1],Key[2],Key[3],
|
|
Key[4],Key[5],Key[6],Key[7],
|
|
Key[8],Key[9],Key[10],Key[11],
|
|
Key[12],Key[13],Key[14],Key[15]);
|
|
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* Copyright (C) RSA Data Security, Inc. created 1993. This is an
|
|
unpublished work protected as such under copyright law. This work
|
|
contains proprietary, confidential, and trade secret information of
|
|
RSA Data Security, Inc. Use, disclosure or reproduction without the
|
|
express written authorization of RSA Data Security, Inc. is
|
|
prohibited.
|
|
*/
|
|
|
|
/* SHA initialization. Begins an SHA operation, writing a new context.
|
|
*/
|
|
void A_SHAInitCommon (context)
|
|
A_SHA_COMM_CTX *context;
|
|
{
|
|
context->count[0] = context->count[1] = 0;
|
|
|
|
/* Load magic initialization constants.
|
|
*/
|
|
context->state[0] = 0x67452301;
|
|
context->state[1] = 0xefcdab89;
|
|
context->state[2] = 0x98badcfe;
|
|
context->state[3] = 0x10325476;
|
|
context->state[4] = 0xc3d2e1f0;
|
|
}
|
|
|
|
/* SHA block update operation. Continues an SHA message-digest
|
|
operation, processing another message block, and updating the
|
|
context.
|
|
*/
|
|
void A_SHAUpdateCommon (context, partIn, partInLen, Transform)
|
|
A_SHA_COMM_CTX *context;
|
|
unsigned char *partIn;
|
|
ULONG partInLen;
|
|
A_SHA_TRANSFORM *Transform;
|
|
{
|
|
unsigned int bufferLen;
|
|
|
|
/* Compute length of buffer */
|
|
bufferLen = (unsigned int)(context->count[1] & 0x3f);
|
|
|
|
/* Update number of bytes */
|
|
if ((context->count[1] += partInLen) < partInLen)
|
|
context->count[0]++;
|
|
|
|
/* If previous input in buffer, buffer new input and transform if
|
|
possible.
|
|
*/
|
|
if (bufferLen > 0 && bufferLen + partInLen >= 64) {
|
|
NdisMoveMemory(context->buffer+bufferLen, partIn, 64-bufferLen);
|
|
partIn += (64-bufferLen);
|
|
partInLen -= (64-bufferLen);
|
|
(*Transform) (context->state, context->buffer);
|
|
bufferLen = 0;
|
|
}
|
|
|
|
/* Transform directly from input.
|
|
*/
|
|
while (partInLen >= 64) {
|
|
(*Transform) (context->state, partIn);
|
|
partIn += 64;
|
|
partInLen -= 64;
|
|
}
|
|
|
|
/* Buffer remaining input */
|
|
NdisMoveMemory((context->buffer+bufferLen), partIn, partInLen);
|
|
}
|
|
|
|
/* SHA finalization. Ends an SHA message-digest operation, writing
|
|
the message digest and zeroizing the context.
|
|
*/
|
|
void A_SHAFinalCommon (context, digest, Transform)
|
|
A_SHA_COMM_CTX *context;
|
|
unsigned char digest[A_SHA_DIGEST_LEN];
|
|
A_SHA_TRANSFORM *Transform;
|
|
{
|
|
ULONG bitCount[2];
|
|
unsigned char pad[72];
|
|
unsigned int padLen;
|
|
|
|
/* Compute padding: 80 00 00 ... 00 00 <bit count>
|
|
*/
|
|
padLen = 64 - (unsigned int)(context->count[1] & 0x3f);
|
|
if (padLen <= 8)
|
|
padLen += 64;
|
|
pad[0] = 0x80;
|
|
NdisZeroMemory(pad+1, padLen-7);
|
|
bitCount[0] = (context->count[0] << 3) | (context->count[1] >> 29);
|
|
bitCount[1] = context->count[1] << 3;
|
|
ByteReverse ((UNALIGNED ULONG*)(pad+padLen-8), bitCount, 2);
|
|
|
|
/* Digest padding */
|
|
A_SHAUpdateCommon (context, pad, padLen, Transform);
|
|
|
|
/* Store digest */
|
|
ByteReverse ((UNALIGNED ULONG*)digest, context->state, 5);
|
|
|
|
/* Restart the context */
|
|
A_SHAInitCommon (context);
|
|
}
|
|
|
|
void A_SHAInit (A_SHA_CTX *context)
|
|
{
|
|
A_SHAInitCommon (&context->commonContext);
|
|
}
|
|
|
|
void A_SHAUpdate (context, partIn, partInLen)
|
|
A_SHA_CTX *context;
|
|
unsigned char *partIn;
|
|
unsigned int partInLen;
|
|
{
|
|
A_SHAUpdateCommon (&context->commonContext, partIn, partInLen, SHATransform);
|
|
}
|
|
|
|
void A_SHAFinal (context, digest)
|
|
A_SHA_CTX *context;
|
|
unsigned char digest[A_SHA_DIGEST_LEN];
|
|
{
|
|
A_SHAFinalCommon (&context->commonContext, digest, SHATransform);
|
|
}
|
|
|
|
void SHATransform (state, block)
|
|
ULONG state[5];
|
|
unsigned char block[64];
|
|
{
|
|
ULONG a = state[0], b = state[1], c = state[2], d = state[3],
|
|
e = state[4], x[80];
|
|
|
|
ByteReverse (x, (ULONG*)block, 16);
|
|
SHAExpand (x);
|
|
|
|
/* Round 1 */
|
|
FF (a, b, c, d, e, x[ 0]);
|
|
FF (e, a, b, c, d, x[ 1]);
|
|
FF (d, e, a, b, c, x[ 2]);
|
|
FF (c, d, e, a, b, x[ 3]);
|
|
FF (b, c, d, e, a, x[ 4]);
|
|
FF (a, b, c, d, e, x[ 5]);
|
|
FF (e, a, b, c, d, x[ 6]);
|
|
FF (d, e, a, b, c, x[ 7]);
|
|
FF (c, d, e, a, b, x[ 8]);
|
|
FF (b, c, d, e, a, x[ 9]);
|
|
FF (a, b, c, d, e, x[10]);
|
|
FF (e, a, b, c, d, x[11]);
|
|
FF (d, e, a, b, c, x[12]);
|
|
FF (c, d, e, a, b, x[13]);
|
|
FF (b, c, d, e, a, x[14]);
|
|
FF (a, b, c, d, e, x[15]);
|
|
FF (e, a, b, c, d, x[16]);
|
|
FF (d, e, a, b, c, x[17]);
|
|
FF (c, d, e, a, b, x[18]);
|
|
FF (b, c, d, e, a, x[19]);
|
|
|
|
/* Round 2 */
|
|
GG (a, b, c, d, e, x[20]);
|
|
GG (e, a, b, c, d, x[21]);
|
|
GG (d, e, a, b, c, x[22]);
|
|
GG (c, d, e, a, b, x[23]);
|
|
GG (b, c, d, e, a, x[24]);
|
|
GG (a, b, c, d, e, x[25]);
|
|
GG (e, a, b, c, d, x[26]);
|
|
GG (d, e, a, b, c, x[27]);
|
|
GG (c, d, e, a, b, x[28]);
|
|
GG (b, c, d, e, a, x[29]);
|
|
GG (a, b, c, d, e, x[30]);
|
|
GG (e, a, b, c, d, x[31]);
|
|
GG (d, e, a, b, c, x[32]);
|
|
GG (c, d, e, a, b, x[33]);
|
|
GG (b, c, d, e, a, x[34]);
|
|
GG (a, b, c, d, e, x[35]);
|
|
GG (e, a, b, c, d, x[36]);
|
|
GG (d, e, a, b, c, x[37]);
|
|
GG (c, d, e, a, b, x[38]);
|
|
GG (b, c, d, e, a, x[39]);
|
|
|
|
/* Round 3 */
|
|
HH (a, b, c, d, e, x[40]);
|
|
HH (e, a, b, c, d, x[41]);
|
|
HH (d, e, a, b, c, x[42]);
|
|
HH (c, d, e, a, b, x[43]);
|
|
HH (b, c, d, e, a, x[44]);
|
|
HH (a, b, c, d, e, x[45]);
|
|
HH (e, a, b, c, d, x[46]);
|
|
HH (d, e, a, b, c, x[47]);
|
|
HH (c, d, e, a, b, x[48]);
|
|
HH (b, c, d, e, a, x[49]);
|
|
HH (a, b, c, d, e, x[50]);
|
|
HH (e, a, b, c, d, x[51]);
|
|
HH (d, e, a, b, c, x[52]);
|
|
HH (c, d, e, a, b, x[53]);
|
|
HH (b, c, d, e, a, x[54]);
|
|
HH (a, b, c, d, e, x[55]);
|
|
HH (e, a, b, c, d, x[56]);
|
|
HH (d, e, a, b, c, x[57]);
|
|
HH (c, d, e, a, b, x[58]);
|
|
HH (b, c, d, e, a, x[59]);
|
|
|
|
/* Round 4 */
|
|
II (a, b, c, d, e, x[60]);
|
|
II (e, a, b, c, d, x[61]);
|
|
II (d, e, a, b, c, x[62]);
|
|
II (c, d, e, a, b, x[63]);
|
|
II (b, c, d, e, a, x[64]);
|
|
II (a, b, c, d, e, x[65]);
|
|
II (e, a, b, c, d, x[66]);
|
|
II (d, e, a, b, c, x[67]);
|
|
II (c, d, e, a, b, x[68]);
|
|
II (b, c, d, e, a, x[69]);
|
|
II (a, b, c, d, e, x[70]);
|
|
II (e, a, b, c, d, x[71]);
|
|
II (d, e, a, b, c, x[72]);
|
|
II (c, d, e, a, b, x[73]);
|
|
II (b, c, d, e, a, x[74]);
|
|
II (a, b, c, d, e, x[75]);
|
|
II (e, a, b, c, d, x[76]);
|
|
II (d, e, a, b, c, x[77]);
|
|
II (c, d, e, a, b, x[78]);
|
|
II (b, c, d, e, a, x[79]);
|
|
|
|
state[0] += a;
|
|
state[1] += b;
|
|
state[2] += c;
|
|
state[3] += d;
|
|
state[4] += e;
|
|
|
|
/* Zeroize potentially sensitive information.
|
|
*/
|
|
NdisZeroMemory((void *)x, sizeof (x));
|
|
}
|
|
|
|
/* Expands x[0..15] into x[16..79], according to the recurrence
|
|
x[i] = x[i-3] ^ x[i-8] ^ x[i-14] ^ x[i-16].
|
|
*/
|
|
void SHAExpand (x)
|
|
ULONG x[80];
|
|
{
|
|
unsigned int i;
|
|
ULONG tmp;
|
|
|
|
for (i = 16; i < 80; i++)
|
|
{
|
|
tmp = x[i-3] ^ x[i-8] ^ x[i-14] ^ x[i-16];
|
|
x[i] = (tmp << 1) | (tmp >> 31);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ByteReverse(
|
|
UNALIGNED ULONG *Out,
|
|
ULONG *In,
|
|
ULONG Count
|
|
)
|
|
{
|
|
ULONG i;
|
|
ULONG Value;
|
|
|
|
for (i = 0; i < Count; i++) {
|
|
Value = (ULONG)(In[i] << 16) | (In[i] >> 16);
|
|
Out[i] = ((Value & 0xFF00FF00L) >> 8) | ((Value & 0x00FF00FFL) << 8);
|
|
}
|
|
}
|
|
|