/** * MIT License * * Copyright (c) 2018 Infineon Technologies AG * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE * * * \file DtlsFlightHandler.c * * \brief This file implements the DTLS Flight handling details. * * \addtogroup grMutualAuth * @{ */ #include "optiga/dtls/DtlsFlightHandler.h" #ifdef MODULE_ENABLE_DTLS_MUTUAL_AUTH /// @cond hidden #define LSBREM8(x) (x & 0x07) #define LSTBYTE(x) ( ((LSBREM8(x))) ? 1 : 0) #define DIVBY8(x) (x >> 3) #define DIVBY4(x) (x >> 2) #define UPDATEGRANLRTY 32 #define MSG_BITMAP8SET(dwNumBits, pbByte2Set, dwStartBit) (*pbByte2Set |= (uint8_t)((uint8_t)((1 << dwNumBits)-1) << dwStartBit)) #define MSG_BITMAP32SET(dwNumBits, pbWord2Set, dwStartBit) (*pbWord2Set |= ((uint32_t)(0-1)) << dwStartBit) #define MSG_ID(X) (X & 0xFF) #define FLIGHT_IDLIMITCHK(LL, X, UL) (((X)>=(LL) && (X)<=(UL)) ? OCP_FL_OK : OCP_FL_ERROR) ///Maximum message payload #define MAX_MSG_PAYLOAD 1536 //1558-5(APDU)-12(Msg header)-5(Session ID) ///Offset for handshake message #define HANDSHAKE_HEADER_OFFSET 0x00 ///Offset for Message ID in handshake header #define OFFSET_HS_MSG_TYPE (HANDSHAKE_HEADER_OFFSET + 0) ///Offset for Message length in handshake header #define OFFSET_HS_MSG_LENGTH (OFFSET_HS_MSG_TYPE + 1) ///Offset for Message Sequence number in handshake header #define OFFSET_HS_MSG_SEQNUM (OFFSET_HS_MSG_LENGTH + 3) ///Offset for Fragment offset in handshake header #define OFFSET_HS_MSG_FRAGOFFSET (OFFSET_HS_MSG_SEQNUM + 2) ///Offset for Fragment length in handshake header #define OFFSET_HS_MSG_FRAGLEN (OFFSET_HS_MSG_FRAGOFFSET + 3) ///Offset for message data #define OFFSET_HS_MSG_DATA (OFFSET_HS_MSG_FRAGLEN + 3) //12 ///Message header length #define LENGTH_HS_MSG_HEADER (OFFSET_HS_MSG_DATA) ///Value of Message type in handshake header #define HS_MESSAGE_TYPE(X) (*((X)+(OFFSET_HS_MSG_TYPE))) ///Value of Message length in handshake header #define HS_MESSAGE_LENGTH(X) (Utility_GetUint24((X)+(OFFSET_HS_MSG_LENGTH))) ///Value of Message sequence number in handshake header #define HS_MESSAGE_SEQNUM(X) (Utility_GetUint16((X)+(OFFSET_HS_MSG_SEQNUM))) ///Value of Message fragment offset in handshake header #define HS_MESSAGE_FRAGOFFSET(X) (Utility_GetUint24((X)+(OFFSET_HS_MSG_FRAGOFFSET))) ///Value of Message fragment length in handshake header #define HS_MESSAGE_FRAGLEN(X) (Utility_GetUint24((X)+(OFFSET_HS_MSG_FRAGLEN))) #define UPDATE_RX_MSGSEQNUM(X,Y) (X=Y) #define OCP_FLIGHT_TABLE_MAX_SIZE 3 #define UPDATE_MSGSTATE(X,Y) (X=Y) /// @endcond ///Maximum number of retransmission of a flight in a session during the handshake protocol #define OCP_MSGRX_MAX_COUNT 6 /** * \brief Initializes the pointer to bit map representing message status.
*/ _STATIC_H int32_t DtlsHS_MsgCompleteInit(uint32_t PdwMsgLen, uint8_t** PppbMapPtr); /** * \brief Sets the number of bits in bit map equal to the number of bytes received in message/ fragment.
*/ _STATIC_H int32_t DtlsHS_MsgUptBitMsk(uint32_t PdwOffset, uint32_t PdwFragLen, uint8_t* PprgbMapPtr, uint32_t PdwMsgLen); /** * \brief Checks if all the bits in the bitmap are set for the message completion.
*/ _STATIC_H int32_t DtlsHS_MsgCompleteCheck(uint8_t* PprgbMapPtr, uint32_t PdwMsgLen); /** * \brief Clears all the bits in the bitmap.
*/ _STATIC_H int32_t DtlsHS_MsgClearBitMap(uint8_t* PprgbMapPtr, uint32_t PdwMsgLen); /** * \brief Searches the look-up table and returns the flight descriptor.
*/ _STATIC_H int32_t DtlsHS_GetFlightDescriptor(uint8_t PbFlightID, uint16_t* PpwFlightID); /** * \brief Searches the look-up table and returns the flight handler.
*/ _STATIC_H int32_t DtlsHS_GetFlightHandler(uint8_t PeFlightID, fFlightHandler * PfHndler); /** * \brief Inserts the message node to flight head node.
*/ _STATIC_H void DtlsHS_InsertMsgNode(sMsgInfo_d** PppsNodeHead, sMsgInfo_d* PpsNewNode); /** * \brief Adds a message node to the end of the message list.
*/ _STATIC_H void DtlsHS_AddMsgNode(sMsgInfo_d** PppsNodeHead, sMsgInfo_d* PpsNewNode); /** * \brief Initialises message node to respective parameters.
*/ _STATIC_H int32_t DtlsHS_SInit_MessageNode(sMsgInfo_d* PpsMsgNode, const sMsgLyr_d* PpsMessageLayer); /** * \brief Checks if given optional message is in the list.
*/ _STATIC_H int32_t DtlsHS_CheckOptMsg(uint8_t PbMsgID, const uint8_t* PpbOptMsgList); /** * \brief Checks if the given message can be sent to the server or not.
*/ _STATIC_H int32_t DtlsHS_Flight5_CheckOptMsg(uint8_t PbMsgID, const uint8_t* PpbOptMsgList, const sMsgLyr_d* PpsMessageLayer); /** * \brief Forms the change cipher spec message.
*/ _STATIC_H int32_t DtlsHS_SInit_ChangeCipherSpec(sMsgInfo_d* PpsMsgNode); /** * \brief Returns the sequence number of the last message in a flight.
*/ _STATIC_H void DtlsHS_FlightGetLastMsgSeqNum(const sMsgInfo_d *PpsMessageList, uint16_t *PwLastMsgSeqNum); /** * \brief Initializes the message node with respective parameters and updates the bit map.
*/ _STATIC_H int32_t DtlsHS_RInit_MessageNode(sMsgInfo_d* PpsMsgNode, sMsgLyr_d* PpsMessageLayer); /** * \brief Returns the total number of messages in a flight.
*/ _STATIC_H void DtlsHS_GetTotalMsgCount(const uint16_t *PwMsgDescList, uint8_t *PbMsgCount); /** * \brief Returns the number of optional messages in a flight.
*/ _STATIC_H void DtlsHS_GetOptMsgCount(const uint16_t *PwMsgDescList, uint8_t *PbOptMsgCount); /** * \brief Returns the message descriptor from the list of messages.
*/ _STATIC_H void DtlsHS_GetMsgDesc(const uint16_t *PwMsgDescList, uint8_t PbMsgType, uint16_t *PwMsgDesc); /** * \brief Adds a optional message to the list of optional messages.
*/ _STATIC_H void DtlsHS_Update_OptList(sMsgLyr_d* PpsMessageLayer, uint8_t PbMsgType, uint8_t PeFlightID); /** * \brief Checks if all the messages of a flight are completely received.
*/ _STATIC_H int32_t DtlsHS_CheckFlight_Compl(sMsgInfo_d *PpsMessageList, uint8_t PeFlightID, const sMsgLyr_d* PpsMessageLayer); /** * \brief Checks if a message is received more than or equal to six times.
*/ _STATIC_H int32_t DtlsHS_MessageLimitCheck(sMsgInfo_d *PpsMsgNode); /** * \brief Buffers the received message/ fragment.
*/ _STATIC_H int32_t DtlsHS_FlightMsgChkAndBuffer(sMsgInfo_d *PpsMessageList, uint8_t bMsgID, const sbBlob_d* PpsMsgIn, sMsgLyr_d* PpsMessageLayer, uint8_t PeFlightID); /** * \brief Checks if the message type of the received message/ fragment belongs to the flight.
*/ _STATIC_H int32_t DtlsHS_Flight_LimitChk(uint8_t PbFlightID, uint8_t PbMsgID); /** * \brief Sends the message to be processed to Security Chip.
*/ _STATIC_H int32_t DtlsHS_SendFlightToOptiga(sMsgInfo_d *PpsMessageList, const sMsgLyr_d* PpsMessageLayer); /** * \brief Resets the flight 2 node.
*/ _STATIC_H void DtlsHS_ResetFlight2MsgNode(const sFlightStats_d* PpsThisFlight); /** * \brief Checks if message sequence number of received message/ fragment of flight4 is correct.
*/ _STATIC_H int32_t DtlsHS_Flight4CheckMsgSeqNum(const sMsgLyr_d* PpsMessageLayer, uint8_t PbRxMsgID, uint16_t PwRxMsgSeqNum); /** * \brief Checks if message sequence number and length of received message/ fragment of flight4 is the same as the buffered one.
*/ _STATIC_H int32_t DtlsHS_Flight4CheckBuffMsg(uint8_t PbMsgType, uint16_t PwMsgSeqNum, uint32_t PdwMsgLen, sMsgInfo_d *PpsMsgList); /** * \brief Checks for flight4 completion.
*/ _STATIC_H int32_t DtlsHS_Flight4ReRxCompl(sMsgInfo_d *PpsMsgList); /** * \brief Clears the messages of a flight and resets the bit map.
*/ _STATIC_H void DtlsHS_Flight4ClearMsgsInList(sMsgInfo_d *PpsMsgList); /** * \brief Updates bit map and sets the message state.
*/ _STATIC_H int32_t DtlsHS_Flight4UpdateMsgStat(uint8_t PbMsgID, sMsgInfo_d *PpsMsgList, const sMsgLyr_d* PpsMessageLayer); /** * \brief Checks whether flight six is received.
*/ _STATIC_H int32_t DtlsHS_CheckFlight6_Compl(sMsgInfo_d *PpsMessageList); /** * \brief Checks Message Sequence number of flight six messages.
*/ _STATIC_H int32_t DtlsHS_Flight6CheckMsgSeqNum(const sMsgLyr_d* PpsMessageLayer, uint8_t PbMsgID, uint16_t PwMsgSeqNum); /** * \brief Frees a node and all the pointers in it .
*/ _STATIC_H void DtlsHS_FreeMsgNode(sMsgInfo_d *PpsMsgNode); /** * Initializes the pointer to bit map representing message status.
* * \param[in] PdwMsgLen Total length of the message received. * \param[out] PppbMapPtr Pointer container to map pointer. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_MSG_ERROR Failure in execution \if ENABLE_NULL_CHECKS * \retval #OCP_FL_NULL_PARAM Null parameter \endif */ _STATIC_H int32_t DtlsHS_MsgCompleteInit(uint32_t PdwMsgLen, uint8_t** PppbMapPtr) { int32_t i4Status = (int32_t)OCP_FL_MSG_ERROR; uint32_t dwMapSize; uint8_t* pbMapPtr = NULL; uint8_t bLbyteMsk; do { #ifdef ENABLE_NULL_CHECKS if(NULL == PppbMapPtr) { i4Status = (int32_t)OCP_FL_NULL_PARAM; break; } #endif dwMapSize = DIVBY8(PdwMsgLen) + LSTBYTE(PdwMsgLen); if(*PppbMapPtr == NULL) { pbMapPtr = (uint8_t*)OCP_CALLOC(dwMapSize, sizeof(uint8_t)); if(pbMapPtr == NULL) { i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } *PppbMapPtr = pbMapPtr; // Set remaining bits in last byte bLbyteMsk = (uint8_t)((uint8_t)( (1 << (8 - (LSBREM8(PdwMsgLen) ))) - (LSTBYTE(PdwMsgLen)) ) << (LSBREM8(PdwMsgLen))); *(pbMapPtr+(dwMapSize-1)) |= bLbyteMsk; } i4Status = (int32_t)OCP_FL_OK; }while(0); return i4Status; } /** * Sets the number of bits in bit map equal to the number of bytes received in message/ fragment.
* * \param[in] PdwOffset Offset of the message/ fragment received. * \param[in] PdwFragLen Length of the message/ fragment received. * \param[in,out] PprgbMapPtr Pointer to bit map. * \param[in] PdwMsgLen Length of the message/ fragment received. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_MSG_ERROR Failure in execution \if ENABLE_NULL_CHECKS * \retval #OCP_FL_NULL_PARAM Null parameter \endif */ _STATIC_H int32_t DtlsHS_MsgUptBitMsk(uint32_t PdwOffset, uint32_t PdwFragLen, uint8_t* PprgbMapPtr, uint32_t PdwMsgLen) { int32_t i4Status = (int32_t)OCP_FL_MSG_ERROR; uint32_t dwStartByte, dwStartBit, dwNumofBit2Set, dwLoopCount, dwCount; uint8_t* prgbByte2Set = NULL; do { #ifdef ENABLE_NULL_CHECKS if(NULL == PprgbMapPtr) { i4Status = (int32_t)OCP_FL_NULL_PARAM; break; } #endif dwStartByte = DIVBY8(PdwOffset); dwStartBit = LSBREM8(PdwOffset); dwNumofBit2Set = PdwFragLen; prgbByte2Set = PprgbMapPtr + dwStartByte; if(dwStartBit != 0) { if(dwNumofBit2Set < (8-dwStartBit)) { MSG_BITMAP8SET(dwNumofBit2Set, prgbByte2Set, dwStartBit); dwNumofBit2Set -= dwNumofBit2Set; } else { MSG_BITMAP8SET((8-dwStartBit), prgbByte2Set, dwStartBit); dwNumofBit2Set -= (8-dwStartBit); } prgbByte2Set++; } if(prgbByte2Set < ( PprgbMapPtr+(DIVBY8(PdwMsgLen)+LSTBYTE(PdwMsgLen))) ) { dwLoopCount = dwNumofBit2Set/UPDATEGRANLRTY; for(dwCount=0; dwCount < dwLoopCount; dwCount++) { //lint --e{826} suppress "Implicit type casting to 32 bit pointer for 32 bit granularity check" MSG_BITMAP32SET(UPDATEGRANLRTY, (uint32_t*)prgbByte2Set, 0); prgbByte2Set += (UPDATEGRANLRTY >> 3); dwNumofBit2Set -= UPDATEGRANLRTY; } if(dwNumofBit2Set >= 0x08) { dwLoopCount = DIVBY8(dwNumofBit2Set); for(dwCount=0; dwCount < dwLoopCount; dwCount++) { MSG_BITMAP8SET(8, prgbByte2Set, 0); prgbByte2Set++; dwNumofBit2Set -= 8; } } if(dwNumofBit2Set) { MSG_BITMAP8SET(dwNumofBit2Set, prgbByte2Set, 0); dwNumofBit2Set -= dwNumofBit2Set; } } i4Status = (int32_t)OCP_FL_OK; }while(0); return i4Status; } /** * Checks if all the bits in the bitmap is set for the message completion.
* * \param[in] PprgbMapPtr Pointer to bit map. * \param[in] PdwMsgLen Total Length of the message received. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_MSG_ERROR Failure in execution \if ENABLE_NULL_CHECKS * \retval #OCP_FL_NULL_PARAM Null parameter \endif */ _STATIC_H int32_t DtlsHS_MsgCompleteCheck(uint8_t* PprgbMapPtr, uint32_t PdwMsgLen) { uint32_t dwLoopCount; int32_t i4Status = (int32_t)OCP_FL_OK; uint32_t* pdwMapptr = NULL; uint8_t* pbMapptr = NULL; dwLoopCount = DIVBY4(DIVBY8(PdwMsgLen)); /// @cond hidden #define DWVAL 0xFFFFFFFF /// @endcond do { #ifdef ENABLE_NULL_CHECKS if(NULL == PprgbMapPtr) { i4Status = (int32_t)OCP_FL_NULL_PARAM; break; } #endif //lint --e{826} suppress "Implicit type casting to 32 bit pointer for 32 bit granularity check" pdwMapptr = (uint32_t*)PprgbMapPtr; while(dwLoopCount--) { if(*pdwMapptr++ < DWVAL ) { i4Status = (int32_t)OCP_FL_MSG_ERROR; break; } PdwMsgLen -= UPDATEGRANLRTY; } if(i4Status != (int32_t)OCP_FL_MSG_ERROR) { dwLoopCount = DIVBY8(PdwMsgLen)+LSTBYTE(PdwMsgLen); pbMapptr = (uint8_t*)pdwMapptr; while(dwLoopCount--) { if(*pbMapptr++ < ((1<<8)-1)) { i4Status = (int32_t)OCP_FL_MSG_ERROR; break; } } } }while(0); /// @cond hidden #undef DWVAL /// @endcond return i4Status; } /** * Clears all the bits in the bitmap.
* * \param[in,out] PprgbMapPtr Pointer to bit map. * \param[in] PdwMsgLen Total length of the message received. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_MSG_ERROR Failure in execution \if ENABLE_NULL_CHECKS * \retval #OCP_FL_NULL_PARAM Null parameter \endif */ _STATIC_H int32_t DtlsHS_MsgClearBitMap(uint8_t* PprgbMapPtr, uint32_t PdwMsgLen) { uint32_t dwLoopCount, dwMapSize; int32_t i4Status = (int32_t)OCP_FL_MSG_ERROR; uint32_t* pdwMapptr = NULL; uint8_t* pbMapptr = NULL; uint8_t bLbyteMsk; do { #ifdef ENABLE_NULL_CHECKS if(NULL == PprgbMapPtr) { i4Status = (int32_t)OCP_FL_NULL_PARAM; break; } #endif //lint --e{826} suppress "Implicit type casting to 32 bit pointer for 32 bit granularity check" pdwMapptr = (uint32_t*)PprgbMapPtr; dwMapSize = DIVBY8(PdwMsgLen) + LSTBYTE(PdwMsgLen); dwLoopCount = DIVBY4(DIVBY8(PdwMsgLen)); while(dwLoopCount--) { *pdwMapptr++ = 0x00; PdwMsgLen -= UPDATEGRANLRTY; } dwLoopCount = DIVBY8(PdwMsgLen)+LSTBYTE(PdwMsgLen); pbMapptr = (uint8_t*)pdwMapptr; while(dwLoopCount--) { *pbMapptr++ = 0x00; } bLbyteMsk = (uint8_t)((uint8_t)((1 << (8 - (LSBREM8(PdwMsgLen) ))) - (LSTBYTE(PdwMsgLen)) ) << (LSBREM8(PdwMsgLen))); *(PprgbMapPtr+(dwMapSize-1)) |= bLbyteMsk; i4Status = (int32_t)OCP_FL_OK; }while(0); return i4Status; } /** * Searches the look-up table and returns the flight descriptor.
* * \param[in] PbFlightID Flight number * \param[in,out] PpwFlightID Container to flight descriptor * * \retval #OCP_HL_OK Successful Execution * \retval #OCP_HL_ERROR Failure Execution */ _STATIC_H int32_t DtlsHS_GetFlightDescriptor(uint8_t PbFlightID, uint16_t* PpwFlightID) { int32_t i4Status = (int32_t)OCP_FL_ERROR; uint8_t bIndex = 0; do { for(bIndex = 0; bIndex < OCP_FLIGHT_TABLE_MAX_SIZE; bIndex++) { if(((rgsSFlightInfo[bIndex].wFlightDesc) & 0xFF) == (PbFlightID)) { *PpwFlightID = rgsSFlightInfo[bIndex].wFlightDesc; i4Status = (int32_t)OCP_FL_OK; break; } } if((int32_t)OCP_FL_ERROR == i4Status) { for(bIndex = 0; bIndex < OCP_FLIGHT_TABLE_MAX_SIZE; bIndex++) { if((rgsRFlightInfo[bIndex].wFlightDesc & 0xFF) == (PbFlightID)) { *PpwFlightID = rgsRFlightInfo[bIndex].wFlightDesc; i4Status = (int32_t)OCP_FL_OK; break; } } } }while(0); return i4Status; } /** * Searches the look-up table and returns the flight handler.
* * \param[in] PeFlightID Flight number * \param[in,out] PfHndler Container to flight handler * * \retval #OCP_HL_OK Successful Execution * \retval #OCP_HL_ERROR Failure Execution */ _STATIC_H int32_t DtlsHS_GetFlightHandler(uint8_t PeFlightID, fFlightHandler * PfHndler) { int32_t i4Status = (int32_t)OCP_FL_ERROR; uint8_t bIndex; do { for(bIndex = 0; bIndex < OCP_FLIGHT_TABLE_MAX_SIZE; bIndex++) { if(((rgsSFlightInfo[bIndex].wFlightDesc) & 0xFF) == (uint8_t)PeFlightID) { *PfHndler = (rgsSFlightInfo[bIndex].pFlightHndlr); i4Status = (int32_t)OCP_FL_OK; break; } } if((int32_t)OCP_FL_ERROR == i4Status) { for(bIndex = 0; bIndex < OCP_FLIGHT_TABLE_MAX_SIZE; bIndex++) { if(((rgsRFlightInfo[bIndex].wFlightDesc) & 0xFF) == (uint8_t)PeFlightID) { *PfHndler = (rgsRFlightInfo[bIndex].pFlightHndlr); i4Status = (int32_t)OCP_FL_OK; break; } } } }while(0); return i4Status; } /** * Inserts the message node to flight head node .
* * \param[in,out] PppsNodeHead Pointer container holding head node pointer. * \param[in] PpsNewNode Pointer to the message node to be inserted. * */ _STATIC_H void DtlsHS_InsertMsgNode(sMsgInfo_d** PppsNodeHead, sMsgInfo_d* PpsNewNode) { sMsgInfo_d* pTravA = *PppsNodeHead; sMsgInfo_d* pTravB = NULL; do { if(NULL == pTravA) { *PppsNodeHead = PpsNewNode; } else { do { pTravB = pTravA->psNext; if (PpsNewNode->bMsgType < pTravA->bMsgType) { PpsNewNode->psNext = pTravA; *PppsNodeHead = PpsNewNode; break; } else if (NULL != pTravB) { if((PpsNewNode->bMsgType > pTravA->bMsgType) && (PpsNewNode->bMsgType < pTravB->bMsgType)) { pTravA->psNext = PpsNewNode; PpsNewNode->psNext = pTravB; break; } } else { if(PpsNewNode->bMsgType > pTravA->bMsgType) { pTravA->psNext = PpsNewNode; PpsNewNode->psNext = NULL; } break; } pTravA = pTravA->psNext; }while(NULL != pTravA); } }while(0); } /** * Adds a message node to the end of the message list.
* * \param[in,out] PppsNodeHead Pointer container holding head node pointer. * \param[in] PpsNewNode Pointer to the message node to be added. * */ _STATIC_H void DtlsHS_AddMsgNode(sMsgInfo_d** PppsNodeHead, sMsgInfo_d* PpsNewNode) { sMsgInfo_d* psTrav = *PppsNodeHead; do { if(NULL == psTrav) { *PppsNodeHead = PpsNewNode; } else { while(NULL != psTrav->psNext) { psTrav = psTrav->psNext; } psTrav->psNext = PpsNewNode; } }while(0); } /** * Initialises message node to respective parameters.
* - Calls message layer to get the message.
* - Checks the header of the message received from message layer.
* - Updates the bit map.
* * \param[in,out] PpsMsgNode Pointer to the message node. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_FL_OK Successful Execution * \retval #OCP_FL_ERROR Failure Execution */ _STATIC_H int32_t DtlsHS_SInit_MessageNode(sMsgInfo_d* PpsMsgNode, const sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = (int32_t)OCP_FL_OK; sbBlob_d sbBlobMessage; sbBlob_d sMessage; sMessageLayer_d sMessageLayer; uint32_t dwTotalLength; sMessageLayer.wOIDDevCertificate = PpsMessageLayer->wOIDDevCertificate; sMessageLayer.pfGetUnixTIme = PpsMessageLayer->pfGetUnixTIme; sMessageLayer.psConfigRL = PpsMessageLayer->psConfigRL; sMessageLayer.wMaxPmtu = PpsMessageLayer->wMaxPmtu; sMessageLayer.wSessionID = PpsMessageLayer->wSessionID; do { i4Status = MsgLayer_FormMessage((eMsgType_d)PpsMsgNode->bMsgType, &sMessageLayer, &sbBlobMessage); if(OCP_ML_OK != i4Status) { break; } PpsMsgNode->psMsgHolder = sbBlobMessage.prgbStream; //Assign the pointer from Handshake message header to local blob sMessage.prgbStream = sbBlobMessage.prgbStream + (OVERHEAD_LEN - MSG_HEADER_LEN); sMessage.wLen = sbBlobMessage.wLen - (OVERHEAD_LEN - MSG_HEADER_LEN); dwTotalLength = HS_MESSAGE_LENGTH(sMessage.prgbStream); if(sMessage.wLen != (dwTotalLength + MSG_HEADER_LEN)) { break; } PpsMsgNode->psMsgMapPtr = NULL; PpsMsgNode->dwMsgLength = dwTotalLength; PpsMsgNode->wMsgSequence = HS_MESSAGE_SEQNUM(sMessage.prgbStream); PpsMsgNode->eMsgState = eComplete; i4Status = (int32_t)OCP_FL_OK; }while(0); return i4Status; } /** * Checks if given optional message is in the list.
* * \param[in] PbMsgID Message type. * \param[in] PpbOptMsgList List of received optional messages. * * \retval #OCP_FL_OK Requested message found in list * \retval #OCP_FL_ERROR Requested message not found in list */ _STATIC_H int32_t DtlsHS_CheckOptMsg(uint8_t PbMsgID, const uint8_t* PpbOptMsgList) { int32_t i4Status = (int32_t)OCP_FL_ERROR; do { if(NULL == PpbOptMsgList) { break; } while(0xFF != *(PpbOptMsgList)) { if(PbMsgID == *PpbOptMsgList) { i4Status = (int32_t)OCP_FL_OK; break; } PpbOptMsgList++; } }while(0); return i4Status; } /** * Checks if the given message can be sent to the server or not.
* * \param[in] PbMsgID Message type. * \param[in] PpbOptMsgList List of received optional messages. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_FL_OK Requested message can be sent * \retval #OCP_FL_ERROR Requested message cannot be sent */ _STATIC_H int32_t DtlsHS_Flight5_CheckOptMsg(uint8_t PbMsgID, const uint8_t* PpbOptMsgList, const sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = (int32_t)OCP_FL_OK; do { if(((uint8_t)eClientCertificate == PbMsgID) || ((uint8_t)eCertificateVerify == PbMsgID)) { if(OCP_FL_OK != DtlsHS_CheckOptMsg((uint8_t)eCertificateRequest, PpbOptMsgList)) { i4Status = (int32_t)OCP_FL_ERROR; break; } } if(((uint8_t)eCertificateVerify == PbMsgID) && (0x0000 == PpsMessageLayer->wOIDDevCertificate)) { i4Status = (int32_t)OCP_FL_ERROR; break; } }while(0); return i4Status; } /** * Initialises message node to respective parameters.
* - Forms the change cipher spec message.
* * \param[in,out] PpsMsgNode Pointer to the message node. * * \retval #OCP_FL_OK Requested message can be sent * \retval #OCP_FL_ERROR Requested message cannot be sent */ _STATIC_H int32_t DtlsHS_SInit_ChangeCipherSpec(sMsgInfo_d* PpsMsgNode) { int32_t i4Status = (int32_t)OCP_FL_OK; /// @cond hidden #define CHANGE_CIPHERSPEC_MSGSIZE 1 /// @endcond do { PpsMsgNode->psMsgHolder = (uint8_t*)OCP_MALLOC(CHANGE_CIPHERSPEC_MSGSIZE); if(NULL == PpsMsgNode->psMsgHolder) { i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } *PpsMsgNode->psMsgHolder = (int32_t)0x01; PpsMsgNode->dwMsgLength = CHANGE_CIPHERSPEC_MSGSIZE; PpsMsgNode->psMsgMapPtr = NULL; }while(0); /// @cond hidden #undef CHANGE_CIPHERSPEC_MSGSIZE /// @endcond return i4Status; } /** * Returns the sequence number of the last message in a flight.
* * \param[in] PpsMessageList Pointer to list of messages. * \param[out] PwLastMsgSeqNum Pointer to last sequence number. * * \retval #OCP_FL_OK Successful Execution * \retval #OCP_FL_ERROR Failure Execution */ _STATIC_H void DtlsHS_FlightGetLastMsgSeqNum(const sMsgInfo_d *PpsMessageList, uint16_t *PwLastMsgSeqNum) { do { if(NULL == PpsMessageList) { break; } while(NULL != PpsMessageList->psNext) { PpsMessageList = PpsMessageList->psNext; } *PwLastMsgSeqNum = PpsMessageList->wMsgSequence; }while(0); } /** * Initializes the message node with respective parameters and updates the bit map.
* * \param[in,out] PpsMsgNode Pointer to new message node. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_FL_OK Successful Execution * \retval #OCP_FL_ERROR Failure Execution * \retval #OCP_FL_MSG_INCOMPLETE Message is not completely received */ _STATIC_H int32_t DtlsHS_RInit_MessageNode(sMsgInfo_d* PpsMsgNode, sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = OCP_FL_OK; uint32_t dwOffset; uint32_t dwFragLen; uint32_t dwTotalLen; do { PpsMsgNode->bMsgType = HS_MESSAGE_TYPE(PpsMessageLayer->sMsg.prgbStream); dwOffset = HS_MESSAGE_FRAGOFFSET(PpsMessageLayer->sMsg.prgbStream); dwFragLen = HS_MESSAGE_FRAGLEN(PpsMessageLayer->sMsg.prgbStream); dwTotalLen = HS_MESSAGE_LENGTH(PpsMessageLayer->sMsg.prgbStream); //Length of the message payload should not exceed 1536 bytes if(MAX_MSG_PAYLOAD < dwTotalLen) { i4Status = (int32_t)OCP_HL_BUFFER_OVERFLOW; break; } memcpy((PpsMsgNode->psMsgHolder + OVERHEAD_LEN + dwOffset), PpsMessageLayer->sMsg.prgbStream + LENGTH_HS_MSG_HEADER, dwFragLen); PpsMsgNode->wMsgSequence = HS_MESSAGE_SEQNUM(PpsMessageLayer->sMsg.prgbStream); PpsMsgNode->dwMsgLength = dwTotalLen; PpsMsgNode->psMsgMapPtr = NULL; PpsMsgNode->bMsgCount = 0; //lint --e{534} suppress "Return value is not required to be checked" DtlsHS_PrepareMsgHeader((PpsMsgNode->psMsgHolder + (OVERHEAD_LEN - MSG_HEADER_LEN)), PpsMsgNode); //Initialise Bit Map for message status if(OCP_FL_OK != DtlsHS_MsgCompleteInit(PpsMsgNode->dwMsgLength, &PpsMsgNode->psMsgMapPtr)) { i4Status = (int32_t)OCP_FL_ERROR; break; } //lint --e{534} suppress "Return value is not required to be checked" DtlsHS_MsgUptBitMsk(dwOffset, dwFragLen, PpsMsgNode->psMsgMapPtr, PpsMsgNode->dwMsgLength); // Check Message Completeness if(OCP_FL_OK != DtlsHS_MsgCompleteCheck(PpsMsgNode->psMsgMapPtr, PpsMsgNode->dwMsgLength)) { i4Status = (int32_t)OCP_FL_MSG_INCOMPLETE; break; } DtlsHS_Update_OptList(PpsMessageLayer, PpsMsgNode->bMsgType, (uint8_t)PpsMessageLayer->eFlight); // If message is completely received, change state to Received UPDATE_MSGSTATE(PpsMsgNode->eMsgState, eComplete); PpsMsgNode->bMsgCount++; }while(0); return i4Status; } /** * Returns the total number of messages in a flight.
* * \param[in] PwMsgDescList Pointer to list of messages. * \param[out] PbMsgCount Pointer to message counter. * */ _STATIC_H void DtlsHS_GetTotalMsgCount(const uint16_t *PwMsgDescList, uint8_t *PbMsgCount) { *PbMsgCount = 0; do { (*PbMsgCount)++; }while(0xFFFF != *(++PwMsgDescList)); } /** * Returns the number of optional messages in a flight.
* * \param[in] PwMsgDescList Pointer to list of messages. * \param[out] PbOptMsgCount Pointer to message counter. * */ _STATIC_H void DtlsHS_GetOptMsgCount(const uint16_t *PwMsgDescList, uint8_t *PbOptMsgCount) { do { if(IsOptional(*PwMsgDescList)) { (*PbOptMsgCount)++; } }while(0xFFFF != *(++PwMsgDescList)); } /** * Returns the message descriptor from the list of messages.
* * \param[in] PwMsgDescList Pointer to list of messages. * \param[in] PbMsgType Message ID of which descriptor is required. * \param[out] PwMsgDesc Pointer to message descriptor. * */ _STATIC_H void DtlsHS_GetMsgDesc(const uint16_t *PwMsgDescList, uint8_t PbMsgType, uint16_t *PwMsgDesc) { do { if(MSG_ID(*PwMsgDescList) == PbMsgType) { *PwMsgDesc = *PwMsgDescList; } PwMsgDescList++; }while(0xFFFF != *PwMsgDescList); } /** * Adds a optional message to the list of optional messages.
* * \param[in,out] PpsMessageLayer Pointer to the structure containing message configuration information. * \param[in] PbMsgType Optional Message ID. * \param[in] PeFlightID Flight ID. * */ _STATIC_H void DtlsHS_Update_OptList(sMsgLyr_d* PpsMessageLayer, uint8_t PbMsgType, uint8_t PeFlightID) { int32_t i4Status = (int32_t)OCP_FL_ERROR; uint8_t bIndex = 0; uint16_t *pwFlightMsgs; do { DtlsHS_GetFlightMsgInfo(PeFlightID, &pwFlightMsgs); //Check whether given message is optional while(0xFFFF != *pwFlightMsgs) { if(MSG_ID(*pwFlightMsgs) == PbMsgType) { if(IsOptional(*pwFlightMsgs)) { i4Status = (int32_t)OCP_FL_OK; break; } } pwFlightMsgs++; } //If the Message is optional, then store the message ID in Optional Message list if((int32_t)OCP_FL_OK == i4Status) { do { if((PpsMessageLayer->rgbOptMsgList[bIndex] == PbMsgType) || (PpsMessageLayer->rgbOptMsgList[bIndex] == 0xFF)) { PpsMessageLayer->rgbOptMsgList[bIndex] = PbMsgType; break; } }while(++bIndex < ((sizeof(PpsMessageLayer->rgbOptMsgList)/sizeof(PpsMessageLayer->rgbOptMsgList[0])))); } }while(0); } /** * Checks if all the messages of a flight are completely received.
* * \param[in] PpsMessageList Pointer to list of messages of a flight. * \param[in] PeFlightID Flight ID. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_FL_OK All messages are completely received * \retval #OCP_FL_ERROR Atleast one message is incomplete */ _STATIC_H int32_t DtlsHS_CheckFlight_Compl(sMsgInfo_d *PpsMessageList, uint8_t PeFlightID, const sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = (int32_t)OCP_FL_ERROR; sMsgInfo_d* psMsgListTrav = PpsMessageList; uint32_t dwLastMsgSeq, dwPrevFlightMsgSeq; uint16_t *pwFlightMsgs; uint8_t bOptMsgCount = 0; uint8_t bTotalMsgInFlight = 0; uint8_t bTotalOptMsgInFlight = 0; uint8_t bTotalMsgRxDInFlight = 0; uint16_t wMsgDesc; uint8_t bSeqNumFlag = TRUE, bLoopCount, bIndex; dwLastMsgSeq = PpsMessageLayer->dwRMsgSeqNum; dwPrevFlightMsgSeq = PpsMessageLayer->dwRMsgSeqNum; do { #ifdef ENABLE_NULL_CHECKS if(NULL == psMsgListTrav) { break; } #endif DtlsHS_GetFlightMsgInfo(PeFlightID, &pwFlightMsgs); DtlsHS_GetTotalMsgCount(pwFlightMsgs, &bTotalMsgInFlight); DtlsHS_GetOptMsgCount(pwFlightMsgs, &bTotalOptMsgInFlight); if(dwPrevFlightMsgSeq == 0xFFFFFFFF) { bLoopCount = 2; } else { bLoopCount = 1; } for(bIndex = 0; bIndex < bLoopCount; bIndex++) { psMsgListTrav = PpsMessageList; do { if(eComplete == psMsgListTrav->eMsgState) { DtlsHS_GetMsgDesc(pwFlightMsgs, psMsgListTrav->bMsgType, &wMsgDesc); if(IsOptional(wMsgDesc)) { bOptMsgCount++; } if(psMsgListTrav->wMsgSequence != dwLastMsgSeq+1) { bSeqNumFlag = FALSE; } dwLastMsgSeq = psMsgListTrav->wMsgSequence; bTotalMsgRxDInFlight++; } psMsgListTrav = psMsgListTrav->psNext; }while(NULL != psMsgListTrav); if((bOptMsgCount != 0) && ((bTotalMsgInFlight == bTotalMsgRxDInFlight) && (TRUE == bSeqNumFlag))) { i4Status = (int32_t)OCP_FL_OK; break; } else if((bOptMsgCount == 0) && ((bTotalMsgRxDInFlight == bTotalMsgInFlight-bTotalOptMsgInFlight) && (TRUE == bSeqNumFlag))) { i4Status = (int32_t)OCP_FL_OK; break; } else { i4Status = (int32_t)OCP_FL_MSG_INCOMPLETE; } dwLastMsgSeq = dwPrevFlightMsgSeq+1; bOptMsgCount = 0; bTotalMsgRxDInFlight = 0; bSeqNumFlag = TRUE; } }while(0); return i4Status; } /** * Checks if a message is received more than or equal to six times.
* * \param[in] PpsMsgNode Pointer to message node. * * \retval #OCP_FL_OK Message is received less than six times * \retval #OCP_FL_ERROR Message is received six times */ _STATIC_H int32_t DtlsHS_MessageLimitCheck(sMsgInfo_d *PpsMsgNode) { int32_t i4Status = OCP_FL_OK; do { if(++(PpsMsgNode->bMsgCount) > OCP_MSGRX_MAX_COUNT) { PpsMsgNode->bMsgCount = OCP_MSGRX_MAX_COUNT; i4Status = (int32_t)OCP_FL_ERROR; } }while(0); return i4Status; } /** * Buffers the received message/ fragment.
* * \param[in,out] PpsMessageList Pointer to list of messages in a flight. * \param[in] PbMsgID Received message type. * \param[in] PpsMsgIn Pointer to the received message buffer. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * \param[in] PeFlightID Flight number. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_ERROR Failure in execution * \retval #OCP_FL_MSG_NODE_NOT_AVAIL Node corresponding to message is not in the list of messages * \retval #OCP_FL_MALLOC_FAILURE Memory allocation failure * \retval #OCP_FL_INVALID_MSG_LENGTH Message Length of new fragment does not match the buffered message length * \retval #OCP_FL_INVALID_MSG_SEQ Sequence number of new fragment does not match the buffered message/ fragment sequence length * \retval #OCP_FL_MSG_INCOMPLETE Message is not completely received * \retval #OCP_FL_MSG_MAXCOUNT Message is received six times */ _STATIC_H int32_t DtlsHS_FlightMsgChkAndBuffer(sMsgInfo_d *PpsMessageList, uint8_t PbMsgID, const sbBlob_d* PpsMsgIn, sMsgLyr_d* PpsMessageLayer, uint8_t PeFlightID) { int32_t i4Status = (int32_t)OCP_FL_MSG_NODE_NOT_AVAIL; uint32_t dwOffset = 0; uint32_t dwFragLength = 0; sMsgInfo_d *psMsgListTrav = PpsMessageList; do { if(NULL == psMsgListTrav) { break; } do { if(psMsgListTrav->bMsgType == PbMsgID) { if((ePartial == psMsgListTrav->eMsgState)) { dwOffset = HS_MESSAGE_FRAGOFFSET(PpsMsgIn->prgbStream); dwFragLength = HS_MESSAGE_FRAGLEN(PpsMsgIn->prgbStream); if(NULL == psMsgListTrav->psMsgHolder) { psMsgListTrav->dwMsgLength = HS_MESSAGE_LENGTH(PpsMsgIn->prgbStream); psMsgListTrav->bMsgType = *PpsMsgIn->prgbStream; psMsgListTrav->psMsgHolder = (uint8_t*)OCP_MALLOC( psMsgListTrav->dwMsgLength + OVERHEAD_LEN); if(NULL == psMsgListTrav->psMsgHolder) { i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } //lint --e{534} suppress "Return value is not required to be checked" DtlsHS_PrepareMsgHeader((psMsgListTrav->psMsgHolder + (OVERHEAD_LEN - MSG_HEADER_LEN)), psMsgListTrav); } if(NULL == psMsgListTrav->psMsgMapPtr) { //Initialise Bit Map for message status if(OCP_FL_OK != DtlsHS_MsgCompleteInit(psMsgListTrav->dwMsgLength, &psMsgListTrav->psMsgMapPtr)) { i4Status = (int32_t)OCP_FL_ERROR; break; } } if(psMsgListTrav->dwMsgLength != HS_MESSAGE_LENGTH(PpsMsgIn->prgbStream)) { i4Status = (int32_t)OCP_FL_INVALID_MSG_LENGTH; break; } if(psMsgListTrav->wMsgSequence != HS_MESSAGE_SEQNUM(PpsMsgIn->prgbStream)) { i4Status = (int32_t)OCP_FL_INVALID_MSG_SEQ; break; } //Buffer the message memcpy(psMsgListTrav->psMsgHolder+OVERHEAD_LEN+dwOffset, PpsMsgIn->prgbStream+LENGTH_HS_MSG_HEADER, dwFragLength); //Update message status //lint --e{534} suppress "Return value is not required to be checked" DtlsHS_MsgUptBitMsk(dwOffset, dwFragLength, psMsgListTrav->psMsgMapPtr, psMsgListTrav->dwMsgLength); } // Check Message Completeness if(OCP_FL_OK != DtlsHS_MsgCompleteCheck(psMsgListTrav->psMsgMapPtr, psMsgListTrav->dwMsgLength)) { i4Status = (int32_t)OCP_FL_MSG_INCOMPLETE; break; } // If message is completely received, change state to Complete UPDATE_MSGSTATE(psMsgListTrav->eMsgState, eComplete); DtlsHS_Update_OptList(PpsMessageLayer, psMsgListTrav->bMsgType, PeFlightID); if(OCP_FL_OK != DtlsHS_MessageLimitCheck(psMsgListTrav)) { i4Status = (int32_t)OCP_FL_MSG_MAXCOUNT; break; } i4Status = OCP_FL_OK; } psMsgListTrav = psMsgListTrav->psNext; }while(NULL != psMsgListTrav); }while(0); return i4Status; } /** * Checks if the message type of the received message/ fragment belongs to the flight.
* * \param[in] PbFlightID Flight ID. * \param[in] PbMsgID Received Message type * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_MSG_NOT_IN_FLIGHT Received message is not in flight */ _STATIC_H int32_t DtlsHS_Flight_LimitChk(uint8_t PbFlightID, uint8_t PbMsgID) { int32_t i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; uint16_t* pwMsgList = NULL; do { DtlsHS_GetFlightMsgInfo(PbFlightID, &pwMsgList); while(0xFFFF != *pwMsgList) { if(PbMsgID == FLIGHTID(*pwMsgList)) { i4Status = OCP_FL_OK; break; } pwMsgList++; } }while(0); return i4Status; } /** * Sends the message to be processed to Security Chip.
* * \param[in] PpsMessageList Pointer to the structure containing message linked list. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_ML_OK Successful execution * \retval #OCP_ML_ERROR Failure in execution * \retval #CMD_DEV_ERROR Command lib error * \retval #OCP_FL_SEND_MSG_TO_OPTIGA_ERROR Message processing failed on Security Chip * */ _STATIC_H int32_t DtlsHS_SendFlightToOptiga(sMsgInfo_d *PpsMessageList, const sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = (int32_t)OCP_ML_ERROR; sMessageLayer_d sMessageLayer; sbBlob_d sMessage; do { sMessageLayer.wOIDDevCertificate = PpsMessageLayer->wOIDDevCertificate; sMessageLayer.pfGetUnixTIme = PpsMessageLayer->pfGetUnixTIme; sMessageLayer.psConfigRL = PpsMessageLayer->psConfigRL; sMessageLayer.wMaxPmtu = PpsMessageLayer->wMaxPmtu; sMessageLayer.wSessionID = PpsMessageLayer->wSessionID; while(NULL != PpsMessageList) { if(NULL != PpsMessageList->psMsgHolder) { sMessage.prgbStream = PpsMessageList->psMsgHolder; sMessage.wLen = (uint16_t)PpsMessageList->dwMsgLength + OVERHEAD_LEN; //Process the obtained message by sending the message to Security Chip i4Status = MsgLayer_ProcessMessage((eMsgType_d)PpsMessageList->bMsgType, &sMessageLayer, &sMessage); if((i4Status & (int32_t)DEV_ERROR_CODE_MASK) == (int32_t)CMD_DEV_ERROR) { break; } else if((int32_t)OCP_ML_OK != i4Status) { i4Status = (int32_t)OCP_FL_SEND_MSG_TO_OPTIGA_ERROR; break; } } UPDATE_MSGSTATE(PpsMessageList->eMsgState, eProcessed); PpsMessageList = PpsMessageList->psNext; } }while(0); return i4Status; } /** * Resets the flight 2 node .
* * \param[in,out] PpsThisFlight Pointer to the structure containing flight status. * */ _STATIC_H void DtlsHS_ResetFlight2MsgNode(const sFlightStats_d* PpsThisFlight) { do { if(NULL != PpsThisFlight->psMessageList->psMsgHolder) { OCP_FREE(PpsThisFlight->psMessageList->psMsgHolder); PpsThisFlight->psMessageList->psMsgHolder = NULL; } if(NULL != PpsThisFlight->psMessageList->psMsgMapPtr) { OCP_FREE(PpsThisFlight->psMessageList->psMsgMapPtr); PpsThisFlight->psMessageList->psMsgMapPtr = NULL; } PpsThisFlight->psMessageList->eMsgState = ePartial; }while(0); } /** * Frees a node and all the pointers in it .
* * \param[in] PpsMsgNode Pointer to the message node. * */ _STATIC_H void DtlsHS_FreeMsgNode(sMsgInfo_d *PpsMsgNode) { if(NULL != PpsMsgNode->psMsgHolder) { OCP_FREE(PpsMsgNode->psMsgHolder); PpsMsgNode->psMsgHolder = NULL; } if(NULL != PpsMsgNode->psMsgMapPtr) { OCP_FREE(PpsMsgNode->psMsgMapPtr); PpsMsgNode->psMsgMapPtr = NULL; } OCP_FREE(PpsMsgNode); } /** * Checks if message sequence number and length of received message/ fragment of flight4 is the same as the buffered one.
* * \param[in] PbRxMsgType Message type of received message/ fragment. * \param[in] PwRxMsgSeqNum Message sequence number of received message/ fragment. * \param[in] PdwRxMsgLen Message sequence number of received message/ fragment. * \param[in] PpsMsgList Pointer to list of messages in the flight. * * \retval #OCP_FL_OK Sequence number and message length of buffered message is same as re-received message/ fragment * \retval #OCP_FL_ERROR Received message/ fragment can be ignored */ _STATIC_H int32_t DtlsHS_Flight4CheckBuffMsg(uint8_t PbRxMsgType, uint16_t PwRxMsgSeqNum, uint32_t PdwRxMsgLen, sMsgInfo_d *PpsMsgList) { int32_t i4Status = (int32_t)OCP_FL_ERROR; sMsgInfo_d *psMsgListTrav = PpsMsgList; do { if(psMsgListTrav->bMsgType == PbRxMsgType) { if((psMsgListTrav->wMsgSequence == PwRxMsgSeqNum) && (psMsgListTrav->dwMsgLength == PdwRxMsgLen)) { i4Status = (int32_t)OCP_FL_OK; break; } } psMsgListTrav = psMsgListTrav->psNext; }while(NULL != psMsgListTrav); return i4Status; } /** * Checks for flight4 completion.
* * \param[in] PpsMsgList Pointer to message list of the flight. * * \retval #OCP_FL_OK Flight 4 is received completely * \retval #OCP_FL_ERROR Flight 4 is not received completely */ _STATIC_H int32_t DtlsHS_Flight4ReRxCompl(sMsgInfo_d *PpsMsgList) { int32_t i4Status = (int32_t)OCP_FL_OK; sMsgInfo_d *psMsgListTrav = PpsMsgList; do { if(eProcessed != psMsgListTrav->eMsgState) { i4Status = (int32_t)OCP_FL_ERROR; break; } psMsgListTrav = psMsgListTrav->psNext; }while(NULL != psMsgListTrav); return i4Status; } /** * Updates bit map and sets the message state.
* * \param[in] PbMsgID Message type of received message/ fragment. * \param[in] PpsMsgList Pointer to message list of the flight. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_ERROR Received message/ fragment can be ignored */ _STATIC_H int32_t DtlsHS_Flight4UpdateMsgStat(uint8_t PbMsgID, sMsgInfo_d *PpsMsgList, const sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = (int32_t)OCP_FL_ERROR; sMsgInfo_d *psMsgListTrav = PpsMsgList; uint32_t dwOffset, dwFragLen; dwOffset = HS_MESSAGE_FRAGOFFSET(PpsMessageLayer->sMsg.prgbStream); dwFragLen = HS_MESSAGE_FRAGLEN(PpsMessageLayer->sMsg.prgbStream); do { do { if(NULL != psMsgListTrav) { if(psMsgListTrav->bMsgType == PbMsgID) { i4Status = (int32_t)OCP_FL_OK; break; } psMsgListTrav = psMsgListTrav->psNext; } }while(NULL != psMsgListTrav); //lint --e{613} suppress "If 'psMsgListTrav' parameter is null then based on return code it doesnt enter the below path" if(OCP_FL_OK == i4Status) { if(OCP_FL_OK != DtlsHS_MsgUptBitMsk(dwOffset, dwFragLen, psMsgListTrav->psMsgMapPtr, psMsgListTrav->dwMsgLength)) { i4Status = (int32_t)OCP_FL_ERROR; break; } // Check Message Completeness if(OCP_FL_OK != DtlsHS_MsgCompleteCheck(psMsgListTrav->psMsgMapPtr, psMsgListTrav->dwMsgLength)) { i4Status = (int32_t)OCP_FL_MSG_INCOMPLETE; break; } UPDATE_MSGSTATE(psMsgListTrav->eMsgState, eProcessed); if(OCP_FL_OK != DtlsHS_MessageLimitCheck(psMsgListTrav)) { i4Status = (int32_t)OCP_FL_MSG_MAXCOUNT; break; } } }while(0); return i4Status; } /** * Clears the messages of a flight and resets the bit map.
* * \param[in, out] PpsMsgList Pointer to list of messages. * */ _STATIC_H void DtlsHS_Flight4ClearMsgsInList(sMsgInfo_d *PpsMsgList) { sMsgInfo_d *psMsgListTrav = PpsMsgList; do { if(NULL!= psMsgListTrav->psMsgHolder) { OCP_FREE(psMsgListTrav->psMsgHolder); psMsgListTrav->psMsgHolder = NULL; } if(NULL != psMsgListTrav->psMsgMapPtr) { if(OCP_FL_OK == DtlsHS_MsgClearBitMap(psMsgListTrav->psMsgMapPtr, psMsgListTrav->dwMsgLength)) { UPDATE_MSGSTATE(psMsgListTrav->eMsgState, ePartial); } else { break; } } psMsgListTrav = psMsgListTrav->psNext; }while(NULL != psMsgListTrav); } /** * Checks Message Sequence number of flight six messages.
* * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * \param[in] PbMsgID Message Type of the received message/ fragment. * \param[in] PwMsgSeqNum Message sequence number of received message. * * \retval #OCP_FL_OK Sequence number is correct * \retval #OCP_FL_ERROR Sequence number is incorrect */ _STATIC_H int32_t DtlsHS_Flight6CheckMsgSeqNum(const sMsgLyr_d* PpsMessageLayer, uint8_t PbMsgID, uint16_t PwMsgSeqNum) { int32_t i4Status = (int32_t)OCP_FL_OK; do { if((PbMsgID == (uint8_t)eServerFinished) && (PwMsgSeqNum != (uint16_t)PpsMessageLayer->dwRMsgSeqNum+1)) { i4Status = (int32_t)OCP_FL_ERROR; } else if(PbMsgID == (uint8_t)eChangeCipherSpec) { i4Status = (int32_t)OCP_FL_OK; } }while(0); return i4Status; } /** * Searches the look-up table and returns the message descriptors of a flight.
* * \param[in] PeFlightID Flight number. * \param[in,out] PpwMessageList Pointer container to message descriptor. * */ void DtlsHS_GetFlightMsgInfo(uint8_t PeFlightID, uint16_t** PpwMessageList) { int32_t i4Status = (int32_t)OCP_FL_ERROR; uint8_t bIndex; do { for(bIndex = 0; bIndex < OCP_FLIGHT_TABLE_MAX_SIZE; bIndex++) { if(((rgsSFlightInfo[bIndex].wFlightDesc) & 0xFF) == (uint8_t)PeFlightID) { *PpwMessageList = (uint16_t*)&(rgsSFlightInfo[bIndex].wMsgTypes[0]); i4Status = (int32_t)OCP_FL_OK; break; } } if((int32_t)OCP_FL_ERROR == i4Status) { for(bIndex = 0; bIndex < OCP_FLIGHT_TABLE_MAX_SIZE; bIndex++) { if(((rgsRFlightInfo[bIndex].wFlightDesc) & 0xFF) == (uint8_t)PeFlightID) { *PpwMessageList = (uint16_t*)&(rgsRFlightInfo[bIndex].wMsgTypes[0]); break; } } } }while(0); } /** * Initialises flight node to default parameters.
* * \param[in,out] PpsFlightNode Pointer to flight node * \param[in] PbLastProcFlight Last processed flight ID * * \retval #OCP_HL_OK Successful Execution * \retval #OCP_HL_ERROR Failure Execution */ int32_t DtlsHS_FlightNodeInit(sFlightDetails_d* PpsFlightNode, uint8_t PbLastProcFlight) { int32_t i4Status = (int32_t)OCP_FL_OK; do { PpsFlightNode->psNext = NULL; if(OCP_FL_OK != DtlsHS_GetFlightDescriptor(PbLastProcFlight+1, &PpsFlightNode->wFlightDecp)) { i4Status = (int32_t)OCP_FL_ERROR; break; } if(OCP_FL_OK != DtlsHS_GetFlightHandler(FLIGHTID(PpsFlightNode->wFlightDecp), &PpsFlightNode->pFlightHndlr)) { i4Status = (int32_t)OCP_FL_ERROR; break; } PpsFlightNode->sFlightStats.psMessageList = NULL; UPDATE_FSTATE(PpsFlightNode->sFlightStats.bFlightState, (uint8_t)efInit); }while(0); return i4Status; } /** * Gets the Flight type for the corresponding message type.
* * \param[in] PbMsgType Message type * \param[in,out] PpFlightID Pointer to the flight number * * \retval #OCP_FL_OK Successful Execution * \retval #OCP_FL_ERROR Failure Execution */ int32_t DtlsHS_GetFlightID(uint8_t PbMsgType, uint8_t* PpFlightID) { int32_t i4Status = (int32_t)OCP_FL_ERROR; uint8_t bFlightIndex,bMsgIndex ; do { for(bFlightIndex = 0; bFlightIndex < OCP_FLIGHT_TABLE_MAX_SIZE; bFlightIndex++) { bMsgIndex = 0; while(MSG_ID(rgsRFlightInfo[bFlightIndex].wMsgTypes[bMsgIndex]) != 0xFF) { if(MSG_ID(rgsRFlightInfo[bFlightIndex].wMsgTypes[bMsgIndex]) == PbMsgType) { *PpFlightID = FLIGHTID(rgsRFlightInfo[bFlightIndex].wFlightDesc); i4Status = (int32_t)OCP_FL_OK; break; } bMsgIndex++; } if((int32_t)OCP_FL_OK == i4Status) { break; } } }while(0); return i4Status; } /** * Checks whether the received message belongs to the expected flight.
* * \param[in] PbLastProcFlight Last processed flight number * \param[in,out] PpsBlobMessage Pointer to the Blob containing record * \param[in] PpsMessageLayer Pointer to the structure containing message layer information * * \retval #OCP_FL_OK Successful Execution * \retval #OCP_FL_ERROR Failure Execution */ int32_t DtlsHS_MsgCheck(uint8_t PbLastProcFlight, const sbBlob_d* PpsBlobMessage, const sMsgLyr_d* PpsMessageLayer) { uint8_t bFlightA = 0; uint8_t bFlightB = 0; int32_t i4Status = (int32_t)OCP_FL_OK; uint8_t bMsgType; uint32_t dwTotalMsgLen = 0; uint8_t bFirstMsgFlightID = 0; uint8_t bMsgFlightID; sbBlob_d sMsgIn; do { //Change cipher spec record is received if(PpsMessageLayer->psConfigRL->sRL.bRecvCCSRecord == CCS_RECORD_RECV) { if((PpsMessageLayer->eFlight != eFlight5) && (PpsMessageLayer->eFlight != eFlight6)) { //CCS message doesn't belongs to flight 6 i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; PpsMessageLayer->psConfigRL->sRL.bRecvCCSRecord = CCS_RECORD_NOTRECV; } break; } //Minimum length check if(LENGTH_HS_MSG_HEADER > PpsBlobMessage->wLen) { i4Status = (int32_t)OCP_HL_INVALID_LENGTH; break; } sMsgIn.prgbStream = PpsBlobMessage->prgbStream; sMsgIn.wLen = PpsBlobMessage->wLen; //Check for default flight state if((uint8_t)PpsMessageLayer->eFlight == PbLastProcFlight) { if((PbLastProcFlight == 1) || (PbLastProcFlight == 3)) { bFlightA = (uint8_t)eFlight2; bFlightB = (uint8_t)eFlight4; } else if(PbLastProcFlight == 5) { bFlightA = (uint8_t)eFlight4; bFlightB = (uint8_t)eFlight6; } bMsgType = *(sMsgIn.prgbStream); //Get the flight number to which the message belongs if(OCP_FL_OK != DtlsHS_GetFlightID(bMsgType, &bFirstMsgFlightID)) { i4Status = (int32_t)OCP_FL_MSG_NOT_LISTED; break; } //Check if the flight number belongs to the expected the flight if((bFlightA != bFirstMsgFlightID) && (bFlightB != bFirstMsgFlightID)) { i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; break; } //Header validation i4Status = DtlsHS_ProcHeader(sMsgIn); if(OCP_HL_OK == i4Status) { i4Status = (int32_t)OCP_FL_OK; } else { break; } dwTotalMsgLen = Utility_GetUint24(sMsgIn.prgbStream + OFFSET_HS_MSG_FRAGLEN); sMsgIn.prgbStream += dwTotalMsgLen + LENGTH_HS_MSG_HEADER; sMsgIn.wLen -= (uint16_t)dwTotalMsgLen + LENGTH_HS_MSG_HEADER; } //For multiple messages in a record while(sMsgIn.wLen != 0) { bMsgType = *(sMsgIn.prgbStream); //Minimum length check if(LENGTH_HS_MSG_HEADER > sMsgIn.wLen) { i4Status = (int32_t)OCP_HL_INVALID_LENGTH; break; } //Get the flight number to which the message belongs if(OCP_FL_OK != DtlsHS_GetFlightID(bMsgType, &bMsgFlightID)) { i4Status = (int32_t)OCP_FL_MSG_NOT_LISTED; break; } if((uint8_t)PpsMessageLayer->eFlight == PbLastProcFlight) { if(bFirstMsgFlightID != bMsgFlightID) { i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; break; } } else { if(PpsMessageLayer->eFlight != (eFlight_d)bMsgFlightID) { i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; break; } } i4Status = DtlsHS_ProcHeader(sMsgIn); if(OCP_HL_OK == i4Status) { i4Status = (int32_t)OCP_FL_OK; } else { break; } dwTotalMsgLen = Utility_GetUint24(sMsgIn.prgbStream + OFFSET_HS_MSG_FRAGLEN); sMsgIn.wLen -= (uint16_t)dwTotalMsgLen + LENGTH_HS_MSG_HEADER; if(sMsgIn.wLen != 0) { sMsgIn.prgbStream += dwTotalMsgLen + LENGTH_HS_MSG_HEADER; } } }while(0); return i4Status; } /** * Flight one handler to process flight 1 messages .
* * \param[in] PbLastProcFlight Last processed flight. * \param[in,out] PpsThisFlight Pointer to structure containing flight1 status. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_MSG_ERROR Failure in execution * \retval #OCP_FL_MALLOC_FAILURE Malloc failure * \retval #OCP_FL_GET_MSG_FROM_OPTIGA_ERROR Error from Security Chip * \retval #OCP_FL_FLIGHTSEND_ERROR Error while sending flight to Security Chip */ //lint --e{818} suppress "This is ignored as same flight handler pointer is used for both send and receive" int32_t DtlsHS_Flight1Handler(uint8_t PbLastProcFlight, sFlightStats_d* PpsThisFlight, sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = (int32_t)OCP_FL_OK; sMsgInfo_d* psMsgListTrav = NULL; uint16_t *pwMsgIDList = NULL; do { if(((uint8_t)efInit == PpsThisFlight->bFlightState) && ((uint8_t)eFlight0 == PbLastProcFlight)) { //Generate List of Messages of this flight //create list of messages of this flight and call Command lib to get messages from Security Chip DtlsHS_GetFlightMsgInfo((uint8_t)eFlight1, &pwMsgIDList); while(0xFF != MSG_ID(*pwMsgIDList)) { psMsgListTrav = (sMsgInfo_d*)OCP_MALLOC(sizeof(sMsgInfo_d)); if(NULL == psMsgListTrav) { i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } psMsgListTrav->bMsgType = MSG_ID(*pwMsgIDList); psMsgListTrav->eMsgState = ePartial; psMsgListTrav->psNext = NULL; psMsgListTrav->psMsgMapPtr = NULL; psMsgListTrav->psMsgHolder = NULL; DtlsHS_InsertMsgNode(&PpsThisFlight->psMessageList, psMsgListTrav); pwMsgIDList++; } if((int32_t)OCP_FL_OK == i4Status) { UPDATE_FSTATE(PpsThisFlight->bFlightState, (uint8_t)efReady); } } else if(((uint8_t)eFlight1 == PbLastProcFlight+1) || ((uint8_t)eFlight1 == PbLastProcFlight)) { if((uint8_t)efReady == PpsThisFlight->bFlightState) { //Get Message from Security Chip and Send to Server psMsgListTrav = PpsThisFlight->psMessageList; while(NULL != psMsgListTrav) { if(ePartial == psMsgListTrav->eMsgState) { i4Status = DtlsHS_SInit_MessageNode(psMsgListTrav, PpsMessageLayer); if((i4Status & (int32_t)DEV_ERROR_CODE_MASK) == (int32_t)CMD_DEV_ERROR) { break; } else if((int32_t)OCP_FL_OK != i4Status) { i4Status = (int32_t)OCP_FL_GET_MSG_FROM_OPTIGA_ERROR; break; } psMsgListTrav->eMsgState = eComplete; } if(OCP_HL_OK != DtlsHS_FSendMessage(psMsgListTrav, PpsMessageLayer)) { i4Status = (int32_t)OCP_FL_FLIGHTSEND_ERROR; break; } psMsgListTrav->eMsgState = eProcessed; psMsgListTrav = psMsgListTrav->psNext; } if((int32_t)OCP_FL_OK == i4Status) { PpsMessageLayer->eFlight = eFlight1; UPDATE_FSTATE(PpsThisFlight->bFlightState, (uint8_t)efTransmitted); } } else if((uint8_t)efReTransmit == PpsThisFlight->bFlightState) { psMsgListTrav = PpsThisFlight->psMessageList; //If already transmitted, now retransmit while(NULL != psMsgListTrav) { if(OCP_HL_OK != DtlsHS_FSendMessage(psMsgListTrav, PpsMessageLayer)) { i4Status = (int32_t)OCP_FL_FLIGHTSEND_ERROR; break; } psMsgListTrav = psMsgListTrav->psNext; } if((int32_t)OCP_FL_OK == i4Status) { UPDATE_FSTATE(PpsThisFlight->bFlightState, (uint8_t)efTransmitted); } } } else { PpsThisFlight->bFlightState = (uint8_t)efDone; break; } }while(0); return i4Status; } /** * Flight three handler to process flight 3 message.
* * \param[in] PbLastProcFlight Last processed flight. * \param[in,out] PpsThisFlight Pointer to structure containing flight3 status. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_MSG_ERROR Failure in execution * \retval #OCP_FL_MALLOC_FAILURE Malloc failure * \retval #OCP_FL_GET_MSG_FROM_OPTIGA_ERROR Error from Security Chip * \retval #OCP_FL_FLIGHTSEND_ERROR Error while sending flight to Security Chip */ int32_t DtlsHS_Flight3Handler(uint8_t PbLastProcFlight, sFlightStats_d* PpsThisFlight, sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = (int32_t)OCP_FL_OK; sMsgInfo_d* psMsgListTrav = NULL; uint16_t *pwMsgIDList = NULL; uint8_t bMsgType = 0; do { if(((uint8_t)efInit == PpsThisFlight->bFlightState) && ((uint8_t)eFlight2 == PbLastProcFlight)) { //create list of messages of this flight and call Command lib to get messages from Security Chip DtlsHS_GetFlightMsgInfo((uint8_t)eFlight3, &pwMsgIDList); while(0xFF != MSG_ID(*pwMsgIDList)) { psMsgListTrav = (sMsgInfo_d*)OCP_MALLOC(sizeof(sMsgInfo_d)); if(NULL == psMsgListTrav) { i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } psMsgListTrav->bMsgType = MSG_ID(*pwMsgIDList); psMsgListTrav->eMsgState = ePartial; psMsgListTrav->psNext = NULL; psMsgListTrav->psMsgMapPtr = NULL; psMsgListTrav->psMsgHolder = NULL; DtlsHS_InsertMsgNode(&PpsThisFlight->psMessageList, psMsgListTrav); pwMsgIDList++; } if((int32_t)OCP_FL_OK == i4Status) { UPDATE_FSTATE(PpsThisFlight->bFlightState, (uint8_t)efReady); } } else if((uint8_t)eFlight3 == PbLastProcFlight+1) { if(((uint8_t)efReady == PpsThisFlight->bFlightState) || ((uint8_t)efTransmitted == PpsThisFlight->bFlightState)) { //Get Message from Security Chip and Send to Server psMsgListTrav = PpsThisFlight->psMessageList; if((uint8_t)efTransmitted == PpsThisFlight->bFlightState) { OCP_FREE(psMsgListTrav->psMsgHolder); psMsgListTrav->psMsgHolder = NULL; psMsgListTrav->eMsgState = ePartial; } while(NULL != psMsgListTrav) { if(ePartial == psMsgListTrav->eMsgState) { bMsgType = psMsgListTrav->bMsgType; psMsgListTrav->bMsgType = (uint8_t)eClientHelloWithCookie; i4Status = DtlsHS_SInit_MessageNode(psMsgListTrav, PpsMessageLayer); psMsgListTrav->bMsgType = bMsgType; if((i4Status & (int32_t)DEV_ERROR_CODE_MASK) == (int32_t)CMD_DEV_ERROR) { break; } else if((int32_t)OCP_FL_OK != i4Status) { i4Status = (int32_t)OCP_FL_GET_MSG_FROM_OPTIGA_ERROR; break; } psMsgListTrav->eMsgState = eComplete; } if(OCP_HL_OK != DtlsHS_FSendMessage(psMsgListTrav, PpsMessageLayer)) { i4Status = (int32_t)OCP_FL_FLIGHTSEND_ERROR; break; } psMsgListTrav->eMsgState = eProcessed; psMsgListTrav = psMsgListTrav->psNext; } if(OCP_FL_OK == i4Status) { PpsMessageLayer->eFlight = eFlight3; UPDATE_FSTATE(PpsThisFlight->bFlightState, (uint8_t)efTransmitted); } } } else if((uint8_t)eFlight3 == PbLastProcFlight) { if((uint8_t)efReTransmit == PpsThisFlight->bFlightState) { psMsgListTrav = PpsThisFlight->psMessageList; //If already transmitted, now retransmit while(NULL != psMsgListTrav) { if(OCP_HL_OK != DtlsHS_FSendMessage(psMsgListTrav, PpsMessageLayer)) { i4Status = (int32_t)OCP_FL_FLIGHTSEND_ERROR; break; } psMsgListTrav = psMsgListTrav->psNext; } if(OCP_FL_OK == i4Status) { UPDATE_FSTATE(PpsThisFlight->bFlightState, (uint8_t)efTransmitted); } } } else { PpsThisFlight->bFlightState = (uint8_t)efDone; break; } }while(0); return i4Status; } /** * Flight five handler to process flight 5 messages .
* * \param[in] PbLastProcFlight Last processed flight. * \param[in,out] PpsThisFlight Pointer to structure containing flight5 status. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_MSG_ERROR Failure in execution * \retval #OCP_FL_MALLOC_FAILURE Malloc failure * \retval #OCP_FL_GET_MSG_FROM_OPTIGA_ERROR Error from Security Chip * \retval #OCP_FL_FLIGHTSEND_ERROR Error while sending flight to Security Chip */ //lint --e{818} suppress "This is ignored as same flight handler pointer is used for both send and receive" int32_t DtlsHS_Flight5Handler(uint8_t PbLastProcFlight, sFlightStats_d* PpsThisFlight, sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = (int32_t)OCP_FL_OK; sMsgInfo_d* psMsgListTrav = NULL; uint16_t *pwMsgIDList = NULL; do { if(((uint8_t)efInit == PpsThisFlight->bFlightState) && ((uint8_t)eFlight4 == PbLastProcFlight)) { //create list of messages of this flight and call Command lib to get messages from Security Chip DtlsHS_GetFlightMsgInfo((uint8_t)eFlight5, &pwMsgIDList); while(0xFF != MSG_ID(*pwMsgIDList)) { if(OCP_FL_OK == DtlsHS_Flight5_CheckOptMsg(MSG_ID(*pwMsgIDList), &(PpsMessageLayer->rgbOptMsgList[0]), PpsMessageLayer)) { psMsgListTrav = (sMsgInfo_d*)OCP_MALLOC(sizeof(sMsgInfo_d)); if(NULL == psMsgListTrav) { i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } psMsgListTrav->bMsgType = MSG_ID(*pwMsgIDList); psMsgListTrav->eMsgState = ePartial; psMsgListTrav->psNext = NULL; psMsgListTrav->psMsgMapPtr = NULL; psMsgListTrav->psMsgHolder = NULL; DtlsHS_AddMsgNode(&PpsThisFlight->psMessageList, psMsgListTrav); } pwMsgIDList++; } if((int32_t)OCP_FL_OK == i4Status) { UPDATE_FSTATE(PpsThisFlight->bFlightState, (uint8_t)efReady); } } else if(((uint8_t)eFlight5 == PbLastProcFlight+1) || ((uint8_t)eFlight5 == PbLastProcFlight)) { if((uint8_t)efReady == PpsThisFlight->bFlightState) { //Get Message from Security Chip and Send to Server psMsgListTrav = PpsThisFlight->psMessageList; while(NULL != psMsgListTrav) { if(ePartial == psMsgListTrav->eMsgState) { if((uint8_t)eChangeCipherSpec == psMsgListTrav->bMsgType) { i4Status = DtlsHS_SInit_ChangeCipherSpec(psMsgListTrav); } else { i4Status = DtlsHS_SInit_MessageNode(psMsgListTrav, PpsMessageLayer); } if((i4Status & (int32_t)DEV_ERROR_CODE_MASK) == (int32_t)CMD_DEV_ERROR) { break; } else if((int32_t)OCP_FL_OK != i4Status) { i4Status = (int32_t)OCP_FL_GET_MSG_FROM_OPTIGA_ERROR; break; } psMsgListTrav->eMsgState = eComplete; } if(OCP_HL_OK != DtlsHS_FSendMessage(psMsgListTrav, PpsMessageLayer)) { i4Status = (int32_t)OCP_FL_FLIGHTSEND_ERROR; break; } psMsgListTrav->eMsgState = eProcessed; psMsgListTrav = psMsgListTrav->psNext; } if((int32_t)OCP_FL_OK == i4Status) { PpsMessageLayer->eFlight = eFlight5; UPDATE_FSTATE(PpsThisFlight->bFlightState, (uint8_t)efTransmitted); } } else if(((uint8_t)efReTransmit == PpsThisFlight->bFlightState) || ((uint8_t)efTransmitted == PpsThisFlight->bFlightState)) { PpsMessageLayer->psConfigRL->sRL.fRetransmit = TRUE; psMsgListTrav = PpsThisFlight->psMessageList; //If already transmitted, now retransmit while(NULL != psMsgListTrav) { if(OCP_HL_OK != DtlsHS_FSendMessage(psMsgListTrav, PpsMessageLayer)) { i4Status = (int32_t)OCP_FL_FLIGHTSEND_ERROR; break; } psMsgListTrav = psMsgListTrav->psNext; } if((int32_t)OCP_FL_OK == i4Status) { UPDATE_FSTATE(PpsThisFlight->bFlightState, (uint8_t)efTransmitted); } } } }while(0); return i4Status; } /** * Validates the sequence number of message/ fragment received of flight 2.
* * \param[in] PbRxMsgID Message type of the received message/ fragment. * \param[in] PwRxMsgSeqNum Message sequence number of the received message/ fragment. * \param[in] PpsMessageList Pointer to list of messages. * * \retval #OCP_FL_OK Successful Execution * \retval #OCP_FL_INVALID_MSG_SEQNUM Sequence number does not match to buffered fragment sequence number */ int32_t DtlsHS_Flight2CheckMsgSeqNum(uint8_t PbRxMsgID, uint16_t PwRxMsgSeqNum, const sMsgInfo_d *PpsMessageList) { int32_t i4Status = (int32_t)OCP_FL_OK; do { if(PwRxMsgSeqNum > 1) { i4Status = (int32_t)OCP_FL_INVALID_MSG_SEQNUM; break; } while(NULL != PpsMessageList) { if(PpsMessageList->bMsgType == PbRxMsgID) { if(PpsMessageList->wMsgSequence != PwRxMsgSeqNum) { i4Status = (int32_t)OCP_FL_INVALID_MSG_SEQNUM; break; } } PpsMessageList = PpsMessageList->psNext; } }while(0); return i4Status; } /** * Flight two handler to process flight 2 messages.
* * \param[in] PbLastProcFlight Last processed flight. * \param[in,out] PpsThisFlight Pointer to the structure containing flight2 status. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_MSG_ERROR Failure in execution * \retval #OCP_FL_MALLOC_FAILURE Memory allocation failure * \retval #OCP_FL_INVALID_MSG_SEQNUM Invalid Message sequence number * \retval #OCP_FL_MSG_NOT_IN_FLIGHT Message doesn't belong to current flight * \retval #OCP_FL_RXING Message is not yet completely received */ //lint --e{818} suppress "This is ignored as same flight handler pointer is used for both send and receive" int32_t DtlsHS_Flight2Handler(uint8_t PbLastProcFlight, sFlightStats_d* PpsThisFlight, sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = (int32_t)OCP_FL_OK; uint16_t bMsgSeqNum; uint8_t bMsgID; sMsgInfo_d* psMsgListTrav = NULL; uint16_t wFlightLastMsgSeqNum = 0xFFFF; do { //Check Message/ Fragment //Optional Message Check //Check Message Sequence Number //Buffer the message/ De-Fragmentation() //Message Completeness() //Send to Security Chip for Processing() if((uint8_t)efInit == PpsThisFlight->bFlightState) { PpsThisFlight->bFlightState = (uint8_t)efReady; break; } else if((PpsThisFlight->bFlightState == (uint8_t)efReady) || (PpsThisFlight->bFlightState == (uint8_t)efProcessed) || (PpsThisFlight->bFlightState == (uint8_t)efReReceive)) { if(PpsThisFlight->bFlightState == (uint8_t)efProcessed) { PpsThisFlight->bFlightState = (uint8_t)efReReceive; } bMsgSeqNum = HS_MESSAGE_SEQNUM(PpsMessageLayer->sMsg.prgbStream); bMsgID = HS_MESSAGE_TYPE(PpsMessageLayer->sMsg.prgbStream); if(OCP_FL_OK != DtlsHS_Flight_LimitChk((uint8_t)eFlight2,bMsgID)) { i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; break; } if(OCP_FL_OK != FLIGHT_IDLIMITCHK(1, PbLastProcFlight, 3)) { i4Status = (int32_t)OCP_FL_INVALID_PROCFLIGHT; break; } if(OCP_FL_OK != DtlsHS_Flight2CheckMsgSeqNum(bMsgID, bMsgSeqNum, PpsThisFlight->psMessageList)) { i4Status = (int32_t)OCP_FL_INVALID_MSG_SEQNUM; break; } i4Status = DtlsHS_FlightMsgChkAndBuffer(PpsThisFlight->psMessageList, bMsgID, &(PpsMessageLayer->sMsg), PpsMessageLayer, (uint8_t)eFlight2); if(((int32_t)OCP_FL_ERROR == i4Status) || ((int32_t)OCP_FL_MSG_MAXCOUNT == i4Status) || ((int32_t)OCP_FL_MALLOC_FAILURE == i4Status)) { break; } PpsMessageLayer->eFlight = eFlight2; if((int32_t)OCP_FL_MSG_NODE_NOT_AVAIL == i4Status) { // Buffer the message psMsgListTrav = (sMsgInfo_d*)OCP_MALLOC(sizeof(sMsgInfo_d)); if(NULL == psMsgListTrav) { i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } psMsgListTrav->eMsgState = ePartial; psMsgListTrav->psNext = NULL; psMsgListTrav->psMsgMapPtr = NULL; psMsgListTrav->psMsgHolder = (uint8_t*)OCP_MALLOC(HS_MESSAGE_LENGTH(PpsMessageLayer->sMsg.prgbStream) + OVERHEAD_LEN); if(NULL == psMsgListTrav->psMsgHolder) { DtlsHS_FreeMsgNode(psMsgListTrav); i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } i4Status = DtlsHS_RInit_MessageNode(psMsgListTrav, PpsMessageLayer); if(((int32_t)OCP_FL_OK != i4Status) && ((int32_t)OCP_FL_MSG_INCOMPLETE != i4Status)) { DtlsHS_FreeMsgNode(psMsgListTrav); break; } DtlsHS_InsertMsgNode(&PpsThisFlight->psMessageList, psMsgListTrav); } //Check Flight Completeness if(NULL != PpsThisFlight->psMessageList) { if((eComplete != PpsThisFlight->psMessageList->eMsgState) && (eProcessed != PpsThisFlight->psMessageList->eMsgState)) { i4Status = (int32_t)OCP_FL_RXING; break; } } else { i4Status = (int32_t)OCP_FL_ERROR; break; } PpsThisFlight->bFlightState = (uint8_t)efReceived; //Send to Security Chip For Processing i4Status = DtlsHS_SendFlightToOptiga(PpsThisFlight->psMessageList, PpsMessageLayer); if(OCP_ML_OK != i4Status) { break; } //Update Flight Status PpsThisFlight->bFlightState = (uint8_t)efProcessed; DtlsHS_ResetFlight2MsgNode(PpsThisFlight); DtlsHS_FlightGetLastMsgSeqNum(PpsThisFlight->psMessageList, &wFlightLastMsgSeqNum); UPDATE_RX_MSGSEQNUM(PpsMessageLayer->dwRMsgSeqNum, wFlightLastMsgSeqNum); } i4Status = OCP_FL_OK; }while(0); return i4Status; } /** * Checks if message sequence number of received message/ fragment of flight4 is correct.
* * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * \param[in] PbRxMsgID Message type of received message/ fragment. * \param[in] PwRxMsgSeqNum Message sequence number of received message/ fragment. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_ERROR Message Sequence number incorrect */ int32_t DtlsHS_Flight4CheckMsgSeqNum(const sMsgLyr_d* PpsMessageLayer, uint8_t PbRxMsgID, uint16_t PwRxMsgSeqNum) { int32_t i4Status = (int32_t)OCP_FL_ERROR; uint16_t *pwFlightMsgs = NULL; uint32_t dwPrevFlightMsgSeq, dwLastFlightSeqNum ; uint8_t bOptMsgCount = 0; uint8_t bLoopCount, bIndex, bMandtryMsgCount = 0; do { dwLastFlightSeqNum = PpsMessageLayer->dwRMsgSeqNum; dwPrevFlightMsgSeq = PpsMessageLayer->dwRMsgSeqNum; if(dwPrevFlightMsgSeq == 0xFFFFFFFF) { bLoopCount = 2; } else { bLoopCount = 1; } for(bIndex = 0; bIndex < bLoopCount; bIndex++) { DtlsHS_GetFlightMsgInfo((uint8_t)eFlight4, &pwFlightMsgs); do { if(IsMandatory(*pwFlightMsgs)) { bMandtryMsgCount++; } else { bOptMsgCount++; } if(MSG_ID(*pwFlightMsgs) == PbRxMsgID) { if(((dwLastFlightSeqNum+bMandtryMsgCount+bOptMsgCount) == PwRxMsgSeqNum) || ((dwLastFlightSeqNum+bMandtryMsgCount) == PwRxMsgSeqNum)) { i4Status = (int32_t)OCP_FL_OK; break; } } }while(0xFFFF != *(++pwFlightMsgs)); if((int32_t)OCP_FL_OK == i4Status) { break; } dwLastFlightSeqNum = dwPrevFlightMsgSeq + 1; bMandtryMsgCount = 0; bOptMsgCount = 0; } }while(FALSE); return i4Status; } /** * Flight four handler to process flight 4 messages.
* * \param[in] PbLastProcFlight Last processed flight. * \param[in,out] PpsThisFlight Pointer to the structure containing flight4 status. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_MSG_ERROR Failure in execution * \retval #OCP_FL_MALLOC_FAILURE Memory allocation failure * \retval #OCP_FL_INVALID_MSG_SEQNUM Invalid Message sequence number * \retval #OCP_FL_MSG_NOT_IN_FLIGHT Message doesn't belong to current flight * \retval #OCP_FL_RXING Message is not yet completely received * \retval #OCP_FL_MSG_MAXCOUNT Message is received at least 6 times */ int32_t DtlsHS_Flight4Handler(uint8_t PbLastProcFlight, sFlightStats_d* PpsThisFlight, sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = (int32_t)OCP_FL_OK; sMsgInfo_d* psMsgListTrav = NULL; uint8_t bMsgID; uint16_t wMsgSeqNum; uint32_t dwMsgLen; uint16_t wFlightLastMsgSeqNum = 0xFFFF; do { //Check Message/ Fragment //Optional Message Check //Check Message Sequence Number //Buffer the message/ De-Fragmentation() //Message Completeness() //Send to Security Chip for Processing() if((uint8_t)efInit == PpsThisFlight->bFlightState) { PpsThisFlight->bFlightState = (uint8_t)efReady; break; } else if((uint8_t)efReady == PpsThisFlight->bFlightState) { bMsgID = HS_MESSAGE_TYPE(PpsMessageLayer->sMsg.prgbStream); wMsgSeqNum = HS_MESSAGE_SEQNUM(PpsMessageLayer->sMsg.prgbStream); dwMsgLen = HS_MESSAGE_LENGTH(PpsMessageLayer->sMsg.prgbStream); if(OCP_FL_OK != DtlsHS_Flight_LimitChk((uint8_t)eFlight4,bMsgID)) { i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; break; } if(0x00 != PpsMessageLayer->psConfigRL->sRL.bDecRecord) { i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; break; } if(OCP_FL_OK != FLIGHT_IDLIMITCHK(1, PbLastProcFlight, 5)) { i4Status = (int32_t)OCP_FL_INVALID_PROCFLIGHT; break; } if(OCP_FL_OK != DtlsHS_Flight4CheckMsgSeqNum(PpsMessageLayer, bMsgID, wMsgSeqNum)) { i4Status = (int32_t)OCP_FL_INVALID_MSG_SEQNUM; break; } i4Status = DtlsHS_FlightMsgChkAndBuffer(PpsThisFlight->psMessageList, bMsgID, &(PpsMessageLayer->sMsg), PpsMessageLayer, (uint8_t)eFlight4); if(((int32_t)OCP_FL_ERROR == i4Status) || ((int32_t)OCP_FL_MSG_MAXCOUNT == i4Status) || ((int32_t)OCP_FL_MALLOC_FAILURE == i4Status)) { break; } PpsMessageLayer->eFlight = eFlight4; if((int32_t)OCP_FL_MSG_NODE_NOT_AVAIL == i4Status) { // Buffer the message psMsgListTrav = (sMsgInfo_d*)OCP_MALLOC(sizeof(sMsgInfo_d)); if(NULL == psMsgListTrav) { i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } psMsgListTrav->eMsgState = ePartial; psMsgListTrav->psNext = NULL; psMsgListTrav->psMsgMapPtr = NULL; psMsgListTrav->psMsgHolder = (uint8_t*)OCP_MALLOC(HS_MESSAGE_LENGTH(PpsMessageLayer->sMsg.prgbStream) + OVERHEAD_LEN); if(NULL == psMsgListTrav->psMsgHolder) { DtlsHS_FreeMsgNode(psMsgListTrav); i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } i4Status = DtlsHS_RInit_MessageNode(psMsgListTrav, PpsMessageLayer); if(((int32_t)OCP_FL_OK != i4Status) && ((int32_t)OCP_FL_MSG_INCOMPLETE != i4Status)) { DtlsHS_FreeMsgNode(psMsgListTrav); break; } DtlsHS_InsertMsgNode(&PpsThisFlight->psMessageList, psMsgListTrav); } //Check Flight Completeness i4Status = DtlsHS_CheckFlight_Compl(PpsThisFlight->psMessageList, (uint8_t)eFlight4, PpsMessageLayer); if((int32_t)OCP_FL_MSG_INCOMPLETE == i4Status) { i4Status = (int32_t)OCP_FL_RXING; break; } if(OCP_FL_OK != i4Status) { break; } PpsThisFlight->bFlightState = (uint8_t)efReceived; //Send to Security Chip For Processing i4Status = DtlsHS_SendFlightToOptiga(PpsThisFlight->psMessageList, PpsMessageLayer); if(OCP_ML_OK != i4Status) { break; } //Update Flight Status PpsThisFlight->bFlightState = (uint8_t)efProcessed; DtlsHS_FlightGetLastMsgSeqNum(PpsThisFlight->psMessageList, &wFlightLastMsgSeqNum); UPDATE_RX_MSGSEQNUM(PpsMessageLayer->dwRMsgSeqNum, wFlightLastMsgSeqNum); PpsMessageLayer->eFlight = eFlight0; DtlsHS_Flight4ClearMsgsInList(PpsThisFlight->psMessageList); } else if (((uint8_t)efProcessed == PpsThisFlight->bFlightState) || ((uint8_t)efReReceive == PpsThisFlight->bFlightState)) { if((uint8_t)efProcessed == PpsThisFlight->bFlightState) { UPDATE_FSTATE(PpsThisFlight->bFlightState, (uint8_t)efReReceive); } if(PpsMessageLayer->psConfigRL->sRL.bRecvCCSRecord == CCS_RECORD_RECV) { i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; break; } bMsgID = HS_MESSAGE_TYPE(PpsMessageLayer->sMsg.prgbStream); wMsgSeqNum = HS_MESSAGE_SEQNUM(PpsMessageLayer->sMsg.prgbStream); dwMsgLen = HS_MESSAGE_LENGTH(PpsMessageLayer->sMsg.prgbStream); psMsgListTrav = PpsThisFlight->psMessageList; if(OCP_FL_OK != DtlsHS_Flight_LimitChk((uint8_t)eFlight4,bMsgID)) { i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; break; } if(0x00 != PpsMessageLayer->psConfigRL->sRL.bDecRecord) { i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; break; } if(OCP_FL_OK != DtlsHS_Flight4CheckBuffMsg(bMsgID, wMsgSeqNum, dwMsgLen, PpsThisFlight->psMessageList)) { i4Status = (int32_t)OCP_FL_MSG_IGNORE; break; } PpsMessageLayer->eFlight = eFlight4; i4Status = DtlsHS_Flight4UpdateMsgStat(bMsgID, PpsThisFlight->psMessageList, PpsMessageLayer); if(((int32_t)OCP_FL_OK != i4Status) && ((int32_t)OCP_FL_MSG_INCOMPLETE != i4Status)) { break; } if(OCP_FL_OK != DtlsHS_Flight4ReRxCompl(PpsThisFlight->psMessageList)) { i4Status = (int32_t)OCP_FL_RXING; break; } //Update Flight Status UPDATE_FSTATE(PpsThisFlight->bFlightState, (uint8_t)efProcessed); DtlsHS_Flight4ClearMsgsInList(PpsThisFlight->psMessageList); } i4Status = (int32_t)OCP_FL_OK; }while(0); return i4Status; } /** * Checks whether flight six is received.
* * \param[in] PpsMessageList Pointer to the list of messages of flight6. * * \retval #OCP_FL_OK Flight six is received * \retval #OCP_FL_ERROR Flight six is not received */ _STATIC_H int32_t DtlsHS_CheckFlight6_Compl(sMsgInfo_d *PpsMessageList) { int32_t i4Status = (int32_t)OCP_FL_OK; sMsgInfo_d * psMsgListTrav = PpsMessageList; uint16_t * pwFlightMsgs; uint8_t bTotalMsgInFlight; uint8_t bNumMsgRxdInFlight = 0; DtlsHS_GetFlightMsgInfo((uint8_t)eFlight6, &pwFlightMsgs); DtlsHS_GetTotalMsgCount(pwFlightMsgs, &bTotalMsgInFlight); do { while(NULL != psMsgListTrav) { bNumMsgRxdInFlight++; if(eComplete != psMsgListTrav->eMsgState) { i4Status = (int32_t)OCP_FL_MSG_INCOMPLETE; break; } psMsgListTrav = psMsgListTrav->psNext; } if(((int32_t)OCP_FL_OK == i4Status) && (bNumMsgRxdInFlight != bTotalMsgInFlight)) { i4Status = (int32_t)OCP_FL_MSG_INCOMPLETE; break; } }while(0); return i4Status; } /** * Flight six handler to process flight 6 messages.
* * \param[in] PbLastProcFlight Last processed flight. * \param[in,out] PpsThisFlight Pointer to the structure containing flight6 status. * \param[in] PpsMessageLayer Pointer to the structure containing message configuration information. * * \retval #OCP_FL_OK Successful execution * \retval #OCP_FL_MSG_ERROR Failure in execution * \retval #OCP_FL_MALLOC_FAILURE Memory allocation failure * \retval #OCP_FL_INVALID_MSG_SEQNUM Invalid Message sequence number * \retval #OCP_FL_MSG_NOT_IN_FLIGHT Message doesn't belong to current flight * \retval #OCP_FL_RXING Message is not yet completely received * \retval #OCP_FL_MSG_MAXCOUNT Message is received at least 6 times */ int32_t DtlsHS_Flight6Handler(uint8_t PbLastProcFlight, sFlightStats_d* PpsThisFlight, sMsgLyr_d* PpsMessageLayer) { int32_t i4Status = (int32_t)OCP_FL_OK; sMsgInfo_d* psMsgListTrav = NULL; uint8_t bMsgID; uint16_t wMsgSeqNum = 0; sCBStateTrn_d sCBStateTrn; uint16_t wFlightLastMsgSeqNum = 0xFFFF; /// @cond hidden #define SETFULL_BITMAP 0xFF #define SIZE_OF_CCSMSG 0x01 #define CHANGE_CIPHER_SPEC_PROTOCOL 0x01 #define INTERNAL_PROC_ERROR 0x06 #define INVALID_HS_MESSAGE 0x21 /// @endcond do { //Check Message/ Fragment //Optional Message Check //Check Message Sequence Number //Buffer the message/ De-Fragmentation() //Message Completeness() //Send to Security Chip for Processing() if((uint8_t)efInit == PpsThisFlight->bFlightState) { PpsThisFlight->bFlightState = (uint8_t)efReady; break; } else if((uint8_t)efReady == PpsThisFlight->bFlightState) { if(PpsMessageLayer->psConfigRL->sRL.bRecvCCSRecord == CCS_RECORD_RECV) { if((*(PpsMessageLayer->sMsg.prgbStream) != (uint8_t)CHANGE_CIPHER_SPEC_PROTOCOL) || (PpsMessageLayer->sMsg.wLen != (uint16_t)SIZE_OF_CCSMSG)) { i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; PpsMessageLayer->psConfigRL->sRL.bRecvCCSRecord = CCS_RECORD_NOTRECV; break; } if(NULL != PpsMessageLayer->psConfigRL->sRL.fServerStateTrn) { sCBStateTrn.phRLHdl = PpsMessageLayer->psConfigRL->sRL.phRLHdl; PpsMessageLayer->psConfigRL->sRL.fServerStateTrn((Void*)&sCBStateTrn); } else { i4Status = (int32_t)OCP_FL_NULL_PARAM; break; } bMsgID = (uint8_t)eChangeCipherSpec; } else { bMsgID = HS_MESSAGE_TYPE(PpsMessageLayer->sMsg.prgbStream); wMsgSeqNum = HS_MESSAGE_SEQNUM(PpsMessageLayer->sMsg.prgbStream); } if(OCP_FL_OK != DtlsHS_Flight_LimitChk((uint8_t)eFlight6, bMsgID)) { i4Status = (int32_t)OCP_FL_MSG_NOT_IN_FLIGHT; break; } if(OCP_FL_OK != FLIGHT_IDLIMITCHK(4, PbLastProcFlight, 6)) { i4Status = (int32_t)OCP_FL_INVALID_PROCFLIGHT; break; } if(OCP_FL_OK != DtlsHS_Flight6CheckMsgSeqNum(PpsMessageLayer, bMsgID, wMsgSeqNum)) { i4Status = (int32_t)OCP_FL_INVALID_MSG_SEQNUM; break; } i4Status = DtlsHS_FlightMsgChkAndBuffer(PpsThisFlight->psMessageList, bMsgID, &(PpsMessageLayer->sMsg), PpsMessageLayer, (uint8_t)eFlight6); if(((int32_t)OCP_FL_ERROR == i4Status) || ((int32_t)OCP_FL_MSG_MAXCOUNT == i4Status) || ((int32_t)OCP_FL_MALLOC_FAILURE == i4Status)) { break; } PpsMessageLayer->eFlight = eFlight6; if((int32_t)OCP_FL_MSG_NODE_NOT_AVAIL == i4Status) { // Buffer the message psMsgListTrav = (sMsgInfo_d*)OCP_MALLOC(sizeof(sMsgInfo_d)); if(NULL == psMsgListTrav) { i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } if((uint8_t)eChangeCipherSpec == bMsgID) { psMsgListTrav->bMsgType = (uint8_t)eChangeCipherSpec; psMsgListTrav->psNext = NULL; psMsgListTrav->psMsgHolder = NULL; psMsgListTrav->bMsgCount = 1; psMsgListTrav->psMsgMapPtr = (uint8_t*)OCP_MALLOC(SIZE_OF_CCSMSG); if(NULL == psMsgListTrav->psMsgMapPtr) { DtlsHS_FreeMsgNode(psMsgListTrav); i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } *psMsgListTrav->psMsgMapPtr = SETFULL_BITMAP; psMsgListTrav->dwMsgLength = SIZE_OF_CCSMSG; psMsgListTrav->eMsgState = eComplete; i4Status = OCP_FL_OK; } else { psMsgListTrav->eMsgState = ePartial; psMsgListTrav->psNext = NULL; psMsgListTrav->psMsgMapPtr = NULL; psMsgListTrav->psMsgHolder = (uint8_t*)OCP_MALLOC(HS_MESSAGE_LENGTH(PpsMessageLayer->sMsg.prgbStream) + OVERHEAD_LEN); if(NULL == psMsgListTrav->psMsgHolder) { DtlsHS_FreeMsgNode(psMsgListTrav); i4Status = (int32_t)OCP_FL_MALLOC_FAILURE; break; } i4Status = DtlsHS_RInit_MessageNode(psMsgListTrav, PpsMessageLayer); if(((int32_t)OCP_FL_OK != i4Status) && ((int32_t)OCP_FL_MSG_INCOMPLETE != i4Status)) { DtlsHS_FreeMsgNode(psMsgListTrav); break; } } DtlsHS_InsertMsgNode(&PpsThisFlight->psMessageList, psMsgListTrav); } //Check Flight Completeness if((int32_t)OCP_FL_MSG_INCOMPLETE == DtlsHS_CheckFlight6_Compl(PpsThisFlight->psMessageList)) { i4Status = (int32_t)OCP_FL_RXING; break; } if(OCP_FL_OK != i4Status) { break; } PpsThisFlight->bFlightState = (uint8_t)efReceived; //Send to Security Chip For Processing i4Status = DtlsHS_SendFlightToOptiga(PpsThisFlight->psMessageList, PpsMessageLayer); if(OCP_ML_OK != i4Status) { if((i4Status & (int32_t)DEV_ERROR_CODE_MASK) == (int32_t)CMD_DEV_ERROR) { if((i4Status & (int32_t)DEV_ERROR_LSBCODE_MASK) == INTERNAL_PROC_ERROR) { i4Status = (int32_t)OCP_FL_INT_ERROR; } else if((i4Status & (int32_t)DEV_ERROR_LSBCODE_MASK) == INVALID_HS_MESSAGE) { i4Status = (int32_t)OCP_FL_HS_ERROR; } } break; } //Update Flight Status PpsThisFlight->bFlightState = (uint8_t)efProcessed; DtlsHS_FlightGetLastMsgSeqNum(PpsThisFlight->psMessageList, &wFlightLastMsgSeqNum); UPDATE_RX_MSGSEQNUM(PpsMessageLayer->dwRMsgSeqNum, wFlightLastMsgSeqNum); } i4Status = (int32_t)OCP_FL_OK; }while(0); /// @cond hidden #undef SETFULL_BITMAP #undef SIZE_OF_CCSMSG #undef CHANGE_CIPHER_SPEC_PROTOCOL #undef INTERNAL_PROC_ERROR #undef INVALID_HS_MESSAGE /// @endcond return i4Status; } /** * @} */ #endif /*MODULE_ENABLE_DTLS_MUTUAL_AUTH*/