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.

489 lines
11 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. encrypt.c
  5. Abstract:
  6. This module will support data encryption and decryption
  7. Author:
  8. Robert Gu (robertg) 08-Dec-1996
  9. Environment:
  10. Kernel Mode Only
  11. Revision History:
  12. --*/
  13. #include "efsrtl.h"
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text(PAGE, EFSDesEnc)
  16. #pragma alloc_text(PAGE, EFSDesDec)
  17. #pragma alloc_text(PAGE, EFSDesXEnc)
  18. #pragma alloc_text(PAGE, EFSDesXDec)
  19. #pragma alloc_text(PAGE, EFSDes3Enc)
  20. #pragma alloc_text(PAGE, EFSDes3Dec)
  21. #pragma alloc_text(PAGE, EFSAesEnc)
  22. #pragma alloc_text(PAGE, EFSAesDec)
  23. #endif
  24. VOID
  25. EFSDesEnc(
  26. IN PUCHAR InBuffer,
  27. OUT PUCHAR OutBuffer,
  28. IN PUCHAR IV,
  29. IN PKEY_BLOB KeyBlob,
  30. IN LONG Length
  31. )
  32. /*++
  33. Routine Description:
  34. This routine implements DES CBC encryption. The DES is implemented by LIB
  35. function des().
  36. Arguments:
  37. InBuffer - Pointer to the data buffer (encryption in place)
  38. IV - Initial chaining vector (DES_BLOCKLEN bytes)
  39. KeyBlob - Set during the create or FSCTL
  40. Length - Length of the data in the buffer ( Length % DES_BLOCKLEN = 0)
  41. Note:
  42. Input buffer can only be touched once. This the requirement by the Ntfs & CC.
  43. --*/
  44. {
  45. ULONGLONG chainBlock;
  46. ULONGLONG tmpData;
  47. PUCHAR KeyTable;
  48. PAGED_CODE();
  49. ASSERT (Length % DES_BLOCKLEN == 0);
  50. chainBlock = *(ULONGLONG *)IV;
  51. KeyTable = &(KeyBlob->Key[0]);
  52. while (Length > 0){
  53. //
  54. // Block chaining
  55. //
  56. tmpData = *(ULONGLONG *)InBuffer;
  57. tmpData ^= chainBlock;
  58. //
  59. // Call DES LIB to encrypt the DES_BLOCKLEN bytes
  60. // We are using DECRYPT/ENCRYPT for real ENCRYPT/DECRYPT. This is for the backward
  61. // compatiblity. The old definitions were reversed.
  62. //
  63. des( OutBuffer, (PUCHAR) &tmpData, KeyTable, DECRYPT );
  64. chainBlock = *(ULONGLONG *)OutBuffer;
  65. Length -= DES_BLOCKLEN;
  66. InBuffer += DES_BLOCKLEN;
  67. OutBuffer += DES_BLOCKLEN;
  68. }
  69. }
  70. VOID
  71. EFSDesDec(
  72. IN OUT PUCHAR Buffer,
  73. IN PUCHAR IV,
  74. IN PKEY_BLOB KeyBlob,
  75. IN LONG Length
  76. )
  77. /*++
  78. Routine Description:
  79. This routine implements DES CBC decryption. The DES is implemented by LIB
  80. function des().
  81. Arguments:
  82. Buffer - Pointer to the data buffer (decryption in place)
  83. IV - Initial chaining vector (DES_BLOCKLEN bytes)
  84. KeyBlob - Set during the create or FSCTL
  85. Length - Length of the data in the buffer ( Length % DES_BLOCKLEN = 0)
  86. --*/
  87. {
  88. ULONGLONG chainBlock;
  89. PUCHAR pBuffer;
  90. PUCHAR KeyTable;
  91. PAGED_CODE();
  92. ASSERT (Length % DES_BLOCKLEN == 0);
  93. pBuffer = Buffer + Length - DES_BLOCKLEN;
  94. KeyTable = &(KeyBlob->Key[0]);
  95. while (pBuffer > Buffer){
  96. //
  97. // Call DES LIB to decrypt the DES_BLOCKLEN bytes
  98. // We are using DECRYPT/ENCRYPT for real ENCRYPT/DECRYPT. This is for the backward
  99. // compatiblity. The old definitions were reversed.
  100. //
  101. des( pBuffer, pBuffer, KeyTable, ENCRYPT );
  102. //
  103. // Undo the block chaining
  104. //
  105. chainBlock = *(ULONGLONG *)( pBuffer - DES_BLOCKLEN );
  106. *(ULONGLONG *)pBuffer ^= chainBlock;
  107. pBuffer -= DES_BLOCKLEN;
  108. }
  109. //
  110. // Now decrypt the first block
  111. //
  112. des( pBuffer, pBuffer, KeyTable, ENCRYPT );
  113. chainBlock = *(ULONGLONG *)IV;
  114. *(ULONGLONG *)pBuffer ^= chainBlock;
  115. }
  116. VOID
  117. EFSDesXEnc(
  118. IN PUCHAR InBuffer,
  119. OUT PUCHAR OutBuffer,
  120. IN PUCHAR IV,
  121. IN PKEY_BLOB KeyBlob,
  122. IN LONG Length
  123. )
  124. /*++
  125. Routine Description:
  126. This routine implements DESX CBC encryption. The DESX is implemented by
  127. LIBRARY function desx().
  128. Arguments:
  129. InBuffer - Pointer to the data buffer (encryption in place)
  130. IV - Initial chaining vector (DESX_BLOCKLEN bytes)
  131. KeyBlob - Set during the create or FSCTL
  132. Length - Length of the data in the buffer ( Length % DESX_BLOCKLEN = 0)
  133. Note:
  134. Input buffer can only be touched once. This the requirement by the Ntfs & CC.
  135. --*/
  136. {
  137. ULONGLONG chainBlock;
  138. ULONGLONG tmpData;
  139. PUCHAR KeyTable;
  140. PAGED_CODE();
  141. ASSERT (Length % DESX_BLOCKLEN == 0);
  142. chainBlock = *(ULONGLONG *)IV;
  143. KeyTable = &(KeyBlob->Key[0]);
  144. while (Length > 0){
  145. //
  146. // Block chaining
  147. //
  148. tmpData = *(ULONGLONG *)InBuffer;
  149. tmpData ^= chainBlock;
  150. //
  151. // Call LIB to encrypt the DESX_BLOCKLEN bytes
  152. // We are using DECRYPT/ENCRYPT for real ENCRYPT/DECRYPT. This is for the backward
  153. // compatiblity. The old definitions were reversed.
  154. //
  155. desx( OutBuffer, (PUCHAR) &tmpData, KeyTable, DECRYPT );
  156. chainBlock = *(ULONGLONG *)OutBuffer;
  157. Length -= DESX_BLOCKLEN;
  158. InBuffer += DESX_BLOCKLEN;
  159. OutBuffer += DESX_BLOCKLEN;
  160. }
  161. }
  162. VOID
  163. EFSDesXDec(
  164. IN OUT PUCHAR Buffer,
  165. IN PUCHAR IV,
  166. IN PKEY_BLOB KeyBlob,
  167. IN LONG Length
  168. )
  169. /*++
  170. Routine Description:
  171. This routine implements DESX CBC decryption. The DESX is implemented by
  172. LIBRARY function desx().
  173. Arguments:
  174. Buffer - Pointer to the data buffer (decryption in place)
  175. IV - Initial chaining vector (DESX_BLOCKLEN bytes)
  176. KeyBlob - Set during the create or FSCTL
  177. Length - Length of the data in the buffer ( Length % DESX_BLOCKLEN = 0)
  178. --*/
  179. {
  180. ULONGLONG chainBlock;
  181. PUCHAR pBuffer;
  182. PUCHAR KeyTable;
  183. PAGED_CODE();
  184. ASSERT (Length % DESX_BLOCKLEN == 0);
  185. pBuffer = Buffer + Length - DESX_BLOCKLEN;
  186. KeyTable = &(KeyBlob->Key[0]);
  187. while (pBuffer > Buffer){
  188. //
  189. // Call LIB to decrypt the DESX_BLOCKLEN bytes
  190. // We are using DECRYPT/ENCRYPT for real ENCRYPT/DECRYPT. This is for the backward
  191. // compatiblity. The old definitions were reversed.
  192. //
  193. desx( pBuffer, pBuffer, KeyTable, ENCRYPT );
  194. //
  195. // Undo the block chaining
  196. //
  197. chainBlock = *(ULONGLONG *)( pBuffer - DESX_BLOCKLEN );
  198. *(ULONGLONG *)pBuffer ^= chainBlock;
  199. pBuffer -= DESX_BLOCKLEN;
  200. }
  201. //
  202. // Now decrypt the first block
  203. //
  204. desx( pBuffer, pBuffer, KeyTable, ENCRYPT );
  205. chainBlock = *(ULONGLONG *)IV;
  206. *(ULONGLONG *)pBuffer ^= chainBlock;
  207. }
  208. VOID
  209. EFSDes3Enc(
  210. IN PUCHAR InBuffer,
  211. OUT PUCHAR OutBuffer,
  212. IN PUCHAR IV,
  213. IN PKEY_BLOB KeyBlob,
  214. IN LONG Length
  215. )
  216. /*++
  217. Routine Description:
  218. This routine implements DES3 CBC encryption. The DES3 is implemented by
  219. LIBRARY function tripledes().
  220. Arguments:
  221. InBuffer - Pointer to the data buffer (encryption in place)
  222. IV - Initial chaining vector (DES_BLOCKLEN bytes)
  223. KeyBlob - Set during the create or FSCTL
  224. Length - Length of the data in the buffer ( Length % DES_BLOCKLEN = 0)
  225. Note:
  226. Input buffer can only be touched once. This the requirement by the Ntfs & CC.
  227. --*/
  228. {
  229. ULONGLONG chainBlock = *(ULONGLONG *)IV;
  230. ULONGLONG tmpData;
  231. PUCHAR KeyTable;
  232. ASSERT (Length % DES_BLOCKLEN == 0);
  233. EfsData.FipsFunctionTable.FipsBlockCBC(
  234. FIPS_CBC_3DES,
  235. OutBuffer,
  236. InBuffer,
  237. Length,
  238. &(KeyBlob->Key[0]),
  239. ENCRYPT,
  240. (PUCHAR) &chainBlock
  241. );
  242. }
  243. VOID
  244. EFSDes3Dec(
  245. IN OUT PUCHAR Buffer,
  246. IN PUCHAR IV,
  247. IN PKEY_BLOB KeyBlob,
  248. IN LONG Length
  249. )
  250. /*++
  251. Routine Description:
  252. This routine implements DES3 CBC decryption. The DES3 is implemented by
  253. LIBRARY function tripledes().
  254. Arguments:
  255. Buffer - Pointer to the data buffer (decryption in place)
  256. IV - Initial chaining vector (DES_BLOCKLEN bytes)
  257. KeyBlob - Set during the create or FSCTL
  258. Length - Length of the data in the buffer ( Length % DES_BLOCKLEN = 0)
  259. --*/
  260. {
  261. ULONGLONG ChainIV = *(ULONGLONG *)IV;
  262. ASSERT (Length % DESX_BLOCKLEN == 0);
  263. EfsData.FipsFunctionTable.FipsBlockCBC(
  264. FIPS_CBC_3DES,
  265. Buffer,
  266. Buffer,
  267. Length,
  268. &(KeyBlob->Key[0]),
  269. DECRYPT,
  270. (PUCHAR) &ChainIV
  271. );
  272. }
  273. VOID
  274. EFSAesEnc(
  275. IN PUCHAR InBuffer,
  276. OUT PUCHAR OutBuffer,
  277. IN PUCHAR IV,
  278. IN PKEY_BLOB KeyBlob,
  279. IN LONG Length
  280. )
  281. /*++
  282. Routine Description:
  283. This routine implements AES CBC encryption. The AES is implemented by
  284. LIBRARY function aes().
  285. Arguments:
  286. InBuffer - Pointer to the data buffer (encryption in place)
  287. IV - Initial chaining vector (AES_BLOCKLEN bytes)
  288. KeyBlob - Set during the create or FSCTL
  289. Length - Length of the data in the buffer ( Length % AES_BLOCKLEN = 0)
  290. Note:
  291. Input buffer can only be touched once. This the requirement by the Ntfs & CC.
  292. --*/
  293. {
  294. ULONGLONG chainBlock[2];
  295. ULONGLONG tmpData[2];
  296. PUCHAR KeyTable;
  297. PAGED_CODE();
  298. ASSERT (Length % AES_BLOCKLEN == 0);
  299. chainBlock[0] = *(ULONGLONG *)IV;
  300. chainBlock[1] = *(ULONGLONG *)(IV+sizeof(ULONGLONG));
  301. KeyTable = &(KeyBlob->Key[0]);
  302. while (Length > 0){
  303. //
  304. // Block chaining
  305. //
  306. tmpData[0] = *(ULONGLONG *)InBuffer;
  307. tmpData[1] = *(ULONGLONG *)(InBuffer+sizeof(ULONGLONG));
  308. tmpData[0] ^= chainBlock[0];
  309. tmpData[1] ^= chainBlock[1];
  310. aes256( OutBuffer, (PUCHAR) &tmpData[0], KeyTable, ENCRYPT );
  311. chainBlock[0] = *(ULONGLONG *)OutBuffer;
  312. chainBlock[1] = *(ULONGLONG *)(OutBuffer+sizeof(ULONGLONG));
  313. Length -= AES_BLOCKLEN;
  314. InBuffer += AES_BLOCKLEN;
  315. OutBuffer += AES_BLOCKLEN;
  316. }
  317. }
  318. VOID
  319. EFSAesDec(
  320. IN OUT PUCHAR Buffer,
  321. IN PUCHAR IV,
  322. IN PKEY_BLOB KeyBlob,
  323. IN LONG Length
  324. )
  325. /*++
  326. Routine Description:
  327. This routine implements DESX CBC decryption. The DESX is implemented by
  328. LIBRARY function desx().
  329. Arguments:
  330. Buffer - Pointer to the data buffer (decryption in place)
  331. IV - Initial chaining vector (AES_BLOCKLEN bytes)
  332. KeyBlob - Set during the create or FSCTL
  333. Length - Length of the data in the buffer ( Length % AES_BLOCKLEN = 0)
  334. --*/
  335. {
  336. ULONGLONG chainBlock[2];
  337. PUCHAR pBuffer;
  338. PUCHAR KeyTable;
  339. PAGED_CODE();
  340. ASSERT (Length % AES_BLOCKLEN == 0);
  341. pBuffer = Buffer + Length - AES_BLOCKLEN;
  342. KeyTable = &(KeyBlob->Key[0]);
  343. while (pBuffer > Buffer){
  344. aes256( pBuffer, pBuffer, KeyTable, DECRYPT );
  345. //
  346. // Undo the block chaining
  347. //
  348. chainBlock[0] = *(ULONGLONG *)( pBuffer - AES_BLOCKLEN );
  349. chainBlock[1] = *(ULONGLONG *)(pBuffer - sizeof(ULONGLONG));
  350. *(ULONGLONG *)pBuffer ^= chainBlock[0];
  351. *(ULONGLONG *)(pBuffer+sizeof(ULONGLONG)) ^= chainBlock[1];
  352. pBuffer -= AES_BLOCKLEN;
  353. }
  354. //
  355. // Now decrypt the first block
  356. //
  357. aes256( pBuffer, pBuffer, KeyTable, DECRYPT );
  358. *(ULONGLONG *)pBuffer ^= *(ULONGLONG *)IV;
  359. *(ULONGLONG *)(pBuffer+sizeof(ULONGLONG)) ^= *(ULONGLONG *)(IV+sizeof(ULONGLONG));
  360. }