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.

389 lines
10 KiB

  1. /*++
  2. Copyright (c) 1999, Microsoft Corporation
  3. Module Name:
  4. elkey.c
  5. Abstract:
  6. This module deals with the key management for EAPOL
  7. Revision History:
  8. Dec 26 2001, Created
  9. --*/
  10. #include "pcheapol.h"
  11. #pragma hdrstop
  12. DWORD
  13. ElQueryMasterKeys (
  14. IN EAPOL_PCB *pPCB,
  15. IN OUT SESSION_KEYS *pSessionKeys
  16. )
  17. {
  18. SESSION_KEYS WZCSessionKeys = {0};
  19. SESSION_KEYS EAPOLSessionKeys = {0};
  20. BOOLEAN fGotWZCKeys = FALSE, fGotEAPOLKeys = FALSE;
  21. DWORD dwRetCode = NO_ERROR;
  22. do
  23. {
  24. if ((dwRetCode = ElQueryWZCMasterKeys (
  25. pPCB,
  26. &WZCSessionKeys
  27. )) != NO_ERROR)
  28. {
  29. TRACE1 (ANY, "ElQueryMasterKeys: ElQueryWZCMasterKeys failed with error %ld",
  30. dwRetCode);
  31. dwRetCode = NO_ERROR;
  32. }
  33. else
  34. {
  35. fGotWZCKeys = TRUE;
  36. }
  37. if (WZCSessionKeys.dwKeyLength == 0)
  38. {
  39. fGotWZCKeys = FALSE;
  40. }
  41. if ((dwRetCode = ElQueryEAPOLMasterKeys (
  42. pPCB,
  43. &EAPOLSessionKeys
  44. )) != NO_ERROR)
  45. {
  46. TRACE1 (ANY, "ElQueryMasterKeys: ElQueryEAPOLMasterKeys failed with error %ld",
  47. dwRetCode);
  48. dwRetCode = NO_ERROR;
  49. }
  50. else
  51. {
  52. fGotEAPOLKeys = TRUE;
  53. }
  54. if (EAPOLSessionKeys.dwKeyLength == 0)
  55. {
  56. fGotEAPOLKeys = FALSE;
  57. }
  58. if (fGotEAPOLKeys)
  59. {
  60. TRACE0 (ANY, "ElQueryMasterKeys: Using EAPOL Keys as Master Keys for Re-keying");
  61. memcpy ((PBYTE)pSessionKeys, (PBYTE)&EAPOLSessionKeys,
  62. sizeof(SESSION_KEYS));
  63. pPCB->fLastUsedEAPOLKeys = TRUE;
  64. }
  65. else
  66. {
  67. if (fGotWZCKeys)
  68. {
  69. TRACE0 (ANY, "ElQueryMasterKeys: Using WZC Keys as Master Keys for Re-keying");
  70. memcpy ((PBYTE)pSessionKeys, (PBYTE)&WZCSessionKeys,
  71. sizeof(SESSION_KEYS));
  72. pPCB->fLastUsedEAPOLKeys = FALSE;
  73. }
  74. else
  75. {
  76. DbLogPCBEvent (DBLOG_CATEG_ERR, pPCB, EAPOL_NOT_CONFIGURED_KEYS);
  77. TRACE0 (ANY, "ElQueryMasterKeys: Did not get any keys. Error !!");
  78. dwRetCode = ERROR_INVALID_DATA;
  79. }
  80. }
  81. }
  82. while (FALSE);
  83. return dwRetCode;
  84. }
  85. DWORD
  86. ElSetMasterKeys (
  87. IN EAPOL_PCB *pPCB,
  88. IN SESSION_KEYS *pSessionKeys
  89. )
  90. {
  91. DWORD dwRetCode = NO_ERROR;
  92. do
  93. {
  94. if (pPCB->fLastUsedEAPOLKeys)
  95. {
  96. TRACE0 (ANY, "ElSetMasterKeys: Updating EAPOL Keys after Re-keying");
  97. if ((dwRetCode = ElSetEAPOLMasterKeys (
  98. pPCB,
  99. pSessionKeys
  100. )) != NO_ERROR)
  101. {
  102. TRACE1 (ANY, "ElSetMasterKeys: ElSetMasterKeys failed with error %ld",
  103. dwRetCode);
  104. dwRetCode = NO_ERROR;
  105. }
  106. }
  107. else
  108. {
  109. TRACE0 (ANY, "ElSetMasterKeys: Updating WZC Keys after Re-keying");
  110. if ((dwRetCode = ElSetWZCMasterKeys (
  111. pPCB,
  112. pSessionKeys
  113. )) != NO_ERROR)
  114. {
  115. TRACE1 (ANY, "ElSetMasterKeys: ElSetWZCMasterKeys failed with error %ld",
  116. dwRetCode);
  117. dwRetCode = NO_ERROR;
  118. }
  119. }
  120. // Reset the flag for next run
  121. pPCB->fLastUsedEAPOLKeys = FALSE;
  122. }
  123. while (FALSE);
  124. return dwRetCode;
  125. }
  126. DWORD
  127. ElQueryEAPOLMasterKeys (
  128. IN EAPOL_PCB *pPCB,
  129. IN OUT SESSION_KEYS *pSessionKeys
  130. )
  131. {
  132. SESSION_KEYS EAPOLSessionKeys = {0};
  133. PBYTE pbMasterSecretSend = NULL, pbMasterSecretRecv = NULL;
  134. DWORD dwMasterSecretSendLength = 0, dwMasterSecretRecvLength = 0;
  135. DWORD dwRetCode = NO_ERROR;
  136. do
  137. {
  138. // Access the Master Send and Recv key stored locally
  139. if ((dwRetCode = ElSecureDecodePw (
  140. &(pPCB->MasterSecretSend),
  141. &(pbMasterSecretSend),
  142. &dwMasterSecretSendLength
  143. )) != NO_ERROR)
  144. {
  145. TRACE1 (ANY, "ElQueryEAPOLMasterKeys: ElSecureDecodePw failed for MasterSecretSend with error %ld",
  146. dwRetCode);
  147. break;
  148. }
  149. if ((dwRetCode = ElSecureDecodePw (
  150. &(pPCB->MasterSecretRecv),
  151. &(pbMasterSecretRecv),
  152. &dwMasterSecretRecvLength
  153. )) != NO_ERROR)
  154. {
  155. TRACE1 (ANY, "ElKeyReceivePerSTA: ElSecureDecodePw failed for MasterSecretRecv with error %ld",
  156. dwRetCode);
  157. break;
  158. }
  159. if (dwMasterSecretSendLength != dwMasterSecretRecvLength)
  160. {
  161. dwRetCode = ERROR_INVALID_PARAMETER;
  162. TRACE2 (ANY, "ElQueryEAPOLMasterKeys: Send Secret Length (%ld) != Recv Secret Lenght (%ld): Invalid values",
  163. dwMasterSecretSendLength, dwMasterSecretRecvLength);
  164. break;
  165. }
  166. memcpy (pSessionKeys->bSendKey, pbMasterSecretSend,
  167. dwMasterSecretSendLength);
  168. memcpy (pSessionKeys->bReceiveKey, pbMasterSecretRecv,
  169. dwMasterSecretRecvLength);
  170. pSessionKeys->dwKeyLength = dwMasterSecretSendLength;
  171. }
  172. while (FALSE);
  173. if (pbMasterSecretSend != NULL)
  174. {
  175. FREE (pbMasterSecretSend);
  176. }
  177. if (pbMasterSecretRecv != NULL)
  178. {
  179. FREE (pbMasterSecretRecv);
  180. }
  181. return dwRetCode;
  182. }
  183. DWORD
  184. ElSetEAPOLMasterKeys (
  185. IN EAPOL_PCB *pPCB,
  186. IN SESSION_KEYS *pSessionKeys
  187. )
  188. {
  189. DWORD dwRetCode = NO_ERROR;
  190. do
  191. {
  192. if (pPCB->MasterSecretSend.cbData != 0)
  193. {
  194. FREE (pPCB->MasterSecretSend.pbData);
  195. pPCB->MasterSecretSend.cbData = 0;
  196. pPCB->MasterSecretSend.pbData = NULL;
  197. }
  198. if ((dwRetCode = ElSecureEncodePw (
  199. pSessionKeys->bSendKey,
  200. pSessionKeys->dwKeyLength,
  201. &(pPCB->MasterSecretSend)
  202. )) != NO_ERROR)
  203. {
  204. TRACE1 (ANY, "ElSetEAPOLMasterKeys: ElSecureEncodePw for MasterSecretSend failed with error %ld",
  205. dwRetCode);
  206. break;
  207. }
  208. if (pPCB->MasterSecretRecv.cbData != 0)
  209. {
  210. FREE (pPCB->MasterSecretRecv.pbData);
  211. pPCB->MasterSecretRecv.cbData = 0;
  212. pPCB->MasterSecretRecv.pbData = NULL;
  213. }
  214. if ((dwRetCode = ElSecureEncodePw (
  215. pSessionKeys->bReceiveKey,
  216. pSessionKeys->dwKeyLength,
  217. &(pPCB->MasterSecretRecv)
  218. )) != NO_ERROR)
  219. {
  220. TRACE1 (ANY, "ElSetEAPOLMasterKeys: ElSecureEncodePw for MasterSecretRecv failed with error %ld",
  221. dwRetCode);
  222. break;
  223. }
  224. }
  225. while (FALSE);
  226. return dwRetCode;
  227. }
  228. DWORD
  229. ElQueryWZCMasterKeys (
  230. IN EAPOL_PCB *pPCB,
  231. IN OUT SESSION_KEYS *pSessionKeys
  232. )
  233. {
  234. RAW_DATA rdUserData = {0};
  235. DWORD dwRetCode = NO_ERROR;
  236. do
  237. {
  238. rdUserData.dwDataLen = sizeof (SESSION_KEYS);
  239. rdUserData.pData = (PBYTE)pSessionKeys;
  240. if ((dwRetCode = RpcCmdInterface (
  241. pPCB->dwZeroConfigId,
  242. WZCCMD_SKEY_QUERY,
  243. pPCB->pwszDeviceGUID,
  244. &rdUserData
  245. )) != NO_ERROR)
  246. {
  247. TRACE1 (ANY, "ElQueryWZCMasterKeys: RpcCmdInterface failed with error %ld",
  248. dwRetCode);
  249. }
  250. }
  251. while (FALSE);
  252. return dwRetCode;
  253. }
  254. DWORD
  255. ElSetWZCMasterKeys (
  256. IN EAPOL_PCB *pPCB,
  257. IN SESSION_KEYS *pSessionKeys
  258. )
  259. {
  260. RAW_DATA rdUserData = {0};
  261. DWORD dwRetCode = NO_ERROR;
  262. do
  263. {
  264. rdUserData.dwDataLen = sizeof (SESSION_KEYS);
  265. rdUserData.pData = (PBYTE)pSessionKeys;
  266. if ((dwRetCode = RpcCmdInterface (
  267. pPCB->dwZeroConfigId,
  268. WZCCMD_SKEY_SET,
  269. pPCB->pwszDeviceGUID,
  270. &rdUserData
  271. )) != NO_ERROR)
  272. {
  273. TRACE1 (ANY, "ElSetWZCMasterKeys: RpcCmdInterface failed with error %ld",
  274. dwRetCode);
  275. }
  276. }
  277. while (FALSE);
  278. return dwRetCode;
  279. }
  280. DWORD
  281. ElReloadMasterSecrets (
  282. IN EAPOL_PCB *pPCB
  283. )
  284. {
  285. PBYTE pbSendKey = NULL;
  286. PBYTE pbRecvKey = NULL;
  287. DWORD dwRetCode = NO_ERROR;
  288. do
  289. {
  290. if (pPCB->MPPESendKey.cbData != 0)
  291. {
  292. if ((pbSendKey = MALLOC(pPCB->MPPESendKey.cbData)) == NULL)
  293. {
  294. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  295. break;
  296. }
  297. memcpy (pbSendKey, pPCB->MPPESendKey.pbData,
  298. pPCB->MPPESendKey.cbData);
  299. }
  300. if (pPCB->MPPERecvKey.cbData != 0)
  301. {
  302. if ((pbRecvKey = MALLOC(pPCB->MPPERecvKey.cbData)) == NULL)
  303. {
  304. dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
  305. break;
  306. }
  307. memcpy (pbRecvKey, pPCB->MPPERecvKey.pbData,
  308. pPCB->MPPERecvKey.cbData);
  309. }
  310. if (pPCB->MasterSecretSend.cbData != 0)
  311. {
  312. FREE (pPCB->MasterSecretSend.pbData);
  313. pPCB->MasterSecretSend.cbData = 0;
  314. pPCB->MasterSecretSend.pbData = NULL;
  315. }
  316. pPCB->MasterSecretSend.pbData = pbSendKey;
  317. pPCB->MasterSecretSend.cbData = pPCB->MPPESendKey.cbData;
  318. if (pPCB->MasterSecretRecv.cbData != 0)
  319. {
  320. FREE (pPCB->MasterSecretRecv.pbData);
  321. pPCB->MasterSecretRecv.cbData = 0;
  322. pPCB->MasterSecretRecv.pbData = NULL;
  323. }
  324. pPCB->MasterSecretRecv.pbData = pbRecvKey;
  325. pPCB->MasterSecretRecv.cbData = pPCB->MPPERecvKey.cbData;
  326. }
  327. while (FALSE);
  328. if (dwRetCode != NO_ERROR)
  329. {
  330. if (pbSendKey != NULL)
  331. {
  332. FREE (pbSendKey);
  333. }
  334. if (pbRecvKey != NULL)
  335. {
  336. FREE (pbRecvKey);
  337. }
  338. }
  339. return dwRetCode;
  340. }