1509 lines
56 KiB
C
1509 lines
56 KiB
C
/**
|
|
* 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*/
|