Leaked source code of windows server 2003
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.

387 lines
7.7 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name:
  4. encrypt.c
  5. Abstract:
  6. Contains functions that encrypt and decrypt data sent accross client and
  7. server.
  8. Author:
  9. Madan Appiah (madana) 24-Jan-1998
  10. Environment:
  11. User Mode - Win32
  12. Revision History:
  13. --*/
  14. #include <seccom.h>
  15. VOID
  16. GenerateMACSignature(
  17. LPBYTE pbData,
  18. DWORD dwDataLen,
  19. LPBYTE pbMACSaltKey,
  20. DWORD dwMACSaltKey,
  21. LPBYTE pbSignature,
  22. BOOL fIncludeEncryptionCount,
  23. DWORD dwEncryptionCount
  24. )
  25. /*++
  26. Routine Description:
  27. This function generates a message authentication signature.
  28. Arguments:
  29. pbData - pointer to a data buffer.
  30. dwDataLen - length of the above data.
  31. pbMACSaltKey - pointer to a MAC salt key.
  32. pbSignature - pointer a signature buffer.
  33. fIncludeEncryptionCount - TRUE to salt in the encryption count
  34. dwEncryptionCount - total encryption count
  35. Return Value:
  36. None.
  37. --*/
  38. {
  39. A_SHA_CTX SHAHash;
  40. MD5_CTX MD5Hash;
  41. BYTE abSHADigest[A_SHA_DIGEST_LEN];
  42. //
  43. // make a SHA(MACSalt + g_abPad1 + Length + Content) hash.
  44. //
  45. A_SHAInit(&SHAHash);
  46. A_SHAUpdate(&SHAHash, pbMACSaltKey, dwMACSaltKey);
  47. A_SHAUpdate(&SHAHash, (unsigned char *)g_abPad1, 40);
  48. A_SHAUpdate(&SHAHash, (LPBYTE)&dwDataLen, sizeof(DWORD));
  49. A_SHAUpdate(&SHAHash, pbData, dwDataLen);
  50. if (fIncludeEncryptionCount) {
  51. A_SHAUpdate(&SHAHash, (LPBYTE)&dwEncryptionCount, sizeof(DWORD));
  52. }
  53. A_SHAFinal(&SHAHash, abSHADigest);
  54. //
  55. // make a MD5(MACSalt + g_abPad2 + SHAHash) hash.
  56. //
  57. MD5Init(&MD5Hash);
  58. MD5Update(&MD5Hash, pbMACSaltKey, dwMACSaltKey);
  59. MD5Update(&MD5Hash, g_abPad2, 48);
  60. MD5Update(&MD5Hash, abSHADigest, A_SHA_DIGEST_LEN);
  61. MD5Final(&MD5Hash);
  62. ASSERT( DATA_SIGNATURE_SIZE <= MD5DIGESTLEN );
  63. memcpy(pbSignature, MD5Hash.digest, DATA_SIGNATURE_SIZE);
  64. return;
  65. }
  66. BOOL
  67. EncryptData(
  68. DWORD dwEncryptionLevel,
  69. LPBYTE pSessionKey,
  70. struct RC4_KEYSTRUCT FAR *prc4EncryptKey,
  71. DWORD dwKeyLength,
  72. LPBYTE pbData,
  73. DWORD dwDataLen,
  74. LPBYTE pbMACSaltKey,
  75. LPBYTE pbSignature,
  76. BOOL fSecureChecksum,
  77. DWORD dwEncryptionCount
  78. )
  79. /*++
  80. Routine Description:
  81. Encrypt the given data buffer in place.
  82. Arguments:
  83. dwEncryptionLevel - encryption level, used to select the encryption
  84. algorithm.
  85. pSessionKey - pointer to the session key.
  86. prc4EncryptKey - pointer to a RC4 key.
  87. dwKeyLength - length of the session key.
  88. pbData - pointer to the data buffer being encrypted, encrypted data is
  89. returned in the same buffer.
  90. dwDataLen - length of the data buffer.
  91. pbMACSaltKey - pointer to a message authentication key buffer.
  92. pbSignature - pointer to a signature buffer where the data signature is
  93. returned.
  94. fSecureChecksum - TRUE if the checksum is to be salted with the encryption
  95. count
  96. dwDecryptionCount - running counter of all encryptions
  97. Return Value:
  98. TRUE - if successfully encrypted the data.
  99. FALSE - otherwise.
  100. --*/
  101. {
  102. //
  103. // generate the MAC signature first.
  104. //
  105. GenerateMACSignature (
  106. pbData,
  107. dwDataLen,
  108. pbMACSaltKey,
  109. dwKeyLength,
  110. pbSignature,
  111. fSecureChecksum,
  112. dwEncryptionCount
  113. );
  114. //
  115. // encrypt data.
  116. //
  117. //
  118. // use microsoft version of rc4 algorithm (super fast!) for level 1 and
  119. // level 2 encryption, for level 3 use RSA rc4 algorithm.
  120. //
  121. if( dwEncryptionLevel <= 2 ) {
  122. msrc4(prc4EncryptKey, (UINT)dwDataLen, pbData );
  123. }
  124. else {
  125. rc4(prc4EncryptKey, (UINT)dwDataLen, pbData );
  126. }
  127. return( TRUE );
  128. }
  129. BOOL
  130. DecryptData(
  131. DWORD dwEncryptionLevel,
  132. LPBYTE pSessionKey,
  133. struct RC4_KEYSTRUCT FAR *prc4DecryptKey,
  134. DWORD dwKeyLength,
  135. LPBYTE pbData,
  136. DWORD dwDataLen,
  137. LPBYTE pbMACSaltKey,
  138. LPBYTE pbSignature,
  139. BOOL fSecureChecksum,
  140. DWORD dwDecryptionCount
  141. )
  142. /*++
  143. Routine Description:
  144. Decrypt the given data buffer in place.
  145. Arguments:
  146. dwEncryptionLevel - encryption level, used to select the encryption
  147. algorithm.
  148. pSessionKey - pointer to the session key.
  149. prc4DecryptKey - pointer to a RC4 key.
  150. dwKeyLength - length of the session key.
  151. pbData - pointer to the data buffer being decrypted, decrypted data is
  152. returned in the same buffer.
  153. dwDataLen - length of the data buffer.
  154. pbMACSaltKey - pointer to a message authentication key buffer.
  155. pbSignature - pointer to a signature buffer where the data signature is
  156. returned.
  157. fSecureChecksum - TRUE if the checksum is to be salted with the encryption
  158. count
  159. dwDecryptionCount - running counter of all encryptions
  160. Return Value:
  161. TRUE - if successfully encrypted the data.
  162. FALSE - otherwise.
  163. --*/
  164. {
  165. BYTE abSignature[DATA_SIGNATURE_SIZE];
  166. //
  167. // decrypt data.
  168. //
  169. //
  170. // use microsoft version of rc4 algorithm (super fast!) for level 1 and
  171. // level 2 encryption, for level 3 use RSA rc4 algorithm.
  172. //
  173. if( dwEncryptionLevel <= 2 ) {
  174. msrc4(prc4DecryptKey, (UINT)dwDataLen, pbData );
  175. }
  176. else {
  177. rc4(prc4DecryptKey, (UINT)dwDataLen, pbData );
  178. }
  179. GenerateMACSignature (
  180. pbData,
  181. dwDataLen,
  182. pbMACSaltKey,
  183. dwKeyLength,
  184. (LPBYTE)abSignature,
  185. fSecureChecksum,
  186. dwDecryptionCount
  187. );
  188. //
  189. // check to see the sigature match.
  190. //
  191. if( memcmp(
  192. (LPBYTE)abSignature,
  193. pbSignature,
  194. sizeof(abSignature) ) ) {
  195. return( FALSE );
  196. }
  197. return( TRUE );
  198. }
  199. #ifdef USE_MSRC4
  200. VOID
  201. msrc4_key(
  202. struct RC4_KEYSTRUCT FAR *pKS,
  203. DWORD dwLen,
  204. LPBYTE pbKey
  205. )
  206. /*++
  207. Routine Description:
  208. Generate the key control structure. Key can be any size.
  209. Assumes pKS is locked against simultaneous use.
  210. Arguments:
  211. pKS - pointer to a KEYSTRUCT structure that will be initialized.
  212. dwLen - Size of the key, in bytes.
  213. pbKey - Pointer to the key.
  214. Return Value:
  215. NONE.
  216. --*/
  217. {
  218. #define SWAP(_x_, _y_) { BYTE _t_; _t_ = (_x_); (_x_) = (_y_); (_y_) = _t_; }
  219. BYTE index1;
  220. BYTE index2;
  221. UINT counter;
  222. BYTE bLen;
  223. ASSERT( dwLen < 256 );
  224. bLen = ( dwLen >= 256 ) ? 255 : (BYTE)dwLen;
  225. for (counter = 0; counter < 256; counter++) {
  226. pKS->S[counter] = (BYTE) counter;
  227. }
  228. pKS->i = 0;
  229. pKS->j = 0;
  230. index1 = 0;
  231. index2 = 0;
  232. for (counter = 0; counter < 256; counter++) {
  233. index2 = (pbKey[index1] + pKS->S[counter] + index2);
  234. SWAP(pKS->S[counter], pKS->S[index2]);
  235. index1 = (index1 + 1) % bLen;
  236. }
  237. }
  238. VOID
  239. msrc4(
  240. struct RC4_KEYSTRUCT FAR *pKS,
  241. DWORD dwLen,
  242. LPBYTE pbuf
  243. )
  244. /*++
  245. Routine Description:
  246. Performs the actual encryption or decryption.
  247. Assumes pKS is locked against simultaneous use.
  248. Arguments:
  249. pKS - Pointer to the KEYSTRUCT created using msrc4_key().
  250. dwLen - Size of buffer, in bytes.
  251. pbuf - Buffer to be encrypted.
  252. Return Value:
  253. NONE.
  254. --*/
  255. {
  256. BYTE FAR *const s = pKS->S;
  257. BYTE a, b;
  258. while(dwLen--) {
  259. a = s[++(pKS->i)];
  260. pKS->j += a;
  261. b = s[pKS->j];
  262. s[pKS->j] = a;
  263. a += b;
  264. s[pKS->i] = b;
  265. *pbuf++ ^= s[a];
  266. }
  267. }
  268. #endif // USE_MSRC4