12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508 |
- /**
- * 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 DtlsHandshakeProtocol.c
- *
- * \brief This file implements the DTLS Handshake protocol.
- *
- * \addtogroup grMutualAuth
- * @{
- */
- #include "optiga/dtls/DtlsHandshakeProtocol.h"
- #include "optiga/dtls/AlertProtocol.h"
- #include "optiga/optiga_dtls.h"
- #include "optiga/dtls/DtlsRecordLayer.h"
- #include "optiga/dtls/DtlsFlightHandler.h"
- #ifdef MODULE_ENABLE_DTLS_MUTUAL_AUTH
- ///Flight retransmission timeout default value for the first time
- #define DEFAULT_TIMEOUT 2
- ///Maximum Timeout value
- #define MAX_FLIGHT_TIMEOUT 60
- /// @cond hidden
- ///Offset for message type
- #define OFFSET_MSG_TYPE (0)
- ///Offset for Total length
- #define OFFSET_MSG_TOTAL_LENGTH (OFFSET_MSG_TYPE + 1) //1
- ///Offset for message sequence
- #define OFFSET_MSG_SEQUENCE (OFFSET_MSG_TOTAL_LENGTH + 3) //4
- ///Offset for fragment offset
- #define OFFSET_MSG_FRAGMENT_OFFSET (OFFSET_MSG_SEQUENCE + 2) //6
- ///Offset for message fragment length
- #define OFFSET_MSG_FRAG_LENGTH (OFFSET_MSG_FRAGMENT_OFFSET+ 3) //9
- ///Offset for message data
- #define OFFSET_MSG_DATA (OFFSET_MSG_FRAG_LENGTH + 3) //12
- ///Message header length
- #define LENGTH_MSG_HEADER (OFFSET_MSG_DATA)
- ///Offset for second byte of message fragment length field
- #define OFFSET_MSG_FRAG_LENGTH_2BYTE (OFFSET_MSG_FRAG_LENGTH + 1)
- ///Macro for Receive Flight
- #ifndef DISABLE_RECEIVE_FLIGHT
- #define REC_FLIGHT_INITIALIZE(PbLastProcFlight, PppsFlightHead, PpsMessageLayer) DtlsHS_RFlightInitialise(PbLastProcFlight, PppsFlightHead, PpsMessageLayer)
- #define REC_FLIGHT_PROCESS(PpbLastProcFlight, PppsRFlightHead, PpsMessageLayer, PbFlightTimeout) DtlsHS_RFlightProcess(PpbLastProcFlight, PppsRFlightHead, PpsMessageLayer, PbFlightTimeout)
- #else
- extern int32_t StubRFlightInitialise(uint8_t PbLastProcFlight, sFlightDetails_d** PppsFlightHead, sMsgLyr_d* PpsMessageLayer);
- extern int32_t StubRFlightProcess(uint8_t* PpbLastProcFlight, sFlightDetails_d** PppsRFlightHead, sMsgLyr_d* PpsMessageLayer, uint8_t PbFlightTimeout);
- #define REC_FLIGHT_INITIALIZE(PbLastProcFlight, PppsFlightHead, PpsMessageLayer) StubRFlightInitialise(PbLastProcFlight, PppsFlightHead, PpsMessageLayer)
- #define REC_FLIGHT_PROCESS(PpbLastProcFlight, PppsRFlightHead, PpsMessageLayer, PbFlightTimeout) StubRFlightProcess(PpbLastProcFlight, PppsRFlightHead, PpsMessageLayer, PbFlightTimeout)
- #endif
- ///Macro for Send Flight
- #ifndef DISABLE_SEND_FLIGHT
- #define SEND_FLIGHT_INITIALIZE(PbLastProcFlight, PppsFlightHead, PpsMessageLayer) DtlsHS_SFlightInitialise(PbLastProcFlight, PppsFlightHead, PpsMessageLayer)
- #define SEND_FLIGHT_PROCESS(PpbLastProcFlight, PpsSFlightHead, PpsMessageLayer) DtlsHS_SFlightProcess(PpbLastProcFlight, PpsSFlightHead, PpsMessageLayer)
- #else
- extern int32_t StubSFlightInitialise(uint8_t PbLastProcFlight, sFlightDetails_d** PppsFlightHead, sMsgLyr_d* PpsMessageLayer);
- extern int32_t StubSFlightProcess(uint8_t *PpbLastProcFlight, sFlightDetails_d* PpsSFlightHead, sMsgLyr_d* PpsMessageLayer);
- #define SEND_FLIGHT_INITIALIZE(PbLastProcFlight, PppsFlightHead, PpsMessageLayer) StubSFlightInitialise(PbLastProcFlight, PppsFlightHead, PpsMessageLayer)
- #define SEND_FLIGHT_PROCESS(PpbLastProcFlight, PpsSFlightHead, PpsMessageLayer) StubSFlightProcess(PpbLastProcFlight, PpsSFlightHead, PpsMessageLayer)
- #endif
- #define FLIGHTLoHi(x,y) ((x) | (y<<8))
- #define MSGLoHi(x,y) ((x) | (y<<8))
- #define IsEVEN_FLIGHT(X) (((X%2) == 0) ? 1 : 0)
- ///Flight mapping table for the send flights
- const sFlightTable_d rgsSFlightInfo[] = {
- {FLIGHTLoHi((uint8_t)eFlight1, \
- (uint8_t)eMandatory), {MSGLoHi((uint8_t)eClientHello, (uint8_t)eMandatory), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF)},\
- DtlsHS_Flight1Handler},
- {FLIGHTLoHi((uint8_t)eFlight3, \
- (uint8_t)eOptional), {MSGLoHi((uint8_t)eClientHello, (uint8_t)eOptional), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF)}, \
- DtlsHS_Flight3Handler},
- {FLIGHTLoHi((uint8_t)eFlight5, (uint8_t)eMandatory), \
- {MSGLoHi((uint8_t)eClientCertificate, (uint8_t)eOptional), MSGLoHi((uint8_t)eClientKeyExchange, (uint8_t)eMandatory), MSGLoHi((uint8_t)eCertificateVerify, (uint8_t)eOptional), MSGLoHi((uint8_t)eChangeCipherSpec, (uint8_t)eMandatory), MSGLoHi((uint8_t)eClientFinished, (uint8_t)eMandatory), MSGLoHi(0xFF, 0xFF)}, \
- DtlsHS_Flight5Handler},
- };
- ///Flight mapping table for the receive flights
- const sFlightTable_d rgsRFlightInfo[] = {
- {FLIGHTLoHi((uint8_t)eFlight2, (uint8_t)eOptional), \
- {MSGLoHi((uint8_t)eHelloVerifyRequest, (uint8_t)eOptional), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF)}, \
- DtlsHS_Flight2Handler},
- {FLIGHTLoHi((uint8_t)eFlight4, (uint8_t)eMandatory), \
- {MSGLoHi((uint8_t)eServerHello, (uint8_t)eMandatory), MSGLoHi((uint8_t)eServerCertificate, (uint8_t)eMandatory), MSGLoHi((uint8_t)eServerKeyExchange, (uint8_t)eMandatory), MSGLoHi((uint8_t)eCertificateRequest, (uint8_t)eOptional), MSGLoHi((uint8_t)eServerHelloDone, (uint8_t)eMandatory), MSGLoHi(0xFF, 0xFF)}, \
- DtlsHS_Flight4Handler},
- {FLIGHTLoHi((uint8_t)eFlight6, (uint8_t)eMandatory), \
- {MSGLoHi((uint8_t)eChangeCipherSpec, (uint8_t)eMandatory), MSGLoHi((uint8_t)eServerFinished, (uint8_t)eMandatory), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF), MSGLoHi(0xFF, 0xFF)}, \
- DtlsHS_Flight6Handler},
- };
- /// @endcond
- /**
- * \brief Fragments a handshake message into smaller fragments.<br>
- */
- _STATIC_H int32_t DtlsHS_FragmentMsg(sFragmentMsg_d* PpsFragmentMsg);
- /**
- * \brief Frees the complete message list of a flight.<br>
- */
- _STATIC_H void DtlsHS_FreeMessageList(sMsgInfo_d **PppsMsgListPtr);
- /**
- * \brief Frees flight list except the flight node of interest.<br>
- */
- _STATIC_H void DtlsHS_FreeFlightList(uint8_t PbFlightID, sFlightDetails_d** PppsFlightHead);
- /**
- * \brief Frees specified flight node.<br>
- */
- _STATIC_H void DtlsHS_FreeFlightNode(uint8_t PbFlightID, sFlightDetails_d** PppsFlightHead);
- /**
- * \brief Receives a handshake messages from the server.<br>
- */
- _STATIC_H int32_t DtlsHS_ReceiveFlightMessage(uint8_t* PpbLastProcFlight, sFlightDetails_d** PppsRFlightHead, sMsgLyr_d* PpsMessageLayer, uint8_t PbFlightTimeout,uint32_t PdwBasetime);
- /**
- * \brief Frees flight node.<br>
- */
- _STATIC_H void DtlsHS_ClearBuffer(sFlightDetails_d** PppsFlightHead);
- /**
- * \brief Checks a flight is in the list or not.<br>
- */
- _STATIC_H int32_t DtlsHS_CheckFlightList(sFlightDetails_d* PpsFlightHead, uint8_t PbFlightID);
- /**
- * \brief Initialises the Flight List for Send.<br>
- */
- _STATIC_H int32_t DtlsHS_SFlightInitialise(uint8_t PbLastProcFlight, sFlightDetails_d** PppsFlightHead, sMsgLyr_d* PpsMessageLayer);
- /**
- * \brief Initialises the Flight List for Receive.<br>
- */
- _STATIC_H int32_t DtlsHS_RFlightInitialise(uint8_t PbLastProcFlight, sFlightDetails_d** PppsFlightHead, sMsgLyr_d* PpsMessageLayer);
- /**
- * \brief Processes the send Flight.<br>
- */
- _STATIC_H int32_t DtlsHS_SFlightProcess(uint8_t *PpbLastProcFlight, sFlightDetails_d* PpsSFlightHead, sMsgLyr_d* PpsMessageLayer);
- /**
- * \brief Processes the receive Flight.<br>
- */
- _STATIC_H int32_t DtlsHS_RFlightProcess(uint8_t* PpbLastProcFlight, sFlightDetails_d** PppsRFlightHead, sMsgLyr_d* PpsMessageLayer, uint8_t PbFlightTimeout);
- /**
- * \brief Appends a Flight Node to the end of the list.<br>
- */
- _STATIC_H void DtlsHS_CreateFlightList(sFlightDetails_d** PppsFlightHead, sFlightDetails_d* PpsFlightNode);
- /**
- * \brief Creates a flight node based on the last processed flight and inserts the node to the head node.<br>
- */
- _STATIC_H int32_t DtlsHS_CreateFlightNode(uint8_t PbLastProcFlight, sFlightDetails_d** PppsFlightHead, sMsgLyr_d* PpsMessageLayer);
- /**
- * Fragments a handshake message into smaller fragments.<br>
- * Returns a fragment of the handshake message.
- *
- * \param[in,out] PpsFragmentMsg Pointer to a structure containing handshake message, fragment size and other
- * information required for fragmentation
- *
- * \retval #OCP_HL_OK Successful execution
- * \retval #OCP_HL_ERROR Failure in execution
- \if ENABLE_NULL_CHECKS
- * \retval #OCP_HL_NULL_PARAM Null parameter(s)
- \endif
- * \retval #OCP_HL_LENZERO_ERROR Length of input parameter is zero
- * \retval #OCP_HL_INVALID_FRAGMENT_SIZE Invalid fragment size
- * \retval #OCP_HL_INVALID_OFFSET_LEN Invalid offset length
- * \retval #OCP_HL_INSUFFICIENT_MEMORY Insufficient buffer size
- */
- _STATIC_H int32_t DtlsHS_FragmentMsg(sFragmentMsg_d* PpsFragmentMsg)
- {
- int32_t i4Status = (int32_t)OCP_HL_ERROR;
- puint8_t prgbSrcBuf;
- puint8_t prgbDesBuf;
- uint16_t wLength;
- do
- {
- #ifdef ENABLE_NULL_CHECKS
- //Null Check for input parameters
- if((NULL == PpsFragmentMsg) || (NULL == PpsFragmentMsg->psCompleteMsg) || (NULL == PpsFragmentMsg->psMsgFrag)
- || (NULL == PpsFragmentMsg->psCompleteMsg->prgbStream) ||(NULL == PpsFragmentMsg->psMsgFrag->prgbStream))
- {
- i4Status = (int32_t)OCP_HL_NULL_PARAM;
- break;
- }
- #endif
- //Length validation for input parameters
- if((0 == PpsFragmentMsg->psCompleteMsg->wLen) || (0 == PpsFragmentMsg->psMsgFrag->wLen))
- {
- i4Status = (int32_t)OCP_HL_LENZERO_ERROR;
- break;
- }
- //Invalid Fragment size
- if(0 == PpsFragmentMsg->wFragmentSize)
- {
- i4Status = (int32_t)OCP_HL_INVALID_FRAGMENT_SIZE;
- break;
- }
- //Check for sufficient buffer size
- if(PpsFragmentMsg->psMsgFrag->wLen < PpsFragmentMsg->wFragmentSize)
- {
- i4Status = (int32_t)OCP_HL_INSUFFICIENT_MEMORY;
- break;
- }
- //Current offset check
- if(PpsFragmentMsg->wCurrentOffset >= PpsFragmentMsg->psCompleteMsg->wLen)
- {
- i4Status = (int32_t)OCP_HL_INVALID_OFFSET_LEN;
- break;
- }
- if(0 == PpsFragmentMsg->wRemainingLen)
- {
- i4Status = (int32_t)OCP_HL_LENZERO_ERROR;
- break;
- }
- if( 0 == PpsFragmentMsg->wCurrentOffset)
- {
- //Assign the address to copy the message
- prgbSrcBuf = PpsFragmentMsg->psCompleteMsg->prgbStream;
- prgbDesBuf = PpsFragmentMsg->psMsgFrag->prgbStream;
- //If the fragment size is greater than complete message size
- //Length is set to message size
- //else
- //Length is set to fragment size
- wLength = (PpsFragmentMsg->wFragmentSize > PpsFragmentMsg->psCompleteMsg->wLen)? PpsFragmentMsg->psCompleteMsg->wLen : PpsFragmentMsg->wFragmentSize;
- PpsFragmentMsg->psMsgFrag->wLen = wLength;
- }
- else
- {
- //Copy the message header to psMsgFrag
- Utility_Memmove(PpsFragmentMsg->psMsgFrag->prgbStream, PpsFragmentMsg->psCompleteMsg->prgbStream,
- LENGTH_MSG_HEADER);
- prgbSrcBuf = PpsFragmentMsg->psCompleteMsg->prgbStream + OFFSET_MSG_DATA + PpsFragmentMsg->wCurrentOffset;
- prgbDesBuf = PpsFragmentMsg->psMsgFrag->prgbStream + OFFSET_MSG_DATA;
- //If the remaining length is less than fragment size(Last fragment)
- if(PpsFragmentMsg->wFragmentSize > (PpsFragmentMsg->wRemainingLen + LENGTH_MSG_HEADER))
- {
- //Assign the address to copy the message of size (wRemainingLen) from current offset to psMsgFrag at index msgHeaderLen
- wLength = (uint16_t)PpsFragmentMsg->wRemainingLen;
- PpsFragmentMsg->psMsgFrag->wLen = (uint16_t)(PpsFragmentMsg->wRemainingLen + LENGTH_MSG_HEADER);
- }
- else
- {
- //Assign the address to copy the message of size (wFragmentSize - msgHeaderLen) from current offset to psMsgFrag at index msgHeaderLen
- wLength = PpsFragmentMsg->wFragmentSize - LENGTH_MSG_HEADER;
- PpsFragmentMsg->psMsgFrag->wLen = PpsFragmentMsg->wFragmentSize;
- }
- }
- //To copy the Fragmented message to psMsgFrag
- Utility_Memmove(prgbDesBuf, prgbSrcBuf, wLength);
- if(PpsFragmentMsg->wFragmentSize < PpsFragmentMsg->psCompleteMsg->wLen)
- {
- //Update the fragment header with current offset at index fragment offset
- Utility_SetUint24 ((PpsFragmentMsg->psMsgFrag->prgbStream + OFFSET_MSG_FRAGMENT_OFFSET),PpsFragmentMsg->wCurrentOffset);
- if(PpsFragmentMsg->wFragmentSize > (PpsFragmentMsg->wRemainingLen + LENGTH_MSG_HEADER))
- {
- //Update the fragment length with wRemainingLen at index fragment length(Last Fragment)
- Utility_SetUint16((PpsFragmentMsg->psMsgFrag->prgbStream + OFFSET_MSG_FRAG_LENGTH_2BYTE),(uint16_t)PpsFragmentMsg->wRemainingLen);
- }
- else
- {
- //Update the fragment length with (fragment size - header length) at index fragment length
- Utility_SetUint16((PpsFragmentMsg->psMsgFrag->prgbStream + OFFSET_MSG_FRAG_LENGTH_2BYTE),(PpsFragmentMsg->wFragmentSize - LENGTH_MSG_HEADER));
- }
- }
- //Update the current offset and remaining length
- //If Last Fragment
- if(PpsFragmentMsg->wFragmentSize > (PpsFragmentMsg->wRemainingLen + LENGTH_MSG_HEADER))
- {
- PpsFragmentMsg->wCurrentOffset += PpsFragmentMsg->wRemainingLen;
- PpsFragmentMsg->wRemainingLen = 0 ;
- }
- //For other fragment
- else
- {
- PpsFragmentMsg->wCurrentOffset += (uint16_t)(PpsFragmentMsg->wFragmentSize - LENGTH_MSG_HEADER);
- PpsFragmentMsg->wRemainingLen -= (uint16_t)(PpsFragmentMsg->wFragmentSize - LENGTH_MSG_HEADER);
- }
- i4Status = (int32_t)OCP_HL_OK;
- }while(0);
- return i4Status;
- }
- /**
- * Frees the complete message list of a flight.<br>
- *
- * \param[in,out] PppsMsgListPtr Pointer to Message list
- *
- */
- _STATIC_H void DtlsHS_FreeMessageList(sMsgInfo_d **PppsMsgListPtr)
- {
- sMsgInfo_d *pMsgNodeAPtr;
- sMsgInfo_d *pMsgNodeBPtr = NULL;
- do
- {
- if((NULL == PppsMsgListPtr) || (NULL == *PppsMsgListPtr))
- {
- break;
- }
- pMsgNodeAPtr = *PppsMsgListPtr;
- do
- {
- if(NULL != pMsgNodeAPtr->psMsgMapPtr)
- {
- OCP_FREE(pMsgNodeAPtr->psMsgMapPtr);
- pMsgNodeAPtr->psMsgMapPtr = NULL;
- }
- if(NULL != pMsgNodeAPtr->psMsgHolder)
- {
- OCP_FREE(pMsgNodeAPtr->psMsgHolder);
- pMsgNodeAPtr->psMsgHolder = NULL;
- }
- pMsgNodeBPtr = pMsgNodeAPtr->psNext;
- OCP_FREE(pMsgNodeAPtr);
- pMsgNodeAPtr = pMsgNodeBPtr;
- }while(pMsgNodeBPtr != NULL);
- *PppsMsgListPtr = NULL;
- }while(0);
- }
- /**
- * Frees all flight node from flight list except the flight node of interest.<br>
- *
- * \param[in] PbFlightID Flight ID of the flight to be freed
- * \param[in,out] PppsFlightHead Pointer to beginning of flight list
- *
- */
- _STATIC_H void DtlsHS_FreeFlightList(uint8_t PbFlightID, sFlightDetails_d** PppsFlightHead)
- {
- sFlightDetails_d *pNodeToFreePtr = NULL;
- sFlightDetails_d *pCurrentNode = NULL, *pPreviousNode = NULL;
- do
- {
- if(NULL != PppsFlightHead)
- {
- pCurrentNode = *PppsFlightHead;
- pPreviousNode = pCurrentNode;
- if(NULL != pCurrentNode)
- {
- do
- {
- if(FLIGHTID(pCurrentNode->wFlightDecp) != PbFlightID)
- {
- if(NULL != pCurrentNode->sFlightStats.psMessageList)
- {
- DtlsHS_FreeMessageList(&(pCurrentNode->sFlightStats.psMessageList));
- }
- pNodeToFreePtr = pCurrentNode;
- if(pNodeToFreePtr == *PppsFlightHead)
- {
- *PppsFlightHead = pNodeToFreePtr->psNext;
- }
- else
- {
- pPreviousNode->psNext = pCurrentNode->psNext;
- }
- OCP_FREE(pNodeToFreePtr);
- break;
- }
- pPreviousNode = pCurrentNode;
- pCurrentNode = pCurrentNode->psNext;
- }while(NULL != pCurrentNode);
- }
- }
- }while(NULL != pCurrentNode);
- }
- /**
- * Frees a flight node from the flight list which as two flight node at a time.<br>
- *
- * \param[in] PbFlightID Flight ID of the flight to be freed
- * \param[in,out] PppsFlightHead Pointer to beginning of flight list
- */
- _STATIC_H void DtlsHS_FreeFlightNode(uint8_t PbFlightID, sFlightDetails_d** PppsFlightHead)
- {
- sFlightDetails_d* pFlightTrav = NULL;
- sFlightDetails_d *pNodeToFreePtr = NULL;
- if((NULL != PppsFlightHead) && (NULL != *PppsFlightHead))
- {
- pFlightTrav = *PppsFlightHead;
- while(NULL != pFlightTrav)
- {
- if(FLIGHTID(pFlightTrav->wFlightDecp) == PbFlightID)
- {
- if(NULL != pFlightTrav->sFlightStats.psMessageList)
- {
- DtlsHS_FreeMessageList(&(pFlightTrav->sFlightStats.psMessageList));
- }
- pNodeToFreePtr = pFlightTrav;
- if(pNodeToFreePtr == *PppsFlightHead)
- {
- *PppsFlightHead = pNodeToFreePtr->psNext;
- }
- OCP_FREE(pNodeToFreePtr);
- break;
- }
- pFlightTrav = pFlightTrav->psNext;
- }
- }
- }
- /**
- * Receives a handshake message from the server.<br>
- * Under some erroneous conditions, error codes from Record Layer and Handshake Layer can also be returned.<br>
- *
- * \param[in] PpbLastProcFlight pointer to the last processed flight number
- * \param[in] PppsRFlightHead Flight head node for the receive message
- * \param[in,out] PpsMessageLayer Pointer to structure containing information required for Message Layer
- * \param[in] PbFlightTimeout Flight timeout value
- * \param[in] PdwBasetime Time at which State changed to receive mode
- *
- * \retval #OCP_HL_OK Successful Execution
- * \retval #OCP_HL_ERROR Failure Execution
- */
- _STATIC_H int32_t DtlsHS_ReceiveFlightMessage(uint8_t* PpbLastProcFlight, sFlightDetails_d** PppsRFlightHead, sMsgLyr_d* PpsMessageLayer, uint8_t PbFlightTimeout,uint32_t PdwBasetime)
- {
- int32_t i4Status = (int32_t)OCP_HL_OK;
- int32_t i4Alert ;
- uint32_t dwFragLen = 0;
- uint16_t wTotalMsgLen;
- sbBlob_d sMessage;
- uint8_t bRecvCCSRecord;
- sbBlob_d sBlobMessage;
- sFlightDetails_d *pRNextFlight;
- sFlightDetails_d *pRFlightTrav;
- /// @cond hidden
- #define B_MULTIPLERECORD (PpsMessageLayer->psConfigRL->sRL.bMultipleRecord)
- /// @endcond
- do
- {
- //Assign buffer to store the received message from record layer interface
- sMessage.prgbStream = PpsMessageLayer->sTLMsg.prgbStream;
- sMessage.wLen = PpsMessageLayer->sTLMsg.wLen;
- do
- {
- PpsMessageLayer->psConfigRL->sRL.bContentType = CONTENTTYPE_HANDSHAKE;
- //Invoke Record Layer interface to get the message over UDP
- i4Status = PpsMessageLayer->psConfigRL->pfRecv(&PpsMessageLayer->psConfigRL->sRL, sMessage.prgbStream, &sMessage.wLen);
- //Enter Flight Handler only if its a valid record
- if((int32_t)OCP_RL_OK == i4Status)
- {
- wTotalMsgLen = sMessage.wLen;
- sBlobMessage.prgbStream = sMessage.prgbStream;
- sBlobMessage.wLen = wTotalMsgLen;
- i4Status = DtlsHS_MsgCheck(*PpbLastProcFlight, &sBlobMessage, PpsMessageLayer);
- if(OCP_FL_OK != i4Status)
- {
- i4Status = (int32_t)OCP_HL_IGNORE_RECORD;
- }
- if(OCP_FL_OK == i4Status)
- {
- bRecvCCSRecord = PpsMessageLayer->psConfigRL->sRL.bRecvCCSRecord;
- while(0 != wTotalMsgLen)
- {
- pRNextFlight = *PppsRFlightHead;
- if(bRecvCCSRecord != CCS_RECORD_RECV)
- {
- dwFragLen = Utility_GetUint24(sBlobMessage.prgbStream + OFFSET_MSG_FRAG_LENGTH);
- PpsMessageLayer->sMsg.wLen = (uint16_t)dwFragLen + LENGTH_MSG_HEADER;
- }
- else
- {
- PpsMessageLayer->sMsg.wLen = 0x01;
- }
- PpsMessageLayer->sMsg.prgbStream = sBlobMessage.prgbStream;
- do
- {
- pRFlightTrav = pRNextFlight ;
- //Invoke the Flight Handler
- i4Status = pRFlightTrav->pFlightHndlr(*PpbLastProcFlight, &(pRFlightTrav->sFlightStats), PpsMessageLayer);
- if((int32_t)OCP_FL_MSG_NOT_IN_FLIGHT != i4Status)
- {
- DtlsHS_FreeFlightList(FLIGHTID(pRFlightTrav->wFlightDecp), PppsRFlightHead);
- }
- pRNextFlight = pRFlightTrav->psNext;
- }while(NULL != pRNextFlight);
- //Error checks to be added
- if(((int32_t)OCP_HL_MALLOC_FAILURE == i4Status) || ((int32_t)OCP_FL_MSG_MAXCOUNT == i4Status) || ((int32_t)OCP_HL_BUFFER_OVERFLOW == i4Status) ||
- ((int32_t)OCP_FL_MALLOC_FAILURE == i4Status) || (((int32_t)OCP_FL_ERROR == i4Status)) || ((int32_t)OCP_FL_INT_ERROR == i4Status) || ((int32_t)OCP_FL_HS_ERROR == i4Status))
- {
- break;
- }
- if((((int32_t)DEV_ERROR_CODE_MASK & i4Status) == (int32_t)CMD_DEV_ERROR) || ((int32_t)OCP_FL_SEND_MSG_TO_OPTIGA_ERROR == i4Status))
- {
- break;
- }
- if(((int32_t)OCP_FL_OK == i4Status))
- {
- break;
- }
- if(bRecvCCSRecord != CCS_RECORD_RECV)
- {
- wTotalMsgLen -= (uint16_t)dwFragLen + LENGTH_MSG_HEADER;
- if(wTotalMsgLen != 0x00)
- {
- sBlobMessage.prgbStream += dwFragLen + LENGTH_MSG_HEADER;
- }
- }
- else
- {
- wTotalMsgLen-= PpsMessageLayer->sMsg.wLen;
- }
- sBlobMessage.wLen = wTotalMsgLen;
- }
- }
- //Error checks to be added
- if(((int32_t)OCP_HL_MALLOC_FAILURE == i4Status) || ((int32_t)OCP_FL_MSG_MAXCOUNT == i4Status) || ((int32_t)OCP_HL_BUFFER_OVERFLOW == i4Status) ||
- ((int32_t)OCP_FL_MALLOC_FAILURE == i4Status) || (((int32_t)OCP_FL_ERROR == i4Status)) || ((int32_t)OCP_FL_INT_ERROR == i4Status) || ((int32_t)OCP_FL_HS_ERROR == i4Status))
- {
- break;
- }
- //Device error from Security Chip
- if((((int32_t)DEV_ERROR_CODE_MASK & i4Status) == (int32_t)CMD_DEV_ERROR) || ((int32_t)OCP_FL_SEND_MSG_TO_OPTIGA_ERROR == i4Status))
- {
- break;
- }
- //If complete flight is received come out of the loop
- if((int32_t)OCP_FL_OK == i4Status)
- {
- *PpbLastProcFlight = FLIGHTID((*PppsRFlightHead)->wFlightDecp);
- B_MULTIPLERECORD = 0;
- i4Status = (int32_t)OCP_HL_OK;
- break;
- }
- }
- //Malloc failure
- if(((int32_t)OCP_RL_MALLOC_FAILURE == i4Status))
- {
- //Exit the state machine
- break;
- }
- //Alert record received
- if((int32_t)OCP_RL_ALERT_RECEIVED == i4Status)
- {
- i4Status = Alert_ProcessMsg(&sMessage,&i4Alert);
- if(((int32_t)OCP_AL_FATAL_ERROR == i4Alert))
- {
- i4Status = i4Alert;
- break;
- }
- }
- //Sequence overflow
- if((int32_t)OCP_RL_SEQUENCE_OVERFLOW == i4Status)
- {
- //Exit the state machine
- break;
- }
- if(((int32_t)OCP_RL_NO_DATA != i4Status) && ((int32_t)OCP_FL_RXING != i4Status))
- {
- i4Status = (int32_t)OCP_HL_IGNORE_RECORD;
- }
- //If timeout expired return timeout error and exit if flight status is not efreceived
- if(!TIMEELAPSED(PdwBasetime, PbFlightTimeout) && (((*PppsRFlightHead)->sFlightStats.bFlightState < (uint8_t)efReceived) || ((*PppsRFlightHead)->sFlightStats.bFlightState == (uint8_t)efReReceive)
- || ((*PppsRFlightHead)->sFlightStats.bFlightState == (uint8_t)efProcessed)))
- {
- i4Status = (int32_t)OCP_HL_TIMEOUT;
- break;
- }
- //Dynamically setting the UDP timeout
- PpsMessageLayer->psConfigRL->sRL.psConfigTL->sTL.wTimeout = (uint16_t)((PbFlightTimeout*1000) - (uint32_t)(pal_os_timer_get_time_in_milliseconds() - PdwBasetime));
- //If multiple record is received in a single datagram loop back and receive other records
- }while(0 != B_MULTIPLERECORD);
- }while(FALSE);
- /// @cond hidden
- #undef B_MULTIPLERECORD
- /// @endcond
- return i4Status;
- }
- /**
- * Prepares Handshake message header<br>
- *
- * \param[in,out] PpbMsgHeader Pointer to buffer where handshake message header is formed
- * \param[in] PpsMsgInfo Pointer to #sMsgInfo_d
- *
- * \retval #OCP_HL_OK Successful execution
- \if ENABLE_NULL_CHECKS
- * \retval #OCP_HL_NULL_PARAM Null Parameters
- \endif
- */
- int32_t DtlsHS_PrepareMsgHeader(uint8_t* PpbMsgHeader, const sMsgInfo_d *PpsMsgInfo)
- {
- int32_t i4Status = (int32_t)OCP_HL_NULL_PARAM;
- do
- {
- #ifdef ENABLE_NULL_CHECKS
- if((NULL == PpbMsgHeader)||(NULL == PpsMsgInfo))
- {
- break;
- }
- #endif
- *(PpbMsgHeader+OFFSET_MSG_TYPE) = PpsMsgInfo->bMsgType;
- Utility_SetUint24(PpbMsgHeader+OFFSET_MSG_TOTAL_LENGTH, PpsMsgInfo->dwMsgLength);
- Utility_SetUint16(PpbMsgHeader+OFFSET_MSG_SEQUENCE,PpsMsgInfo->wMsgSequence);
- Utility_SetUint24(PpbMsgHeader+OFFSET_MSG_FRAGMENT_OFFSET,(uint32_t)0x00);
- Utility_SetUint24(PpbMsgHeader+OFFSET_MSG_FRAG_LENGTH, PpsMsgInfo->dwMsgLength);
- i4Status = (int32_t)OCP_HL_OK;
- }while(FALSE);
- return i4Status;
- }
- /**
- * Frees flight node.<br>
- *
- * \param[in,out] PppsFlightHead Pointer to beginning of flight list
- *
- */
- _STATIC_H void DtlsHS_ClearBuffer(sFlightDetails_d** PppsFlightHead)
- {
- sFlightDetails_d* pFlightTrav = *PppsFlightHead;
- sFlightDetails_d *pNodeToFreePtr = NULL;
- do
- {
- if(NULL != pFlightTrav)
- {
- if(NULL != pFlightTrav->sFlightStats.psMessageList)
- {
- DtlsHS_FreeMessageList(&(pFlightTrav->sFlightStats.psMessageList));
- }
- pNodeToFreePtr = pFlightTrav;
- pFlightTrav = pFlightTrav->psNext;
- OCP_FREE(pNodeToFreePtr);
- }
- }while(NULL != pFlightTrav);
- *PppsFlightHead = NULL ;
- }
- /**
- * Checks a flight is in the list or not.<br>
- *
- * \param[in] PpsFlightHead Pointer to list of Flights
- * \param[in] PbFlightID Flight number
- *
- * \retval #OCP_HL_OK Successful Execution
- * \retval #OCP_HL_ERROR Failure Execution
- */
- _STATIC_H int32_t DtlsHS_CheckFlightList(sFlightDetails_d* PpsFlightHead, uint8_t PbFlightID)
- {
- int32_t i4Status = (int32_t)OCP_HL_ERROR;
- sFlightDetails_d* psFlightList = PpsFlightHead;
- do
- {
- if(NULL == PpsFlightHead)
- {
- break;
- }
- do
- {
- if(FLIGHTID(psFlightList->wFlightDecp) == PbFlightID)
- {
- i4Status = (int32_t)OCP_HL_OK;
- }
- psFlightList = psFlightList->psNext;
- }while(NULL != psFlightList);
- }while(0);
- return i4Status;
- }
- /**
- * Appends a Flight Node to the end of the list.<br>
- *
- * \param[in,out] PppsFlightHead Pointer to Flight head node list
- * \param[in] PpsFlightNode Pointer to new Flight node
- *
- */
- _STATIC_H void DtlsHS_CreateFlightList(sFlightDetails_d** PppsFlightHead, sFlightDetails_d* PpsFlightNode)
- {
- sFlightDetails_d* psFlightTrav = *PppsFlightHead;
- do
- {
- if(NULL == psFlightTrav)
- {
- PpsFlightNode->psNext = NULL;
- *PppsFlightHead = PpsFlightNode;
- }
- else
- {
- while(psFlightTrav->psNext != NULL)
- {
- psFlightTrav = psFlightTrav->psNext;
- }
- psFlightTrav->psNext = PpsFlightNode;
- PpsFlightNode->psNext = NULL;
- }
- }while(0);
- }
- /**
- * Creates a flight node based on the last processed flight and inserts the node to the head node..<br>
- *
- * \param[in,out] PbLastProcFlight Last processed flight number
- * \param[in] PppsFlightHead Pointer to the flight head node
- * \param[in] PpsMessageLayer Pointer to message information
- *
- * \retval #OCP_HL_OK Successful Execution
- * \retval #OCP_HL_MALLOC_FAILURE Malloc failure
- * \retval #OCP_HL_ERROR Failure Execution
- */
- _STATIC_H int32_t DtlsHS_CreateFlightNode(uint8_t PbLastProcFlight, sFlightDetails_d** PppsFlightHead, sMsgLyr_d* PpsMessageLayer)
- {
- int32_t i4Status = (int32_t)OCP_HL_OK;
- sFlightDetails_d* pFlightNode = NULL;
- do
- {
- pFlightNode = (sFlightDetails_d*)OCP_MALLOC(sizeof(sFlightDetails_d));
- if(NULL == pFlightNode)
- {
- i4Status = (int32_t)OCP_HL_MALLOC_FAILURE;
- break;
- }
- else
- {
- if((int32_t)OCP_FL_ERROR == DtlsHS_FlightNodeInit(pFlightNode, PbLastProcFlight))
- {
- OCP_FREE(pFlightNode);
- i4Status = (int32_t)OCP_HL_ERROR;
- break;
- }
- i4Status = pFlightNode->pFlightHndlr(PbLastProcFlight, &pFlightNode->sFlightStats, PpsMessageLayer);
- if(OCP_FL_OK != i4Status)
- {
- break;
- }
- DtlsHS_CreateFlightList(PppsFlightHead, pFlightNode);
- i4Status = (int32_t)OCP_HL_OK;
- }
- }while(0);
- return i4Status;
- }
- /**
- * Initialises the Flight List for Send.<br>
- *
- * \param[in] PbLastProcFlight Last processed flight ID
- * \param[in,out] PppsFlightHead Pointer to list of Flight nodes
- * \param[in] PpsMessageLayer Pointer to message information
- *
- * \retval #OCP_HL_OK Successful Execution
- * \retval #OCP_HL_ERROR Failure Execution
- */
- _STATIC_H int32_t DtlsHS_SFlightInitialise(uint8_t PbLastProcFlight, sFlightDetails_d** PppsFlightHead, sMsgLyr_d* PpsMessageLayer)
- {
- sFlightDetails_d* pFlightNode = NULL;
- sFlightDetails_d* pFlightTrav ;
- int32_t i4Status = (int32_t)OCP_HL_OK;
- do
- {
- #ifdef ENABLE_NULL_CHECKS
- if((NULL == PppsFlightHead) || (NULL == PpsMessageLayer) ||(NULL == PpsMessageLayer->psConfigRL->pfSend))
- {
- i4Status = (int32_t)OCP_HL_NULL_PARAM;
- break;
- }
- #endif
- pFlightTrav = *PppsFlightHead;
- if((NULL != pFlightTrav))
- {
- do
- {
- pFlightNode = pFlightTrav;
- pFlightTrav = pFlightTrav->psNext;
- if(PbLastProcFlight > FLIGHTID(pFlightNode->wFlightDecp))
- {
- if((int32_t)OCP_FL_OK == pFlightNode->pFlightHndlr(PbLastProcFlight, &pFlightNode->sFlightStats, PpsMessageLayer))
- {
- if(efDone == (eFlightState_d)pFlightNode->sFlightStats.bFlightState)
- {
- DtlsHS_FreeFlightNode(FLIGHTID(pFlightNode->wFlightDecp), PppsFlightHead);
- }
- }
- }
- else if(PbLastProcFlight == FLIGHTID(pFlightNode->wFlightDecp))
- {
- if(efTransmitted == (eFlightState_d)pFlightNode->sFlightStats.bFlightState)
- {
- pFlightNode->sFlightStats.bFlightState = (uint8_t)efReTransmit;
- }
- }
- }while(NULL != pFlightTrav);
- }
- //Create Flight List
- if(IsEVEN_FLIGHT(PbLastProcFlight))
- {
- if((int32_t)OCP_HL_ERROR == DtlsHS_CheckFlightList(*PppsFlightHead, PbLastProcFlight+1))
- {
- i4Status = DtlsHS_CreateFlightNode(PbLastProcFlight, PppsFlightHead, PpsMessageLayer);
- if(OCP_HL_OK != i4Status)
- {
- break;
- }
- }
- }
- }while(0);
- return i4Status;
- }
- /**
- * Initialises the Flight List for Receive.<br>
- *
- * \param[in] PbLastProcFlight Last processed flight ID
- * \param[in,out] PppsFlightHead Pointer to list of Flight nodes
- * \param[in] PpsMessageLayer Pointer to message information
- *
- * \retval #OCP_HL_OK Successful Execution
- * \retval #OCP_HL_ERROR Failure Execution
- */
- _STATIC_H int32_t DtlsHS_RFlightInitialise(uint8_t PbLastProcFlight, sFlightDetails_d** PppsFlightHead, sMsgLyr_d* PpsMessageLayer)
- {
- uint8_t bFlightA = 0;
- uint8_t bFlightB = 0;
- int32_t i4Status = (int32_t)OCP_HL_OK;
- do
- {
- //Create Flight List
- 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;
- }
- else
- {
- i4Status = (int32_t)OCP_HL_ERROR;
- break;
- }
- if((int32_t)OCP_HL_ERROR == DtlsHS_CheckFlightList(*PppsFlightHead, bFlightA))
- {
- //CreateFlightNode expects last processed flight ID, hence flight corrected with offset 1
- i4Status = DtlsHS_CreateFlightNode(bFlightA-1, PppsFlightHead, PpsMessageLayer);
- if(OCP_HL_OK != i4Status)
- {
- break;
- }
- if((int32_t)OCP_HL_ERROR == DtlsHS_CheckFlightList(*PppsFlightHead, bFlightB))
- {
- //CreateFlightNode expects last processed flight ID, hence flight corrected with offset 1
- i4Status = DtlsHS_CreateFlightNode(bFlightB-1, PppsFlightHead, PpsMessageLayer);
- if(OCP_HL_OK != i4Status)
- {
- break;
- }
- }
- }
- else if((uint8_t)efProcessed ==(*PppsFlightHead)->sFlightStats.bFlightState)
- {
- if((int32_t)OCP_HL_ERROR == DtlsHS_CheckFlightList(*PppsFlightHead, bFlightB))
- {
- //CreateFlightNode expects last processed flight ID, hence flight corrected with offset 1
- i4Status = DtlsHS_CreateFlightNode(bFlightB-1, PppsFlightHead, PpsMessageLayer);
- if(OCP_HL_OK != i4Status)
- {
- break;
- }
- }
- }
- }while(0);
- return i4Status;
- }
- /**
- * Processes the send Flight.<br>
- *
- * \param[in] PpbLastProcFlight Pointer to last processed flight ID
- * \param[in,out] PpsSFlightHead Pointer to list of Send Flight list
- * \param[in] PpsMessageLayer Message layer information
- *
- * \retval #OCP_HL_OK Successful Execution
- * \retval #OCP_HL_ERROR Failure Execution
- * \retval #OCP_FL_NOT_LISTED Flight not found in the list
- */
- _STATIC_H int32_t DtlsHS_SFlightProcess(uint8_t *PpbLastProcFlight, sFlightDetails_d* PpsSFlightHead, sMsgLyr_d* PpsMessageLayer)
- {
- int32_t i4Status = (int32_t)OCP_HL_ERROR;
- sFlightDetails_d* pSFlightTrav = PpsSFlightHead;
- do
- {
- if(NULL == pSFlightTrav)
- {
- i4Status = (int32_t)OCP_FL_NOT_LISTED;
- break;
- }
- do
- {
- i4Status = pSFlightTrav->pFlightHndlr(*PpbLastProcFlight, &pSFlightTrav->sFlightStats, PpsMessageLayer);
- if((int32_t)OCP_FL_OK != i4Status)
- {
- break;
- }
- if((uint8_t)efTransmitted == pSFlightTrav->sFlightStats.bFlightState)
- {
- *PpbLastProcFlight = FLIGHTID(pSFlightTrav->wFlightDecp);
- }
- pSFlightTrav = pSFlightTrav->psNext;
- }while(NULL != pSFlightTrav);
- if((int32_t)OCP_FL_OK == i4Status)
- {
- i4Status = (int32_t)OCP_HL_OK;
- }
- }while(0);
- return i4Status;
- }
- /**
- * Processes the receive Flight.<br>
- * Under some erroneous conditions, error codes from respective layer can also be returned.<br>
- *
- * \param[in] PpbLastProcFlight pointer to the last processed flight ID
- * \param[in] PppsRFlightHead Pointer to list of receivable Flight list
- * \param[in] PpsMessageLayer Message layer information
- * \param[in] PbFlightTimeout Flight time out value
- *
- * \retval #OCP_HL_OK Successful Execution
- * \retval #OCP_HL_ERROR Failure Execution
- \if ENABLE_NULL_CHECKS
- * \retval #OCP_HL_NULL_PARAM NULL parameters
- \endif
- */
- _STATIC_H int32_t DtlsHS_RFlightProcess(uint8_t* PpbLastProcFlight, sFlightDetails_d** PppsRFlightHead, sMsgLyr_d* PpsMessageLayer, uint8_t PbFlightTimeout)
- {
- int32_t i4Status = (int32_t)OCP_HL_ERROR;
- uint32_t dwBasetime;
- do
- {
- #ifdef ENABLE_NULL_CHECKS
- //NULL check
- if((NULL == PppsRFlightHead) || (NULL == PpsMessageLayer) || (NULL == PpsMessageLayer->psConfigRL) || (NULL == PpsMessageLayer->psConfigRL->pfRecv))
- {
- i4Status = (int32_t)OCP_HL_NULL_PARAM;
- break;
- }
- #endif
- //Start value for the Flight timeout
- dwBasetime = (uint32_t)pal_os_timer_get_time_in_milliseconds();
- do
- {
- i4Status = DtlsHS_ReceiveFlightMessage(PpbLastProcFlight, PppsRFlightHead, PpsMessageLayer, PbFlightTimeout, dwBasetime);
- //If timeout expired and complete flight is not received then return timeout error and come out of loop
- if((!TIMEELAPSED(dwBasetime, PbFlightTimeout) || ((int32_t)OCP_HL_TIMEOUT == i4Status)) && \
- ((int32_t)OCP_HL_OK != i4Status) && (((*PppsRFlightHead)->sFlightStats.bFlightState < (uint8_t)efReceived) ||
- ((*PppsRFlightHead)->sFlightStats.bFlightState == (uint8_t)efReReceive) || ((*PppsRFlightHead)->sFlightStats.bFlightState == (uint8_t)efProcessed)))
- {
- i4Status = (int32_t)OCP_HL_TIMEOUT;
- break;
- }
- //If complete flight message is not received or if no data is received from record layer loop back to get remaining message
- }while((i4Status == (int32_t)OCP_FL_RXING) || (i4Status == (int32_t)OCP_RL_NO_DATA) || (i4Status == (int32_t)OCP_HL_IGNORE_RECORD));
- }while(FALSE);
- return i4Status;
- }
- /**
- * Sends Handshake message to the server.Fragments the message if the message is greater than PMTU.<br>
- * Under some erroneous conditions, error codes from respective Layer can also be returned. <br>
- *
- * \param[in] PpsMsgPtr pointer to the structure containing message information
- * \param[in] PpsMessageLayer Pointer to the structure containing list of message
- *
- * \retval #OCP_HL_OK Successful Execution
- * \retval #OCP_HL_ERROR Failure Execution
- */
- int32_t DtlsHS_FSendMessage(const sMsgInfo_d* PpsMsgPtr, const sMsgLyr_d* PpsMessageLayer)
- {
- int32_t i4Status = (int32_t)OCP_HL_ERROR;
- uint8_t* pbTotalFragMem = NULL;
- sFragmentMsg_d sFragmentMsg;
- sbBlob_d sMessage;
- sbBlob_d sbBlobMessage;
- /// @cond hidden
- #define CHANGE_CIPHERSPEC_MSGSIZE 1
- /// @endcond
- do{
- if(PpsMsgPtr->bMsgType == (uint8_t)eChangeCipherSpec)
- {
- pbTotalFragMem = (uint8_t*)OCP_MALLOC(CHANGE_CIPHERSPEC_MSGSIZE + LENGTH_RL_HEADER);
- if(NULL == pbTotalFragMem)
- {
- i4Status = (int32_t)OCP_HL_MALLOC_FAILURE;
- break;
- }
- OCP_MEMCPY((pbTotalFragMem + LENGTH_RL_HEADER), PpsMsgPtr->psMsgHolder, PpsMsgPtr->dwMsgLength);
- PpsMessageLayer->psConfigRL->sRL.bContentType = CONTENTTYPE_CIPHER_SPEC;
- PpsMessageLayer->psConfigRL->sRL.bMemoryAllocated = TRUE;
- //Send Data
- i4Status = PpsMessageLayer->psConfigRL->pfSend(&PpsMessageLayer->psConfigRL->sRL,
- pbTotalFragMem,(uint16_t)(PpsMsgPtr->dwMsgLength + LENGTH_RL_HEADER));
- if(OCP_RL_OK != i4Status)
- {
- break;
- }
- i4Status = (int32_t)OCP_HL_OK;
- }
- else
- {
- //Assign pointer of the buffer where the message is buffered
- sbBlobMessage.prgbStream = PpsMsgPtr->psMsgHolder;
- sbBlobMessage.wLen = (uint16_t)PpsMsgPtr->dwMsgLength + OVERHEAD_LEN;
- //Move the pointer to the Handshake message header location
- sbBlobMessage.prgbStream+= (OVERHEAD_LEN - MSG_HEADER_LEN);
- sbBlobMessage.wLen-= (OVERHEAD_LEN - MSG_HEADER_LEN);
- //If the length of the message is within the given PMTU value
- if(sbBlobMessage.wLen <= PpsMessageLayer->wMaxPmtu - UDP_RECORD_OVERHEAD)
- {
- //Assign Buffer
- pbTotalFragMem = (uint8_t*)OCP_MALLOC(sbBlobMessage.wLen + LENGTH_RL_HEADER);
- if(NULL == pbTotalFragMem)
- {
- i4Status = (int32_t)OCP_HL_MALLOC_FAILURE;
- break;
- }
- Utility_Memmove(pbTotalFragMem + LENGTH_RL_HEADER, sbBlobMessage.prgbStream, sbBlobMessage.wLen);
- PpsMessageLayer->psConfigRL->sRL.bContentType = CONTENTTYPE_HANDSHAKE;
- PpsMessageLayer->psConfigRL->sRL.bMemoryAllocated = TRUE;
- //Send Data
- i4Status = PpsMessageLayer->psConfigRL->pfSend(&PpsMessageLayer->psConfigRL->sRL,
- pbTotalFragMem,sbBlobMessage.wLen + LENGTH_RL_HEADER);
- if(OCP_RL_OK != i4Status)
- {
- break;
- }
- i4Status = (int32_t)OCP_HL_OK;
- break;
- }
- else
- {
- sFragmentMsg.psCompleteMsg = &sbBlobMessage;
- sFragmentMsg.wFragmentSize = PpsMessageLayer->wMaxPmtu - UDP_RECORD_OVERHEAD;
- //Assign Buffer
- pbTotalFragMem = (uint8_t*)OCP_MALLOC(sFragmentMsg.wFragmentSize + LENGTH_RL_HEADER);
- if(NULL == pbTotalFragMem)
- {
- i4Status = (int32_t)OCP_HL_MALLOC_FAILURE;
- break;
- }
- sFragmentMsg.psMsgFrag = &sMessage;
- sMessage.prgbStream = pbTotalFragMem + LENGTH_RL_HEADER;
- sMessage.wLen = sFragmentMsg.wFragmentSize;
- sFragmentMsg.wRemainingLen = sbBlobMessage.wLen - LENGTH_MSG_HEADER;
- sFragmentMsg.wCurrentOffset = 0;
- do
- {
- i4Status = (int32_t)OCP_HL_ERROR;
- //Fragment the message
- i4Status = DtlsHS_FragmentMsg(&sFragmentMsg);
- if(OCP_HL_OK != i4Status)
- {
- break;
- }
- PpsMessageLayer->psConfigRL->sRL.bContentType = CONTENTTYPE_HANDSHAKE;
- PpsMessageLayer->psConfigRL->sRL.bMemoryAllocated = TRUE;
- //Send Data
- i4Status = PpsMessageLayer->psConfigRL->pfSend(&PpsMessageLayer->psConfigRL->sRL,
- pbTotalFragMem,sMessage.wLen + LENGTH_RL_HEADER);
- if(OCP_RL_OK != i4Status)
- {
- break;
- }
- i4Status = (int32_t)OCP_HL_OK;
- }while(0 != sFragmentMsg.wRemainingLen);
- }
- }
- }while(FALSE);
- //Clear the message header list
- if(NULL != pbTotalFragMem)
- {
- OCP_FREE(pbTotalFragMem);
- }
- /// @cond hidden
- #undef CHANGE_CIPHERSPEC_MSGSIZE
- /// @endcond
- return i4Status;
- }
- /**
- *
- * Process and validates Handshake message header.<br>
- *
- * \param[in] PsBlobMessage Pointer to a blob with Message including header.
- *
- * \retval #OCP_HL_OK Successful execution
- * \retval #OCP_HL_ERROR Failure in execution
- * \retval #OCP_HL_LEN_MISMATCH Fragment length mismatch
- * \retval #OCP_HL_TOTALLEN_MISMATCH Total length mismatch
- * \retval #OCP_HL_BUFFER_OVERFLOW Message length exceeded the limit
- *
- */
- int32_t DtlsHS_ProcHeader(sbBlob_d PsBlobMessage)
- {
- int32_t i4Status = (int32_t)OCP_HL_ERROR;
- uint32_t dwFragLen;
- uint32_t dwFragOffset;
- do
- {
- if(!((((uint8_t)eServer_Certificate <=*PsBlobMessage.prgbStream) && ((uint8_t)eServer_Hello_Done >= *PsBlobMessage.prgbStream)) ||
- ((uint8_t)eServer_Hello == *PsBlobMessage.prgbStream) || ((uint8_t)eHello_Verify_Request == *PsBlobMessage.prgbStream)||
- ((uint8_t)eServer_Finished == *PsBlobMessage.prgbStream)))
- {
- i4Status = (int32_t)OCP_HL_INVALID_MSGTYPE;
- break;
- }
- dwFragLen = Utility_GetUint24(PsBlobMessage.prgbStream + OFFSET_MSG_FRAG_LENGTH);
- //check if length fragment len + hmsg header is less than total stream length
- if((dwFragLen + LENGTH_MSG_HEADER) > PsBlobMessage.wLen)
- {
- //Length indicated by fragment length not available
- i4Status = (int32_t)OCP_HL_LEN_MISMATCH;
- break;
- }
- //Fragment offset,3 bytes
- dwFragOffset = Utility_GetUint24(PsBlobMessage.prgbStream+OFFSET_MSG_FRAGMENT_OFFSET);
- if((dwFragOffset+ dwFragLen) > Utility_GetUint24(PsBlobMessage.prgbStream+OFFSET_MSG_TOTAL_LENGTH))
- {
- i4Status = (int32_t)OCP_HL_TOTALLEN_MISMATCH;
- break;
- }
- i4Status = (int32_t)OCP_HL_OK;
- }while(0);
- return i4Status;
- }
- /**
- *
- * Validates the Hello request message.<br>
- *
- * \param[in] PprgbData Pointer to the Hello Request Message.
- * \param[in] PwLen Length of the Message.
- *
- * \retval #OCP_HL_OK Successful execution
- * \retval #OCP_HL_INVALID_HRMSG Invalid Handshake message
- *
- */
- int32_t DtlsHS_VerifyHR(const uint8_t* PprgbData, uint16_t PwLen)
- {
- int32_t i4Status = (int32_t)OCP_HL_INVALID_HRMSG;
- uint32_t dwFragLen;
- uint32_t dwFragOffset;
- uint32_t dwTotalLen;
- do
- {
- if(0x00 != *PprgbData)
- {
- //Invalid Msg type
- break;
- }
- //Fragment Length,3 bytes
- dwFragLen = Utility_GetUint24(PprgbData + OFFSET_MSG_FRAG_LENGTH);
- //Fragment offset,3 bytes
- dwFragOffset = Utility_GetUint24(PprgbData + OFFSET_MSG_FRAGMENT_OFFSET);
- //Total Length,3 bytes
- dwTotalLen = Utility_GetUint24(PprgbData + OFFSET_MSG_TOTAL_LENGTH);
- if(PwLen != LENGTH_MSG_HEADER)
- {
- //Incorrect length
- break;
- }
- if(0x00 != Utility_GetUint24(PprgbData + OFFSET_MSG_SEQUENCE))
- {
- //Incorrect Msg sequence
- break;
- }
- //check if length fragment len + fragment 0ffset + total len is less than total stream length
- if((dwFragLen + dwFragOffset + dwTotalLen) > 0x00)
- {
- //Length fields indicated in the message are incorrect
- break;
- }
- i4Status = (int32_t)OCP_HL_OK;
- }while(0);
- return i4Status;
- }
- /**
- * Performs a DTLS handshake.<br>
- * The state machine is configurable as a client or as a server based on the selected protocol.Currently server configuration is not supported.<br>
- *
- * \param[in,out] PphHandshake Pointer to structure containing data to perform handshake
- *
- * \retval #OCP_HL_OK Successful Execution
- * \retval #OCP_HL_ERROR Failure Execution
- */
- int32_t DtlsHS_Handshake(sHandshake_d* PphHandshake)
- {
- /// @cond hidden
- #define STATE_SEND 0x11
- #define STATE_RECV 0x22
- #define STATE_EXIT 0x33
- /// @endcond
- uint8_t bLastProcFlight=0;
- uint8_t bSmMode = STATE_RECV;
- uint8_t bIndex;
- uint8_t bFlightTimeout = DEFAULT_TIMEOUT;
- sFlightDetails_d* pSFlightHead=NULL;
- sFlightDetails_d* pRFlightHead=NULL;
- sMsgLyr_d sMessageLayer;
- int32_t i4Status = (int32_t)OCP_HL_ERROR;
- if(eClient == PphHandshake->eMode)
- {
- bSmMode = STATE_SEND;
- }
- else
- {
- bSmMode = STATE_EXIT;
- }
- //Populate structure to be passed to MessageLayer
- sMessageLayer.psConfigRL = PphHandshake->psConfigRL;
- sMessageLayer.wSessionID = PphHandshake->wSessionOID;
- ((sRecordLayer_d*)PphHandshake->psConfigRL->sRL.phRLHdl)->wSessionKeyOID = PphHandshake->wSessionOID;
- sMessageLayer.wMaxPmtu = PphHandshake->wMaxPmtu;
- sMessageLayer.wOIDDevCertificate = PphHandshake->wOIDDevCertificate;
- sMessageLayer.pfGetUnixTIme = PphHandshake->pfGetUnixTIme;
- sMessageLayer.eFlight = eFlight0;
- sMessageLayer.dwRMsgSeqNum = 0xFFFFFFFF;
- sMessageLayer.sTLMsg.prgbStream = (uint8_t*)OCP_MALLOC(TLBUFFER_SIZE);
- if(NULL == sMessageLayer.sTLMsg.prgbStream)
- {
- i4Status = (int32_t)OCP_LIB_MALLOC_FAILURE;
- bSmMode = STATE_EXIT;
- }
- sMessageLayer.sTLMsg.wLen = (uint16_t)TLBUFFER_SIZE;
- for(bIndex = 0; bIndex < (sizeof(sMessageLayer.rgbOptMsgList)/sizeof(sMessageLayer.rgbOptMsgList[0])); bIndex++)
- {
- sMessageLayer.rgbOptMsgList[bIndex] = 0xFF;
- }
- //Start state machine
- do
- {
- switch(bSmMode)
- {
- case STATE_SEND:
- {
- i4Status = SEND_FLIGHT_INITIALIZE(bLastProcFlight, &pSFlightHead, &sMessageLayer);
- if((int32_t)OCP_HL_OK != i4Status)
- {
- if(PphHandshake->eAuthState == eAuthStarted)
- {
- PphHandshake->fFatalError = TRUE;
- SEND_ALERT(sMessageLayer.psConfigRL, i4Status);
- }
- DtlsHS_ClearBuffer(&pRFlightHead);
- DtlsHS_ClearBuffer(&pSFlightHead);
- bSmMode = STATE_EXIT;
- break;
- }
- i4Status = SEND_FLIGHT_PROCESS(&bLastProcFlight, pSFlightHead, &sMessageLayer);
- if(OCP_HL_OK == i4Status)
- {
- if(PphHandshake->eAuthState == eAuthInitialised)
- {
- PphHandshake->eAuthState = eAuthStarted;
- }
- bSmMode = STATE_RECV;
- }
- else
- {
- if(PphHandshake->eAuthState == eAuthStarted)
- {
- PphHandshake->fFatalError = TRUE;
- SEND_ALERT(sMessageLayer.psConfigRL, i4Status);
- }
- bSmMode = STATE_EXIT;
- DtlsHS_ClearBuffer(&pRFlightHead);
- DtlsHS_ClearBuffer(&pSFlightHead);
- }
- break;
- }
- case STATE_RECV:
- {
- i4Status = REC_FLIGHT_INITIALIZE(bLastProcFlight, &pRFlightHead, &sMessageLayer);
- if((int32_t)OCP_HL_OK != i4Status)
- {
- PphHandshake->fFatalError = TRUE;
- DtlsHS_ClearBuffer(&pRFlightHead);
- DtlsHS_ClearBuffer(&pSFlightHead);
- SEND_ALERT(sMessageLayer.psConfigRL, i4Status);
- bSmMode = STATE_EXIT;
- break;
- }
- i4Status = REC_FLIGHT_PROCESS(&bLastProcFlight, &pRFlightHead, &sMessageLayer, bFlightTimeout);
- if ((int32_t)OCP_HL_TIMEOUT == i4Status)
- {
- bFlightTimeout = ((bFlightTimeout*2) == 64)?(uint8_t)MAX_FLIGHT_TIMEOUT: (uint8_t)(bFlightTimeout*2);
- //Check for Maximum Flight timeout value
- if(bFlightTimeout > MAX_FLIGHT_TIMEOUT)
- {
- PphHandshake->fFatalError = FALSE;
- DtlsHS_ClearBuffer(&pRFlightHead);
- DtlsHS_ClearBuffer(&pSFlightHead);
- bSmMode = STATE_EXIT;
- break;
- }
- sMessageLayer.psConfigRL->sRL.psConfigTL->sTL.wTimeout = (uint16_t)(bFlightTimeout * 1000);
- bSmMode = STATE_SEND;
- }
- //Fatal Alert received
- else if((int32_t)OCP_AL_FATAL_ERROR == i4Status)
- {
- PphHandshake->fFatalError = FALSE;
- DtlsHS_ClearBuffer(&pRFlightHead);
- DtlsHS_ClearBuffer(&pSFlightHead);
- bSmMode = STATE_EXIT;
- }
- else if(OCP_HL_OK != i4Status)
- {
- PphHandshake->fFatalError = TRUE;
- SEND_ALERT(sMessageLayer.psConfigRL, i4Status);
- DtlsHS_ClearBuffer(&pRFlightHead);
- DtlsHS_ClearBuffer(&pSFlightHead);
- bSmMode = STATE_EXIT;
- }
- else if(bLastProcFlight != (uint8_t)eFlight6)
- {
- bFlightTimeout = DEFAULT_TIMEOUT;
- //Initial UDP Time out
- sMessageLayer.psConfigRL->sRL.psConfigTL->sTL.wTimeout = 200;
- Dtls_SlideWindow(&sMessageLayer.psConfigRL->sRL, PphHandshake->eAuthState);
- bSmMode = STATE_SEND;
- }
- else
- {
- //state machine is over
- PphHandshake->eAuthState = eAuthCompleted;
- Dtls_SlideWindow(&sMessageLayer.psConfigRL->sRL, PphHandshake->eAuthState);
- PphHandshake->fFatalError = FALSE;
- bSmMode = STATE_EXIT;
- DtlsHS_ClearBuffer(&pRFlightHead);
- DtlsHS_ClearBuffer(&pSFlightHead);
- }
- break;
- }
- default:
- {
- PphHandshake->fFatalError = TRUE;
- bSmMode = STATE_EXIT;
- }
- break;
- }
- }while(STATE_EXIT != bSmMode);
- /// @cond hidden
- #undef STATE_SEND
- #undef STATE_RECV
- #undef STATE_EXIT
- /// @endcond
- if(sMessageLayer.sTLMsg.prgbStream != NULL)
- {
- OCP_FREE(sMessageLayer.sTLMsg.prgbStream);
- }
- return i4Status;
- }
- /**
- * @}
- */
- #endif /*MODULE_ENABLE_DTLS_MUTUAL_AUTH*/
|