Source code of Windows XP (NT5)
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.

352 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. crc32.c
  5. Abstract:
  6. CRC-32 alogorithm
  7. Author:
  8. MikeSw
  9. Revision History:
  10. 31-Mar-94 MikeSw Created
  11. 25-Jul-96 ChandanS Copied from net\svcdlls\ntlmssp\client\crc32.c
  12. 27-Jan-07 MikeSw Incorporated x86 ASM code for performance
  13. --*/
  14. #ifndef KERNEL_MODE
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <nturtl.h>
  18. #include <windows.h>
  19. #else
  20. #include <ntifs.h>
  21. #include <winerror.h>
  22. #endif
  23. #include <string.h>
  24. #include <malloc.h>
  25. #include <kerbcon.h>
  26. #include <security.h>
  27. #include <cryptdll.h>
  28. #define CRC32_LEN 4
  29. NTSTATUS
  30. Crc32Initialize(ULONG dwSeed,
  31. PCHECKSUM_BUFFER * ppcsBuffer);
  32. NTSTATUS
  33. KerbCrc32Initialize(ULONG dwSeed,
  34. PCHECKSUM_BUFFER * ppcsBuffer);
  35. NTSTATUS
  36. Crc32Sum( PCHECKSUM_BUFFER pcsBuffer,
  37. ULONG cbData,
  38. PUCHAR pbData );
  39. NTSTATUS
  40. Crc32Finalize( PCHECKSUM_BUFFER pcsBuffer,
  41. PUCHAR pbSum);
  42. NTSTATUS
  43. KerbCrc32Finalize( PCHECKSUM_BUFFER pcsBuffer,
  44. PUCHAR pbSum);
  45. NTSTATUS
  46. Crc32InitializeEx( PUCHAR Key,
  47. ULONG KeySize,
  48. ULONG MessageType,
  49. PCHECKSUM_BUFFER *pcsBuffer);
  50. NTSTATUS
  51. KerbCrc32InitializeEx( PUCHAR Key,
  52. ULONG KeySize,
  53. ULONG MessageType,
  54. PCHECKSUM_BUFFER *pcsBuffer);
  55. NTSTATUS
  56. Crc32Finish(PCHECKSUM_BUFFER * ppcsBuffer);
  57. CHECKSUM_FUNCTION csfCRC32 = {
  58. KERB_CHECKSUM_REAL_CRC32,
  59. CRC32_LEN,
  60. 0,
  61. Crc32Initialize,
  62. Crc32Sum,
  63. Crc32Finalize,
  64. Crc32Finish,
  65. Crc32InitializeEx,
  66. NULL
  67. };
  68. CHECKSUM_FUNCTION csfKERB_CRC32 = {
  69. KERB_CHECKSUM_CRC32,
  70. CRC32_LEN,
  71. 0,
  72. KerbCrc32Initialize,
  73. Crc32Sum,
  74. KerbCrc32Finalize,
  75. Crc32Finish,
  76. KerbCrc32InitializeEx,
  77. NULL
  78. };
  79. #ifdef KERNEL_MODE
  80. #pragma alloc_text( PAGEMSG, Crc32Initialize )
  81. #pragma alloc_text( PAGEMSG, Crc32Sum )
  82. #pragma alloc_text( PAGEMSG, Crc32Finalize )
  83. #pragma alloc_text( PAGEMSG, Crc32Finish )
  84. #pragma alloc_text( PAGEMSG, Crc32InitializeEx )
  85. #pragma alloc_text( PAGEMSG, KerbCrc32Initialize )
  86. #pragma alloc_text( PAGEMSG, KerbCrc32Finalize )
  87. #pragma alloc_text( PAGEMSG, KerbCrc32InitializeEx )
  88. #endif
  89. typedef struct _CRC32_CONTEXT {
  90. ULONG crc;
  91. } CRC32_CONTEXT, *PCRC32_CONTEXT;
  92. //
  93. // This code comes from Dr. Dobbs Journal, May 1992
  94. //
  95. static unsigned long CRCTable[256] = {
  96. 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
  97. 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
  98. 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
  99. 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
  100. 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
  101. 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
  102. 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
  103. 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
  104. 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
  105. 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
  106. 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
  107. 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
  108. 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
  109. 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
  110. 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
  111. 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
  112. 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
  113. 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
  114. 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
  115. 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
  116. 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
  117. 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
  118. 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
  119. 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
  120. 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
  121. 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
  122. 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
  123. 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
  124. 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
  125. 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
  126. 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
  127. 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
  128. 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
  129. 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
  130. 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
  131. 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
  132. 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
  133. 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
  134. 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
  135. 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
  136. 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
  137. 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
  138. 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
  139. NTSTATUS
  140. Crc32Sum( PCHECKSUM_BUFFER pcsBuffer,
  141. ULONG cbBuffer,
  142. PUCHAR pvBuffer )
  143. {
  144. PCRC32_CONTEXT pContext = pcsBuffer;
  145. unsigned long dwCrc = pContext->crc;
  146. unsigned char * pbBuffer;
  147. #ifdef _X86_
  148. _asm
  149. {
  150. mov ecx, DWORD PTR cbBuffer
  151. shr ecx, 2
  152. mov eax, ecx
  153. dec ecx
  154. mov esi, DWORD PTR pvBuffer
  155. mov edx, DWORD PTR dwCrc
  156. test eax, eax
  157. je SHORT $LABEL2
  158. inc ecx
  159. $LABEL1:
  160. mov ebx, DWORD PTR [esi]
  161. add esi, 4
  162. mov eax, ebx
  163. shr ebx, 8
  164. xor eax, edx
  165. and eax, 0FFh
  166. shr edx, 8
  167. mov edi, DWORD PTR CRCTable[eax*4]
  168. xor edx, edi
  169. mov eax, ebx
  170. shr ebx, 8
  171. xor eax, edx
  172. and eax, 0FFh
  173. shr edx, 8
  174. mov edi, DWORD PTR CRCTable[eax*4]
  175. xor edx, edi
  176. mov eax, ebx
  177. shr ebx, 8
  178. xor eax, edx
  179. and eax, 0FFh
  180. shr edx, 8
  181. mov edi, DWORD PTR CRCTable[eax*4]
  182. xor edx, edi
  183. mov eax, ebx
  184. ; shr ebx, 8 -- Not needed on last byte
  185. xor eax, edx
  186. and eax, 0FFh
  187. shr edx, 8
  188. mov edi, DWORD PTR CRCTable[eax*4]
  189. xor edx, edi
  190. dec ecx
  191. jne SHORT $LABEL1
  192. $LABEL2:
  193. mov DWORD PTR dwCrc, edx
  194. mov DWORD PTR pbBuffer, esi
  195. }
  196. cbBuffer &= 0x3;
  197. #else // _X86_
  198. pbBuffer = (unsigned char *) pvBuffer;
  199. #endif
  200. while (cbBuffer-- != 0)
  201. {
  202. dwCrc = (dwCrc >> 8) ^ CRCTable[(unsigned char) dwCrc ^ *pbBuffer++];
  203. }
  204. pContext->crc= dwCrc;
  205. return(STATUS_SUCCESS);
  206. }
  207. NTSTATUS
  208. Crc32Initialize(ULONG dwSeed,
  209. PCHECKSUM_BUFFER * ppcsBuffer)
  210. {
  211. PCRC32_CONTEXT pContext;
  212. #ifdef KERNEL_MODE
  213. pContext = ExAllocatePool(NonPagedPool, sizeof(CRC32_CONTEXT));
  214. #else
  215. pContext = malloc(sizeof(CRC32_CONTEXT));
  216. #endif
  217. if (!pContext)
  218. {
  219. return(SEC_E_INSUFFICIENT_MEMORY);
  220. }
  221. pContext->crc = 0xffffffff;
  222. *ppcsBuffer = (PCHECKSUM_BUFFER) pContext;
  223. return(STATUS_SUCCESS);
  224. }
  225. NTSTATUS
  226. KerbCrc32Initialize(
  227. ULONG dwSeed,
  228. PCHECKSUM_BUFFER * ppcsBuffer
  229. )
  230. {
  231. PCRC32_CONTEXT pContext;
  232. #ifdef KERNEL_MODE
  233. pContext = ExAllocatePool(NonPagedPool, sizeof(CRC32_CONTEXT));
  234. #else
  235. pContext = malloc(sizeof(CRC32_CONTEXT));
  236. #endif
  237. if (!pContext)
  238. {
  239. return(SEC_E_INSUFFICIENT_MEMORY);
  240. }
  241. pContext->crc = 0;
  242. *ppcsBuffer = (PCHECKSUM_BUFFER) pContext;
  243. return(STATUS_SUCCESS);
  244. }
  245. NTSTATUS
  246. Crc32Finalize( PCHECKSUM_BUFFER pcsBuffer,
  247. PUCHAR pbSum)
  248. {
  249. *(PULONG)pbSum = ((PCRC32_CONTEXT)pcsBuffer)->crc ^ 0xffffffff;
  250. return(STATUS_SUCCESS);
  251. }
  252. NTSTATUS
  253. KerbCrc32Finalize(
  254. PCHECKSUM_BUFFER pcsBuffer,
  255. PUCHAR pbSum
  256. )
  257. {
  258. *(PULONG)pbSum = ((PCRC32_CONTEXT)pcsBuffer)->crc;
  259. return(STATUS_SUCCESS);
  260. }
  261. NTSTATUS
  262. Crc32Finish(PCHECKSUM_BUFFER * ppcsBuffer)
  263. {
  264. #ifdef KERNEL_MODE
  265. ExFreePool(*ppcsBuffer);
  266. #else
  267. free(*ppcsBuffer);
  268. #endif
  269. *ppcsBuffer = NULL;
  270. return(STATUS_SUCCESS);
  271. }
  272. NTSTATUS
  273. Crc32InitializeEx( PUCHAR Key,
  274. ULONG KeySize,
  275. ULONG MessageType,
  276. PCHECKSUM_BUFFER *pcsBuffer)
  277. {
  278. return(Crc32Initialize(0, pcsBuffer));
  279. }
  280. NTSTATUS
  281. KerbCrc32InitializeEx( PUCHAR Key,
  282. ULONG KeySize,
  283. ULONG MessageType,
  284. PCHECKSUM_BUFFER *pcsBuffer)
  285. {
  286. return(KerbCrc32Initialize(0, pcsBuffer));
  287. }
  288.