MessageLayer.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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
  26. *
  27. * \brief This file implements the functionality to form and process DTLS messages for OCP Library.
  28. *
  29. * \addtogroup grMutualAuth
  30. * @{
  31. */
  32. #include "optiga/dtls/MessageLayer.h"
  33. #ifdef MODULE_ENABLE_DTLS_MUTUAL_AUTH
  34. #define CALL_BACK_OK 0x00000001
  35. /**
  36. * Call back function to allocate memory to the received message from Security Chip.<br>
  37. *
  38. * \param[in,out] PpCBParam Pointer to structure containing information required to allocate memory
  39. * \param[in] psInOutMsg Pointer to sBlob containing the received Handshake message from Security Chip
  40. *
  41. * \retval #CMD_LIB_OK Successful Execution
  42. * \retval #CMD_LIB_ERROR Failure Execution
  43. */
  44. int32_t CallBack_GetMessage(Void* PpCBParam, const sbBlob_d* psInOutMsg)
  45. {
  46. int32_t i4Status = (int32_t) CMD_LIB_ERROR;
  47. uint32_t dwFragLen;
  48. uint32_t dwTotalLen;
  49. uint32_t dwOffset;
  50. /// @cond hidden
  51. #define PS_CBGETMSG ((sCBGetMsg_d*)PpCBParam)
  52. #define OFFSET_MSG_FRAG_LENGTH 9
  53. #define OFFSET_MSG_TOTAL_LENGTH 1
  54. #define OFFSET_MSG_FRAGMENT_OFFSET 6
  55. /// @endcond
  56. do
  57. {
  58. dwFragLen = Utility_GetUint24(psInOutMsg->prgbStream + OFFSET_MSG_FRAG_LENGTH);
  59. dwTotalLen = Utility_GetUint24(psInOutMsg->prgbStream + OFFSET_MSG_TOTAL_LENGTH);
  60. dwOffset = Utility_GetUint24(psInOutMsg->prgbStream + OFFSET_MSG_FRAGMENT_OFFSET);
  61. //If first time, allocate memory
  62. if(FALSE == PS_CBGETMSG->bRepeatCall)
  63. {
  64. //Allocate memory
  65. PS_CBGETMSG->dwMsgLen = (uint16_t)dwTotalLen + OVERHEAD_LEN;
  66. PS_CBGETMSG->pbActualMsg = (uint8_t*)OCP_MALLOC(dwTotalLen + OVERHEAD_LEN);
  67. if(PS_CBGETMSG->pbActualMsg == NULL)
  68. {
  69. i4Status = (int32_t)OCP_ML_MALLOC_FAILURE;
  70. break;
  71. }
  72. //Set to true indicating memory is already allocated
  73. PS_CBGETMSG->bRepeatCall = TRUE;
  74. OCP_MEMCPY(PS_CBGETMSG->pbActualMsg + (OVERHEAD_LEN - MSG_HEADER_LEN),psInOutMsg->prgbStream,(uint16_t)(dwFragLen + MSG_HEADER_LEN));
  75. //Set fragment offset to zero and fragment len to total len
  76. Utility_SetUint24((PS_CBGETMSG->pbActualMsg + (OVERHEAD_LEN - 3)), dwTotalLen);
  77. }
  78. else
  79. {
  80. //copy data from offset
  81. OCP_MEMCPY(PS_CBGETMSG->pbActualMsg + dwOffset + OVERHEAD_LEN, (psInOutMsg->prgbStream + MSG_HEADER_LEN), (uint16_t)dwFragLen);
  82. }
  83. i4Status = CMD_LIB_OK;
  84. }while(FALSE);
  85. /// @cond hidden
  86. #undef OFFSET_MSG_FRAG_LENGTH
  87. #undef OFFSET_MSG_TOTAL_LENGTH
  88. #undef OFFSET_MSG_FRAGMENT_OFFSET
  89. #undef PS_CBGETMSG
  90. /// @endcond
  91. return i4Status;
  92. }
  93. /**
  94. * Provide Handshake message using Command Library.<br>
  95. * Under some erroneous conditions, error codes from Command Library can also be returned.<br>
  96. *
  97. * \param[in] eMsgType Message type of the handshake message to be received from Security Chip
  98. * \param[in] PpsMessageLayer Pointer to structure containing information required for Message Layer
  99. * \param[out] PpsMessage Pointer to sBlob containing the Handshake message
  100. *
  101. * \retval #OCP_ML_OK Successful Execution
  102. * \retval #OCP_ML_ERROR Failure Execution
  103. * \retval #OCP_ML_INVALID_UNIXTIME Invalid unix time provided by user
  104. */
  105. int32_t MsgLayer_FormMessage(eMsgType_d eMsgType,const sMessageLayer_d* PpsMessageLayer, sbBlob_d* PpsMessage)
  106. {
  107. int32_t i4Status = (int32_t) OCP_ML_ERROR;
  108. sProcMsgData_d sGMsgVector;
  109. sCallBack_d sCallBack;
  110. sCBGetMsg_d sCBGetMsg;
  111. uMsgParams_d uMsgParams;
  112. do
  113. {
  114. //Null Check
  115. if((NULL == PpsMessageLayer) || (NULL == PpsMessage))
  116. {
  117. i4Status = (int32_t)OCP_ML_NULL_PARAM;
  118. break;
  119. }
  120. //Assign the call back function parameters
  121. sCBGetMsg.bRepeatCall = FALSE;
  122. sCBGetMsg.pbActualMsg = NULL;
  123. sCBGetMsg.dwMsgLen = 0;
  124. //Assign call back function to allocate memory
  125. sCallBack.pfAcceptMessage = CallBack_GetMessage;
  126. sCallBack.fvParams = (Void*) &sCBGetMsg;
  127. //Form the Get message command APDU parameters
  128. sGMsgVector.eParam = eMsgType;
  129. sGMsgVector.wSessionKeyOID = PpsMessageLayer->wSessionID;
  130. sGMsgVector.psCallBack = &sCallBack;
  131. sGMsgVector.psBlobInBuffer = NULL;
  132. //sGMsgVector.puMsgParams = &uMsgParams;
  133. sGMsgVector.puMsgParams = NULL;
  134. //Based on the message type set the message specific data
  135. switch((uint8_t)eMsgType)
  136. {
  137. case eClientHello:
  138. if(NULL != PpsMessageLayer->pfGetUnixTIme)
  139. {
  140. sGMsgVector.puMsgParams = &uMsgParams;
  141. //To use the unix time provided
  142. i4Status = PpsMessageLayer->pfGetUnixTIme(&sGMsgVector.puMsgParams->sMsgParamCH_d.dwUnixTime);
  143. if(CALL_BACK_OK != i4Status)
  144. {
  145. i4Status = (int32_t) OCP_ML_INVALID_UNIXTIME;
  146. break;
  147. }
  148. }
  149. break;
  150. case eClientCertificate:
  151. if(0x0000 != PpsMessageLayer->wOIDDevCertificate)
  152. {
  153. sGMsgVector.puMsgParams = &uMsgParams;
  154. sGMsgVector.puMsgParams->sMsgParamCert_d.wCertOID = PpsMessageLayer->wOIDDevCertificate;
  155. }
  156. break;
  157. default:
  158. //lint -e788 suppress "Default values for return are already set.No more operation required here"
  159. //For other messages there is no message specific data
  160. break;
  161. }
  162. if(((int32_t) OCP_ML_INVALID_UNIXTIME == i4Status) || ((int32_t) OCP_ML_INVALID_CERTTYPE == i4Status))
  163. {
  164. break;
  165. }
  166. //Get the Message using Get Message command from the Security Chip
  167. i4Status = CmdLib_GetMessage(&sGMsgVector);
  168. if(CMD_LIB_OK != i4Status)
  169. {
  170. LOG_TRANSPORTDBVAL(i4Status,eInfo);
  171. break;
  172. }
  173. //Allocated memory is assigned the sBlob
  174. PpsMessage->prgbStream = sCBGetMsg.pbActualMsg;
  175. PpsMessage->wLen = sCBGetMsg.dwMsgLen;
  176. i4Status = (int32_t) OCP_ML_OK ;
  177. }while(FALSE);
  178. return i4Status;
  179. }
  180. /**
  181. * Process Handshake message using Command Library.<br>
  182. * Under some erroneous conditions, error codes from Command Library can also be returned. <br>
  183. *
  184. * \param[in] eMsgType Message type of the handshake message to be send to Security Chip
  185. * \param[in] PpsMessageLayer Pointer to structure containing information required for Message Layer
  186. * \param[in] PpsMessage Pointer to sBlob containing the Handshake message
  187. *
  188. * \retval #OCP_ML_OK Successful Execution
  189. * \retval #OCP_ML_ERROR Failure Execution
  190. */
  191. int32_t MsgLayer_ProcessMessage(eMsgType_d eMsgType,const sMessageLayer_d* PpsMessageLayer, sbBlob_d* PpsMessage)
  192. {
  193. int32_t i4Status = (int32_t) OCP_ML_ERROR;
  194. sProcMsgData_d sPMsgVector ;
  195. do
  196. {
  197. //Null Check
  198. if((NULL == PpsMessageLayer) || (NULL == PpsMessage) || (NULL == PpsMessage->prgbStream))
  199. {
  200. i4Status = (int32_t)OCP_ML_NULL_PARAM;
  201. break;
  202. }
  203. //Length check for input parameters
  204. if(0 == PpsMessage->wLen)
  205. {
  206. i4Status = (int32_t)OCP_ML_ZERO_LEN;
  207. break;
  208. }
  209. //Assign the required parameter(s) for the Put Message command
  210. sPMsgVector.eParam = eMsgType;
  211. sPMsgVector.psBlobInBuffer = PpsMessage;
  212. sPMsgVector.wSessionKeyOID = PpsMessageLayer->wSessionID;
  213. sPMsgVector.puMsgParams = NULL;
  214. sPMsgVector.psCallBack = NULL;
  215. //Invoke the Put Message command API from the command library to send the message to Security Chip to Process
  216. i4Status = CmdLib_PutMessage(&sPMsgVector);
  217. if(CMD_LIB_OK != i4Status)
  218. {
  219. LOG_TRANSPORTDBVAL(i4Status,eInfo);
  220. break;
  221. }
  222. i4Status = (int32_t) OCP_ML_OK;
  223. }while(FALSE);
  224. #undef PhOCPHandle
  225. return i4Status;
  226. }
  227. /**
  228. * @}
  229. */
  230. #endif /*MODULE_ENABLE_DTLS_MUTUAL_AUTH*/