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.

1070 lines
44 KiB

  1. /****************************************************************************/
  2. /* slapi.cpp */
  3. /* */
  4. /* Security Layer API */
  5. /* */
  6. /* Copyright (C) 1997-1999 Microsoft Corporation */
  7. /****************************************************************************/
  8. #include <adcg.h>
  9. extern "C" {
  10. #define TRC_GROUP TRC_GROUP_SECURITY
  11. #define TRC_FILE "aslapi"
  12. #include <atrcapi.h>
  13. }
  14. #include "autil.h"
  15. #include "wui.h"
  16. #include "sl.h"
  17. #include "nl.h"
  18. #include "td.h"
  19. #include "cd.h"
  20. #include "clicense.h"
  21. CSL::CSL(CObjs* objs)
  22. {
  23. _pClientObjects = objs;
  24. _fSLInitComplete = FALSE;
  25. }
  26. CSL::~CSL()
  27. {
  28. }
  29. /****************************************************************************/
  30. /* Name: SL_Init */
  31. /* */
  32. /* Purpose: Initialize the Security Layer */
  33. /* */
  34. /* Params: pCallbacks - list of callbacks */
  35. /* */
  36. /* Operation: Called in the Send context */
  37. /****************************************************************************/
  38. DCVOID DCINTERNAL CSL::SL_Init(PSL_CALLBACKS pCallbacks)
  39. {
  40. SL_CALLBACKS myCallbacks;
  41. DC_BEGIN_FN("SL_Init");
  42. SL_DBG_SETINFO(SL_DBG_INIT_CALLED);
  43. _pUt = _pClientObjects->_pUtObject;
  44. _pUi = _pClientObjects->_pUiObject;
  45. _pNl = _pClientObjects->_pNlObject;
  46. _pUh = _pClientObjects->_pUHObject;
  47. _pRcv = _pClientObjects->_pRcvObject;
  48. _pCd = _pClientObjects->_pCdObject;
  49. _pSnd = _pClientObjects->_pSndObject;
  50. _pCc = _pClientObjects->_pCcObject;
  51. _pIh = _pClientObjects->_pIhObject;
  52. _pOr = _pClientObjects->_pOrObject;
  53. _pSp = _pClientObjects->_pSPObject;
  54. _pMcs = _pClientObjects->_pMCSObject;
  55. _pTd = _pClientObjects->_pTDObject;
  56. _pCo = _pClientObjects->_pCoObject;
  57. _pClx = _pClientObjects->_pCLXObject;
  58. _pLic = _pClientObjects->_pLicObject;
  59. _pChan = _pClientObjects->_pChanObject;
  60. /************************************************************************/
  61. /* Initialize global data */
  62. /************************************************************************/
  63. DC_MEMSET(&_SL, 0, sizeof(_SL));
  64. SL_CHECK_STATE(SL_EVENT_SL_INIT);
  65. /************************************************************************/
  66. /* Check parameters */
  67. /************************************************************************/
  68. TRC_ASSERT((pCallbacks != NULL), (TB, _T("Null callback list")));
  69. TRC_ASSERT((pCallbacks->onInitialized != NULL),
  70. (TB, _T("NULL onInitialized callback")));
  71. TRC_ASSERT((pCallbacks->onTerminating != NULL),
  72. (TB, _T("NULL onTerminating callback")));
  73. TRC_ASSERT((pCallbacks->onConnected != NULL),
  74. (TB, _T("NULL onConnected callback")));
  75. TRC_ASSERT((pCallbacks->onDisconnected != NULL),
  76. (TB, _T("NULL onDisconnected callback")));
  77. TRC_ASSERT((pCallbacks->onPacketReceived != NULL),
  78. (TB, _T("NULL onPacketReceived callback")));
  79. TRC_ASSERT((pCallbacks->onBufferAvailable != NULL),
  80. (TB, _T("NULL onBufferAvailable callback")));
  81. /************************************************************************/
  82. /* Store callbacks */
  83. /************************************************************************/
  84. DC_MEMCPY(&_SL.callbacks, pCallbacks, sizeof(_SL.callbacks));
  85. /************************************************************************/
  86. /* Initialize Security stuff. The call to SLInitSecurity will attempt */
  87. /* to load the security DLL and find the required entry points. This */
  88. /* may fail - in which case we just carry on but without any */
  89. /* encryption. In either case we need to call SLInitCSUserData to set */
  90. /* up the necessary user data. */
  91. /************************************************************************/
  92. SLInitSecurity();
  93. SLInitCSUserData();
  94. /************************************************************************/
  95. /* Initialize list of callbacks to pass to NL */
  96. /************************************************************************/
  97. myCallbacks.onInitialized = CSL::SL_StaticOnInitialized;
  98. myCallbacks.onTerminating = CSL::SL_StaticOnTerminating;
  99. myCallbacks.onConnected = CSL::SL_StaticOnConnected;
  100. myCallbacks.onDisconnected = CSL::SL_StaticOnDisconnected;
  101. myCallbacks.onPacketReceived = CSL::SL_StaticOnPacketReceived;
  102. myCallbacks.onBufferAvailable = CSL::SL_StaticOnBufferAvailable;
  103. SL_SET_STATE(SL_STATE_INITIALIZING);
  104. /************************************************************************/
  105. /* Initialize NL */
  106. /************************************************************************/
  107. TRC_NRM((TB, _T("Initialize NL")));
  108. _pNl->NL_Init(&myCallbacks);
  109. _fSLInitComplete = TRUE;
  110. SL_DBG_SETINFO(SL_DBG_INIT_DONE);
  111. /************************************************************************/
  112. /* Return to caller */
  113. /************************************************************************/
  114. DC_EXIT_POINT:
  115. DC_END_FN();
  116. return;
  117. } /* SL_Init */
  118. /****************************************************************************/
  119. /* Name: SL_Term */
  120. /* */
  121. /* Purpose: Terminate the Security Layer */
  122. /* */
  123. /* Operation: Called in the Send context */
  124. /****************************************************************************/
  125. DCVOID DCAPI CSL::SL_Term(DCVOID)
  126. {
  127. DC_BEGIN_FN("SL_Term");
  128. SL_DBG_SETINFO(SL_DBG_TERM_CALLED);
  129. SL_CHECK_STATE(SL_EVENT_SL_TERM);
  130. SL_SET_STATE(SL_STATE_TERMINATING);
  131. TRC_NRM((TB, _T("Terminate NL")));
  132. _pNl->NL_Term();
  133. if (_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  134. TSCAPI_Term(&(_SL.SLCapiData));
  135. }
  136. SL_DBG_SETINFO(SL_DBG_TERM_DONE);
  137. DC_EXIT_POINT:
  138. SL_DBG_SETINFO(SL_DBG_TERM_DONE1);
  139. DC_END_FN();
  140. return;
  141. } /* SL_Term */
  142. /****************************************************************************/
  143. /* Name: SL_Connect */
  144. /* */
  145. /* Purpose: Connect to a Server */
  146. /* */
  147. /* Params: bInitiateConnect - Initiate connection */
  148. /* pServerAddress - address of the Server to connect to */
  149. /* transportType - protocol type: SL_TRANSPORT_TCP */
  150. /* pProtocolName - protocol name, one of */
  151. /* - SL_PROTOCOL_T128 */
  152. /* - Er, that's it. */
  153. /* pUserData - user data to pass to Server Security Manager */
  154. /* userDataLength - length of user data */
  155. /* */
  156. /* Operation: Called in the Send context */
  157. /****************************************************************************/
  158. DCVOID DCAPI CSL::SL_Connect(BOOL bInitiateConnect,
  159. PDCTCHAR pServerAddress,
  160. DCUINT transportType,
  161. PDCTCHAR pProtocolName,
  162. PDCUINT8 pUserData,
  163. DCUINT userDataLength)
  164. {
  165. DCUINT newUserDataLength;
  166. PDCUINT8 pUserDataOut = NULL;
  167. DCBOOL userDataAllocated = FALSE;
  168. DC_BEGIN_FN("SL_Connect");
  169. SL_DBG_SETINFO(SL_DBG_CONNECT_CALLED);
  170. SL_CHECK_STATE(SL_EVENT_SL_CONNECT);
  171. if( bInitiateConnect )
  172. {
  173. TRC_ASSERT((pServerAddress != NULL), (TB, _T("NULL Server address")));
  174. }
  175. //
  176. // Reset this for every connection
  177. //
  178. SL_SetEncSafeChecksumCS(FALSE);
  179. SL_SetEncSafeChecksumSC(FALSE);
  180. TRC_ASSERT((pProtocolName != NULL), (TB, _T("NULL protocol name")));
  181. TRC_ASSERT((DC_TSTRCMP(pProtocolName, SL_PROTOCOL_T128) == 0),
  182. (TB, _T("Unknown protocol %s"), pProtocolName));
  183. TRC_ASSERT((transportType == SL_TRANSPORT_TCP),
  184. (TB,_T("Illegal transport type %u"), transportType));
  185. if( bInitiateConnect )
  186. {
  187. TRC_NRM((TB, _T("Connect Server %s, protocol %s, %u bytes user data"),
  188. pServerAddress, pProtocolName, userDataLength));
  189. }
  190. else
  191. {
  192. TRC_NRM((TB, _T("Connect endpoint protocol %s, %u bytes user data"),
  193. pProtocolName, userDataLength));
  194. }
  195. /************************************************************************/
  196. /* Allocate space for all user data */
  197. /************************************************************************/
  198. if (_SL.CSUserDataLength != 0)
  199. {
  200. newUserDataLength = userDataLength + _SL.CSUserDataLength;
  201. pUserDataOut = (PDCUINT8)UT_Malloc(_pUt, newUserDataLength);
  202. if (pUserDataOut == NULL)
  203. {
  204. TRC_ERR((TB, _T("Failed to alloc %u bytes for user data"),
  205. newUserDataLength));
  206. /****************************************************************/
  207. /* We've not tried to connect the lower layers yet so we need */
  208. /* to do no more than just decouple to the receiver thread and */
  209. /* generate a onDisconnected callback. */
  210. /****************************************************************/
  211. _pCd->CD_DecoupleSimpleNotification(CD_RCV_COMPONENT, this,
  212. CD_NOTIFICATION_FUNC(CSL,SLIssueDisconnectedCallback),
  213. (ULONG_PTR) SL_ERR_NOMEMFORSENDUD);
  214. DC_QUIT;
  215. }
  216. TRC_NRM((TB, _T("Allocated %u bytes for user data"), newUserDataLength));
  217. userDataAllocated = TRUE;
  218. /********************************************************************/
  219. /* Copy user data passed by Core (if any) to new user data buffer */
  220. /********************************************************************/
  221. if (pUserData != NULL)
  222. {
  223. TRC_NRM((TB, _T("Copy %u bytes of Core user data"), userDataLength));
  224. DC_MEMCPY(pUserDataOut, pUserData, userDataLength);
  225. }
  226. /********************************************************************/
  227. /* Copy security user data */
  228. /********************************************************************/
  229. TRC_NRM((TB, _T("Copy %u bytes of security user data"),
  230. _SL.CSUserDataLength));
  231. DC_MEMCPY(pUserDataOut + userDataLength,
  232. _SL.pCSUserData,
  233. _SL.CSUserDataLength);
  234. }
  235. else
  236. {
  237. /********************************************************************/
  238. /* NO SL user data - just pass on Core data. */
  239. /********************************************************************/
  240. TRC_DBG((TB, _T("No SL user data")));
  241. newUserDataLength = userDataLength;
  242. pUserDataOut = pUserData;
  243. }
  244. /************************************************************************/
  245. /* Next state */
  246. /************************************************************************/
  247. SL_SET_STATE(SL_STATE_NL_CONNECTING);
  248. /************************************************************************/
  249. /* Call NL */
  250. /************************************************************************/
  251. if( bInitiateConnect )
  252. {
  253. TRC_NRM((TB, _T("Connect to %s"), pServerAddress));
  254. }
  255. else
  256. {
  257. TRC_NRM((TB, _T("Connect with end point")));
  258. }
  259. _pNl->NL_Connect(
  260. bInitiateConnect, // initate connection
  261. pServerAddress,
  262. transportType,
  263. pProtocolName,
  264. pUserDataOut,
  265. newUserDataLength);
  266. SL_DBG_SETINFO(SL_DBG_CONNECT_DONE);
  267. DC_EXIT_POINT:
  268. /************************************************************************/
  269. /* Free user data (if any) */
  270. /************************************************************************/
  271. if ( userDataAllocated )
  272. {
  273. TRC_NRM((TB, _T("Free user data")));
  274. UT_Free(_pUt, pUserDataOut);
  275. }
  276. DC_END_FN();
  277. } /* SL_Connect */
  278. /****************************************************************************/
  279. /* Name: SL_Disconnect */
  280. /* */
  281. /* Purpose: Disconnect from the Server */
  282. /* */
  283. /* Operation: Called in the Send context */
  284. /****************************************************************************/
  285. DCVOID DCAPI CSL::SL_Disconnect(DCVOID)
  286. {
  287. DC_BEGIN_FN("SL_Disconnect");
  288. SL_DBG_SETINFO(SL_DBG_DISCONNECT_CALLED);
  289. SL_CHECK_STATE(SL_EVENT_SL_DISCONNECT);
  290. SL_DBG_SETINFO(SL_DBG_DISCONNECT_DONE1);
  291. DC_EXIT_POINT:
  292. /************************************************************************/
  293. /* Regardless of the outcome of the state check we want to try and */
  294. /* disconnect - so always call NL_Disconnect. */
  295. /************************************************************************/
  296. TRC_NRM((TB, _T("Disconnect from Server")));
  297. SL_SET_STATE(SL_STATE_DISCONNECTING);
  298. _pNl->NL_Disconnect();
  299. SL_DBG_SETINFO(SL_DBG_DISCONNECT_DONE2);
  300. DC_END_FN();
  301. } /* SL_Disconnect */
  302. /****************************************************************************/
  303. /* Name: SL_SendPacket */
  304. /* */
  305. /* Purpose: Send a packet */
  306. /* */
  307. /* Params: pData - pointer to data to send (buffer returned by */
  308. /* SL_GetBuffer()) */
  309. /* dataLen - length of data to send (excluding security */
  310. /* header) */
  311. /* flags - zero or more of the RNS_SEC flags */
  312. /* bufHandle - buffer handle returned by SL_GetBuffer() */
  313. /* userID - MCS user ID */
  314. /* channel - channel ID to send data on */
  315. /* priority - priority of data - one of */
  316. /* - TS_LOWPRIORITY */
  317. /* - TS_MEDPRIORITY */
  318. /* - TS_HIGHPRIORITY */
  319. /* */
  320. /* Operation: Note that the contents of the packet are changed by this */
  321. /* function. */
  322. /* */
  323. /* Called in the Send context */
  324. /****************************************************************************/
  325. DCVOID DCAPI CSL::SL_SendPacket(PDCUINT8 pData,
  326. DCUINT dataLen,
  327. DCUINT flags,
  328. SL_BUFHND bufHandle,
  329. DCUINT userID,
  330. DCUINT channel,
  331. DCUINT priority)
  332. {
  333. DCBOOL rc = FALSE;
  334. DC_BEGIN_FN("SL_SendPacket");
  335. SL_CHECK_STATE(SL_EVENT_SL_SENDPACKET);
  336. /************************************************************************/
  337. /* Check if we're encrypting this message */
  338. /************************************************************************/
  339. if (_SL.encrypting ||
  340. (flags & RNS_SEC_INFO_PKT) ||
  341. (flags & RNS_SEC_LICENSE_PKT))
  342. {
  343. TRC_DBG((TB, _T("Encrypting")));
  344. if (_SL.encrypting && (flags & RNS_SEC_ENCRYPT))
  345. {
  346. PRNS_SECURITY_HEADER1 pSecHeader1;
  347. PRNS_SECURITY_HEADER2 pSecHeader2;
  348. TRC_DBG((TB, _T("Encrypt this message")));
  349. if (_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  350. pSecHeader2 = (PRNS_SECURITY_HEADER2)
  351. (pData - sizeof(RNS_SECURITY_HEADER2));
  352. pSecHeader2->padlen = TSCAPI_AdjustDataLen(dataLen) - dataLen;
  353. pSecHeader2->length = sizeof(RNS_SECURITY_HEADER2);
  354. pSecHeader2->version = TSFIPS_VERSION1;
  355. }
  356. else {
  357. pSecHeader1 = (PRNS_SECURITY_HEADER1)
  358. (pData - sizeof(RNS_SECURITY_HEADER1));
  359. }
  360. /****************************************************************/
  361. /* check to see we need to update the session key. */
  362. /****************************************************************/
  363. if( _SL.encryptCount == UPDATE_SESSION_KEY_COUNT ) {
  364. TRC_ALT((TB, _T("Update Encrypt Session Key, Count=%d"),
  365. _SL.encryptCount));
  366. rc = TRUE;
  367. // Don't need to update the session key if using FIPS
  368. if (_SL.encryptionMethodSelected != SM_FIPS_ENCRYPTION_FLAG) {
  369. rc = UpdateSessionKey(
  370. _SL.startEncryptKey,
  371. _SL.currentEncryptKey,
  372. _SL.encryptionMethodSelected,
  373. _SL.keyLength,
  374. &_SL.rc4EncryptKey,
  375. _SL.encryptionLevel);
  376. }
  377. if (rc) {
  378. // Reset counter.
  379. _SL.encryptCount = 0;
  380. }
  381. else {
  382. TRC_ERR((TB, _T("SL failed to update session key")));
  383. DC_QUIT;
  384. }
  385. }
  386. TRC_ASSERT((_SL.encryptCount < UPDATE_SESSION_KEY_COUNT),
  387. (TB, _T("Invalid encrypt count")));
  388. TRC_DATA_DBG("Data buffer before encryption", pData, dataLen);
  389. if (_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  390. DWORD dataLenTemp;
  391. dataLenTemp = dataLen;
  392. rc = TSCAPI_EncryptData(
  393. &(_SL.SLCapiData),
  394. pData,
  395. &dataLenTemp,
  396. dataLen + pSecHeader2->padlen,
  397. (LPBYTE)pSecHeader2->dataSignature,
  398. _SL.totalEncryptCount);
  399. }
  400. else {
  401. rc = EncryptData(
  402. _SL.encryptionLevel,
  403. _SL.currentEncryptKey,
  404. &_SL.rc4EncryptKey,
  405. _SL.keyLength,
  406. pData,
  407. dataLen,
  408. _SL.macSaltKey,
  409. (LPBYTE)pSecHeader1->dataSignature,
  410. SL_GetEncSafeChecksumCS(),
  411. _SL.totalEncryptCount);
  412. }
  413. if (rc) {
  414. TRC_DBG((TB, _T("Data encrypted")));
  415. TRC_DATA_DBG("Data buffer after encryption", pData, dataLen);
  416. // Increment the encryption counter.
  417. _SL.encryptCount++;
  418. _SL.totalEncryptCount++;
  419. if (SL_GetEncSafeChecksumCS()) {
  420. flags |= RDP_SEC_SECURE_CHECKSUM;
  421. }
  422. // Message encrypted successfully. Set up security header and
  423. // NL data pointer and length.
  424. if (_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  425. pSecHeader2->flags = (DCUINT16)flags;
  426. pData = (PDCUINT8)pSecHeader2;
  427. dataLen += (sizeof(RNS_SECURITY_HEADER2) + pSecHeader2->padlen);
  428. }
  429. else {
  430. pSecHeader1->flags = (DCUINT16)flags;
  431. pData = (PDCUINT8)pSecHeader1;
  432. dataLen += sizeof(RNS_SECURITY_HEADER1);
  433. }
  434. }
  435. else {
  436. TRC_ERR((TB, _T("SM failed to encrypt data")));
  437. //
  438. // This call is made on the Send thread so there is no need
  439. // to trigger an immediate disconnect with SL_DropLinkImmediate
  440. //
  441. SLSetReasonAndDisconnect(SL_ERR_ENCRYPTFAILED);
  442. DC_QUIT;
  443. }
  444. }
  445. else
  446. {
  447. PRNS_SECURITY_HEADER pSecHeader;
  448. /****************************************************************/
  449. /* Packet not encrypted - send flags, but not the signature. */
  450. /****************************************************************/
  451. pSecHeader = (PRNS_SECURITY_HEADER)
  452. (pData - sizeof(RNS_SECURITY_HEADER));
  453. /****************************************************************/
  454. /* setup security headers and NL data pointer and length */
  455. /****************************************************************/
  456. pSecHeader->flags = (DCUINT16)flags;
  457. pData = (PDCUINT8)pSecHeader;
  458. dataLen += sizeof(RNS_SECURITY_HEADER);
  459. TRC_DATA_DBG("Send unencrypted data", pData, dataLen);
  460. }
  461. }
  462. /************************************************************************/
  463. /* Trace out parameters and send the packet. */
  464. /************************************************************************/
  465. TRC_DBG((TB, _T("Send buf:%p len:%u flags:%#x handle:%#x userID:%u chan:%u")
  466. _T("pri:%u"),
  467. pData,
  468. dataLen,
  469. flags,
  470. bufHandle,
  471. userID,
  472. channel,
  473. priority));
  474. //NL_SendPacket is a macro to an MCS function.
  475. _pMcs->NL_SendPacket(pData,
  476. dataLen,
  477. flags,
  478. bufHandle,
  479. userID,
  480. channel,
  481. priority);
  482. /************************************************************************/
  483. /* No state change */
  484. /************************************************************************/
  485. DC_EXIT_POINT:
  486. DC_END_FN();
  487. } /* SL_SendPacket */
  488. /****************************************************************************/
  489. // SL_SendFastPathInputPacket
  490. //
  491. // Encrypts and assembles the security information and the final header
  492. // format for a fast-path input packet before sending to TD. See at128.h for
  493. // the fast-path input packet format.
  494. /****************************************************************************/
  495. void DCAPI CSL::SL_SendFastPathInputPacket(
  496. BYTE FAR *pData,
  497. unsigned PktLen,
  498. unsigned NumEvents,
  499. SL_BUFHND bufHandle)
  500. {
  501. DCBOOL rc;
  502. unsigned flags;
  503. DWORD dataLenTemp;
  504. PBYTE pDataSignature;
  505. DCUINT8 *pPadLen;
  506. DC_BEGIN_FN("SL_SendFastPathInputPacket");
  507. SL_CHECK_STATE(SL_EVENT_SL_SENDPACKET);
  508. // We're encrypting if encyption enabled on this link.
  509. if (_SL.encrypting) {
  510. // Check to see we need to update the session key.
  511. if (_SL.encryptCount == UPDATE_SESSION_KEY_COUNT) {
  512. TRC_ALT((TB, _T("Update Encrypt Session Key, Count=%d"),
  513. _SL.encryptCount));
  514. rc = TRUE;
  515. // Don't need to update the session key if using FIPS
  516. if (_SL.encryptionMethodSelected != SM_FIPS_ENCRYPTION_FLAG) {
  517. rc = UpdateSessionKey(
  518. _SL.startEncryptKey,
  519. _SL.currentEncryptKey,
  520. _SL.encryptionMethodSelected,
  521. _SL.keyLength,
  522. &_SL.rc4EncryptKey,
  523. _SL.encryptionLevel);
  524. }
  525. if (rc) {
  526. // Reset counter.
  527. _SL.encryptCount = 0;
  528. }
  529. else {
  530. TRC_ERR((TB, _T("SL failed to update session key")));
  531. DC_QUIT;
  532. }
  533. }
  534. TRC_ASSERT((_SL.encryptCount < UPDATE_SESSION_KEY_COUNT),
  535. (TB, _T("Invalid encrypt count")));
  536. // We encrypt into the DATA_SIGNATURE_SIZE bytes immediately before
  537. // the packet data. Unlike the regular send path, we don't waste 4
  538. // extra bytes in an RNS_SECURITY_HEADER1 to contain the 'encrypted'
  539. // bit.
  540. if (_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  541. dataLenTemp = PktLen;
  542. pDataSignature = pData - MAX_SIGN_SIZE;
  543. pPadLen = (DCUINT8 *)(pDataSignature - sizeof(DCUINT8));
  544. *pPadLen = (DCUINT8)(TSCAPI_AdjustDataLen(PktLen) - PktLen);
  545. rc = TSCAPI_EncryptData(
  546. &(_SL.SLCapiData),
  547. pData,
  548. &dataLenTemp,
  549. PktLen + *pPadLen,
  550. pDataSignature,
  551. _SL.totalEncryptCount);
  552. }
  553. else {
  554. rc = EncryptData(
  555. _SL.encryptionLevel,
  556. _SL.currentEncryptKey,
  557. &_SL.rc4EncryptKey,
  558. _SL.keyLength,
  559. pData,
  560. PktLen,
  561. _SL.macSaltKey,
  562. pData - DATA_SIGNATURE_SIZE,
  563. SL_GetEncSafeChecksumCS(),
  564. _SL.totalEncryptCount);
  565. }
  566. if (rc) {
  567. // Increment the encryption counter.
  568. _SL.encryptCount++;
  569. _SL.totalEncryptCount++;
  570. flags = TS_INPUT_FASTPATH_ENCRYPTED;
  571. if (_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  572. pData -= (sizeof(RNS_SECURITY_HEADER2) - 4);
  573. PktLen += (sizeof(RNS_SECURITY_HEADER2) - 4 + *pPadLen);
  574. }
  575. else {
  576. pData -= DATA_SIGNATURE_SIZE;
  577. PktLen += DATA_SIGNATURE_SIZE;
  578. }
  579. TRC_DBG((TB, _T("Data encrypted")));
  580. }
  581. else {
  582. //
  583. // This call is made on the Send thread so there is no need
  584. // to trigger an immediate disconnect with SL_DropLinkImmediate
  585. //
  586. SLSetReasonAndDisconnect(SL_ERR_ENCRYPTFAILED);
  587. TRC_ERR((TB, _T("SM failed to encrypt data")));
  588. DC_QUIT;
  589. }
  590. }
  591. else {
  592. // No encryption flag.
  593. flags = 0;
  594. }
  595. // Now prepend the fast-path header (2 or 3 bytes, see at128.h).
  596. // Work backwards from where we are: First, the total packet length
  597. // including the header.
  598. if (PktLen <= 125) {
  599. // 1-byte form of length, high bit 0.
  600. PktLen += 2;
  601. pData -= 2;
  602. *(pData + 1) = (BYTE)PktLen;
  603. }
  604. else {
  605. // 2-byte form of length, first byte has high bit 1 and 7 most
  606. // significant bits.
  607. PktLen += 3;
  608. pData -= 3;
  609. *(pData + 1) = (BYTE)(0x80 | ((PktLen & 0x7F00) >> 8));
  610. *(pData + 2) = (BYTE)(PktLen & 0xFF);
  611. }
  612. // The header byte.
  613. *pData = (BYTE)(flags | (NumEvents << 2));
  614. //
  615. // Flag if the packet has a checksum of encrypted bytes
  616. //
  617. if (SL_GetEncSafeChecksumCS()) {
  618. *pData |= TS_INPUT_FASTPATH_SECURE_CHECKSUM;
  619. }
  620. // Direct-send the packet through the transport, no more parsing needed.
  621. _pTd->TD_SendBuffer(pData, PktLen, bufHandle);
  622. DC_EXIT_POINT:
  623. DC_END_FN();
  624. }
  625. #ifdef DC_DEBUG
  626. /****************************************************************************/
  627. /* Name: SL_GetBufferDbg */
  628. /* */
  629. /* Purpose: Get a send buffer (debug version) */
  630. /* */
  631. /* Returns: see SL_GetBufferRtl */
  632. /* */
  633. /* Params: see SL_GetBufferRtl */
  634. /* pCaller - name of calling function */
  635. /****************************************************************************/
  636. DCBOOL DCAPI CSL::SL_GetBufferDbg(DCUINT dataLen,
  637. PPDCUINT8 ppBuffer,
  638. PSL_BUFHND pBufHandle,
  639. PDCTCHAR pCaller)
  640. {
  641. DCBOOL bRc;
  642. DC_BEGIN_FN("SL_GetBufferDbg");
  643. /************************************************************************/
  644. /* First get a buffer */
  645. /************************************************************************/
  646. bRc = SL_GetBufferRtl(dataLen, ppBuffer, pBufHandle);
  647. /************************************************************************/
  648. /* If that worked, set its owner */
  649. /************************************************************************/
  650. if (bRc)
  651. {
  652. TRC_NRM((TB, _T("Buffer allocated - set its owner")));
  653. _pTd->TD_SetBufferOwner(*pBufHandle, pCaller);
  654. }
  655. DC_END_FN();
  656. return(bRc);
  657. } /* SL_GetBufferDbg */
  658. #endif /* DC_DEBUG */
  659. /****************************************************************************/
  660. /* Name: SL_GetBufferRtl */
  661. /* */
  662. /* Purpose: Get a send buffer (retail version) */
  663. /* */
  664. /* Returns: TRUE - buffer available */
  665. /* FALSE - buffer not available */
  666. /* */
  667. /* Params: dataLen - Size of buffer required */
  668. /* pBuffer - Pointer to the returned buffer */
  669. /* pBufHandle - Pointer to the buffer handle */
  670. /****************************************************************************/
  671. DCBOOL DCAPI CSL::SL_GetBufferRtl(DCUINT dataLen,
  672. PPDCUINT8 ppBuffer,
  673. PSL_BUFHND pBufHandle)
  674. {
  675. DCBOOL rc = FALSE;
  676. DCUINT myLen;
  677. PDCUINT8 myBuffer;
  678. DCUINT headerLen;
  679. DCUINT newDataLen;
  680. PRNS_SECURITY_HEADER2 pSecHeader2;
  681. DC_BEGIN_FN("SL_GetBufferRtl");
  682. SL_CHECK_STATE(SL_EVENT_SL_GETBUFFER);
  683. /************************************************************************/
  684. /* Adjust requested length to account for SL header */
  685. /************************************************************************/
  686. if (_SL.encrypting)
  687. {
  688. if (_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  689. // If FIPS is used,
  690. // it must have room for an extra block
  691. headerLen = sizeof(RNS_SECURITY_HEADER2);
  692. newDataLen = TSCAPI_AdjustDataLen(dataLen);
  693. myLen = newDataLen + headerLen;
  694. }
  695. else {
  696. headerLen = sizeof(RNS_SECURITY_HEADER1);
  697. myLen = dataLen + headerLen;
  698. }
  699. TRC_DBG((TB, _T("Ask NL for %d (was %d) bytes"), myLen, dataLen));
  700. }
  701. else
  702. {
  703. myLen = dataLen;
  704. headerLen = 0;
  705. TRC_DBG((TB, _T("Not encrypting, ask NL for %d bytes"), myLen));
  706. }
  707. /************************************************************************/
  708. /* Get buffer from NL */
  709. /************************************************************************/
  710. rc = _pMcs->NL_GetBuffer(myLen, &myBuffer, pBufHandle);
  711. if (rc)
  712. {
  713. /********************************************************************/
  714. /* Adjust buffer pointer to account for SL header */
  715. /********************************************************************/
  716. *ppBuffer = myBuffer + headerLen;
  717. // Since FIPS need extra block, fill in the padding size
  718. if (_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  719. pSecHeader2 = (PRNS_SECURITY_HEADER2)myBuffer;
  720. pSecHeader2->padlen = newDataLen - dataLen;
  721. }
  722. /********************************************************************/
  723. /* Assert that NL has returned a correctly aligned buffer. */
  724. /********************************************************************/
  725. TRC_ASSERT(((ULONG_PTR)(*ppBuffer) % 4 == 2),
  726. (TB, _T("non-aligned buffer")));
  727. }
  728. TRC_DBG((TB, _T("Return buffer %p (was %p), rc %d"),
  729. *ppBuffer, myBuffer, rc));
  730. /************************************************************************/
  731. /* Return to caller */
  732. /************************************************************************/
  733. DC_EXIT_POINT:
  734. DC_END_FN();
  735. return(rc);
  736. } /* SL_GetBufferRtl */
  737. /****************************************************************************/
  738. /* Name: SL_FreeBuffer */
  739. /* */
  740. /* Purpose: Frees a buffer previously allocated. */
  741. /* */
  742. /* Params: IN pBufHandle - pointer to the buffer handle. */
  743. /****************************************************************************/
  744. DCVOID DCAPI CSL::SL_FreeBuffer(SL_BUFHND bufHandle)
  745. {
  746. DC_BEGIN_FN("SL_FreeBuffer");
  747. /************************************************************************/
  748. /* Just call onto the NL equivalent. */
  749. /************************************************************************/
  750. _pMcs->NL_FreeBuffer((NL_BUFHND) bufHandle);
  751. DC_END_FN();
  752. } /* SL_FreeBuffer */
  753. /****************************************************************************/
  754. /* Name: SL_SendSecurityPacket */
  755. /* */
  756. /* Purpose: Sends a security packet in the Send context */
  757. /* */
  758. /* Params: pData - data from Receive context (packet to send) */
  759. /* dataLength - length of data passed */
  760. /****************************************************************************/
  761. DCVOID DCAPI CSL::SL_SendSecurityPacket(PDCVOID pData, DCUINT dataLength)
  762. {
  763. DCBOOL rc;
  764. PDCUINT8 pBuffer;
  765. SL_BUFHND bufHnd;
  766. DC_BEGIN_FN("SL_SendSecurityPacket");
  767. /************************************************************************/
  768. /* Get a buffer from NL */
  769. /************************************************************************/
  770. rc = _pMcs->NL_GetBuffer(dataLength, &pBuffer, &bufHnd);
  771. /************************************************************************/
  772. /* We don't expect this getBuffer to fail. However, it can do so in */
  773. /* the following scenario. */
  774. /* - SLSendSecurityPacket decouples to SL_SendSecurityPacket. */
  775. /* - Session is disconnected. */
  776. /* - CD calls SL_SendSecurityPacket. */
  777. /************************************************************************/
  778. if (!rc)
  779. {
  780. TRC_ERR((TB, _T("Failed to alloc buffer for security packet, state %d"),
  781. _SL.state));
  782. DC_QUIT;
  783. }
  784. /************************************************************************/
  785. /* Send the packet */
  786. /************************************************************************/
  787. DC_MEMCPY(pBuffer, pData, dataLength);
  788. TRC_NRM((TB, _T("Send security exchange packet")));
  789. _pMcs->NL_SendPacket(pBuffer,
  790. dataLength,
  791. 0,
  792. bufHnd,
  793. _pUi->UI_GetClientMCSID(),
  794. _SL.channelID,
  795. TS_HIGHPRIORITY);
  796. DC_EXIT_POINT:
  797. DC_END_FN();
  798. }
  799. /****************************************************************************/
  800. /* Name: SL_SendSecInfoPacket */
  801. /* */
  802. /* Purpose: Sends an rns info pkt in the Send context */
  803. /* */
  804. /* Params: pData - data from Receive context (packet to send) */
  805. /* dataLength - length of data passed */
  806. /****************************************************************************/
  807. DCVOID DCAPI CSL::SL_SendSecInfoPacket(PDCVOID pData, DCUINT dataLen)
  808. {
  809. PDCUINT8 pBuffer;
  810. SL_BUFHND BufHandle;
  811. DCUINT headerLen, newDataLen, TotalDataLen;
  812. PRNS_SECURITY_HEADER2 pSecHeader2;
  813. DC_BEGIN_FN("SL_SendSecInfoPacket");
  814. /************************************************************************/
  815. /* Adjust requested length to account for SL header and */
  816. /* get the buffer from NL */
  817. /************************************************************************/
  818. if (_SL.encrypting)
  819. {
  820. if (_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  821. // If FIPS is used,
  822. // it must have room for an extra block
  823. headerLen = sizeof(RNS_SECURITY_HEADER2);
  824. newDataLen = TSCAPI_AdjustDataLen(dataLen);
  825. TotalDataLen = newDataLen + headerLen;
  826. }
  827. else {
  828. headerLen = sizeof(RNS_SECURITY_HEADER1);
  829. TotalDataLen = dataLen + headerLen;
  830. }
  831. }
  832. else {
  833. headerLen = sizeof(RNS_SECURITY_HEADER);
  834. TotalDataLen = dataLen + headerLen;
  835. }
  836. if (!_pMcs->NL_GetBuffer(TotalDataLen, &pBuffer, &BufHandle))
  837. {
  838. TRC_ALT((TB, _T("Failed to get SendSecInfoPacket buffer")));
  839. DC_QUIT;
  840. }
  841. // Since FIPS need extra block, fill in the padding size
  842. if (_SL.encryptionMethodSelected == SM_FIPS_ENCRYPTION_FLAG) {
  843. pSecHeader2 = (PRNS_SECURITY_HEADER2)pBuffer;
  844. pSecHeader2->padlen = newDataLen - dataLen;
  845. }
  846. /********************************************************************/
  847. /* Adjust buffer pointer to account for SL header */
  848. /********************************************************************/
  849. pBuffer += headerLen;
  850. DC_MEMCPY(pBuffer, pData, dataLen);
  851. SL_SendPacket(pBuffer,
  852. dataLen,
  853. RNS_SEC_ENCRYPT | RNS_SEC_INFO_PKT,
  854. BufHandle,
  855. _pUi->UI_GetClientMCSID(),
  856. _SL.channelID,
  857. TS_HIGHPRIORITY);
  858. DC_EXIT_POINT:
  859. DC_END_FN();
  860. }
  861. /****************************************************************************/
  862. /* Name: SL_EnableEncryption */
  863. /* */
  864. /* Purpose: Enables or disables encryption */
  865. /* */
  866. /* Params: enableEncryption - IN - flag indicating whether encryption */
  867. /* should be on or off */
  868. /* 0 - disabled */
  869. /* 1 - enabled */
  870. /****************************************************************************/
  871. DCVOID DCAPI CSL::SL_EnableEncryption(ULONG_PTR enableEncryption)
  872. {
  873. DC_BEGIN_FN("SL_EnableEncryption");
  874. /************************************************************************/
  875. /* @@@ ENH 13.8.97 Need to do something with this notification */
  876. /************************************************************************/
  877. _SL.encryptionEnabled = (DCBOOL) enableEncryption;
  878. DC_END_FN();
  879. } /* SL_EnableEncryption */
  880. //
  881. // SL_DropLinkImmediate
  882. //
  883. // Purpose: Immediately drops the link without doing a gracefull connection
  884. // shutdown (i.e. no DPUm is sent and we don't transition to the SND
  885. // thread at any point before dropping the link). Higher level components
  886. // will still get all the usual disconnect notifications so they can
  887. // be properly torn down.
  888. //
  889. // This call was added to trigger an immediate disconnect in cases
  890. // where we detect invalid data that could be due to an attack, it
  891. // ensures we won't receive any more data after the call returns
  892. //
  893. // Params: reason - SL disconnect reason code
  894. //
  895. // Returns: HRESULT
  896. //
  897. // Thread context: Call on RCV thread
  898. //
  899. HRESULT
  900. CSL::SL_DropLinkImmediate(UINT reason)
  901. {
  902. HRESULT hr = E_FAIL;
  903. DC_BEGIN_FN("SL_DropLinkImmediate");
  904. TRC_NRM((TB, _T("Setting disconnect error code from %u->%u"),
  905. _SL.disconnectErrorCode,
  906. SL_MAKE_DISCONNECT_ERR(reason)));
  907. // Check that the disconnectErrorCode has not already been set and then
  908. // set it.
  909. if (0 != _SL.disconnectErrorCode) {
  910. TRC_ERR((TB, _T("Disconnect error code has already been set! Was %u"),
  911. _SL.disconnectErrorCode));
  912. }
  913. _SL.disconnectErrorCode = SL_MAKE_DISCONNECT_ERR(reason);
  914. TRC_ALT((TB,_T("Triggering immediate drop link")));
  915. _pTd->TD_DropLink();
  916. hr = S_OK;
  917. DC_END_FN();
  918. return hr;
  919. }