OCP.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
  1. /**
  2. * MIT License
  3. *
  4. * Copyright (c) 2018 Infineon Technologies AG
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. * SOFTWARE
  23. *
  24. *
  25. * \file OCP.c
  26. *
  27. * \brief This file implements the API Layer of OCP Library.
  28. *
  29. * \addtogroup grOCP
  30. * @{
  31. */
  32. #include "optiga/optiga_dtls.h"
  33. #include "optiga/cmd/CommandLib.h"
  34. #include "optiga/dtls/AlertProtocol.h"
  35. #ifdef MODULE_ENABLE_DTLS_MUTUAL_AUTH
  36. /// @cond hidden
  37. extern Void ConfigHL(fPerformHandshake_d* PfPerformHandshake_d,eConfiguration_d PeConfiguration);
  38. extern Void ConfigRL(sConfigRL_d* PpsConfigRL,eConfiguration_d PeConfiguration);
  39. extern Void ConfigTL(sConfigTL_d* PpsConfigTL,eConfiguration_d PeConfiguration);
  40. extern Void ConfigCL(sConfigCL_d* PpsConfigCL,eConfiguration_d PeConfiguration);
  41. extern int32_t DtlsHS_VerifyHR(uint8_t* PprgbData, uint16_t PwLen);
  42. ///Identifier for Session ID 1
  43. #define SESSIONID_1 0xE100
  44. ///Session key is in used
  45. #define INUSE 0x4A
  46. ///Session key is not in use
  47. #define NOTUSED 0xA4
  48. /**
  49. * \brief Structure that defines OCP Application context data
  50. */
  51. typedef struct sAppOCPCtx_d
  52. {
  53. ///Pointer to function that performs handshake
  54. fPerformHandshake_d pfPerformHandshake;
  55. ///Structure that contains Handshake data
  56. sHandshake_d sHandshake;
  57. ///Structure that holds Record Layer Configuration
  58. sConfigRL_d sConfigRL;
  59. ///Structure that holds logger parameters
  60. sLogger_d sLogger;
  61. ///Authentication scheme
  62. eAuthScheme_d eAuthScheme;
  63. ///Buffer to store the received application data
  64. uint8_t* pAppDataBuf;
  65. }sAppOCPCtx_d;
  66. /**
  67. * \brief Configures the Handshake, Record, Transport and Crypto Layers based on input parameters
  68. */
  69. _STATIC_H Void OCP_Config(sAppOCPCtx_d* PpsAppOCPCntx,eConfiguration_d PeConfiguration)
  70. {
  71. ConfigHL(&(PpsAppOCPCntx->pfPerformHandshake),PeConfiguration);
  72. ConfigRL(&(PpsAppOCPCntx->sConfigRL),PeConfiguration);
  73. ConfigTL(PpsAppOCPCntx->sConfigRL.sRL.psConfigTL,PeConfiguration);
  74. ConfigCL(PpsAppOCPCntx->sConfigRL.sRL.psConfigCL,PeConfiguration);
  75. }
  76. /**
  77. * Allocates the memory for sAppOCPCtx_d<br>
  78. */
  79. _STATIC_H int32_t OCPAllocateMemory(sAppOCPCtx_d ** PppsAppOCPCntx)
  80. {
  81. int32_t i4Status = (int32_t)OCP_LIB_MALLOC_FAILURE;
  82. #define PS_APPOCPCNTX (* PppsAppOCPCntx)
  83. do
  84. {
  85. //Allocate the memory for OCP context data structure
  86. PS_APPOCPCNTX = (sAppOCPCtx_d *)OCP_MALLOC(sizeof(sAppOCPCtx_d));
  87. if(NULL == PS_APPOCPCNTX)
  88. {
  89. break;
  90. }
  91. (*PS_APPOCPCNTX).pAppDataBuf = NULL;
  92. (*PS_APPOCPCNTX).sConfigRL.sRL.psConfigTL = NULL;
  93. (*PS_APPOCPCNTX).sConfigRL.sRL.psConfigCL = NULL;
  94. //Allocate the memory for the transport layer and crypto layer structure
  95. PS_APPOCPCNTX->sConfigRL.sRL.psConfigTL = (sConfigTL_d*)OCP_MALLOC(sizeof(sConfigTL_d));
  96. if(NULL == PS_APPOCPCNTX->sConfigRL.sRL.psConfigTL)
  97. {
  98. break;
  99. }
  100. PS_APPOCPCNTX->sConfigRL.sRL.psConfigTL->sTL.phTLHdl = NULL;
  101. PS_APPOCPCNTX->sConfigRL.sRL.psConfigCL = (sConfigCL_d*)OCP_MALLOC(sizeof(sConfigCL_d));
  102. if(NULL == PS_APPOCPCNTX->sConfigRL.sRL.psConfigCL)
  103. {
  104. break;
  105. }
  106. PS_APPOCPCNTX->sConfigRL.sRL.psConfigCL->sCL.phCryptoHdl = NULL;
  107. PS_APPOCPCNTX->sConfigRL.sRL.phRLHdl = NULL;
  108. i4Status = (int32_t)OCP_LIB_OK;
  109. }while(FALSE);
  110. #undef PS_APPOCPCNTX
  111. return i4Status;
  112. }
  113. /**
  114. * \brief Frees the allocated memory for sAppOCPCtx_d
  115. */
  116. _STATIC_H Void OCPFreeMemory(sAppOCPCtx_d* PpsAppOCPCntx)
  117. {
  118. if(NULL != PpsAppOCPCntx)
  119. {
  120. if(NULL != (PpsAppOCPCntx)->pAppDataBuf)
  121. {
  122. OCP_FREE((PpsAppOCPCntx)->pAppDataBuf);
  123. }
  124. if(NULL != (PpsAppOCPCntx)->sConfigRL.sRL.psConfigCL)
  125. {
  126. #define S_RL (PpsAppOCPCntx)->sConfigRL
  127. S_RL.sRL.psConfigCL->pfClose(&(PpsAppOCPCntx)->sConfigRL.sRL.psConfigCL->sCL);
  128. OCP_FREE((PpsAppOCPCntx)->sConfigRL.sRL.psConfigCL);
  129. }
  130. if(NULL != (PpsAppOCPCntx)->sConfigRL.sRL.psConfigTL)
  131. {
  132. #define S_TL (PpsAppOCPCntx)->sConfigRL.sRL.psConfigTL->sTL
  133. if(NULL != S_TL.phTLHdl)
  134. {
  135. //Free the allocated memory for Transport layer
  136. OCP_FREE(S_TL.phTLHdl);
  137. S_TL.phTLHdl = NULL;
  138. }
  139. OCP_FREE((PpsAppOCPCntx)->sConfigRL.sRL.psConfigTL);
  140. }
  141. //Free the memory held by record layer
  142. S_RL.pfClose(&S_RL.sRL);
  143. OCP_FREE(PpsAppOCPCntx);
  144. }
  145. #undef S_TL
  146. #undef S_RL
  147. }
  148. /**
  149. * \brief Structure defining Session registry content
  150. */
  151. typedef struct sSessionRegistry_d
  152. {
  153. ///DTLS Session ID
  154. uint16_t wSessionId;
  155. ///OCP Handle
  156. hdl_t hOCPHandle;
  157. ///Variable to indicate the session ID usage
  158. uint8_t bInUse;
  159. }sSessionRegistry_d;
  160. ///Static registry for holding Session key Id information
  161. sSessionRegistry_d sSessionRegistry[1] ={
  162. {SESSIONID_1, (hdl_t)NULL, NOTUSED}
  163. };
  164. /**
  165. * This API returns the available Security Chip Session id
  166. * that can be used by Command Library SetAuthScheme.<br>
  167. *
  168. * \param[in,out] PwSessionId Available session id
  169. *
  170. * \retval #OCP_LIB_OK
  171. * \retval #OCP_LIB_SESSIONID_UNAVAILABLE
  172. */
  173. _STATIC_H int32_t Registry_GetSessionId(uint16_t* PwSessionId)
  174. {
  175. int32_t i4Status = (int32_t)OCP_LIB_SESSIONID_UNAVAILABLE;
  176. uint8_t bCount = 0;
  177. //Search the registry for unused session key id
  178. for(bCount= 0;bCount<(sizeof(sSessionRegistry)/sizeof(sSessionRegistry_d));bCount++)
  179. {
  180. if(NOTUSED == sSessionRegistry[bCount].bInUse)
  181. {
  182. //return unused session key id
  183. *PwSessionId = sSessionRegistry[bCount].wSessionId;
  184. i4Status = (int32_t)OCP_LIB_OK;
  185. break;
  186. }
  187. }
  188. return i4Status;
  189. }
  190. /**
  191. * This function updates OCP handle against the given session key id in the registry if the session key id is not already used.<br>
  192. * The session key is marked as in-use.
  193. *
  194. * \param[in] PdwSessionId Session id
  195. * \param[in,out] PhOCPHandle Context to be updated for input session id
  196. *
  197. * \retval #OCP_LIB_OK
  198. * \retval #OCP_LIB_ERROR
  199. */
  200. _STATIC_H int32_t Registry_Update(uint32_t PdwSessionId,const hdl_t PhOCPHandle)
  201. {
  202. int32_t i4Status = (int32_t)OCP_LIB_ERROR;
  203. uint8_t bCount;
  204. //Search the table for the given session key id
  205. for(bCount= 0;bCount<(sizeof(sSessionRegistry)/sizeof(sSessionRegistry_d));bCount++)
  206. {
  207. if((PdwSessionId == sSessionRegistry[bCount].wSessionId) &&
  208. (NOTUSED == sSessionRegistry[bCount].bInUse))
  209. {
  210. //Update the OCP handle
  211. sSessionRegistry[bCount].hOCPHandle = PhOCPHandle;
  212. //Update the usage status
  213. sSessionRegistry[bCount].bInUse = INUSE;
  214. i4Status = (int32_t) OCP_LIB_OK;
  215. break;
  216. }
  217. }
  218. return i4Status;
  219. }
  220. /**
  221. * This function frees the session key id used for the given OCP handle in the registry.<br>
  222. * The session key is marked as Not used.
  223. *
  224. * \param[in,out] PhOCPHandle Context for which session id to be freed
  225. *
  226. */
  227. //lint --e{818} suppress "PhOCPHandle is declared as const"
  228. _STATIC_H Void Registry_Free(const hdl_t PhOCPHandle)
  229. {
  230. uint8_t bCount;
  231. //Search the table for the given session key id
  232. for(bCount= 0;bCount<(sizeof(sSessionRegistry)/sizeof(sSessionRegistry_d));bCount++)
  233. {
  234. if(PhOCPHandle == sSessionRegistry[bCount].hOCPHandle)
  235. {
  236. //Free the usage status
  237. sSessionRegistry[bCount].bInUse = NOTUSED;
  238. sSessionRegistry[bCount].hOCPHandle = NULL;
  239. break;
  240. }
  241. }
  242. }
  243. /**
  244. * This function Gets the session key id used for the given OCP handle in the registry.<br>
  245. *
  246. * \param[in] PhOCPHandle OCP handle
  247. * \param[out] PpwSessionId Pointer to the session ID
  248. *
  249. * \retval #OCP_LIB_OK
  250. * \retval #OCP_LIB_SESSIONID_UNAVAILABLE
  251. */
  252. //lint --e{818} suppress "PhOCPHandle is declared as const"
  253. _STATIC_H int32_t Registry_GetHandleSessionID(const hdl_t PhOCPHandle, uint16_t *PpwSessionId)
  254. {
  255. int32_t i4Status = (int32_t)OCP_LIB_SESSIONID_UNAVAILABLE;
  256. uint8_t bCount = 0;
  257. //Search the table for the given OCP handle
  258. for(bCount= 0;bCount<(sizeof(sSessionRegistry)/sizeof(sSessionRegistry_d));bCount++)
  259. {
  260. if(PhOCPHandle == sSessionRegistry[bCount].hOCPHandle)
  261. {
  262. *PpwSessionId = sSessionRegistry[bCount].wSessionId;
  263. i4Status = (int32_t)OCP_LIB_OK;
  264. break;
  265. }
  266. }
  267. return i4Status;
  268. }
  269. /**
  270. * This function validates whether handle is associated with a the session key id from the registry.<br>
  271. *
  272. * \param[in] PhOCPHandle OCP handle
  273. *
  274. * \retval #OCP_LIB_OK
  275. * \retval #OCP_LIB_SESSIONID_UNAVAILABLE
  276. */
  277. //lint --e{818} suppress "PhOCPHandle is declared as const"
  278. _STATIC_H int32_t Registry_ValidateHandleSessionID(const hdl_t PhOCPHandle)
  279. {
  280. int32_t i4Status = (int32_t)OCP_LIB_SESSIONID_UNAVAILABLE;
  281. uint8_t bCount;
  282. //Search the table for the given OCP handle
  283. for(bCount= 0;bCount<(sizeof(sSessionRegistry)/sizeof(sSessionRegistry_d));bCount++)
  284. {
  285. if(PhOCPHandle == sSessionRegistry[bCount].hOCPHandle)
  286. {
  287. i4Status = (int32_t)OCP_LIB_OK;
  288. break;
  289. }
  290. }
  291. return i4Status;
  292. }
  293. /**
  294. * This Function closes the session ,free the memory allocated and return close notify alert based on input parameter.<br>
  295. *
  296. * Notes: <br>
  297. * - Under some erroneous conditions,error codes from Command Library and transport layer can also be returned. <br>
  298. *
  299. * \param[in] PhAppOCPCtx OCP handle
  300. * \param[in] PfFatalError Flag indicating whether fatal error as occurred or not
  301. * \param[in] PwSessionId Session ID to be closed
  302. *
  303. */
  304. _STATIC_H Void CloseSession(hdl_t PhAppOCPCtx, bool_t PfFatalError, uint16_t PwSessionId)
  305. {
  306. sAppOCPCtx_d *psCntx = (sAppOCPCtx_d*)PhAppOCPCtx;
  307. #define S_CONFIGURATION_TL (psCntx->sConfigRL.sRL.psConfigTL)
  308. //lint --e{534} ,Return value is ignored as irrespective of this session will be closed"
  309. if(psCntx->sHandshake.eAuthState != eAuthInitialised)
  310. {
  311. if(!PfFatalError)
  312. {
  313. SEND_ALERT(&psCntx->sConfigRL,(int32_t) OCP_RL_ERROR);
  314. }
  315. //Close the DTLS session on Security Chip
  316. CmdLib_CloseSession(PwSessionId);
  317. }
  318. //Disconnect from the server via transport layer
  319. S_CONFIGURATION_TL->pfDisconnect(&S_CONFIGURATION_TL->sTL);
  320. //Clear the session reference ID registry for the handle
  321. Registry_Free(PhAppOCPCtx);
  322. //Free the memory associated with the handle
  323. OCPFreeMemory(psCntx);
  324. #undef S_CONFIGURATION_TL
  325. }
  326. /// @endcond
  327. /**
  328. * This API initialises the OCP context based on the user inputs provided in PpsAppOCPConfig.Once the OCP context
  329. * is initialised,PphAppOCPCtx is returned as a handle.<br>
  330. * PphAppOCPCtx handle is used for all interactions with the OCP APIs #OCP_Connect, #OCP_Disconnect, #OCP_Send and #OCP_Receive.
  331. * <br>
  332. * <br>
  333. * \image html OCPInit.png "OCP_Init()" width=20cm
  334. *
  335. *<b>Pre Conditions:</b>
  336. * - Communication with the security chip is up and running. <br>
  337. * #optiga_comms_open() must be successfully executed.<br>
  338. * - The optiga comms context for command library is registered using CmdLib_SetOptigaCommsContext().
  339. *
  340. *<b>API Details:</b>
  341. * - Checks for an available session OID.
  342. * - Opens application on the security chip using CmdLib_OpenApplication().<br>
  343. * - Allocates the memory for internal structures, initialises it and returns as a #hdl_t*
  344. *
  345. *<b>User Input:</b><br>
  346. *The user must provide configuration information in #sAppOCPConfig_d
  347. * - eMode allows the user to configure the OCP context as a client/server as per #eMode_d. Currently server mode is not supported.<br>
  348. * - eConfiguration allows the user to choose supported OCP context configuration as per #eConfiguration_d. Currently eTLS_12_TCP_HWCRYPTO is not supported.<br>
  349. * - wOIDDevCertificate allows the user to choose the supported certificate for client authentication.
  350. * - If their is no client certificate then set it to 0x0000.<br>
  351. * - wOIDDevPrivKey allows the user to choose the private key used for client authentication.<br>
  352. * - psNetworkParams allows the user to configure the port, IP Address and maximum PMTU required for transport layer connection.<br>
  353. * - Valid IP address and port number must be provided. The correctness of the IP address and port number will not be verified.<br>
  354. * - PMTU value should range between 296 to 1500,else #OCP_LIB_UNSUPPORTED_PMTU error is returned.<br>
  355. * - Logger allows user to log data. User must provide the low level log writer through #sLogger_d.<br>
  356. * - pfGetUnixTIme(#fGetUnixTime_d) is a call-back function pointer that allows user to provide 32-bit Unix time format.<br>
  357. * - If pfGetUnixTIme is set to NULL, the unix time will not be sent to security chip.<br>
  358. * - If pfGetUnixTIme is not set to NULL or valid function pointer, the behavior would be unexpected.<br>
  359. * - The call back function pfGetUnixTIme is expected to return status s as #CALL_BACK_OK for success.
  360. *
  361. *<b>Notes:</b>
  362. * - Currently, only 1 DTLS session is supported by security chip.<br>
  363. * - If user invokes OCP_Init, with out disconnecting/closing the previous session/context(if available), will lead to error #OCP_LIB_SESSIONID_UNAVAILABLE.<br>
  364. * - Under some failure conditions, error codes from lower layers could also be returned. <br>
  365. *
  366. * \param[in] PpsAppOCPConfig Pointer to structure that contains the configuration from user
  367. * \param[in,out] PphAppOCPCtx Pointer to the handle of OCP context
  368. *
  369. * \retval #OCP_LIB_OK
  370. * \retval #OCP_LIB_ERROR
  371. * \retval #OCP_LIB_NULL_PARAM
  372. * \retval #OCP_LIB_UNSUPPORTED_CONFIG
  373. * \retval #OCP_LIB_SESSIONID_UNAVAILABLE
  374. * \retval #OCP_LIB_UNSUPPORTED_PMTU
  375. */
  376. int32_t OCP_Init(const sAppOCPConfig_d* PpsAppOCPConfig,hdl_t* PphAppOCPCtx)
  377. {
  378. int32_t i4Status = (int32_t)OCP_LIB_ERROR;
  379. sAppOCPCtx_d *psAppOCPCntx = NULL;
  380. eAuthScheme_d eAuthScheme;
  381. sOpenApp_d sOpenApp;
  382. uint16_t wSessionKeyId;
  383. do
  384. {
  385. //NULL check for input parameters
  386. if((NULL == PpsAppOCPConfig) || (NULL == PphAppOCPCtx))
  387. {
  388. i4Status = (int32_t)OCP_LIB_NULL_PARAM;
  389. break;
  390. }
  391. //Initialize handle to NULL
  392. * PphAppOCPCtx = NULL;
  393. //Check the registry whether a free session Id is available
  394. i4Status = Registry_GetSessionId(&wSessionKeyId);
  395. if(OCP_LIB_OK != i4Status)
  396. {
  397. break;
  398. }
  399. //Check for valid configuration
  400. if(eDTLS_12_UDP_HWCRYPTO != PpsAppOCPConfig->eConfiguration)
  401. {
  402. i4Status = (int32_t)OCP_LIB_UNSUPPORTED_CONFIG;
  403. break;
  404. }
  405. //Initialize the Auth Scheme type
  406. if((eClient == PpsAppOCPConfig->eMode) && (eDTLS_12_UDP_HWCRYPTO == PpsAppOCPConfig->eConfiguration))
  407. {
  408. eAuthScheme = eDTLSClient;
  409. }
  410. else
  411. {
  412. //If other mode is selected
  413. i4Status = (int32_t)OCP_LIB_UNSUPPORTED_MODE;
  414. break;
  415. }
  416. //Check if the PMTU provided is within limit or not
  417. if((PpsAppOCPConfig->sNetworkParams.wMaxPmtu > MAX_PMTU) || (PpsAppOCPConfig->sNetworkParams.wMaxPmtu < MIN_PMTU))
  418. {
  419. i4Status = (int32_t)OCP_LIB_UNSUPPORTED_PMTU;
  420. break;
  421. }
  422. //Allocate the memory for the Context data structure.It will be used for all interaction with OCP APIs
  423. i4Status = OCPAllocateMemory(&psAppOCPCntx);
  424. if(OCP_LIB_OK != i4Status)
  425. {
  426. break;
  427. }
  428. OCP_Config(psAppOCPCntx,PpsAppOCPConfig->eConfiguration);
  429. sOpenApp.eOpenType = eInit;
  430. //Open Application
  431. i4Status = CmdLib_OpenApplication(&sOpenApp);
  432. if(CMD_LIB_OK != i4Status)
  433. {
  434. break;
  435. }
  436. //Assign the Auth Scheme
  437. psAppOCPCntx->eAuthScheme = eAuthScheme;
  438. //Assign the maximum path transfer unit
  439. psAppOCPCntx->sHandshake.wMaxPmtu = PpsAppOCPConfig->sNetworkParams.wMaxPmtu;
  440. //Assign the Certificate type to be used for Authentication
  441. psAppOCPCntx->sHandshake.wOIDDevCertificate = PpsAppOCPConfig->wOIDDevCertificate;
  442. //Assign the private key to be used for Authentication
  443. psAppOCPCntx->sHandshake.wOIDDevPrivKey = PpsAppOCPConfig->wOIDDevPrivKey;
  444. //Assign the callback function to get unix time
  445. psAppOCPCntx->sHandshake.pfGetUnixTIme = PpsAppOCPConfig->pfGetUnixTIme;
  446. //Assign the record layer configuration pointer to the handshake layer
  447. psAppOCPCntx->sHandshake.psConfigRL = &psAppOCPCntx->sConfigRL;
  448. psAppOCPCntx->sHandshake.eMode = PpsAppOCPConfig->eMode;
  449. //Set the fatal error occur type to false;
  450. psAppOCPCntx->sHandshake.fFatalError = FALSE;
  451. //Assign the logger pointer for psAppOCPCntx layer
  452. psAppOCPCntx->sLogger = PpsAppOCPConfig->sLogger;
  453. //Assign the logger pointer for handshake layer
  454. psAppOCPCntx->sHandshake.phLogger = PpsAppOCPConfig->sLogger;
  455. //Assign the logger pointer for Record layer
  456. psAppOCPCntx->sConfigRL.sRL.sLogger.pHdl = PpsAppOCPConfig->sLogger.pHdl;
  457. psAppOCPCntx->sConfigRL.sRL.sLogger.phfWriter = PpsAppOCPConfig->sLogger.phfWriter;
  458. /// @cond hidden
  459. #define S_TL psAppOCPCntx->sConfigRL.sRL.psConfigTL->sTL
  460. /// @endcond
  461. //Assign the IP address to the transport layer parameter
  462. S_TL.pzIpAddress = PpsAppOCPConfig->sNetworkParams.pzIpAddress;
  463. //Assign the port number to the transport layer parameter
  464. S_TL.wPort = PpsAppOCPConfig->sNetworkParams.wPort;
  465. //Assign the UDP Timeout to the transport layer parameter
  466. S_TL.wTimeout = 200;
  467. //Assign the logger pointer for Transport layer
  468. S_TL.sLogger.pHdl = PpsAppOCPConfig->sLogger.pHdl;
  469. S_TL.sLogger.phfWriter = PpsAppOCPConfig->sLogger.phfWriter;
  470. //Assign the initial connection state of transport layer
  471. S_TL.eIsConnected = eDisconnected;
  472. //Assign receive call function type
  473. S_TL.eCallType = eNonBlocking;
  474. //Assign the logger pointer for Transport layer
  475. psAppOCPCntx->sConfigRL.sRL.psConfigCL->sCL.sLogger.pHdl = PpsAppOCPConfig->sLogger.pHdl;
  476. psAppOCPCntx->sConfigRL.sRL.psConfigCL->sCL.sLogger.phfWriter = PpsAppOCPConfig->sLogger.phfWriter;
  477. //Initialize all the modules
  478. //Init for logger
  479. //lint --e{611} suppress "This is ignored as it is known to the user for data type conversion"
  480. LOG_SETWRITER((pFWriteData2)PpsAppOCPConfig->sLogger.phfWriter,(Void*)PpsAppOCPConfig->sLogger.pHdl);
  481. //Init Record Layer
  482. i4Status = psAppOCPCntx->sConfigRL.pfInit(&psAppOCPCntx->sConfigRL.sRL);
  483. if(OCP_RL_OK != i4Status)
  484. {
  485. break;
  486. }
  487. //Init Transport Layer
  488. i4Status = psAppOCPCntx->sConfigRL.sRL.psConfigTL->pfInit(&S_TL);
  489. if(OCP_TL_OK != i4Status)
  490. {
  491. break;
  492. }
  493. //Init Crypto Layer
  494. i4Status = psAppOCPCntx->sConfigRL.sRL.psConfigCL->pfInit(&psAppOCPCntx->sConfigRL.sRL.psConfigCL->sCL, (Void*)&wSessionKeyId);
  495. if(OCP_CL_OK != i4Status)
  496. {
  497. break;
  498. }
  499. //Update the registry with the session ID being used
  500. i4Status = Registry_Update(wSessionKeyId,(hdl_t) psAppOCPCntx);
  501. if(OCP_LIB_OK != i4Status)
  502. {
  503. break;
  504. }
  505. //Set the Authentication state to initialised
  506. psAppOCPCntx->sHandshake.eAuthState = eAuthInitialised;
  507. *PphAppOCPCtx = (hdl_t) psAppOCPCntx;
  508. psAppOCPCntx->sHandshake.PhAppOCPCtx = *PphAppOCPCtx;
  509. i4Status = (int32_t)OCP_LIB_OK;
  510. }while(FALSE);
  511. if((OCP_LIB_OK != i4Status) && ((int32_t)OCP_LIB_NULL_PARAM != i4Status) && ((int32_t)OCP_LIB_SESSIONID_UNAVAILABLE != i4Status))
  512. {
  513. OCPFreeMemory(psAppOCPCntx);
  514. }
  515. /// @cond hidden
  516. #undef S_TL
  517. /// @endcond
  518. return i4Status;
  519. }
  520. /**
  521. * This API connects to the server and performs a DTLS handshake protocol as per DTLS v1.2
  522. * <br>
  523. * <br>
  524. * \image html OCPConnect.png "OCP_Connect()" width=20cm
  525. *
  526. *<b>Pre Conditions:</b>
  527. * - #OCP_Init() is successful and application context is available.<br>
  528. * - Server trust anchor must be available in the security chip.<br>
  529. *
  530. *<b>API Details:</b>
  531. * - Connects to the server via the transport layer.<br>
  532. * - Invokes CmdLib_SetAuthScheme() based on configuration.<br>
  533. * - Performs a DTLS Handshake.<br>
  534. *
  535. *<b>User Input:</b><br>
  536. * - User must provide a valid PhAppOCPCtx handle otherwise #OCP_LIB_SESSIONID_UNAVAILABLE is returned.<br>
  537. *
  538. *<b>Notes:</b>
  539. * - The default value of timeout for retransmission must be 2 seconds on the server side.<br>
  540. * - If a connection already exists on the given port and IP address, #OCP_LIB_CONNECTION_ALREADY_EXISTS is returned.<br>
  541. * - Under some failure conditions, error codes from lower layers could also be returned. <br>
  542. * - In case of a Failure other than #OCP_LIB_CONNECTION_ALREADY_EXISTS and #OCP_LIB_SESSIONID_UNAVAILABLE<br>
  543. * - The Session gets closed automatically.<br>
  544. * - The memory allocated in #OCP_Init() are freed.<br>
  545. * - OCP handle will not be set to NULL.It is upto the user to check return code and take appropriate action.<br>
  546. * - If the return value is #CMD_DEV_EXEC_ERROR, it might indicate that the application on the security chip is either
  547. * closed or a reset has occurred.<br>
  548. *
  549. *
  550. * \param[in] PhAppOCPCtx Handle to OCP Context
  551. *
  552. * \retval #OCP_LIB_OK
  553. * \retval #OCP_LIB_ERROR
  554. * \retval #OCP_LIB_NULL_PARAM
  555. * \retval #OCP_LIB_CONNECTION_ALREADY_EXISTS
  556. * \retval #OCP_LIB_SESSIONID_UNAVAILABLE
  557. */
  558. int32_t OCP_Connect(const hdl_t PhAppOCPCtx)
  559. {
  560. int32_t i4Status = (int32_t)OCP_LIB_ERROR;
  561. sAuthScheme_d sAuthScheme;
  562. /// @cond hidden
  563. #define PS_CNTX ((sAppOCPCtx_d*)PhAppOCPCtx)
  564. #define S_CONFIGURATION_TL (PS_CNTX->sConfigRL.sRL.psConfigTL)
  565. #define S_CONFIGURATION_CL (PS_CNTX->sConfigRL.sRL.psConfigCL)
  566. #define S_CONFIGURATION_RL (PS_CNTX->sConfigRL)
  567. /// @endcond
  568. do
  569. {
  570. //NULL check for handle
  571. if(NULL == PS_CNTX)
  572. {
  573. i4Status = (int32_t)OCP_LIB_NULL_PARAM;
  574. break;
  575. }
  576. i4Status = Registry_ValidateHandleSessionID(PhAppOCPCtx);
  577. if(OCP_LIB_OK != i4Status)
  578. {
  579. break;
  580. }
  581. //Null checks for other pointers
  582. if((NULL == S_CONFIGURATION_TL) || (NULL== S_CONFIGURATION_TL->pfConnect)|| (NULL == PS_CNTX->pfPerformHandshake)||
  583. (NULL == S_CONFIGURATION_RL.pfSend)|| (NULL == S_CONFIGURATION_RL.pfRecv) || (NULL == S_CONFIGURATION_RL.pfClose) ||
  584. (NULL == S_CONFIGURATION_TL->pfSend) || (NULL == S_CONFIGURATION_TL->pfRecv) || (NULL == S_CONFIGURATION_TL->pfDisconnect) ||
  585. (NULL == S_CONFIGURATION_CL) || (NULL == S_CONFIGURATION_CL->pfEncrypt) || (NULL == S_CONFIGURATION_CL->pfDecrypt) ||
  586. (NULL == S_CONFIGURATION_CL->pfClose))
  587. {
  588. i4Status = (int32_t)OCP_LIB_NULL_PARAM;
  589. break;
  590. }
  591. //Check whether connection is already connected
  592. if(eConnected == S_CONFIGURATION_TL->sTL.eIsConnected)
  593. {
  594. i4Status = (int32_t)OCP_LIB_CONNECTION_ALREADY_EXISTS;
  595. break;
  596. }
  597. //Connect to server
  598. i4Status = S_CONFIGURATION_TL->pfConnect(&S_CONFIGURATION_TL->sTL);
  599. if(OCP_TL_OK != i4Status)
  600. {
  601. break;
  602. }
  603. //Get the Session OID from registry
  604. i4Status = Registry_GetHandleSessionID(PhAppOCPCtx,&(PS_CNTX->sHandshake.wSessionOID));
  605. if(OCP_LIB_OK != i4Status)
  606. {
  607. break;
  608. }
  609. //Initialize Auth scheme structure
  610. sAuthScheme.eAuthScheme = PS_CNTX->eAuthScheme;
  611. sAuthScheme.wDevicePrivKey = PS_CNTX->sHandshake.wOIDDevPrivKey;
  612. sAuthScheme.wSessionKeyId = PS_CNTX->sHandshake.wSessionOID;
  613. //Set the AuthScheme
  614. i4Status = CmdLib_SetAuthScheme(&sAuthScheme);
  615. if(CMD_LIB_OK != i4Status)
  616. {
  617. break;
  618. }
  619. //Perform Handshake
  620. i4Status = PS_CNTX->pfPerformHandshake((hdl_t)&PS_CNTX->sHandshake);
  621. if(OCP_HL_OK != i4Status)
  622. {
  623. break;
  624. }
  625. i4Status = (int32_t) OCP_LIB_OK;
  626. }while(FALSE);
  627. do
  628. {
  629. if((OCP_LIB_OK != i4Status) &&
  630. ((int32_t)OCP_LIB_CONNECTION_ALREADY_EXISTS != i4Status) &&
  631. ((int32_t)OCP_LIB_NULL_PARAM != i4Status) &&
  632. ((int32_t)OCP_LIB_SESSIONID_UNAVAILABLE != i4Status))
  633. {
  634. //lint --e{794} suppress "OCP_LIB_NULL_PARAM check address this lint issue which doesn't allow null pointer in this context,"
  635. CloseSession(PhAppOCPCtx,PS_CNTX->sHandshake.fFatalError, PS_CNTX->sHandshake.wSessionOID);
  636. LOG_TRANSPORTDBVAL(i4Status,eInfo);
  637. }
  638. }while(FALSE);
  639. /// @cond hidden
  640. #undef PS_CNTX
  641. #undef S_CONFIGURATION_CL
  642. #undef S_CONFIGURATION_TL
  643. #undef S_CONFIGURATION_RL
  644. /// @endcond
  645. return i4Status;
  646. }
  647. /**
  648. * This API sends application data to the DTLS server
  649. * <br>
  650. * <br>
  651. * \image html OCPSend.png "OCP_Send()" width=20cm
  652. *
  653. *<b>Pre Conditions:</b>
  654. * - #OCP_Connect() is successful and application context is available.<br>
  655. *
  656. *<b>API Details:</b>
  657. * - Sends application data to DTLS server.<br>
  658. * - Application data is sent only if Mutual Authentication Public Key Scheme (DTLS) was successfully performed.<br>
  659. * - Encryption of the application data is done at the record layer.<br>
  660. *<br>
  661. *
  662. *<b>User Input:</b><br>
  663. * - User must provide a valid PhAppOCPCtx handle.<br>
  664. * - User must provide the data to be sent and its length
  665. * - If the length of the data to be sent is greater then #MAX_APP_DATALEN(PhAppOCPCtx), then #OCP_LIB_INVALID_LEN is returned.
  666. * - If the length of the data to be sent is equal to zero, then #OCP_LIB_LENZERO_ERROR is returned.<br>
  667. *
  668. *<b>Notes:</b>
  669. * - The maximum length of data that can be sent by the API depends upon the PMTU value set during #OCP_Init().This length can be obtained by #MAX_APP_DATALEN(PhAppOCPCtx).<br>
  670. * - Fragmentation of data to be sent should be done by the application. This API does not perform data fragmentation.<br>
  671. * - If the record sequence number has reached maximum value for epoch 1, then #OCP_RL_SEQUENCE_OVERFLOW error is returned.
  672. * User must call #OCP_Disconnect() in this condition.No Alert will be sent due to the unavailability of record sequence number.<br>
  673. * - Under some failure conditions, error codes from lower layers could also be returned. <br>
  674. * - In case of a Failure,<br>
  675. * - Existing session remains open and memory allocated during OCP_Init() is not freed.<br>
  676. * - PhAppOCPCtx handle is not set to NULL.<br>
  677. * - The API does not send any alert to the server.<br>
  678. * - If the return value is #CMD_DEV_EXEC_ERROR, it might indicate that the application on the security chip is either
  679. * closed or a reset has occurred. In such a case, close the existing DTLS session using #OCP_Disconnect.<br>
  680. *
  681. *
  682. * \param[in] PhAppOCPCtx Handle to OCP Context
  683. * \param[in] PprgbData Pointer to data to be sent
  684. * \param[in] PwLen Length of the data to be sent
  685. *
  686. * \retval #OCP_LIB_OK
  687. * \retval #OCP_LIB_ERROR
  688. * \retval #OCP_LIB_NULL_PARAM
  689. * \retval #OCP_LIB_SESSIONID_UNAVAILABLE
  690. * \retval #OCP_LIB_AUTHENTICATION_NOTDONE
  691. * \retval #OCP_LIB_MALLOC_FAILURE
  692. * \retval #OCP_LIB_LENZERO_ERROR
  693. * \retval #OCP_LIB_INVALID_LEN
  694. * \retval #OCP_RL_SEQUENCE_OVERFLOW
  695. */
  696. int32_t OCP_Send(const hdl_t PhAppOCPCtx,const uint8_t* PprgbData,uint16_t PwLen)
  697. {
  698. int32_t i4Status = (int32_t)OCP_LIB_ERROR;
  699. /// @cond hidden
  700. #define PS_CNTX ((sAppOCPCtx_d*)PhAppOCPCtx)
  701. #define S_CONFIGURATION_RL (PS_CNTX->sConfigRL)
  702. #define S_HS (PS_CNTX->sHandshake)
  703. /// @endcond
  704. do
  705. {
  706. //NULL check for handle
  707. if((NULL == PS_CNTX) || (NULL == PprgbData))
  708. {
  709. i4Status = (int32_t)OCP_LIB_NULL_PARAM;
  710. break;
  711. }
  712. //Validate the handle for the sessionID
  713. i4Status = Registry_ValidateHandleSessionID(PhAppOCPCtx);
  714. if(OCP_LIB_OK != i4Status)
  715. {
  716. break;
  717. }
  718. //Null checks for other pointers
  719. if((NULL == PS_CNTX->sConfigRL.sRL.psConfigTL) || (NULL == S_CONFIGURATION_RL.pfSend) ||
  720. (NULL == PS_CNTX->sConfigRL.sRL.psConfigTL->pfSend) || (NULL == PS_CNTX->sConfigRL.sRL.psConfigCL) ||
  721. (NULL == PS_CNTX->sConfigRL.sRL.psConfigCL->pfEncrypt))
  722. {
  723. i4Status = (int32_t)OCP_LIB_NULL_PARAM;
  724. break;
  725. }
  726. //Is Authentication session closed
  727. if(S_HS.eAuthState == eAuthSessionClosed)
  728. {
  729. i4Status = (int32_t)OCP_LIB_OPERATION_NOT_ALLOWED;
  730. break;
  731. }
  732. //Is Mutual Authentication complete
  733. if(S_HS.eAuthState != eAuthCompleted)
  734. {
  735. i4Status = (int32_t)OCP_LIB_AUTHENTICATION_NOTDONE;
  736. break;
  737. }
  738. //Zero Length
  739. if(0x00 == PwLen)
  740. {
  741. i4Status = (int32_t)OCP_LIB_LENZERO_ERROR;
  742. break;
  743. }
  744. //If length of data to be sent is greater then Max value
  745. if(MAX_APP_DATALEN(PhAppOCPCtx) < PwLen)
  746. {
  747. i4Status = (int32_t)OCP_LIB_INVALID_LEN;
  748. break;
  749. }
  750. //Memory need to be allocated
  751. S_CONFIGURATION_RL.sRL.bContentType = CONTENTTYPE_APP_DATA;
  752. S_CONFIGURATION_RL.sRL.bMemoryAllocated = FALSE;
  753. //Call Record layer
  754. i4Status = S_CONFIGURATION_RL.pfSend(&S_CONFIGURATION_RL.sRL, (uint8_t*)PprgbData, PwLen);
  755. if(OCP_RL_OK != i4Status)
  756. {
  757. break;
  758. }
  759. i4Status = (int32_t)OCP_LIB_OK;
  760. }while(FALSE);
  761. /// @cond hidden
  762. #undef PS_CNTX
  763. #undef S_CONFIGURATION_RL
  764. #undef S_HS
  765. /// @endcond
  766. return i4Status;
  767. }
  768. /**
  769. * This API receives application data from the DTLS server
  770. * <br>
  771. * <br>
  772. * \image html OCPRecv.png "OCP_Recv()" width=20cm
  773. *
  774. *<b>Pre Conditions:</b>
  775. * - #OCP_Connect() is successful and application context is available.<br>
  776. *
  777. *<b>API Details:</b>
  778. * - Receives application data from the DTLS server.<br>
  779. * - Application data is received only if Mutual Authentication Public Key Scheme (DTLS) was successfully performed.<br>
  780. * - Received data is assumed to be encrypted and processed accordingly. Decryption of the application data is done at the record layer.<br>
  781. * - Total received application data length is updated in PpwLen.<br>
  782. *<br>
  783. *
  784. *<b>User Input:</b><br>
  785. * - User must provide a valid PhAppOCPCtx handle.<br>
  786. * - User must provide the buffer where application data should be returned.<br>
  787. * - User must provide the length of the buffer.<br>
  788. * - If the length of the buffer is equal to zero, then #OCP_LIB_LENZERO_ERROR is returned.<br>
  789. * - User must provide the timeout value in milliseconds. The value should be greater than 0 and maximum up to (2^16)-1.
  790. * - If the timeout is zero #OCP_LIB_INVALID_TIMEOUT is returned.
  791. *
  792. *<b>Notes:</b>
  793. * - The maximum length of data that can be received by the API depends upon the PMTU value set during #OCP_Init().This length is indicated by #MAX_APP_DATALEN(PhAppOCPCtx).<br>
  794. * - If required, the Re-Assembly of received data should be done by the application. This API does not perform data re-assembly.<br>
  795. * - Failure in decrypting data will return #OCP_LIB_DECRYPT_FAILURE.<br>
  796. * - If a fatal alert with valid description is received,
  797. * - #OCP_AL_FATAL_ERROR is returned.<br>
  798. * - User must invoke #OCP_Disconnect() in this condition.Invoking OCP_Send() or OCP_Recv() will return #OCP_LIB_OPERATION_NOT_ALLOWED.<br>
  799. * - If a valid Hello request is received, the API internally sends a warning alert with description "no-renegotiation" to the server and then waits for data until timeout occurs.<br>
  800. * - If the length of buffer provided by the application is not sufficient to return received data, #OCP_LIB_INSUFFICIENT_MEMORY is returned. This data will not be returned in subsequent API invocation.<br>
  801. * - If timeout occurs,#OCP_LIB_TIMEOUT is returned.
  802. * - Under some failure conditions, error codes from lower layers could also be returned.<br>
  803. * - In case of a Failure,<br>
  804. * - Existing session remains open and memory allocated during OCP_Init() is not freed.<br>
  805. * - PhAppOCPCtx handle is not set to NULL.<br>
  806. * - The API does not send any alert to the server.<br>
  807. * - PpwLen is set to zero.<br>
  808. * - If the return value is #CMD_DEV_EXEC_ERROR, it might indicate that the application on the security chip is either
  809. * closed or a reset has occurred. In such a case, close the existing DTLS session using #OCP_Disconnect.<br>
  810. *
  811. *
  812. * \param[in] PhAppOCPCtx Handle to OCP Context
  813. * \param[in,out] PprgbData Pointer to buffer where data is to be received
  814. * \param[in,out] PpwLen Pointer to the length of buffer. Updated with actual length of received data.
  815. * \param[in] PwTimeout Timeout in milliseconds
  816. *
  817. * \retval #OCP_LIB_OK
  818. * \retval #OCP_LIB_ERROR
  819. * \retval #OCP_LIB_NULL_PARAM
  820. * \retval #OCP_LIB_SESSIONID_UNAVAILABLE
  821. * \retval #OCP_LIB_AUTHENTICATION_NOTDONE
  822. * \retval #OCP_LIB_MALLOC_FAILURE
  823. * \retval #OCP_LIB_LENZERO_ERROR
  824. * \retval #OCP_AL_FATAL_ERROR
  825. * \retval #OCP_LIB_INSUFFICIENT_MEMORY
  826. * \retval #OCP_LIB_INVALID_TIMEOUT
  827. * \retval #OCP_LIB_TIMEOUT
  828. * \retval #OCP_LIB_OPERATION_NOT_ALLOWED
  829. */
  830. int32_t OCP_Receive(const hdl_t PhAppOCPCtx, uint8_t* PprgbData, uint16_t* PpwLen, uint16_t PwTimeout)
  831. {
  832. int32_t i4Status = (int32_t)OCP_LIB_ERROR;
  833. sbBlob_d sAppData;
  834. int32_t i4Alert;
  835. uint32_t dwStarttime;
  836. /// @cond hidden
  837. #define PS_CNTX ((sAppOCPCtx_d*)PhAppOCPCtx)
  838. #define S_CONFIGURATION_RL (PS_CNTX->sConfigRL)
  839. #define S_HS (PS_CNTX->sHandshake)
  840. /// @endcond
  841. do
  842. {
  843. //NULL check for handle
  844. if((NULL == PS_CNTX) || (NULL == PprgbData) || (NULL == PpwLen))
  845. {
  846. i4Status = (int32_t)OCP_LIB_NULL_PARAM;
  847. break;
  848. }
  849. //Validate the handle for the sessionID
  850. i4Status = Registry_ValidateHandleSessionID(PhAppOCPCtx);
  851. if(OCP_LIB_OK != i4Status)
  852. {
  853. break;
  854. }
  855. //Null checks for other pointers
  856. if((NULL == PS_CNTX->sConfigRL.sRL.psConfigTL) || (NULL == S_CONFIGURATION_RL.pfRecv) ||
  857. (NULL == PS_CNTX->sConfigRL.sRL.psConfigTL->pfRecv)|| (NULL == PS_CNTX->sConfigRL.sRL.psConfigCL) ||
  858. (NULL == PS_CNTX->sConfigRL.sRL.psConfigCL->pfDecrypt))
  859. {
  860. i4Status = (int32_t)OCP_LIB_NULL_PARAM;
  861. break;
  862. }
  863. //Is Authentication session closed
  864. if(S_HS.eAuthState == eAuthSessionClosed)
  865. {
  866. i4Status = (int32_t)OCP_LIB_OPERATION_NOT_ALLOWED;
  867. break;
  868. }
  869. //Is Mutual Authentication Public Key Scheme (DTLS) complete
  870. if(S_HS.eAuthState != eAuthCompleted)
  871. {
  872. i4Status = (int32_t)OCP_LIB_AUTHENTICATION_NOTDONE;
  873. break;
  874. }
  875. //Zero Length
  876. if(0x00 == *PpwLen)
  877. {
  878. i4Status = (int32_t)OCP_LIB_LENZERO_ERROR;
  879. break;
  880. }
  881. if(0x00 == PwTimeout)
  882. {
  883. i4Status = (int32_t)OCP_LIB_INVALID_TIMEOUT;
  884. break;
  885. }
  886. if(NULL == PS_CNTX->pAppDataBuf)
  887. {
  888. PS_CNTX->pAppDataBuf = OCP_MALLOC(TLBUFFER_SIZE);
  889. if(NULL == PS_CNTX->pAppDataBuf)
  890. {
  891. i4Status = (int32_t)OCP_LIB_MALLOC_FAILURE;
  892. break;
  893. }
  894. }
  895. PS_CNTX->sConfigRL.sRL.psConfigTL->sTL.wTimeout = PwTimeout;
  896. //Start value for the Flight timeout
  897. dwStarttime = pal_os_timer_get_time_in_milliseconds();
  898. do
  899. {
  900. PS_CNTX->sConfigRL.sRL.bContentType = CONTENTTYPE_APP_DATA;
  901. sAppData.prgbStream = PS_CNTX->pAppDataBuf;
  902. sAppData.wLen = TLBUFFER_SIZE;
  903. i4Status = PS_CNTX->sConfigRL.pfRecv((sRL_d*)&(PS_CNTX->sConfigRL.sRL), sAppData.prgbStream, &sAppData.wLen);
  904. //Application record received
  905. if((int32_t)OCP_RL_APPDATA_RECEIVED == i4Status)
  906. {
  907. if(sAppData.wLen > *PpwLen)
  908. {
  909. i4Status = (int32_t)OCP_LIB_INSUFFICIENT_MEMORY;
  910. break;
  911. }
  912. *PpwLen = sAppData.wLen;
  913. Utility_Memmove(PprgbData, sAppData.prgbStream, sAppData.wLen);
  914. i4Status = OCP_LIB_OK;
  915. break;
  916. }
  917. //Alert record received
  918. if((int32_t)OCP_RL_ALERT_RECEIVED == i4Status)
  919. {
  920. i4Status = Alert_ProcessMsg(&sAppData,&i4Alert);
  921. if(((int32_t)OCP_AL_FATAL_ERROR == i4Alert))
  922. {
  923. S_HS.eAuthState = eAuthSessionClosed;
  924. i4Status = i4Alert;
  925. break;
  926. }
  927. }
  928. //Malloc failure
  929. if(((int32_t)OCP_RL_MALLOC_FAILURE == i4Status))
  930. {
  931. //Exit the state machine
  932. break;
  933. }
  934. //Decryption failure
  935. if(((int32_t)CMD_LIB_DECRYPT_FAILURE == i4Status))
  936. {
  937. i4Status = (int32_t)OCP_LIB_DECRYPT_FAILURE;
  938. //Exit
  939. break;
  940. }
  941. //Handshake record received
  942. if((int32_t)OCP_RL_OK == i4Status)
  943. {
  944. i4Status = DtlsHS_VerifyHR(sAppData.prgbStream, sAppData.wLen);
  945. if(i4Status == OCP_HL_OK)
  946. {
  947. SEND_ALERT(&PS_CNTX->sConfigRL,(int32_t) OCP_LIB_NO_RENEGOTIATE);
  948. }
  949. }
  950. if((uint32_t)(pal_os_timer_get_time_in_milliseconds() - dwStarttime) > (uint32_t)PwTimeout)
  951. {
  952. i4Status = (int32_t)OCP_LIB_TIMEOUT;
  953. break;
  954. }
  955. //Dynamically setting the UDP timeout
  956. PS_CNTX->sConfigRL.sRL.psConfigTL->sTL.wTimeout = (uint16_t)(PwTimeout - (uint16_t)(pal_os_timer_get_time_in_milliseconds() - dwStarttime));
  957. }while(TRUE);
  958. }while(FALSE);
  959. if((OCP_LIB_OK != i4Status) && (NULL != PpwLen))
  960. {
  961. *PpwLen = 0x00;
  962. }
  963. //lint --e{794} suppress "OCP_LIB_NULL_PARAM check addresses this lint issue which doesn't allow null pointer in this context,"
  964. if(((int32_t)OCP_LIB_NULL_PARAM != i4Status) && ((int32_t)OCP_LIB_SESSIONID_UNAVAILABLE != i4Status) &&
  965. ((int32_t)OCP_LIB_OPERATION_NOT_ALLOWED != i4Status) && ((int32_t)OCP_LIB_AUTHENTICATION_NOTDONE != i4Status) &&
  966. ((int32_t)OCP_LIB_LENZERO_ERROR != i4Status) && ((int32_t)OCP_LIB_INVALID_TIMEOUT != i4Status) &&
  967. (NULL != PS_CNTX->pAppDataBuf) && (PS_CNTX->sConfigRL.sRL.bMultipleRecord == 0))
  968. {
  969. OCP_FREE(PS_CNTX->pAppDataBuf);
  970. PS_CNTX->pAppDataBuf = NULL;
  971. }
  972. /// @cond hidden
  973. #undef PS_CNTX
  974. #undef S_CONFIGURATION_RL
  975. #undef S_HS
  976. /// @endcond
  977. return i4Status;
  978. }
  979. /**
  980. * This API disconnects the client from the server and closes the DTLS session
  981. * <br>
  982. * <br>
  983. * \image html OCPDisconnect.png "OCP_Disconnect()" width=20cm
  984. *
  985. *<b>Pre Conditions:</b>
  986. * - OCP_Init() or OCP_Connect() is successful.<br>
  987. *
  988. *<b>API Details:</b>
  989. * - Applicable only if called after a successful OCP_Connect()
  990. * - Closes DTLS session on security chip via CmdLib_CloseSession().<br>
  991. * - Sends closure alert to the server via the transport layer.<br>
  992. * - Disconnects from the server via the transport layer.<br>
  993. * - Applicable if called after successful OCP_Init() or OCP_Connect()
  994. * - Clear memory associated with PhAppOCPCtx handle.<br>
  995. * - Clears the internal session reference Id registry.<br>
  996. * - PhAppOCPCtx handle will not be set to NULL.It is up to the user to check return code and take appropriate action.<br>
  997. * <br>
  998. *
  999. *<b>User Input:</b><br>
  1000. * - User must provide a valid PhAppOCPCtx handle.<br>
  1001. *
  1002. * Notes: <br>
  1003. * - If the record sequence number has reached maximum value for epoch 1, No Alert will be send due to the unavailability of record sequence number.<br>
  1004. * - DTLS server will not be notified of the fault condition that leads to failure while sending Close_Notify alert.
  1005. *
  1006. *
  1007. * \param[in] PhAppOCPCtx Handle to OCP Context
  1008. *
  1009. * \retval #OCP_LIB_OK
  1010. * \retval #OCP_LIB_NULL_PARAM
  1011. * \retval #OCP_LIB_ERROR
  1012. */
  1013. int32_t OCP_Disconnect(hdl_t PhAppOCPCtx)
  1014. {
  1015. int32_t i4Status = (int32_t)OCP_LIB_ERROR;
  1016. uint16_t wSessionId = 0;
  1017. /// @cond hidden
  1018. #define PS_CNTX ((sAppOCPCtx_d*)PhAppOCPCtx)
  1019. #define S_CONFIGURATION_TL (PS_CNTX->sConfigRL.sRL.psConfigTL)
  1020. #define S_CONFIGURATION_CL (PS_CNTX->sConfigRL.sRL.psConfigCL)
  1021. /// @endcond
  1022. do
  1023. {
  1024. //NULL check for handle
  1025. if(NULL == PS_CNTX)
  1026. {
  1027. i4Status = (int32_t)OCP_LIB_NULL_PARAM;
  1028. break;
  1029. }
  1030. //Validate the handle for the sessionID
  1031. i4Status = Registry_ValidateHandleSessionID(PhAppOCPCtx);
  1032. if(OCP_LIB_OK != i4Status)
  1033. {
  1034. break;
  1035. }
  1036. //Null checks
  1037. if((NULL == S_CONFIGURATION_TL) || (NULL == S_CONFIGURATION_CL) || (NULL == S_CONFIGURATION_CL->pfClose) ||
  1038. (NULL == S_CONFIGURATION_TL->pfDisconnect) || (NULL == PS_CNTX->sConfigRL.pfClose))
  1039. {
  1040. i4Status = (int32_t)OCP_LIB_NULL_PARAM;
  1041. break;
  1042. }
  1043. //Get the session ID associated with the handle
  1044. i4Status = Registry_GetHandleSessionID(PhAppOCPCtx, &wSessionId);
  1045. if(OCP_LIB_OK != i4Status)
  1046. {
  1047. break;
  1048. }
  1049. //Close the session and free the memory allocated
  1050. CloseSession(PhAppOCPCtx, PS_CNTX->sHandshake.fFatalError, wSessionId);
  1051. PhAppOCPCtx = NULL;
  1052. }while(FALSE);
  1053. /// @cond hidden
  1054. #undef PS_CNTX
  1055. #undef S_CONFIGURATION_TL
  1056. #undef S_CONFIGURATION_CL
  1057. /// @endcond
  1058. return i4Status;
  1059. }
  1060. /**
  1061. * @}
  1062. */
  1063. #endif /*MODULE_ENABLE_DTLS_MUTUAL_AUTH*/