RMCP+.c 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224
  1. /****************************************************************
  2. ****************************************************************
  3. ** **
  4. ** (C)Copyright 2005-2006, American Megatrends Inc. **
  5. ** **
  6. ** All Rights Reserved. **
  7. ** **
  8. ** 6145-F, Northbelt Parkway, Norcross, **
  9. ** **
  10. ** Georgia - 30071, USA. Phone-(770)-246-8600. **
  11. ** **
  12. ****************************************************************
  13. ****************************************************************/
  14. /*****************************************************************
  15. *
  16. * RMCP.c
  17. * RMCP Message Handler
  18. *
  19. * Author: Govind Kothandapani <govindk@ami.com>
  20. * : Bakka Ravinder Reddy <bakkar@ami.com>
  21. *
  22. *****************************************************************/
  23. #include <stdio.h>
  24. #include <stdint.h>
  25. #include "com_Message.h"
  26. #include "com_IPMIDefs.h"
  27. #include "RMCP.h"
  28. #include "RMCP+.h"
  29. #include "Session.h"
  30. #include "LANIfc.h"
  31. #include "MD.h"
  32. #include "MD5_128.h"
  33. #include "main.h"
  34. #if IPMI20_SUPPORT == 1
  35. /*** Local definitions ***/
  36. #define AUTH_ALGORITHM 00
  37. #define INTEGRITY_ALGORITHM 01
  38. #define CONFIDENTIALITY_ALGORITHM 02
  39. #define MAX_ROLE_SUPPORTED 0x05
  40. #define MAX_REM_CON_RAND_NO_LEN 0x10
  41. #define MAX_MGD_SYS_RAND_NO_LEN 0x10
  42. #define MAX_MGD_SYS_GUID_LEN 0x10
  43. #define MAX_HMAC_BUF_SIZE 128
  44. #define RAKP1_HASH_SIZE 20
  45. #define RAKP1_HASH_HMAC_MD5_SIZE 16
  46. #define RAKP1_HASH_HMAC_SHA256_SIZE 32
  47. /* RSSP and RAKP Message Status Codes */
  48. #define SC_NO_ERROR 0
  49. #define SC_INSUFFICIENT_RESOURCE 1
  50. #define SC_INV_SESSION_ID 2
  51. #define SC_INV_PAYLOAD_TYPE 3
  52. #define SC_INV_AUTH_ALGORITHM 4
  53. #define SC_INV_INTEGRITY_ALGORITHM 5
  54. #define SC_NO_MATCHED_AUTH_PAYLOAD 6
  55. #define SC_NO_MATCHED_INTEGRITY_PAYLOAD 7
  56. #define SC_INACTIVE_SESSION_ID 8
  57. #define SC_INV_ROLE 9
  58. #define SC_UNAUTHORISED_ROLE 10
  59. #define SC_INSUFFICIENT_RESOURCE_AT_ROLE 11
  60. #define SC_INV_NAME_LEN 12
  61. #define SC_UNAUTHORISED_NAME 13
  62. #define SC_UNAUTHORISED_GUID 14
  63. #define SC_INV_INTEGRITY_CHECK 15
  64. #define SC_INV_CONFIDENTIALITY_ALGORTHM 16
  65. #define SC_NO_CIPHER_SUITE_MATCH 17
  66. #define SC_ILLEGAL_OR_UNRECOGNIZED_PARAM 18
  67. /* Authentication Algorithm Numbers */
  68. #define RAKP_NONE 0
  69. #define RAKP_HMAC_SHA1 1
  70. #define RAKP_HMAC_MD5 2
  71. #define RAKP_HMAC_SHA256 3
  72. #define HASH_KEY1_CONST_SIZE 20
  73. #define HASH_KEY2_CONST_SIZE 20
  74. /**
  75. * @var m_SIK
  76. * @brief Session Key.
  77. **/
  78. static _FAR_ INT8U m_SIK [SHA2_HASH_KEY_SIZE];
  79. /*----------------------------------------
  80. * RSSPOpenSessionReq
  81. *----------------------------------------*/
  82. int
  83. RSSPOpenSessionReq (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes, MiscParams_T *pParams, INT8U Channel, int BMCInst)
  84. {
  85. _NEAR_ RSSPOpenSessionReq_T *Req =
  86. (_NEAR_ RSSPOpenSessionReq_T*)pReq;
  87. _NEAR_ RSSPOpenSessionRes_T *Res =
  88. (_NEAR_ RSSPOpenSessionRes_T*)pRes;
  89. _NEAR_ RSSPOpenSessionErrRes_T *ErrRes =
  90. (_NEAR_ RSSPOpenSessionErrRes_T*)pRes;
  91. _FAR_ BMCInfo_t *pBMCInfo =
  92. &g_BMCInfo[BMCInst];
  93. _FAR_ ChannelInfo_T *pChannelInfo;
  94. INT8U Role, i, id;
  95. BOOL IsMatchReq = FALSE;
  96. BOOL TrackRollOver = FALSE;
  97. SessionInfo_T SessionInfo;
  98. INT32U TempSessId;
  99. INT8U CipherSuitePrivilage = 0;
  100. INT8U EthIndex;
  101. INT32U TrackRollOverSeq = SEQNUM_ROLLOVER;
  102. unsigned int seed = 1;
  103. if(Channel == 0xFF)
  104. {
  105. Channel=GetLANChannel(Req->Reserved[0], BMCInst);
  106. }
  107. EthIndex= GetEthIndex(Channel, BMCInst);
  108. if(0xff == EthIndex)
  109. {
  110. IPMI_WARNING("\n Invalid Channel number :%x",Channel);
  111. *pRes = CC_INV_DATA_FIELD;
  112. return sizeof (INT8U);
  113. }
  114. OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->ChUserMutex,WAIT_INFINITE);
  115. /* Get information abt this channel */
  116. pChannelInfo = getChannelInfo (Channel, BMCInst);
  117. if (NULL == pChannelInfo)
  118. {
  119. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  120. Res->StatusCode = SC_INSUFFICIENT_RESOURCE;
  121. return sizeof (RSSPOpenSessionErrRes_T);
  122. }
  123. if(pChannelInfo->ActiveSession >= pChannelInfo->SessionLimit)
  124. {
  125. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  126. /* Session limit reached*/
  127. IPMI_WARNING ("RMCP+.c : OpenSessionReq - Session limit exceeded :%x\t%x BMCInst %x\n ",pChannelInfo->ActiveSession,pChannelInfo->SessionLimit,BMCInst);
  128. Res->StatusCode = SC_INSUFFICIENT_RESOURCE;
  129. return sizeof (RSSPOpenSessionErrRes_T);
  130. }
  131. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  132. /* Get Role */
  133. Role = Req->Role & 0x0F;
  134. /* Fill Err Response to return, in case any error occurred */
  135. ErrRes->Reserved = 0;
  136. ErrRes->RemConSessionID = Req->RemConSessionID;
  137. OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SessionTblMutex,WAIT_INFINITE);
  138. if (GetNumOfUsedSessions(BMCInst) >= pBMCInfo->IpmiConfig.MaxSession)
  139. {
  140. if(FALSE == CleanSession(BMCInst))
  141. {
  142. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  143. /* Session limit reached*/
  144. IPMI_WARNING ("RMCP+.c : OpenSessionReq - Session limit exceeded\n");
  145. Res->StatusCode = SC_INSUFFICIENT_RESOURCE;
  146. return sizeof (RSSPOpenSessionErrRes_T);
  147. }
  148. }
  149. /* Check Role */
  150. if (Role > MAX_ROLE_SUPPORTED)
  151. {
  152. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  153. /* Invalid Payload Type */
  154. IPMI_WARNING ("RMCP+.c : OpenSessionReq - Invalid role\n");
  155. Res->StatusCode = SC_INV_ROLE;
  156. return sizeof (RSSPOpenSessionErrRes_T);
  157. }
  158. /*Check Payload Type */
  159. if ((AUTH_ALGORITHM != Req->Auth.PayloadType) ||
  160. (INTEGRITY_ALGORITHM != Req->Integrity.PayloadType) ||
  161. (CONFIDENTIALITY_ALGORITHM != Req->Confidentiality.PayloadType))
  162. {
  163. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  164. /* Invalid Payload Type */
  165. IPMI_WARNING ("RMCP+.c : OpenSessionReq - Invalid Payload\n");
  166. Res->StatusCode = SC_INV_PAYLOAD_TYPE;
  167. return sizeof (RSSPOpenSessionErrRes_T);
  168. }
  169. /* Search for the matching cipher suite id from Cipher suite record. if matching id found
  170. check for for requested role/privilege is allowed for privilege level for the cipher suite */
  171. for (i = 0, id = 0; i < MAX_CIPHER_SUITES_BYTES; i++, id++)
  172. {
  173. if (i * 5 + 1 > MAX_CIPHER_SUITES_BYTES)
  174. {
  175. break;
  176. }
  177. if (
  178. (((Req->Auth.PayloadType << 6) | (Req->Auth.Algorithm & 0x3F)) == g_CipherRec [(i * 5) + 2]) &&
  179. (((Req->Integrity.PayloadType << 6) | (Req->Integrity.Algorithm & 0x3F)) == g_CipherRec [(i * 5) + 3]) &&
  180. (((Req->Confidentiality.PayloadType<< 6) | (Req->Confidentiality.Algorithm & 0x3F))== g_CipherRec [(i * 5) + 4])
  181. )
  182. {
  183. id = g_CipherRec[(i * 5) + 1];
  184. /* The Cipher Suite ID is matched */
  185. /* get the privilege level for the given cipher suite id, if id is even its lower nibble else upper nibble */
  186. CipherSuitePrivilage = pBMCInfo->LANCfs[EthIndex].CipherSuitePrivLevels [(id/2)+1];
  187. CipherSuitePrivilage = ((id % 2) == 0) ? (CipherSuitePrivilage & 0x0f) : ((CipherSuitePrivilage >> 4) & 0x0f) ;
  188. if(CipherSuitePrivilage == 0)
  189. {
  190. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  191. Res->StatusCode = SC_NO_CIPHER_SUITE_MATCH;
  192. return sizeof (RSSPOpenSessionErrRes_T);
  193. }
  194. /*if requested privilege level is greater than cipher suite id privilege level return errror*/
  195. if ((CipherSuitePrivilage != 0) && (Role > CipherSuitePrivilage))
  196. {
  197. /* Invalid Payload Type */
  198. //Res->StatusCode = SC_UNAUTHORISED_ROLE;
  199. //return sizeof (RSSPOpenSessionErrRes_T);
  200. Role = CipherSuitePrivilage;
  201. }
  202. break;
  203. }
  204. }
  205. /* Role 0 indicates to find possible match */
  206. if (0 == Role)
  207. {
  208. IsMatchReq = TRUE;
  209. Role = MAX_ROLE_SUPPORTED;
  210. }
  211. /* Find Match */
  212. do
  213. {
  214. Res->StatusCode = SC_NO_ERROR;
  215. /*Check if requested authentication Algorithm supported **/
  216. if (0 != Req->Auth.PayloadLen)
  217. {
  218. if ((sizeof (RSSPPayloadInfo_T) != Req->Auth.PayloadLen) ||
  219. (0 == (pBMCInfo->RMCPPlus[EthIndex].Algorithm [Req->Auth.PayloadType] [Role] &
  220. (1 << Req->Auth.Algorithm))))
  221. {
  222. /* AuthAlgorithm not supported */
  223. IPMI_DBG_PRINT ("RMCP+.c : OpenSessionReq - Authentication not supported \n");
  224. Res->StatusCode = SC_NO_CIPHER_SUITE_MATCH;
  225. }
  226. }
  227. /*Check if requested Integrity Algorithm supported **/
  228. if (0 != Req->Integrity.PayloadLen)
  229. {
  230. if ((sizeof (RSSPPayloadInfo_T) != Req->Integrity.PayloadLen) ||
  231. (0 == (pBMCInfo->RMCPPlus[EthIndex].Algorithm [Req->Integrity.PayloadType] [Role] &
  232. (1 << Req->Integrity.Algorithm))))
  233. {
  234. /* Integrity Algorithm not supported */
  235. IPMI_DBG_PRINT ("RMCP+.c : OpenSessionReq - Integrity not supported\n");
  236. Res->StatusCode = SC_NO_CIPHER_SUITE_MATCH;
  237. }
  238. }
  239. /*Check if requested Confidentiality Algorithm supported **/
  240. if (0 != Req->Confidentiality.PayloadLen)
  241. {
  242. if ((sizeof (RSSPPayloadInfo_T) != Req->Confidentiality.PayloadLen) ||
  243. (0 == (pBMCInfo->RMCPPlus[EthIndex].Algorithm [Req->Confidentiality.PayloadType] [Role] &
  244. (1 << Req->Confidentiality.Algorithm))))
  245. {
  246. /* Confidentiality Algorithm not supported */
  247. IPMI_DBG_PRINT ("RMCP+.c : OpenSessionReq - Confidentiality not supported \n");
  248. Res->StatusCode = SC_NO_CIPHER_SUITE_MATCH;
  249. }
  250. }
  251. if ((SC_NO_ERROR == Res->StatusCode) &&
  252. ((CipherSuitePrivilage == 0) || (Role <= CipherSuitePrivilage)))
  253. {
  254. /* Found Match */
  255. break;
  256. }
  257. } while (IsMatchReq && Role--);
  258. /* Return Err response */
  259. if (Res->StatusCode != SC_NO_ERROR)
  260. {
  261. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  262. IPMI_WARNING ("RMCP+.c : OpenSessionReq - Error Response\n");
  263. return sizeof (RSSPOpenSessionErrRes_T);
  264. }
  265. if (GetNumOfActiveSessions (BMCInst) >= pBMCInfo->IpmiConfig.MaxSession)
  266. {
  267. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  268. /* No slot available */
  269. Res->StatusCode = SC_INSUFFICIENT_RESOURCE;
  270. return sizeof (RSSPOpenSessionErrRes_T);
  271. }
  272. /* Add Session Info */
  273. _fmemset (&SessionInfo, 0, sizeof (SessionInfo_T));
  274. /* Activated in ActivateSession Command */
  275. SessionInfo.Activated = FALSE;
  276. SessionInfo.RemConSessionID = Req->RemConSessionID;
  277. SessionInfo.MaxPrivilege = Role;
  278. do{
  279. /*generate 32 bit temp session Id*/
  280. TempSessId = ((INT32U)rand_r(&seed) << 16) | rand_r (&seed);
  281. } while ((NULL != getSessionInfo (SESSION_ID_INFO, &TempSessId, BMCInst)) ||
  282. (0 == TempSessId));
  283. SessionInfo.SessionID = TempSessId;
  284. SessionInfo.Channel = Channel;
  285. SessionInfo.AuthAlgorithm = Req->Auth.Algorithm;
  286. SessionInfo.IntegrityAlgorithm = Req->Integrity.Algorithm;
  287. SessionInfo.ConfidentialityAlgorithm = Req->Confidentiality.Algorithm;
  288. if(pParams->IsPktFromLoopBack)
  289. {
  290. if(IPMITimeout > 0)
  291. {
  292. SessionInfo.TimeOutValue = (IPMITimeout+10);
  293. }
  294. else
  295. {
  296. /*If it is not defined the timeout values for loop back session should be
  297. SESSION_TIMEOUT defined in config.make.ipmi (60 seconds) */
  298. SessionInfo.TimeOutValue = pBMCInfo->IpmiConfig.SessionTimeOut;
  299. }
  300. SessionInfo.IsLoopBack = TRUE;
  301. }
  302. else
  303. SessionInfo.TimeOutValue = pBMCInfo->IpmiConfig.SessionTimeOut;
  304. if(pBMCInfo->IpmiConfig.SOLIfcSupport == 1)
  305. {
  306. if(SessionInfo.SessPyldInfo [PAYLOAD_SOL].Type == PAYLOAD_SOL)
  307. {
  308. SessionInfo.TimeOutValue = pBMCInfo->IpmiConfig.SOLSessionTimeOut;
  309. }
  310. }
  311. SessionInfo.UserId = 0xff;
  312. SessionInfo.SessPyldInfo [0].AuxConfig [0] =
  313. ((0 != Req->Integrity.Algorithm) ? 0x40: 0x00) |
  314. ((0 != Req->Confidentiality.Algorithm) ? 0x80: 0x00);
  315. SessionInfo.InitialInboundSeq = SEQNUM_ROLLOVER;
  316. SessionInfo.InboundSeq = 0x00;
  317. for(i=0; i < RMCPPLUS_SEQLOWLIMIT; i++)
  318. {
  319. if(((SessionInfo.InitialInboundSeq - (i+1)) != 0) &&(TrackRollOver == FALSE))
  320. SessionInfo.InboundTrac[i] = SessionInfo.InitialInboundSeq - (i+1);
  321. else if(((SessionInfo.InitialInboundSeq - (i+1)) == 0) &&(TrackRollOver == FALSE))
  322. {
  323. SessionInfo.InboundTrac[i] = SessionInfo.InitialInboundSeq - (i+1);
  324. TrackRollOver = TRUE;
  325. }
  326. else if(TrackRollOver == TRUE)
  327. {
  328. SessionInfo.InboundTrac[i] = TrackRollOverSeq;
  329. TrackRollOverSeq--;
  330. }
  331. }
  332. SessionInfo.InboundRecv = 0xFF;
  333. AddSession (&SessionInfo, BMCInst);
  334. /* Load RSSP Open session Response */
  335. Res->Role = Role;
  336. Res->Reserved = 0x00;
  337. Res->RemConSessionID = Req->RemConSessionID;
  338. Res->MgdSysSessionID = SessionInfo.SessionID;
  339. /* Auth Algorithm Details */
  340. Res->Auth.PayloadType = AUTH_ALGORITHM;
  341. Res->Auth.Reserved1 = 0;
  342. Res->Auth.PayloadLen = sizeof (RSSPPayloadInfo_T);
  343. Res->Auth.Algorithm = Req->Auth.Algorithm;
  344. memset(Res->Auth.Reserved2, 0x0, 3);
  345. /* Integrity Algorithm Details */
  346. Res->Integrity.PayloadType = INTEGRITY_ALGORITHM;
  347. Res->Integrity.Reserved1 = 0;
  348. Res->Integrity.PayloadLen = sizeof (RSSPPayloadInfo_T);
  349. Res->Integrity.Algorithm = Req->Integrity.Algorithm;
  350. memset(Res->Integrity.Reserved2, 0x0, 3);
  351. /* Confidentiality Algorithm Details */
  352. Res->Confidentiality.PayloadType = CONFIDENTIALITY_ALGORITHM;
  353. Res->Confidentiality.Reserved1 = 0;
  354. Res->Confidentiality.PayloadLen = sizeof (RSSPPayloadInfo_T);
  355. Res->Confidentiality.Algorithm = Req->Confidentiality.Algorithm;
  356. memset(Res->Confidentiality.Reserved2, 0x0, 3);
  357. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  358. return sizeof (RSSPOpenSessionRes_T);
  359. }
  360. /*----------------------------------------
  361. * RAKPMsg1
  362. *----------------------------------------*/
  363. int
  364. RAKPMsg1 (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes, MiscParams_T *pParams, INT8U Channel, int BMCInst)
  365. {
  366. _NEAR_ RAKPMsg1Req_T *Req = (_NEAR_ RAKPMsg1Req_T*) pReq;
  367. _NEAR_ RAKPMsg2Res_T *Res = (_NEAR_ RAKPMsg2Res_T*) pRes;
  368. _NEAR_ RAKPMsg2ErrRes_T *ErrRes = (_NEAR_ RAKPMsg2ErrRes_T*) pRes;
  369. _FAR_ SessionInfo_T *pSessInfo;
  370. _FAR_ ChannelUserInfo_T *pChUserInfo;
  371. _FAR_ ChannelInfo_T *pChannelInfo;
  372. _FAR_ UserInfo_T *pUserInfo;
  373. _FAR_ RAKPMsg1HMAC_T *pMsghmac;
  374. _FAR_ BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst];
  375. INT8U Index;
  376. INT8U AuthCodeLen = 0;
  377. INT8U Role;
  378. INT32U ManSysSessionID;
  379. int i;
  380. unsigned int seed = 1;
  381. INT8U PwdEncKey[MAX_SIZE_KEY + 1] = {0};
  382. /*Validate Mgd session ID*/
  383. Role = Req->Role & 0x0f;
  384. ManSysSessionID = Req->ManSysSessionID;
  385. OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SessionTblMutex,WAIT_INFINITE);
  386. pSessInfo = getSessionInfo (SESSION_ID_INFO, (_FAR_ void*)&ManSysSessionID, BMCInst);
  387. if (NULL == pSessInfo)
  388. {
  389. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  390. IPMI_WARNING ("RMCP+.c : RAKPMsg1 - Invalid Session ID\n");
  391. ErrRes->StatusCode = SC_INV_SESSION_ID;
  392. return sizeof (RAKPMsg2ErrRes_T);
  393. }
  394. /* In case of error, delete this session info */
  395. pBMCInfo->LANConfig.DeleteThisLANSessionID = ManSysSessionID;
  396. if(Channel == 0xFF)
  397. {
  398. Channel= pSessInfo->Channel;
  399. }
  400. ErrRes->RemConSessionID = pSessInfo->RemConSessionID;
  401. /* Check Role */
  402. if (Role > MAX_ROLE_SUPPORTED)
  403. {
  404. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  405. /* Invalid Role */
  406. IPMI_WARNING ("RMCP+.c : RAKPMsg1 - Invalid Role\n");
  407. Res->StatusCode = SC_INV_ROLE;
  408. return sizeof (RAKPMsg2ErrRes_T);
  409. }
  410. /* Check User Name Length */
  411. if (Req->UsrNameLen > MAX_USERNAME_LEN)
  412. {
  413. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  414. /* Invalid Name Len */
  415. IPMI_WARNING ("RMCP+.c : RAKPMsg1 - Username len exceeded\n");
  416. Res->StatusCode = SC_INV_NAME_LEN;
  417. return sizeof (RAKPMsg2ErrRes_T);
  418. }
  419. /* Privilege for the session has to be assigned in RAKP1 only */
  420. pSessInfo->Privilege = Role & 0xF;
  421. /* Pad with NULL characters */
  422. _fmemset (&Req->UsrName [Req->UsrNameLen], 0, MAX_USERNAME_LEN - Req->UsrNameLen);
  423. pChannelInfo = getChannelInfo (Channel, BMCInst);
  424. if (NULL == pChannelInfo)
  425. {
  426. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  427. /* InSufficient resources */
  428. IPMI_WARNING ("RMCP+.c : RAKPMsg1 - Insufficient resource\n");
  429. Res->StatusCode = SC_INSUFFICIENT_RESOURCE;
  430. return sizeof (RAKPMsg2ErrRes_T);
  431. }
  432. OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->ChUserMutex,WAIT_INFINITE);
  433. pSessInfo->Lookup = ((Req->Role & 0x10) >> 0x04);
  434. if( pParams->IsPktFromLoopBack == TRUE && Req->UsrName[0] == 0 )
  435. {
  436. pUserInfo = getUserIdInfo (NULL_USER, BMCInst);
  437. pSessInfo->UserId = NULL_USER;
  438. memset (pSessInfo->Password, 0, MAX_PASSWORD_LEN);
  439. }
  440. else
  441. {
  442. if (USER_ROLE_LOOKUP == pSessInfo->Lookup)
  443. {
  444. /* Get userInfo for the given userName and privilege */
  445. pChUserInfo = getChUserPrivInfo ((_NEAR_ char *)Req->UsrName, Role, &Index,
  446. pChannelInfo->ChannelUserInfo, BMCInst);
  447. /* If user not found */
  448. if (NULL == pChUserInfo)
  449. {
  450. /* Invalid user */
  451. IPMI_WARNING ("RMCP+.c : RAKPMsg1 - user_priv - User not found : %s\n", (_NEAR_ char *)Req->UsrName);
  452. if ( 0 != AddLoginEvent( 0xFF, Req->UsrName, EVENT_LOGIN_FAILURE, BMCInst ) )
  453. {
  454. TCRIT("Problem while adding Log record \n");
  455. }
  456. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  457. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  458. Res->StatusCode = SC_UNAUTHORISED_NAME;
  459. return sizeof (RAKPMsg2ErrRes_T);
  460. }
  461. /* Check Role */
  462. if (pChUserInfo->AccessLimit == 0xF )
  463. {
  464. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  465. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  466. /* Invalid Role */
  467. IPMI_WARNING ("RMCP+.c : RAKPMsg1 - user_priv - Invalid Role\n");
  468. Res->StatusCode = SC_INV_ROLE;
  469. return sizeof (RAKPMsg2ErrRes_T);
  470. }
  471. //we cannot assign the pSessInfo->privilege here..this will cause RAKP3 integrity check to fail
  472. //this is because the client will do integrity with the requested role rather than the max permissible role
  473. // which we set here. client has no way of knowing at that time
  474. //pSessInfo->Privilege = Role;
  475. }
  476. else /* if (NAME_ONLY_LOOKUP == pSessInfo->Lookup) */
  477. {
  478. /* Get userInfo for the given userName*/
  479. pChUserInfo = getChUserInfo ((_NEAR_ char *)Req->UsrName, &Index,
  480. pChannelInfo->ChannelUserInfo, BMCInst);
  481. /* If user not found */
  482. if (NULL == pChUserInfo)
  483. {
  484. /* Invalid user */
  485. IPMI_WARNING ("RMCP+.c : RAKPMsg1 - name_only - User not found\n");
  486. if ( 0 != AddLoginEvent( 0xFF, Req->UsrName, EVENT_LOGIN_FAILURE, BMCInst ))
  487. {
  488. TCRIT("Problem while adding Log record \n");
  489. }
  490. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  491. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  492. Res->StatusCode = SC_UNAUTHORISED_NAME;
  493. return sizeof (RAKPMsg2ErrRes_T);
  494. }
  495. /* Check Role */
  496. if (pChUserInfo->AccessLimit == 0xF )
  497. {
  498. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  499. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  500. /* Invalid Role */
  501. IPMI_WARNING ("RMCP+.c : RAKPMsg1 - name_only - Invalid Role\n");
  502. Res->StatusCode = SC_INV_ROLE;
  503. return sizeof (RAKPMsg2ErrRes_T);
  504. }
  505. }
  506. pUserInfo = getUserIdInfo (pChUserInfo->UserId, BMCInst);
  507. if (pUserInfo == NULL || FALSE == pUserInfo->UserStatus)
  508. {
  509. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  510. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  511. /*user name not enabled*/
  512. IPMI_WARNING ("RMCP+.c : RAKPMsg1 - User not found in database\n");
  513. Res->StatusCode = SC_UNAUTHORISED_NAME;
  514. return sizeof (RAKPMsg2ErrRes_T);
  515. }
  516. /* Load UserId Session Info */
  517. pSessInfo->UserId = (INT8U)pChUserInfo->UserId;
  518. if (g_corefeatures.userpswd_encryption == ENABLED)
  519. {
  520. /* Get Encryption Key from the MBMCInfo_t structure */
  521. memcpy(PwdEncKey, &(g_MBMCInfo.PwdEncKey), MAX_SIZE_KEY);
  522. if(DecryptPassword((INT8S *)(pBMCInfo->EncryptedUserInfo[pChUserInfo->UserId - 1].EncryptedPswd), MAX_PASSWORD_LEN, (INT8S*)pSessInfo->Password, MAX_PASSWORD_LEN, PwdEncKey))
  523. {
  524. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  525. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  526. TCRIT("Error in decrypting the user password for user ID:%d. .\n", pChUserInfo->UserId);
  527. Res->StatusCode = SC_INSUFFICIENT_RESOURCE;
  528. return sizeof(RAKPMsg2ErrRes_T);
  529. }
  530. }
  531. else
  532. {
  533. _fmemcpy (pSessInfo->Password, pUserInfo->UserPassword, MAX_PASSWORD_LEN);
  534. }
  535. }
  536. /* Check for Empty password login */
  537. if ( ENABLED == g_corefeatures.disable_empty_passwd_login && NULL_USER != pSessInfo->UserId && 0 == pSessInfo->Password[0])
  538. {
  539. IPMI_WARNING("RMCP+c : RAKPMsg1 - Empty Password Login is not allowed \n");
  540. if ( 0 != AddLoginEvent(pSessInfo->UserId, NULL, EVENT_LOGIN_FAILURE, BMCInst))
  541. {
  542. TCRIT("Problem while adding Log record \n");
  543. }
  544. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  545. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  546. Res->StatusCode = SC_ILLEGAL_OR_UNRECOGNIZED_PARAM;
  547. return sizeof(RAKPMsg2ErrRes_T);
  548. }
  549. /* Check for Default Empty password login */
  550. if(ENABLED != g_corefeatures.allow_default_empty_passwd_login && NULL_USER != pSessInfo->UserId && 0 == pSessInfo->Password[0] && pUserInfo->UserPasswdConfigured == 0)
  551. {
  552. TDBG("RMCP+c : RAKPMsg1 - User Password is not yet configured; Default Empty Password Login is not allowed \n");
  553. if ( 0 != AddLoginEvent(pSessInfo->UserId, NULL, EVENT_LOGIN_FAILURE, BMCInst))
  554. {
  555. TCRIT("Problem while adding Log record \n");
  556. }
  557. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  558. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  559. Res->StatusCode = SC_ILLEGAL_OR_UNRECOGNIZED_PARAM;
  560. return sizeof(RAKPMsg2ErrRes_T);
  561. }
  562. if(FindUserLockStatus(pSessInfo->UserId, Channel, BMCInst) != 0)
  563. {
  564. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  565. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  566. IPMI_WARNING("RMCP+c : RAKPMsg1 - User is Locked \n");
  567. /* As of now sending Invalid Role for bad password*/
  568. Res->StatusCode = SC_INV_ROLE;
  569. return sizeof(RAKPMsg2ErrRes_T);
  570. }
  571. /* Check the number of active sessions */
  572. if (pUserInfo->CurrentSession >= pUserInfo->MaxSession)
  573. {
  574. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  575. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  576. /*can't accept any more session for this user*/
  577. Res->StatusCode = SC_INSUFFICIENT_RESOURCE;
  578. return sizeof (RAKPMsg2ErrRes_T);
  579. }
  580. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  581. /* Load Response */
  582. Res->StatusCode = SC_NO_ERROR;
  583. /* Store the Remote Console Random number in SessionInfo */
  584. _fmemcpy (pSessInfo->RemConRandomNo, Req->RemConRandomNo,
  585. MAX_REM_CON_RAND_NO_LEN);
  586. for (i = 0 ; i < MAX_MGD_SYS_RAND_NO_LEN; i++)
  587. {
  588. Res->ManSysRandomNo [i] = rand_r (&seed);
  589. }
  590. /* Store the Managed System Random number in SessionInfo */
  591. _fmemcpy (pSessInfo->MgdSysRandomNo, Res->ManSysRandomNo,
  592. MAX_MGD_SYS_RAND_NO_LEN);
  593. /* Copy the System GUID */
  594. _fmemcpy (Res->ManSysGUID, BMC_GET_SHARED_MEM (BMCInst)->SystemGUID, 16);
  595. /* Key Exchange Auth Code */
  596. switch (pSessInfo->AuthAlgorithm)
  597. {
  598. case RAKP_NONE:
  599. AuthCodeLen = 0;
  600. break;
  601. case RAKP_HMAC_SHA1:
  602. {
  603. INT8U PasswdLen = 0;
  604. pMsghmac = (_FAR_ RAKPMsg1HMAC_T*)pBMCInfo->LANConfig.HmacInBuf;
  605. pMsghmac->RemConSessionID = pSessInfo->RemConSessionID;
  606. pMsghmac->MgdSysSessionID = pSessInfo->SessionID;
  607. /* Copy Random no.s and GUID */
  608. _fmemcpy (pMsghmac->RemConRandNo, pSessInfo->RemConRandomNo, 16);
  609. _fmemcpy (pMsghmac->MgdSysRandNo, pSessInfo->MgdSysRandomNo, 16);
  610. _fmemcpy (pMsghmac->MgdSysGUID, Res->ManSysGUID, MAX_MGD_SYS_GUID_LEN);
  611. pMsghmac->Role = Req->Role;
  612. pMsghmac->UsrNameLen = Req->UsrNameLen;
  613. _fmemcpy (pMsghmac->UsrName, Req->UsrName, Req->UsrNameLen);
  614. PasswdLen = _fstrlen ((_FAR_ char*)pSessInfo->Password);
  615. PasswdLen = (PasswdLen > MAX_PASSWORD_LEN) ?
  616. MAX_PASSWORD_LEN : PasswdLen;
  617. hmac_sha1 ((INT8U *)pSessInfo->Password, PasswdLen, (INT8U *)pBMCInfo->LANConfig.HmacInBuf,
  618. (sizeof (RAKPMsg1HMAC_T) - MAX_USERNAME_LEN + Req->UsrNameLen),
  619. (INT8U *)&pRes [sizeof (RAKPMsg2Res_T)], RAKP1_HASH_SIZE);
  620. AuthCodeLen = RAKP1_HASH_SIZE;
  621. break;
  622. }
  623. case RAKP_HMAC_MD5:
  624. {
  625. INT8U PasswdLen = 0;
  626. pMsghmac = (_FAR_ RAKPMsg1HMAC_T*)pBMCInfo->LANConfig.HmacInBuf;
  627. pMsghmac->RemConSessionID = pSessInfo->RemConSessionID;
  628. pMsghmac->MgdSysSessionID = pSessInfo->SessionID;
  629. /* Copy Random no.s and GUID */
  630. _fmemcpy (pMsghmac->RemConRandNo, pSessInfo->RemConRandomNo, 16);
  631. _fmemcpy (pMsghmac->MgdSysRandNo, pSessInfo->MgdSysRandomNo, 16);
  632. _fmemcpy (pMsghmac->MgdSysGUID, Res->ManSysGUID, MAX_MGD_SYS_GUID_LEN);
  633. pMsghmac->Role = Req->Role;
  634. pMsghmac->UsrNameLen = Req->UsrNameLen;
  635. _fmemcpy (pMsghmac->UsrName, Req->UsrName, Req->UsrNameLen);
  636. PasswdLen = _fstrlen ((_FAR_ char*)pSessInfo->Password);
  637. PasswdLen = (PasswdLen > MAX_PASSWORD_LEN) ?
  638. MAX_PASSWORD_LEN : PasswdLen;
  639. hmac_md5(pSessInfo->Password, PasswdLen, pBMCInfo->LANConfig.HmacInBuf,
  640. (sizeof (RAKPMsg1HMAC_T) - MAX_USERNAME_LEN + Req->UsrNameLen),
  641. &pRes [sizeof (RAKPMsg2Res_T)], RAKP1_HASH_HMAC_MD5_SIZE);
  642. AuthCodeLen = RAKP1_HASH_HMAC_MD5_SIZE;
  643. break;
  644. }
  645. case RAKP_HMAC_SHA256:
  646. {
  647. INT8U PasswdLen = 0;
  648. pMsghmac = (_FAR_ RAKPMsg1HMAC_T*)pBMCInfo->LANConfig.HmacInBuf;
  649. pMsghmac->RemConSessionID = pSessInfo->RemConSessionID;
  650. pMsghmac->MgdSysSessionID = pSessInfo->SessionID;
  651. /* Copy Random nos and GUID */
  652. _fmemcpy (pMsghmac->RemConRandNo, pSessInfo->RemConRandomNo, 16);
  653. _fmemcpy (pMsghmac->MgdSysRandNo, pSessInfo->MgdSysRandomNo, 16);
  654. _fmemcpy (pMsghmac->MgdSysGUID, Res->ManSysGUID, MAX_MGD_SYS_GUID_LEN);
  655. pMsghmac->Role = Req->Role;
  656. pMsghmac->UsrNameLen = Req->UsrNameLen;
  657. _fmemcpy (pMsghmac->UsrName, Req->UsrName, Req->UsrNameLen);
  658. PasswdLen = _fstrlen ((_FAR_ char*)pSessInfo->Password);
  659. PasswdLen = (PasswdLen > MAX_PASSWORD_LEN) ?
  660. MAX_PASSWORD_LEN : PasswdLen;
  661. hmac_sha256(pSessInfo->Password, PasswdLen, pBMCInfo->LANConfig.HmacInBuf,
  662. (sizeof (RAKPMsg1HMAC_T) - MAX_USERNAME_LEN + Req->UsrNameLen),
  663. &pRes [ sizeof (RAKPMsg2Res_T)], RAKP1_HASH_HMAC_SHA256_SIZE);
  664. AuthCodeLen = RAKP1_HASH_HMAC_SHA256_SIZE;
  665. break;
  666. }
  667. default:
  668. IPMI_WARNING ("RMCP+.c : RAKPMsg1 - Invalid Authentication\n");
  669. AuthCodeLen = 0;
  670. }
  671. pBMCInfo->LANConfig.DeleteThisLANSessionID = 0;
  672. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  673. return sizeof (RAKPMsg2Res_T) + AuthCodeLen;
  674. }
  675. /*----------------------------------------
  676. * RAKPMsg3
  677. *----------------------------------------*/
  678. int
  679. RAKPMsg3 (_NEAR_ INT8U* pReq, INT8U ReqLen, _NEAR_ INT8U* pRes, MiscParams_T *pParams,INT8U Channel, int BMCInst)
  680. {
  681. _NEAR_ RAKPMsg3Req_T *Req = (_NEAR_ RAKPMsg3Req_T*)pReq;
  682. _NEAR_ RAKPMsg4Res_T *Res = (_NEAR_ RAKPMsg4Res_T*)pRes;
  683. _FAR_ SessionInfo_T *pSessInfo;
  684. _NEAR_ INT8U *pKeyXchgCode;
  685. _NEAR_ SIKhmac_T *pSIKhmac;
  686. _FAR_ Msg3hmac_T *pMsg3hmac;
  687. _FAR_ UserInfo_T *pUserInfo;
  688. _FAR_ RAKPMsg4hmac_T *pMsg4hmac;
  689. _FAR_ ChannelInfo_T *pChannelInfo;
  690. _FAR_ ChannelUserInfo_T *pChUserInfo;
  691. _FAR_ BMCInfo_t *pBMCInfo = &g_BMCInfo[BMCInst];
  692. INT8U TempKey [HASH_KEY1_CONST_SIZE];
  693. INT8U TempKey2 [HASH_KEY2_CONST_SIZE];
  694. INT8U UserPasswdLen=0;
  695. int i;
  696. INT8U ResIntigrityKeyLen=0;
  697. INT8U Index;
  698. INT8U EthIndex;
  699. INT8U UserPswd [MAX_PASSWORD_LEN];
  700. INT32U SessionID;
  701. INT8U PwdEncKey[MAX_SIZE_KEY + 1] = {0};
  702. SessionID = Req->ManSysSessionID;
  703. OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->SessionTblMutex,WAIT_INFINITE);
  704. pSessInfo = getSessionInfo (SESSION_ID_INFO, &SessionID, BMCInst);
  705. /* In case of error, delete this session info */
  706. pBMCInfo->LANConfig.DeleteThisLANSessionID = Req->ManSysSessionID;
  707. /* Check if Management System SessionID */
  708. if (NULL == pSessInfo)
  709. {
  710. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  711. IPMI_WARNING ("RMCP+.c : RAKPMsg3 - Invalid Session ID\n");
  712. Res->StatusCode = SC_INV_SESSION_ID;
  713. return sizeof (RAKPMsg4Res_T);
  714. }
  715. /* Check if previous transactions caused an error */
  716. if (Req->StatusCode != SC_NO_ERROR)
  717. {
  718. if(Req->StatusCode == SC_INV_INTEGRITY_CHECK)
  719. {
  720. OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->ChUserMutex,WAIT_INFINITE);
  721. LockUser(pSessInfo->UserId,Channel, BMCInst);
  722. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  723. }
  724. IPMI_WARNING ("RMCP+.c : RAKPMsg3 - Invalid Status\n");
  725. if ( 0 != AddLoginEvent( pSessInfo->UserId, NULL, EVENT_LOGIN_FAILURE, BMCInst ))
  726. {
  727. IPMI_WARNING("Problem while adding Log record \n");
  728. }
  729. Res->StatusCode = Req->StatusCode;
  730. DeleteSession(pSessInfo,BMCInst);
  731. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  732. return 0;
  733. }
  734. UnlockUser(pSessInfo->UserId,Channel,BMCInst);
  735. if(Channel == 0xFF)
  736. {
  737. Channel= pSessInfo->Channel;
  738. }
  739. EthIndex= GetEthIndex(Channel, BMCInst);
  740. if(0xff == EthIndex)
  741. {
  742. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  743. *pRes = CC_INV_DATA_FIELD;
  744. return sizeof (INT8U);
  745. }
  746. OS_THREAD_MUTEX_ACQUIRE(&pBMCInfo->ChUserMutex,WAIT_INFINITE);
  747. /* Get User Info */
  748. pUserInfo = getUserIdInfo((INT8U)pSessInfo->UserId, BMCInst);
  749. if (NULL == pUserInfo)
  750. {
  751. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  752. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  753. IPMI_WARNING ("RMCP+.c : RAKPMsg3 - User not found\n");
  754. Res->StatusCode = SC_UNAUTHORISED_NAME;
  755. return sizeof (RAKPMsg4Res_T);
  756. }
  757. if (g_corefeatures.userpswd_encryption == ENABLED)
  758. {
  759. /* Get Encryption Key from the MBMCInfo_t structure */
  760. memcpy(PwdEncKey, &(g_MBMCInfo.PwdEncKey), MAX_SIZE_KEY);
  761. if(DecryptPassword((INT8S *)(pBMCInfo->EncryptedUserInfo[pSessInfo->UserId - 1].EncryptedPswd), MAX_PASSWORD_LEN, (char *)UserPswd, MAX_PASSWORD_LEN, PwdEncKey))
  762. {
  763. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  764. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  765. IPMI_ERROR("Error in decrypting the user password for user ID:%d. .\n", pSessInfo->UserId);
  766. Res->StatusCode = CC_UNSPECIFIED_ERR;
  767. return sizeof(RAKPMsg4Res_T);
  768. }
  769. }
  770. else
  771. {
  772. _fmemcpy (UserPswd, pUserInfo->UserPassword, MAX_PASSWORD_LEN);
  773. }
  774. UserPasswdLen = _fstrlen ((_FAR_ char*)UserPswd);
  775. UserPasswdLen = (UserPasswdLen > MAX_PASSWORD_LEN) ?
  776. MAX_PASSWORD_LEN : UserPasswdLen;
  777. /* Check for Key Exchange Auth Code */
  778. pKeyXchgCode = (_FAR_ INT8U*)(pReq + sizeof (RAKPMsg3Req_T));
  779. /*Construct hmac to check Auth code */
  780. pMsg3hmac = (_FAR_ Msg3hmac_T*) &pBMCInfo->LANConfig.HmacInBuf;
  781. _fmemcpy (pMsg3hmac->MgdSysRandNo, pSessInfo->MgdSysRandomNo, 16);
  782. pMsg3hmac->RemConSessionID = pSessInfo->RemConSessionID;
  783. pMsg3hmac->Role = pSessInfo->Privilege | (pSessInfo->Lookup << 4);
  784. pMsg3hmac->UsrNameLen = _fstrlen ((_FAR_ char*)pUserInfo->UserName);
  785. pMsg3hmac->UsrNameLen = (pMsg3hmac->UsrNameLen > MAX_USERNAME_LEN) ?
  786. MAX_USERNAME_LEN : pMsg3hmac->UsrNameLen;
  787. _fmemcpy ((_FAR_ char*)pMsg3hmac->UsrName,
  788. (_FAR_ char*)pUserInfo->UserName, pMsg3hmac->UsrNameLen);
  789. /* Key Exchange Auth Code */
  790. switch (pSessInfo->AuthAlgorithm)
  791. {
  792. case RAKP_NONE:
  793. break;
  794. case RAKP_HMAC_SHA1:
  795. hmac_sha1 ((INT8U *)UserPswd, UserPasswdLen, (INT8U *)pBMCInfo->LANConfig.HmacInBuf,
  796. sizeof (Msg3hmac_T) - (16 - pMsg3hmac->UsrNameLen),
  797. (INT8U *)&pRes [ sizeof (RAKPMsg4Res_T)], RAKP1_HASH_SIZE);
  798. if (0 != _fmemcmp (pKeyXchgCode, &pRes [sizeof (RAKPMsg4Res_T)], RAKP1_HASH_SIZE))
  799. {
  800. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  801. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  802. IPMI_WARNING ("RMCP+.c : RAKPMsg3 - Invalid integrity check\n");
  803. Res->StatusCode = SC_INV_INTEGRITY_CHECK;
  804. return sizeof (RAKPMsg4Res_T);
  805. }
  806. break;
  807. case RAKP_HMAC_MD5:
  808. hmac_md5(UserPswd, UserPasswdLen, pBMCInfo->LANConfig.HmacInBuf,
  809. sizeof (Msg3hmac_T) - (MAX_USERNAME_LEN - pMsg3hmac->UsrNameLen),
  810. &pRes [ sizeof (RAKPMsg4Res_T)], RAKP1_HASH_HMAC_MD5_SIZE);
  811. if (0 != _fmemcmp (pKeyXchgCode, &pRes [sizeof (RAKPMsg4Res_T)], RAKP1_HASH_HMAC_MD5_SIZE))
  812. {
  813. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  814. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  815. IPMI_WARNING ("RMCP+.c : RAKPMsg3 - Invalid integrity check\n");
  816. Res->StatusCode = SC_INV_INTEGRITY_CHECK;
  817. return sizeof (RAKPMsg4Res_T);
  818. }
  819. break;
  820. case RAKP_HMAC_SHA256:
  821. hmac_sha256(pSessInfo->Password, UserPasswdLen, pBMCInfo->LANConfig.HmacInBuf,
  822. sizeof (Msg3hmac_T) - (MAX_USERNAME_LEN - pMsg3hmac->UsrNameLen),
  823. &pRes [ sizeof (RAKPMsg4Res_T)], RAKP1_HASH_HMAC_SHA256_SIZE);
  824. if (0 != _fmemcmp (pKeyXchgCode, &pRes [sizeof (RAKPMsg4Res_T)], RAKP1_HASH_HMAC_SHA256_SIZE))
  825. {
  826. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  827. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  828. IPMI_WARNING ("RMCP+.c : RAKPMsg3 - Invalid integrity check\n");
  829. Res->StatusCode = SC_INV_INTEGRITY_CHECK;
  830. return sizeof (RAKPMsg4Res_T);
  831. }
  832. break;
  833. default:
  834. IPMI_WARNING ("RMCP+.c : RAKPMsg3 - Invalid Authentication\n");
  835. }
  836. /*Construct SIK to send the Integrity check */
  837. memset(pBMCInfo->LANConfig.HmacInBuf,0,sizeof(pBMCInfo->LANConfig.HmacInBuf));
  838. memset(pBMCInfo->LANConfig.SIK,0,sizeof(pBMCInfo->LANConfig.SIK));
  839. pSIKhmac = (_FAR_ SIKhmac_T*) &pBMCInfo->LANConfig.HmacInBuf;
  840. _fmemcpy (pSIKhmac->RemConRandNo, pSessInfo->RemConRandomNo, 16);
  841. _fmemcpy (pSIKhmac->MgdSysRandNo, pSessInfo->MgdSysRandomNo, 16);
  842. pSIKhmac->Role = pSessInfo->Privilege | (pSessInfo->Lookup << 4) ;
  843. pSIKhmac->UsrNameLen = _fstrlen ((_FAR_ char*)pUserInfo->UserName);
  844. pSIKhmac->UsrNameLen = (pSIKhmac->UsrNameLen > MAX_USERNAME_LEN) ?
  845. MAX_USERNAME_LEN : pSIKhmac->UsrNameLen;
  846. _fmemcpy ((_FAR_ char*)pSIKhmac->UsrName,
  847. (_FAR_ char*)pUserInfo->UserName, pSIKhmac->UsrNameLen);
  848. for (i = 0; i < HASH_KEY_LEN; i++)
  849. {
  850. if (pBMCInfo->RMCPPlus[EthIndex].KGHashKey [i] != 0)
  851. {
  852. break;
  853. }
  854. }
  855. switch(pSessInfo->AuthAlgorithm)
  856. {
  857. case RAKP_NONE:
  858. break;
  859. case RAKP_HMAC_SHA1:
  860. {
  861. // Encryption key must not be used for packets from VLAN or Loopback.
  862. #ifdef LAN_RESTRICTIONS_BYPASS_FOR_LOOPBACK_AND_VLAN
  863. if ((i < HASH_KEY_LEN) && !(pParams->IsPktFromVLAN || pParams->IsPktFromLoopBack) )
  864. #else
  865. if ((i < HASH_KEY_LEN))
  866. #endif
  867. {
  868. /* Use the KG (BMC Key set through SetChSecurityKeys command) Key */
  869. hmac_sha1 ((INT8U *)pBMCInfo->RMCPPlus[EthIndex].KGHashKey, HASH_KEY_LEN, (INT8U *)pBMCInfo->LANConfig.HmacInBuf,
  870. (sizeof (SIKhmac_T) - 16 + pSIKhmac->UsrNameLen),
  871. (INT8U *)pBMCInfo->LANConfig.SIK, SESSION_INTEGRITY_KEY_SIZE);
  872. }
  873. else
  874. {
  875. /* Use the KUID (User Password) Key */
  876. hmac_sha1 ((INT8U *)UserPswd, UserPasswdLen, (INT8U *)pBMCInfo->LANConfig.HmacInBuf,
  877. (sizeof (SIKhmac_T) - 16 + pSIKhmac->UsrNameLen),
  878. (INT8U *)pBMCInfo->LANConfig.SIK, SESSION_INTEGRITY_KEY_SIZE);
  879. }
  880. /* Create Key1 & Key2 for Rest of packet Integrity & Encryption */
  881. _fmemset (TempKey, 1, HASH_KEY1_CONST_SIZE);
  882. hmac_sha1 ((INT8U *)pBMCInfo->LANConfig.SIK, SESSION_INTEGRITY_KEY_SIZE, (INT8U *)TempKey, HASH_KEY1_CONST_SIZE,
  883. (INT8U *)pSessInfo->Key1, HASH_KEY1_SIZE);
  884. _fmemset (TempKey2, 2, HASH_KEY2_CONST_SIZE);
  885. hmac_sha1 ((INT8U *)pBMCInfo->LANConfig.SIK, SESSION_INTEGRITY_KEY_SIZE, (INT8U *)TempKey2, HASH_KEY2_CONST_SIZE,
  886. (INT8U *)pSessInfo->Key2, HASH_KEY2_SIZE);
  887. /* Construct HMAC to send the Integrity check value using SIK got from prev hmac*/
  888. pMsg4hmac = (_FAR_ RAKPMsg4hmac_T*) &pBMCInfo->LANConfig.HmacInBuf;
  889. _fmemcpy (pMsg4hmac->RemConRandNo, pSessInfo->RemConRandomNo, 16);
  890. pMsg4hmac->MgdSysSessionID = pSessInfo->SessionID;
  891. /*Get System GUID */
  892. _fmemcpy (pMsg4hmac->MgdSysGUID, BMC_GET_SHARED_MEM (BMCInst)->SystemGUID, 16);
  893. hmac_sha1 ((INT8U *)pBMCInfo->LANConfig.SIK, SESSION_INTEGRITY_KEY_SIZE, (INT8U *)pBMCInfo->LANConfig.HmacInBuf, sizeof (RAKPMsg4hmac_T),
  894. (INT8U *)&pRes [sizeof (RAKPMsg4Res_T)], HASH_KEY1_CONST_SIZE);
  895. ResIntigrityKeyLen = HMAC_SHA1_96_LEN;
  896. break;
  897. }
  898. case RAKP_HMAC_MD5:
  899. {
  900. #ifdef LAN_RESTRICTIONS_BYPASS_FOR_LOOPBACK_AND_VLAN
  901. if ((i < HASH_KEY_LEN) && !(pParams->IsPktFromVLAN || pParams->IsPktFromLoopBack) )
  902. #else
  903. if ((i < HASH_KEY_LEN))
  904. #endif
  905. {
  906. /* Use the KG (BMC Key set through SetChSecurityKeys command) Key */
  907. hmac_md5 (pBMCInfo->RMCPPlus[EthIndex].KGHashKey, HASH_KEY_LEN, pBMCInfo->LANConfig.HmacInBuf,
  908. (sizeof (SIKhmac_T) - 16 + pSIKhmac->UsrNameLen),
  909. pBMCInfo->LANConfig.SIK, SESSION_HMAC_MD5_I_KEY_SIZE);
  910. }
  911. else
  912. {
  913. /* Use the KUID (User Password) Key */
  914. hmac_md5 (UserPswd, UserPasswdLen, pBMCInfo->LANConfig.HmacInBuf,
  915. (sizeof (SIKhmac_T) - 16 + pSIKhmac->UsrNameLen),
  916. pBMCInfo->LANConfig.SIK, SESSION_HMAC_MD5_I_KEY_SIZE);
  917. }
  918. /* Create Key1 & Key2 for Rest of packet Integrity & Encryption */
  919. _fmemset (TempKey, 1, HASH_KEY1_CONST_SIZE);
  920. hmac_md5 (pBMCInfo->LANConfig.SIK, SESSION_HMAC_MD5_I_KEY_SIZE, TempKey, HASH_KEY1_CONST_SIZE,
  921. pSessInfo->Key1, SESSION_HMAC_MD5_I_KEY_SIZE);
  922. _fmemset (TempKey2, 2, HASH_KEY2_CONST_SIZE);
  923. hmac_md5 (pBMCInfo->LANConfig.SIK, SESSION_HMAC_MD5_I_KEY_SIZE, TempKey2, HASH_KEY2_CONST_SIZE,
  924. pSessInfo->Key2, SESSION_HMAC_MD5_I_KEY_SIZE);
  925. /* Construct HMAC to send the Integrity check value using SIK got from prev hmac*/
  926. pMsg4hmac = (_FAR_ RAKPMsg4hmac_T*) &pBMCInfo->LANConfig.HmacInBuf;
  927. _fmemcpy (pMsg4hmac->RemConRandNo, pSessInfo->RemConRandomNo, 16);
  928. pMsg4hmac->MgdSysSessionID = pSessInfo->SessionID;
  929. /*Get System GUID */
  930. _fmemcpy (pMsg4hmac->MgdSysGUID, BMC_GET_SHARED_MEM (BMCInst)->SystemGUID, 16);
  931. hmac_md5 (pBMCInfo->LANConfig.SIK, SESSION_INTEGRITY_KEY_SIZE, pBMCInfo->LANConfig.HmacInBuf, sizeof (RAKPMsg4hmac_T),
  932. &pRes [sizeof (RAKPMsg4Res_T)], SESSION_HMAC_MD5_I_KEY_SIZE);
  933. ResIntigrityKeyLen = HMAC_MD5_LEN;
  934. }
  935. break;
  936. #if 0 //algorithm not specified in IPMI spec, to be removed after review
  937. case AUTH_MD5_128:
  938. {
  939. // Encryption key must not be used for packets from VLAN or Loopback.
  940. #ifdef LAN_RESTRICTIONS_BYPASS_FOR_LOOPBACK_AND_VLAN
  941. if ((i < HASH_KEY_LEN) && !(pParams->IsPktFromVLAN || pParams->IsPktFromLoopBack) )
  942. #else
  943. if ((i < HASH_KEY_LEN))
  944. #endif
  945. {
  946. /* Use the KG (BMC Key set through SetChSecurityKeys command) Key */
  947. MD5_128 ((char *)pBMCInfo->RMCPPlus[EthIndex].KGHashKey, HASH_KEY_LEN, (char *)pBMCInfo->LANConfig.HmacInBuf,
  948. (sizeof (SIKhmac_T) - 16 + pSIKhmac->UsrNameLen),
  949. (char *)pBMCInfo->LANConfig.SIK, SESSION_MD5_KEY_SIZE);
  950. }
  951. else
  952. {
  953. /* Use the KUID (User Password) Key */
  954. MD5_128 ((char *)pUserInfo->UserPassword, UserPasswdLen, (char *)pBMCInfo->LANConfig.HmacInBuf,
  955. (sizeof (SIKhmac_T) - 16 + pSIKhmac->UsrNameLen), (char *)pBMCInfo->LANConfig.SIK, SESSION_MD5_KEY_SIZE);
  956. }
  957. /* Create Key1 & Key2 for Rest of packet Integrity & Encryption */
  958. _fmemset (TempKey, 1, HASH_KEY1_CONST_SIZE);
  959. MD5_128 ((char *)pBMCInfo->LANConfig.SIK, SESSION_INTEGRITY_KEY_SIZE, (char *)TempKey, HASH_KEY1_CONST_SIZE,
  960. (char *)pSessInfo->Key1, SESSION_MD5_KEY_SIZE);
  961. _fmemset (TempKey2, 2, HASH_KEY2_CONST_SIZE);
  962. MD5_128 ((char *)pBMCInfo->LANConfig.SIK, SESSION_INTEGRITY_KEY_SIZE, (char *)TempKey2, HASH_KEY2_CONST_SIZE,
  963. (char *)pSessInfo->Key2, SESSION_MD5_KEY_SIZE);
  964. /* Construct HMAC to send the Integrity check value using SIK got from prev hmac*/
  965. pMsg4hmac = (_FAR_ RAKPMsg4hmac_T*) &pBMCInfo->LANConfig.HmacInBuf;
  966. _fmemcpy (pMsg4hmac->RemConRandNo, pSessInfo->RemConRandomNo, 16);
  967. pMsg4hmac->MgdSysSessionID = pSessInfo->SessionID;
  968. /*Get System GUID */
  969. _fmemcpy (pMsg4hmac->MgdSysGUID, BMC_GET_SHARED_MEM (BMCInst)->SystemGUID, 16);
  970. MD5_128 ((char *)pBMCInfo->LANConfig.SIK, SESSION_INTEGRITY_KEY_SIZE, (char *)pBMCInfo->LANConfig.HmacInBuf, sizeof (RAKPMsg4hmac_T),
  971. (char *)&pRes [sizeof (RAKPMsg4Res_T)], SESSION_MD5_KEY_SIZE);
  972. ResIntigrityKeyLen = MD5_LEN;
  973. break;
  974. }
  975. #endif
  976. case RAKP_HMAC_SHA256:
  977. {
  978. // Encryption key must not be used for packets from VLAN or Loopback.
  979. #ifdef LAN_RESTRICTIONS_BYPASS_FOR_LOOPBACK_AND_VLAN
  980. if ((i < HASH_KEY_LEN) && !(pParams->IsPktFromVLAN || pParams->IsPktFromLoopBack) )
  981. #else
  982. if ((i < HASH_KEY_LEN))
  983. #endif
  984. {
  985. /* Use the KG (BMC Key set through SetChSecurityKeys command) Key */
  986. hmac_sha256((unsigned char *)pBMCInfo->RMCPPlus[EthIndex].KGHashKey, HASH_KEY_LEN, (unsigned char *)pBMCInfo->LANConfig.HmacInBuf,
  987. (sizeof (SIKhmac_T) - 16 + pSIKhmac->UsrNameLen),
  988. (unsigned char *)m_SIK, SHA2_HASH_KEY_SIZE);
  989. }
  990. else
  991. {
  992. /* Use the KUID (User Password) Key */
  993. hmac_sha256 ((unsigned char *)UserPswd, UserPasswdLen, (unsigned char *)pBMCInfo->LANConfig.HmacInBuf,
  994. (sizeof (SIKhmac_T) - 16 + pSIKhmac->UsrNameLen), (unsigned char *)m_SIK, SHA2_HASH_KEY_SIZE);
  995. }
  996. /* Create Key1 & Key2 for Rest of packet Integrity & Encryption */
  997. _fmemset (TempKey, 1, HASH_KEY1_CONST_SIZE);
  998. hmac_sha256 (m_SIK, SHA2_HASH_KEY_SIZE, TempKey, HASH_KEY1_CONST_SIZE,
  999. pSessInfo->Key1, SHA2_HASH_KEY_SIZE);
  1000. _fmemset (TempKey2, 2, HASH_KEY2_CONST_SIZE);
  1001. hmac_sha256 (m_SIK, SHA2_HASH_KEY_SIZE, TempKey2, HASH_KEY2_CONST_SIZE,
  1002. pSessInfo->Key2, SHA2_HASH_KEY_SIZE);
  1003. /* Construct HMAC to send the Integrity check value using SIK got from prev hmac*/
  1004. pMsg4hmac = (_FAR_ RAKPMsg4hmac_T*) &pBMCInfo->LANConfig.HmacInBuf;
  1005. _fmemcpy (pMsg4hmac->RemConRandNo, pSessInfo->RemConRandomNo, 16);
  1006. pMsg4hmac->MgdSysSessionID = pSessInfo->SessionID;
  1007. /*Get System GUID */
  1008. _fmemcpy (pMsg4hmac->MgdSysGUID, BMC_GET_SHARED_MEM (BMCInst)->SystemGUID, 16);
  1009. hmac_sha256 (m_SIK, SHA2_HASH_KEY_SIZE, pBMCInfo->LANConfig.HmacInBuf, sizeof (RAKPMsg4hmac_T),
  1010. &pRes [sizeof (RAKPMsg4Res_T)], HASH_KEY1_CONST_SIZE);
  1011. ResIntigrityKeyLen = HMAC_SHA256_128_LEN;
  1012. break;
  1013. }
  1014. default:
  1015. IPMI_DBG_PRINT("\nRMCP+.c : Invalid Integrity Algorithm \n");
  1016. }
  1017. /* Get information abt this channel */
  1018. pChannelInfo = getChannelInfo (Channel, BMCInst);
  1019. if (NULL == pChannelInfo)
  1020. {
  1021. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  1022. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  1023. IPMI_WARNING ("RMCP+.c : RAKPMsg3 - Invalid Integrity check\n");
  1024. Res->StatusCode = SC_INV_INTEGRITY_CHECK;
  1025. return sizeof (RAKPMsg4Res_T);
  1026. }
  1027. pUserInfo = getUserIdInfo((INT8U)pSessInfo->UserId, BMCInst);
  1028. // check the session activated or not, or it will add repeatedly. And finally it will happen "No session slot available."
  1029. if((!pSessInfo->IsLoopBack) && (pSessInfo->Activated!=TRUE))
  1030. {
  1031. /* Update active sessions for current user */
  1032. pUserInfo->CurrentSession++;
  1033. /* Number of active session */
  1034. pChannelInfo->ActiveSession++;
  1035. }
  1036. /* Get userInfo for the given Used Id & Channel */
  1037. pChUserInfo = getChUserIdInfo (pSessInfo->UserId, &Index, pChannelInfo->ChannelUserInfo, BMCInst);
  1038. #ifdef LAN_RESTRICTIONS_BYPASS_FOR_LOOPBACK_AND_VLAN
  1039. if( pParams->IsPktFromVLAN || pParams->IsPktFromLoopBack )
  1040. {
  1041. /* If the packet is from VLAN or LoopBack, then channel privilege should not be
  1042. considered for session privilege calculation */
  1043. pSessInfo->Privilege = 0x4; //set to admin for loopback and VLAN always
  1044. //UTIL_MIN (pSessInfo->Privilege, pChUserInfo->AccessLimit);
  1045. }
  1046. else
  1047. {
  1048. /* if requested privilege is greater than privilege level for channel or user
  1049. set the minimum of Channel or user privilege*/
  1050. pSessInfo->Privilege =
  1051. UTIL_MIN (pSessInfo->Privilege, UTIL_MIN (pChannelInfo->MaxPrivilege, pChUserInfo->AccessLimit));
  1052. }
  1053. #else
  1054. /* if requested privilege is greater than privilege level for channel or user
  1055. set the minimum of Channel or user privilege*/
  1056. pSessInfo->Privilege =
  1057. UTIL_MIN (pSessInfo->Privilege, UTIL_MIN (pChannelInfo->MaxPrivilege, pChUserInfo->AccessLimit));
  1058. #endif
  1059. pSessInfo->AuthType = RMCP_PLUS_FORMAT;
  1060. pSessInfo->Activated = TRUE;
  1061. /* Set the Max Privilege allowed for the Session*/
  1062. pSessInfo->MaxPrivilege = pSessInfo->Privilege;
  1063. BMC_GET_SHARED_MEM (BMCInst)->SessionHandle += 1;
  1064. pSessInfo->SessionHandle = BMC_GET_SHARED_MEM (BMCInst)->SessionHandle;
  1065. /*Load Response */
  1066. Res->StatusCode = SC_NO_ERROR;
  1067. Res->RemConSessionID = pSessInfo->RemConSessionID;
  1068. pSessInfo->EventFlag = 1;
  1069. pBMCInfo->LANConfig.DeleteThisLANSessionID = 0;
  1070. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->ChUserMutex);
  1071. OS_THREAD_MUTEX_RELEASE(&pBMCInfo->SessionTblMutex);
  1072. return (sizeof (RAKPMsg4Res_T) + ResIntigrityKeyLen);
  1073. }
  1074. #endif /*#if IPMI20_SUPPORT == 1*/