initial commit

This commit is contained in:
jhChun
2026-04-08 16:58:54 +09:00
commit 82e33d8bf9
2578 changed files with 1590432 additions and 0 deletions
+480
View File
@@ -0,0 +1,480 @@
/**
* 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 AlertProtocol.c
*
* \brief This file implements the DTLS Alert Protocol.
*
* \addtogroup grMutualAuth
* @{
*/
#include "optiga/dtls/DtlsRecordLayer.h"
#include "optiga/dtls/AlertProtocol.h"
#include "optiga/dtls/DtlsFlightHandler.h"
#ifdef MODULE_ENABLE_DTLS_MUTUAL_AUTH
/// @cond hidden
/// Maximum size of Alert Message
#define LENGTH_ALERT_MSG 0x02
/// Offset for Alert Message
#define OFFSET_ALERT_MSG 0x01
//Device Error codes
///Invalid OID
#define INVALID_OID 0x01
///Invalid param field in the command
#define INVALID_PARAM_FIELD 0x03
///Invalid length field in the command
#define INVALID_LENGTH_FIELD 0x04
///Invalid parameter in the data field
#define INVALID_PARAMETER_DATA_FIELD 0x05
///Device internal error
#define INTERNAL_PROCESS_ERROR 0x06
///Invalid command field
#define INVALID_COMMAND_FIELD 0x0A
///Command out of sequence
#define COMMAND_OUT_SEQUENCE 0x0B
///Command not available
#define COMMAND_NOT_AVAILABLE 0x0C
///Illegal parameter in the Handshake header
#define INVALID_HANDSHAKE_MESSAGE 0x21
///DTLS Protocol version mismatch
#define VERSION_MISMATCH 0x22
///Cipher suite mismatch between client and server
#define INSUFFICIENT_UNSUPPORTED_CIPHERSUITE 0x23
///Unsupported extension
#define UNSUPPORTED_EXTENSION 0x24
///Unsupported parameters
#define UNSUPPORTED_PARAMETERS 0x25
///Invalid Trust Anchor
#define INVALID_TRUST_ANCHOR 0x26
///Trust Anchor expired
#define TRUST_ANCHOR_EXPIRED 0x27
///Unsupported Trust Anchor
#define UNSUPPORTED_TRUST_ANCHOR 0x28
///Invalid Certificate format
#define INVALID_CERTIFICATE_FORMAT 0x29
///Unsupported certificate/Unsupported Hash or Sign Algorithm
#define UNSUPPORTED_CERTIFICATE_HASHSIGN 0x2A
///Certificate expired
#define CERTIFICATE_EXPIRED 0x2B
///Signature verification failed
#define SIGNATURE_VERIFICATION_FAILURE 0x2C
/**
* \brief DTLS Alert Level.
*/
typedef enum eAlertLevel_d
{
///Connection can continue
eWARNING = 0x01,
///Terminate the connection
eFATAL = 0x02
}eAlertLevel_d;
/**
* \brief DTLS Alert Types.
*/
typedef enum eAlertMsg_d
{
/// Notifies the recipient that the sender will not send any more messages on this connection
eCLOSE_NOTIFY = 0x00,
/// Inappropriate message was received
eUNEXPECTED_MESSAGE = 0x0A ,
/// Notifies record is received with an incorrect MAC
eBAD_RECORD_MAC = 0x14,
///Decryption Failure
eDECRYPTION_FAILURE = 0x15,
/// Notifies record received length is more than 2^14+2048
eRECORD_OVERFLOW = 0x16,
/// Notifies decompression function received improper input
eDECOMPRESSION_FAILURE = 0x1E,
/// Indicates sender was not able to negotiate with the security parameters
eHANDSHAKE_FAILURE = 0x28,
/// Notifies certificate was corrupt
eBAD_CERTIFICATE = 0x2A,
///No certificate
eNO_CERTIFICATE = 0x29,
/// Notifies certificate was unsupported type
eUNSUPPORTED_CERTIFICATE = 0x2B,
/// Notifies the certificate was revoked by signer
eCERTIFICATE_REVOKED = 0x2C,
/// Indicates the certificate is Expired
eCERTIFICATE_EXPIRED = 0x2D,
/// Indicates unknown issue in processing the certificate
eCERTIFICATE_UNKNOWN = 0x2E,
/// Notifies field in handshake is out of range or inconsistent
eILLEGAL_PARAMETER = 0x2F,
/// Indicates CA certificate could not be found or not matched
eUNKNOWN_CA = 0x30,
/// Notifies the access denied
eACCESS_DENIED = 0x31,
/// Notifies message could not be decoded or some field is missing
eDECODE_ERROR = 0x32,
/// Notifies cryptographic operation failed
eDECRYPT_ERROR = 0x33,
///Export restriction
eEXPORT_RESTRICTION = 0x3C,
/// Notifies protocol version attempted to negotiate is not supported
ePROTOCOL_VERSION = 0x46,
/// Notifies negotiation has failed specifically because the server requires ciphers more secure
eINSUFFICIENT_SECURITY = 0x47,
/// Notifies error is unrelated to peer or protocol
eINTERNAL_ERROR = 0x50,
/// Indicates that the handshake is canceled
eUSER_CANCELLED = 0x5A,
/// Notifies that the renegotiation is not initiated
eNO_RENEGOTIATION = 0x64,
/// Notifies unsupported extension was sent to server
eUNSUPPORTED_EXTENSION = 0x6E
}eAlertMsg_d;
/// @endcond
/**
* \brief Maps the Alert types and level to error code.<br>
*/
_STATIC_H int32_t DtlsAlertErrorMapping(const sbBlob_d* PpsAlertMsg, int32_t* Ppi4ErrorCode);
//Alert protocol is defined by default. To disable define DISABLE_ALERT
#ifndef DISABLE_ALERT
/**
* \brief Maps the error code to Alert types and level.<br>
*/
_STATIC_H Void DtlsErrorAlertMapping(int32_t Pi4ErrorCode, sbBlob_d* PpsAlertMsg);
/**
* \brief Forms the alert message based on the given internal error code.<br>
*/
_STATIC_H Void Alert_FormMsg(int32_t Pi4ErrorCode,sbBlob_d* PpsAlertMsg);
/**
* Maps the error code to Alert types and level.<br>
*
* \param[in] Pi4ErrorCode DTLS Internal error code
* \param[in,out] PpsAlertMsg Pointer to a blob containing Alert message as per DTLS Specification
*
*/
_STATIC_H Void DtlsErrorAlertMapping(int32_t Pi4ErrorCode, sbBlob_d* PpsAlertMsg)
{
do
{
if((int32_t)OCP_LIB_NO_RENEGOTIATE == Pi4ErrorCode)
{
*PpsAlertMsg->prgbStream = (uint8_t)eWARNING;
}
else
{
*PpsAlertMsg->prgbStream = (uint8_t)eFATAL;
}
//Set the Blob length to Alert message length
PpsAlertMsg->wLen = LENGTH_ALERT_MSG;
switch(Pi4ErrorCode)
{
case (int32_t)OCP_RL_ERROR:
case (int32_t)OCP_FL_MSG_MAXCOUNT:
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eCLOSE_NOTIFY;
break;
case (int32_t)(CMD_DEV_ERROR | INVALID_HANDSHAKE_MESSAGE):
case (int32_t)(CMD_DEV_ERROR | UNSUPPORTED_PARAMETERS):
case (int32_t)(CMD_DEV_ERROR | VERSION_MISMATCH):
case (int32_t) OCP_FL_HS_ERROR:
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eILLEGAL_PARAMETER;
break;
case (int32_t)OCP_LIB_NO_RENEGOTIATE:
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eNO_RENEGOTIATION;
break;
case (int32_t)(CMD_DEV_ERROR | INSUFFICIENT_UNSUPPORTED_CIPHERSUITE):
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eINSUFFICIENT_SECURITY;
break;
case (int32_t)(CMD_DEV_ERROR | UNSUPPORTED_EXTENSION):
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eUNSUPPORTED_EXTENSION;
break;
case (int32_t)(CMD_DEV_ERROR | INVALID_TRUST_ANCHOR):
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eUNKNOWN_CA;
break;
case (int32_t)(CMD_DEV_ERROR | TRUST_ANCHOR_EXPIRED):
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eCERTIFICATE_EXPIRED;
break;
case (int32_t)(CMD_DEV_ERROR | UNSUPPORTED_TRUST_ANCHOR):
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eUNSUPPORTED_CERTIFICATE;
break;
case (int32_t)(CMD_DEV_ERROR | INVALID_CERTIFICATE_FORMAT):
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eBAD_CERTIFICATE;
break;
case (int32_t)(CMD_DEV_ERROR | UNSUPPORTED_CERTIFICATE_HASHSIGN):
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eUNSUPPORTED_CERTIFICATE;
break;
case (int32_t)(CMD_DEV_ERROR | CERTIFICATE_EXPIRED):
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eCERTIFICATE_EXPIRED;
break;
case (int32_t)(CMD_DEV_ERROR | SIGNATURE_VERIFICATION_FAILURE):
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eDECRYPT_ERROR;
break;
default:
//lint -e750 "The remaining errors returned by the security chip is mapped to Internal error Alert"
//Prepare Alert Message
*(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG) = (uint8_t)eINTERNAL_ERROR;
break;
}
}while(0);
}
/**
* Forms the alert message based on the given internal error code.<br>
*
* \param[in] Pi4ErrorCode DTLS Internal error code
* \param[in,out] PpsAlertMsg Pointer to a blob containing Alert message as per DTLS Specification
*
*/
_STATIC_H Void Alert_FormMsg(int32_t Pi4ErrorCode,sbBlob_d* PpsAlertMsg)
{
//Maps the internal error code to the Alert messages
DtlsErrorAlertMapping(Pi4ErrorCode,PpsAlertMsg);
}
#endif //DISABLE_ALERT
/**
* Maps the Alert types and level to error code.<br>
*
* \param[in] PpsAlertMsg Pointer to a blob containing Alert message as per DTLS Specification
* \param[in,out] Ppi4ErrorCode Pointer to the DTLS Internal error code
*
* \retval #OCP_AL_OK Successful execution
* \retval #OCP_AL_ERROR Failure in execution
*
*/
_STATIC_H int32_t DtlsAlertErrorMapping(const sbBlob_d* PpsAlertMsg, int32_t* Ppi4ErrorCode)
{
int32_t i4Status = (int32_t)OCP_AL_ERROR;
do
{
//Check for the Alert level type
if(eFATAL == (eAlertLevel_d)*PpsAlertMsg->prgbStream)
{
//Check for various fatal alert messages
switch((eAlertMsg_d) *(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG))
{
case eCLOSE_NOTIFY:
case eUNEXPECTED_MESSAGE:
case eBAD_RECORD_MAC:
case eDECRYPTION_FAILURE:
case eRECORD_OVERFLOW:
case eDECOMPRESSION_FAILURE:
case eHANDSHAKE_FAILURE:
case eBAD_CERTIFICATE:
case eUNSUPPORTED_CERTIFICATE:
case eNO_CERTIFICATE:
case eCERTIFICATE_REVOKED:
case eCERTIFICATE_EXPIRED:
case eCERTIFICATE_UNKNOWN:
case eUSER_CANCELLED:
case eNO_RENEGOTIATION:
case eILLEGAL_PARAMETER:
case eUNKNOWN_CA:
case eACCESS_DENIED:
case eDECODE_ERROR:
case eDECRYPT_ERROR:
case eEXPORT_RESTRICTION:
case ePROTOCOL_VERSION:
case eINSUFFICIENT_SECURITY:
case eINTERNAL_ERROR:
case eUNSUPPORTED_EXTENSION:
{
*Ppi4ErrorCode = (int32_t)OCP_AL_FATAL_ERROR;
i4Status = (int32_t)OCP_AL_OK;
}
break;
default:
//Indicates the received Alert is not a valid Fatal Error
break;
}
}
//Check for Warning Alert level type
else if (eWARNING == (eAlertLevel_d)*PpsAlertMsg->prgbStream)
{
//Check for various warning alert messages
switch((eAlertMsg_d) *(PpsAlertMsg->prgbStream + OFFSET_ALERT_MSG))
{
case eBAD_CERTIFICATE:
case eUNSUPPORTED_CERTIFICATE:
case eCERTIFICATE_REVOKED:
case eCERTIFICATE_EXPIRED:
case eCERTIFICATE_UNKNOWN:
case eUSER_CANCELLED:
case eNO_RENEGOTIATION:
{
*Ppi4ErrorCode = (int32_t)OCP_AL_WARNING_ERROR;
i4Status = (int32_t)OCP_AL_OK;
break;
}
default:
//lint -e788 suppress "As the enum values are divided between Fatal and warning levels"
//Indicates the received Alert is not a valid warning Error
break;
}
}
}while(0);
return i4Status;
}
#ifndef DISABLE_ALERT
/**
* Sends Alert based on the internal error code via the Record Layer.<br>
*
* \param[in] PpsConfigRL Pointer to structure containing Record Layer information.
* \param[in] Pi4ErrorCode DTLS Internal error code
*
*/
void Alert_Send(sConfigRL_d *PpsConfigRL,int32_t Pi4ErrorCode)
{
int32_t i4Status = (int32_t)OCP_AL_ERROR;
sbBlob_d sAlertMsg;
uint8_t bEncFlag = 0;
uint8_t bFlagIncr = 0;
uint8_t rgbAlertMsg[LENGTH_ALERT_MSG];
//Null checks
if((NULL != PpsConfigRL) && (NULL != PpsConfigRL->pfSend) && (NULL != PpsConfigRL->sRL.phRLHdl))
{
do
{
/// @cond hidden
#define PS_RECORDLAYER ((sRecordLayer_d*)PpsConfigRL->sRL.phRLHdl)
/// @endcond
sAlertMsg.prgbStream = rgbAlertMsg;
sAlertMsg.wLen = LENGTH_ALERT_MSG;
//Form the Alert message based on internal error code
Alert_FormMsg(Pi4ErrorCode, &sAlertMsg);
PpsConfigRL->sRL.bMemoryAllocated = FALSE;
PpsConfigRL->sRL.bContentType = CONTENTTYPE_ALERT;
//Until successful completion of Mutual Authentication Public Key Scheme (DTLS) the Client should use previous epoch and messages must not be encrypted
if(((PS_RECORDLAYER->wServerEpoch != PS_RECORDLAYER->wClientNextEpoch) && (*PS_RECORDLAYER->pbDec != 0x01)) ||
(Pi4ErrorCode == (int32_t)OCP_FL_INT_ERROR) || (Pi4ErrorCode == (int32_t)OCP_FL_HS_ERROR))
{
if((PS_RECORDLAYER->bEncDecFlag == ENC_DEC_ENABLED) && (PS_RECORDLAYER->wClientEpoch != PS_RECORDLAYER->wClientNextEpoch))
{
bEncFlag = PS_RECORDLAYER->bEncDecFlag;
PS_RECORDLAYER->bEncDecFlag = ENC_DEC_DISABLED;
PS_RECORDLAYER->wClientNextEpoch--;
bFlagIncr = 0x01;
}
}
//Send the Alert message via record layer
i4Status = PpsConfigRL->pfSend(&PpsConfigRL->sRL, sAlertMsg.prgbStream, sAlertMsg.wLen);
if(bFlagIncr == 0x01)
{
PS_RECORDLAYER->bEncDecFlag = bEncFlag;
PS_RECORDLAYER->wClientNextEpoch++;
}
if(OCP_RL_OK != i4Status)
{
break;
}
}while(FALSE);
/// @cond hidden
#undef PS_RECORDLAYER
/// @endcond
}
}
#endif //DISABLE_ALERT
/**
* Processes the received Alert Message<br>
* Returns the corresponding internal error code.<br>
*
* \param[in] PpsAlertMsg Pointer to a blob containing Alert message as per DTLS Specification
* \param[in,out] Ppi4ErrorCode Pointer to the DTLS Internal error code
*
* \retval #OCP_AL_OK Successful execution
* \retval #OCP_AL_ERROR Failure in execution
\if ENABLE_NULL_CHECKS
* \retval #OCP_AL_NULL_PARAM Null parameter(s)
\endif
* \retval #OCP_AL_LENZERO_ERROR Length of input parameter is zero
*
*/
int32_t Alert_ProcessMsg(const sbBlob_d* PpsAlertMsg,int32_t* Ppi4ErrorCode)
{
int32_t i4Status = (int32_t)OCP_AL_ERROR;
do
{
#ifdef ENABLE_NULL_CHECKS
//NULL check for the input parameters
if((NULL == PpsAlertMsg) || (NULL == Ppi4ErrorCode)|| (NULL == PpsAlertMsg->prgbStream))
{
i4Status = (int32_t)OCP_AL_NULL_PARAM;
break;
}
#endif
//Check for length is less than Alert message size
if(LENGTH_ALERT_MSG != PpsAlertMsg->wLen)
{
break;
}
//Maps the received Alert messages to the internal error codes
i4Status = DtlsAlertErrorMapping(PpsAlertMsg, Ppi4ErrorCode);
}while(0);
return i4Status;
}
/**
* @}
*/
#endif /*MODULE_ENABLE_DTLS_MUTUAL_AUTH */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+311
View File
@@ -0,0 +1,311 @@
/**
* 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 DtlsTransportLayer.c
*
* \brief This file provides APIs for the transport layer functionalities.
*
* \addtogroup grOCP
* @{
*
*/
#include "optiga/dtls/DtlsTransportLayer.h"
#include "optiga/common/MemoryMgmt.h"
#ifdef MODULE_ENABLE_DTLS_MUTUAL_AUTH
/// @cond hidden
/// @endcond
/**
* This API initialises transport layer communication structure.
*
* \param[in,out] PpsTL Pointer to the transport layer communication structure
*
* \return #OCP_TL_OK on successful execution
* \return #OCP_TL_ERROR on failure
* \return #OCP_TL_NULL_PARAM on parameter received is NULL
* \return #E_COMMS_UDP_ALLOCATE_FAILURE on failure to allocate memory
*/
int32_t DtlsTL_Init(sTL_d* PpsTL)
{
int32_t i4Status = (int32_t)OCP_TL_ERROR;
do
{
//NULL check
if((NULL == PpsTL) || (NULL == PpsTL->pzIpAddress))
{
i4Status = (int32_t)OCP_TL_NULL_PARAM;
break;
}
//Allocate the memory for the ethernet communication structure
PpsTL->phTLHdl = (pal_socket_t*)OCP_MALLOC(sizeof(pal_socket_t));
if(NULL == PpsTL->phTLHdl)
{
i4Status = (int32_t)OCP_TL_MALLOC_FAILURE;
break;
}
/// @cond hidden
#define PS_COMMS_HANDLE ((pal_socket_t*)PpsTL->phTLHdl)
/// @endcond
PS_COMMS_HANDLE->wPort = PpsTL->wPort;
//Converting IP address from string format to hex format
i4Status = pal_socket_assign_ip_address(PpsTL->pzIpAddress,&(PS_COMMS_HANDLE->sIPAddress));
if(i4Status != E_COMMS_SUCCESS)
{
break;
}
//Assigning the timeout value
PS_COMMS_HANDLE->wTimeout = PpsTL->wTimeout ;
//Non Blockage receive mode
PS_COMMS_HANDLE->bMode = (uint8_t)PpsTL->eCallType;
//Add logging
LOG_TRANSPORTMSG("Initializing UDP Connection",eInfo);
//Initialize the communication handle with the parameters
i4Status = pal_socket_init(PS_COMMS_HANDLE);
if(E_COMMS_SUCCESS != i4Status)
{
break;
}
i4Status = (int32_t)OCP_TL_OK;
}while(FALSE);
if(OCP_TL_OK != i4Status)
{
if((NULL != PpsTL)&& (NULL != PpsTL->phTLHdl))
{
OCP_FREE(PpsTL->phTLHdl);
PpsTL->phTLHdl = NULL;
}
}
/// @cond hidden
#undef PS_COMMS_HANDLE
/// @endcond
return i4Status;
}
/**
* This API creates client port
*
* \param[in,out] PpsTL Pointer to the transport layer communication structure
*
* \return #OCP_TL_OK on successful execution
* \return #OCP_TL_NULL_PARAM on parameter received is NULL
* \return #E_COMMS_UDP_BINDING_FAILURE on port binding failure
* \return #OCP_TL_ERROR on failure
*/
int32_t DtlsTL_Connect(sTL_d* PpsTL)
{
int32_t i4Status = (int32_t)OCP_TL_ERROR;
do
{
//NULL check
if((NULL == PpsTL) || (NULL == PpsTL->phTLHdl))
{
i4Status = (int32_t)OCP_TL_NULL_PARAM;
break;
}
/// @cond hidden
#define PS_COMMS_HANDLE ((pal_socket_t*)PpsTL->phTLHdl)
/// @endcond
//Logging
LOG_TRANSPORTMSG("Connecting to UDP",eInfo);
//Open the client port with the port number initialised
i4Status = pal_socket_connect(PS_COMMS_HANDLE, PS_COMMS_HANDLE->wPort);
if(E_COMMS_SUCCESS != i4Status)
{
LOG_TRANSPORTMSG("Error connecting to UDP",eError);
break;
}
PpsTL->eIsConnected = eConnected;
i4Status = (int32_t)OCP_TL_OK;
}while(FALSE);
/// @cond hidden
#undef PS_COMMS_HANDLE
/// @endcond
return i4Status;
}
/**
* This API transmits the data to the server.
*
* \param[in,out] PpsTL Pointer to the transport layer communication structure
* \param[in] PpbBuffer Pointer to buffer containing data to be transmitted
* \param[in] PdwLen Length of the data to be transmitted
*
* \return #OCP_TL_OK on successful execution
* \return #OCP_TL_NULL_PARAM on parameter received is NULL
* \return #E_COMMS_UDP_NO_DATA_TO_SEND on no date present to send
* \return #E_COMMS_INSUFFICIENT_MEMORY on out of memory failure
* \return #E_COMMS_UDP_ROUTING_FAILURE on failure to route the UDP packet
* \return #E_COMMS_UDP_DEALLOCATION_FAILURE on failure to deallocate
* \return #OCP_TL_ERROR on failure
*/
int32_t DtlsTL_Send(const sTL_d* PpsTL,uint8_t* PpbBuffer,uint16_t PdwLen)
{
int32_t i4Status = (int32_t)OCP_TL_ERROR;
do
{
//NULL check
if((NULL == PpsTL) || (NULL == PpsTL->phTLHdl) ||(NULL == PpbBuffer))
{
i4Status = (int32_t)OCP_TL_NULL_PARAM;
break;
}
LOG_TRANSPORTDBARY("Sending Data over UDP", PpbBuffer, PdwLen, eInfo);
//Send the data over IP address and Port initialized
/// @cond hidden
#define PS_COMMS_HANDLE ((pal_socket_t*)PpsTL->phTLHdl)
/// @endcond
i4Status = pal_socket_send(PS_COMMS_HANDLE, PpbBuffer, PdwLen);
if (E_COMMS_SUCCESS != i4Status)
{
LOG_TRANSPORTMSG("Error while sending data",eError);
break;
}
i4Status = (int32_t)OCP_TL_OK;
}while(FALSE);
/// @cond hidden
#undef PS_COMMS_HANDLE
/// @endcond
return i4Status;
}
/**
* This API receives the data from the server
*
* \param[in] PpsTL Pointer to the transport layer communication structure
* \param[in,out] PpbBuffer Pointer to buffer where data is to be received
* \param[in,out] PpdwLen Length of the buffer/Length of the received data
*
* \return #OCP_TL_OK on successful execution
* \return #OCP_TL_NULL_PARAM on parameter received is NULL
* \return #OCP_TL_NO_DATA on no data received from the target
* \return #E_COMMS_INSUFFICIENT_BUF_SIZE on insufficient buffer size
* \return #OCP_TL_ERROR on failure
*/
int32_t DtlsTL_Recv(const sTL_d* PpsTL,uint8_t* PpbBuffer,uint16_t* PpdwLen)
{
int32_t i4Status = (int32_t)OCP_TL_ERROR;
uint32_t dwRecvLen;
do
{
//NULL check
if((NULL == PpsTL) || (NULL == PpsTL->phTLHdl) || (NULL == PpbBuffer))
{
i4Status = (int32_t)OCP_TL_NULL_PARAM;
break;
}
//logging
LOG_TRANSPORTMSG("Receiving over UDP",eInfo);
/// @cond hidden
#define PS_COMMS_HANDLE ((pal_socket_t*)PpsTL->phTLHdl)
/// @endcond
PS_COMMS_HANDLE->wTimeout = PpsTL->wTimeout;
dwRecvLen = *PpdwLen;
//Listen the server port and receive the data
i4Status = pal_socket_listen(PS_COMMS_HANDLE, PpbBuffer, &dwRecvLen);
if ((int32_t)E_COMMS_UDP_NO_DATA_RECEIVED == i4Status)
{
i4Status = (int32_t)OCP_TL_NO_DATA;
LOG_TRANSPORTMSG("No data received over UDP",eError);
break;
}
if (E_COMMS_SUCCESS != i4Status)
{
LOG_TRANSPORTMSG("Error while receiving data over UDP",eError);
break;
}
LOG_TRANSPORTMSG("Received Data",eInfo);
LOG_TRANSPORTDBARY("Received Data over UDP", PpbBuffer, dwRecvLen, eInfo);
*PpdwLen = (uint16_t)dwRecvLen;
i4Status = (int32_t)OCP_TL_OK;
}while(FALSE);
/// @cond hidden
#undef PS_COMMS_HANDLE
/// @endcond
return i4Status;
}
/**
* This API closes the UDP communication and releases all the resources
*
* \param[in,out] PpsTL Pointer to the transport layer communication structure
*
* \return None
*/
Void DtlsTL_Disconnect(sTL_d* PpsTL)
{
//NULL check
if(NULL != PpsTL)
{
if(NULL != PpsTL->phTLHdl)
{
//logging
LOG_TRANSPORTMSG("Closing UDP Connection",eInfo);
/// @cond hidden
#define PS_COMMS_HANDLE ((pal_socket_t*)PpsTL->phTLHdl)
/// @endcond
//Close the UDP connection
pal_socket_close(PS_COMMS_HANDLE);
//Free the allocated memory for ethernet structure
OCP_FREE(PS_COMMS_HANDLE);
PpsTL->phTLHdl = NULL;
PpsTL->eIsConnected = eDisconnected;
/// @cond hidden
#undef PS_COMMS_HANDLE
/// @endcond
}
}
}
/**
* @}
*/
#endif /*MODULE_ENABLE_DTLS_MUTUAL_AUTH*/
+214
View File
@@ -0,0 +1,214 @@
/**
* 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
*
* \brief This file implements the APIs, types used in the
* for DTLS windowing.
*
* \addtogroup grMutualAuth
* @{
*/
#include <stdint.h>
#include "optiga/dtls/DtlsWindowing.h"
#include "optiga/dtls/DtlsRecordLayer.h"
#ifdef MODULE_ENABLE_DTLS_MUTUAL_AUTH
/// @cond hidden
///Maximum window size supported
#define MAX_WINDOW_SIZE 64
/// @endcond
/**
* Implementation for Record Replay Detection.<br>
* Return status as #OCP_RL_WINDOW_IGNORE if record is already received or record sequence number is less then lower bound of window.<br>
* Under some erroneous conditions, error codes from Record Layer can also be returned.<br>
*
* \param[in] PpsWindow Pointer to the structure that contains details required for windowing like
* record sequence number, lower and higher boundaries.
*
* \retval OCP_RL_WINDOW_UPDATED Valid record is received and window is updated.
* \retval OCP_RL_WINDOW_MOVED Valid record is received and window is updated and moved.
* \retval OCP_RL_WINDOW_IGNORE Failure in execution and record already received.
*
*/
int32_t DtlsCheckReplay(sWindow_d *PpsWindow)
{
int32_t i4Status = (int32_t) OCP_RL_WINDOW_IGNORE;
int32_t i4Retval;
sUint64 sIntermidateVal;
do
{
#ifdef ENABLE_NULL_CHECKS
if((NULL == PpsWindow) || (NULL == PpsWindow->fValidateRecord))
{
break;
}
#endif
if((MAX_WINDOW_SIZE < PpsWindow->bWindowSize) || (WORD_SIZE > PpsWindow->bWindowSize))
{
break;
}
//Compare the received sequence number with the Lower window boundary
i4Retval = CompareUint64(&PpsWindow->sRecvSeqNumber, &PpsWindow->sLowerBound);
//If sequence number is lesser than the low bound of window
if(LESSER_THAN == i4Retval)
{
break;
}
//If sequence number is greater than low bound window
//Compare the received sequence number with the Higher window boundary
i4Retval = CompareUint64(&PpsWindow->sRecvSeqNumber, &PpsWindow->sHigherBound);
//If Sequence number is greater than high bound of the window
//Slide the window
if(GREATER_THAN == i4Retval)
{
//Record validation
i4Retval = PpsWindow->fValidateRecord(PpsWindow->pValidateArgs);
//If record validation fails
if(OCP_RL_OK != i4Retval)
{
if(((int32_t)CMD_LIB_DECRYPT_FAILURE == i4Retval) || ((int32_t)OCP_RL_MALLOC_FAILURE == i4Retval))
{
i4Status = i4Retval;
}
break;
}
else
{
//Calculate the count to slide the window
//lint --e{534} suppress "The return value check is suppressed as this function always return Success.Only error condition where
//RecvSeqNumber < sHigherBound is not possible as it will enter this path only when RecvSeqNumber > sHigherBound"
i4Retval = SubtractUint64(&PpsWindow->sRecvSeqNumber, &PpsWindow->sHigherBound, &sIntermidateVal);
//Slide the window
i4Retval = ShiftLeftUint64(&PpsWindow->sWindowFrame, sIntermidateVal, PpsWindow->bWindowSize, (uint8_t)MAX_WINDOW_SIZE);
if(UTIL_SUCCESS != i4Retval)
{
break;
}
//Set the sequence number received as the Higher Bound
PpsWindow->sHigherBound = PpsWindow->sRecvSeqNumber;
sIntermidateVal.dwHigherByte = DEFAULT_LOWBOUND_DOUBLEWORD ;
sIntermidateVal.dwLowerByte = (uint32_t)PpsWindow->bWindowSize - 1;
//Difference of Higher bound and window size is set as lower bound
i4Retval = SubtractUint64(&PpsWindow->sHigherBound, &sIntermidateVal, &PpsWindow->sLowerBound);
if(UTIL_SUCCESS != i4Retval)
{
break;
}
//Set the bit position of sequence number to 1 which is the MSB of the window frame
i4Retval = Utility_SetBitUint64(&PpsWindow->sWindowFrame, PpsWindow->bWindowSize, PpsWindow->bWindowSize);
if(UTIL_SUCCESS != i4Retval)
{
break;
}
i4Status = (int32_t) OCP_RL_WINDOW_MOVED;
break;
}
}
//Compare the received sequence number with the Higher and Lower window boundary
//lint --e{534} suppress "The return value check is suppressed as this function always return Success.Only error condition where
//RecvSeqNumber > sHigherBound is not possible as it will enter this path only when RecvSeqNumber < sHigherBound"
//Calculate bit position of sequence number from high bound of the window
i4Retval = SubtractUint64(&PpsWindow->sHigherBound, &PpsWindow->sRecvSeqNumber, &sIntermidateVal);
//If window size is equal to 32
if(WORD_SIZE == PpsWindow->bWindowSize)
{
if((MOST_SIGNIFICANT_BIT_HIGH == ((PpsWindow->sWindowFrame.dwHigherByte << (uint32_t)((WORD_SIZE - sIntermidateVal.dwLowerByte) - 1))
& MOST_SIGNIFICANT_BIT_HIGH)))
{
break;
}
}
else
{
//Received sequence number is in the lower byte of the window frame
if((DEFAULT_LOWBOUND_DOUBLEWORD == sIntermidateVal.dwHigherByte) && (sIntermidateVal.dwLowerByte < WORD_SIZE))
{
if((MOST_SIGNIFICANT_BIT_HIGH == ((PpsWindow->sWindowFrame.dwLowerByte << (uint32_t)((WORD_SIZE - sIntermidateVal.dwLowerByte) - 1 )) & MOST_SIGNIFICANT_BIT_HIGH)))
{
break;
}
}
//Received sequence number is in the higher byte of the window frame
else if((DEFAULT_LOWBOUND_DOUBLEWORD == sIntermidateVal.dwHigherByte) && (sIntermidateVal.dwLowerByte >= WORD_SIZE))
{
if((MOST_SIGNIFICANT_BIT_HIGH == ((PpsWindow->sWindowFrame.dwHigherByte << (uint32_t)((MAX_WINDOW_SIZE - sIntermidateVal.dwLowerByte) - 1)) & MOST_SIGNIFICANT_BIT_HIGH)))
{
break;
}
}
}
//Record validation
i4Retval = PpsWindow->fValidateRecord(PpsWindow->pValidateArgs);
//If record validation fails
if(OCP_RL_OK != i4Retval)
{
if(((int32_t)CMD_LIB_DECRYPT_FAILURE == i4Retval) || ((int32_t)OCP_RL_MALLOC_FAILURE == i4Retval))
{
i4Status = i4Retval;
}
break;
}
else
{
i4Retval = SubtractUint64(&PpsWindow->sRecvSeqNumber, &PpsWindow->sLowerBound,&sIntermidateVal);
if(UTIL_SUCCESS != i4Retval)
{
break;
}
//Set the bit position of sequence number to 1
i4Retval = Utility_SetBitUint64(&PpsWindow->sWindowFrame, PpsWindow->bWindowSize, (uint8_t)sIntermidateVal.dwLowerByte);
if(UTIL_SUCCESS != i4Retval)
{
break;
}
if(PpsWindow->bWindowSize > WORD_SIZE)
{
PpsWindow->sWindowFrame.dwHigherByte &= MASK_DOUBLE_WORD >> (MAX_WINDOW_SIZE - PpsWindow->bWindowSize);
}
i4Status = (int32_t)OCP_RL_WINDOW_UPDATED;
}
}while(0);
return i4Status;
}
#endif /*MODULE_ENABLE_DTLS_MUTUAL_AUTH*/
+227
View File
@@ -0,0 +1,227 @@
/**
* 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 HardwareCrypto.c
*
* \brief This file provides APIs for hardware crypto layer.
*
* \addtogroup grMutualAuth
* @{
*
*/
#include "optiga/common/Util.h"
#include "optiga/dtls/HardwareCrypto.h"
#include "optiga/dtls/OcpCommon.h"
#include "optiga/cmd/CommandLib.h"
#ifdef MODULE_ENABLE_DTLS_MUTUAL_AUTH
/**
* Initialises the Hardware Crypto Layer.
*
* \param[in,out] PpsCL Pointer to #sHardwareCrypto_d structure.
* \param[in] PpParam Pointer to the sessionKeyOID to be used for Encryption and Decryption.
*
* \retval #OCP_CL_OK Successful execution
* \retval #OCP_CL_ERROR Failure in execution
*
*/
int32_t HWCL_Init(sCL_d* PpsCL, const void* PpParam)
{
int32_t i4Status = (int32_t)OCP_CL_ERROR;
do
{
PpsCL->phCryptoHdl = (sHardwareCrypto_d*)OCP_MALLOC(sizeof(sHardwareCrypto_d));
if(NULL == PpsCL->phCryptoHdl)
{
i4Status = (int32_t)OCP_CL_MALLOC_FAILURE;
break;
}
memset(PpsCL->phCryptoHdl, 0x00, sizeof(sHardwareCrypto_d));
((sHardwareCrypto_d*)PpsCL->phCryptoHdl)->wSessionKeyOID = *((uint16_t*)PpParam);
i4Status = OCP_CL_OK;
}while(FALSE);
return i4Status;
}
/**
* Encrypts the input plain text using Security chip.
* Under some erroneous conditions, error codes from Command Library can also be returned. <br>
*
* \param[in] PpsCL Pointer to #sHardwareCrypto_d structure.
* \param[in] PpsBlobPlainText Pointer to sbBlob_d containing plain text.
* \param[in,out] PpsBlobCipherText Pointer to sbBlob_d containing cipher text.
* \param[in] PwLen Length of data to be encrypted.
*
* \retval #OCP_CL_OK Successful execution
* \retval #OCP_CL_ERROR Failure in execution
*
*/
int32_t HWCL_Encrypt(const sCL_d* PpsCL, const sbBlob_d* PpsBlobPlainText,sbBlob_d* PpsBlobCipherText,uint16_t PwLen)
{
int32_t i4Status = (int32_t)OCP_CL_ERROR;
sProcCryptoData_d sProcCryptoData;
do
{
//Null Check
if((NULL == PpsBlobPlainText)||(NULL == PpsBlobPlainText->prgbStream) ||
(NULL == PpsBlobCipherText)|| (NULL == PpsBlobCipherText->prgbStream) || (NULL == PpsCL))
{
i4Status = (int32_t)OCP_CL_NULL_PARAM;
break;
}
//Length check for input parameters
if(0 == PwLen)
{
i4Status = (int32_t)OCP_CL_ZERO_LEN;
break;
}
//Length check for input parameters
if(PpsBlobPlainText->wLen < (PwLen + OVERHEAD_UPDOWNLINK) ||
(PpsBlobCipherText->wLen < (PwLen + OVERHEAD_ENCDEC_RESPONSE + MAC_LENGTH + EXPLICIT_NOUNCE_LENGTH)))
{
i4Status = (int32_t)OCP_CL_INSUFFICIENT_MEMORY;
break;
}
//Assign the required parameter(s) for the Encrypt Message command
sProcCryptoData.sInData.prgbStream = PpsBlobPlainText->prgbStream;
sProcCryptoData.sInData.wLen = PpsBlobPlainText->wLen;
sProcCryptoData.wInDataLength = PwLen;
sProcCryptoData.wSessionKeyOID = ((sHardwareCrypto_d*)PpsCL->phCryptoHdl)->wSessionKeyOID;
sProcCryptoData.sOutData.prgbBuffer = PpsBlobCipherText->prgbStream;
sProcCryptoData.sOutData.wBufferLength = PpsBlobCipherText->wLen;
//Invoke the encrypt command API from the command library
i4Status = CmdLib_Encrypt(&sProcCryptoData);
if(CMD_LIB_OK != i4Status)
{
break;
}
PpsBlobCipherText->wLen = sProcCryptoData.sOutData.wRespLength;
i4Status = (int32_t)OCP_CL_OK;
}while(FALSE);
return i4Status;
}
/**
* Decrypts the input cipher text using Security chip.
* Under some erroneous conditions, error codes from Command Library can also be returned. <br>
*
* \param[in] PpsCL Pointer to #sHardwareCrypto_d structure.
* \param[in] PpsBlobCipherText Pointer to sbBlob_d containing cipher text.
* \param[in,out] PpsBlobPlainText Pointer to sbBlob_d containing plain text.
* \param[in] PwLen Length of data to be decrypted.
*
* \retval #OCP_CL_OK Successful execution
* \retval #OCP_CL_ERROR Failure in execution
*
*/
int32_t HWCL_Decrypt(const sCL_d* PpsCL,const sbBlob_d* PpsBlobCipherText,sbBlob_d* PpsBlobPlainText,uint16_t PwLen)
{
int32_t i4Status = (int32_t)OCP_CL_ERROR;
sProcCryptoData_d sProcCryptoData;
do
{
//Null Check
if((NULL == PpsBlobPlainText)||(NULL == PpsBlobPlainText->prgbStream) ||
(NULL == PpsBlobCipherText)|| (NULL == PpsBlobCipherText->prgbStream) || (NULL == PpsCL))
{
i4Status = (int32_t)OCP_CL_NULL_PARAM;
break;
}
//Length check for input parameters
if(0 == PwLen)
{
i4Status = (int32_t)OCP_CL_ZERO_LEN;
break;
}
//Length check for input parameters
if((PpsBlobPlainText->wLen < (PwLen + OVERHEAD_ENCDEC_RESPONSE - (MAC_LENGTH + EXPLICIT_NOUNCE_LENGTH))) ||
(PpsBlobCipherText->wLen < (PwLen + OVERHEAD_UPDOWNLINK)))
{
i4Status = (int32_t)OCP_CL_INSUFFICIENT_MEMORY;
break;
}
//Assign the required parameter(s) for the Decrypt Message command
sProcCryptoData.sInData.prgbStream = PpsBlobCipherText->prgbStream;
sProcCryptoData.sInData.wLen = PpsBlobCipherText->wLen;
sProcCryptoData.wInDataLength = PwLen;
sProcCryptoData.wSessionKeyOID = ((sHardwareCrypto_d*)PpsCL->phCryptoHdl)->wSessionKeyOID;
sProcCryptoData.sOutData.prgbBuffer = PpsBlobPlainText->prgbStream;
sProcCryptoData.sOutData.wBufferLength = PpsBlobPlainText->wLen;
LOG_TRANSPORTMSG("Encrypted Data sent to OPTIGA",eInfo);
//Invoke the Decrypt command API from the command library
i4Status = CmdLib_Decrypt(&sProcCryptoData);
if(CMD_LIB_OK != i4Status)
{
LOG_TRANSPORTDBVAL(i4Status,eInfo);
break;
}
PpsBlobPlainText->wLen = sProcCryptoData.sOutData.wRespLength;
//To log the decrypted data
LOG_TRANSPORTDBARY("Decrypted Data", sProcCryptoData.sOutData.prgbBuffer, PpsBlobPlainText->wLen, eInfo);
i4Status = (int32_t) OCP_CL_OK;
}while(FALSE);
return i4Status;
}
/**
* Closes the Crypto layer.
*
* \param[in,out] PpsCL Pointer to #sHardwareCrypto_d structure.
*
*/
void HWCL_Close(sCL_d* PpsCL)
{
if((NULL != PpsCL) && (NULL != PpsCL->phCryptoHdl))
{
OCP_FREE(PpsCL->phCryptoHdl);
PpsCL->phCryptoHdl = NULL;
}
}
#endif //MODULE_ENABLE_DTLS_MUTUAL_AUTH
+263
View File
@@ -0,0 +1,263 @@
/**
* 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
*
* \brief This file implements the functionality to form and process DTLS messages for OCP Library.
*
* \addtogroup grMutualAuth
* @{
*/
#include "optiga/dtls/MessageLayer.h"
#ifdef MODULE_ENABLE_DTLS_MUTUAL_AUTH
#define CALL_BACK_OK 0x00000001
/**
* Call back function to allocate memory to the received message from Security Chip.<br>
*
* \param[in,out] PpCBParam Pointer to structure containing information required to allocate memory
* \param[in] psInOutMsg Pointer to sBlob containing the received Handshake message from Security Chip
*
* \retval #CMD_LIB_OK Successful Execution
* \retval #CMD_LIB_ERROR Failure Execution
*/
int32_t CallBack_GetMessage(Void* PpCBParam, const sbBlob_d* psInOutMsg)
{
int32_t i4Status = (int32_t) CMD_LIB_ERROR;
uint32_t dwFragLen;
uint32_t dwTotalLen;
uint32_t dwOffset;
/// @cond hidden
#define PS_CBGETMSG ((sCBGetMsg_d*)PpCBParam)
#define OFFSET_MSG_FRAG_LENGTH 9
#define OFFSET_MSG_TOTAL_LENGTH 1
#define OFFSET_MSG_FRAGMENT_OFFSET 6
/// @endcond
do
{
dwFragLen = Utility_GetUint24(psInOutMsg->prgbStream + OFFSET_MSG_FRAG_LENGTH);
dwTotalLen = Utility_GetUint24(psInOutMsg->prgbStream + OFFSET_MSG_TOTAL_LENGTH);
dwOffset = Utility_GetUint24(psInOutMsg->prgbStream + OFFSET_MSG_FRAGMENT_OFFSET);
//If first time, allocate memory
if(FALSE == PS_CBGETMSG->bRepeatCall)
{
//Allocate memory
PS_CBGETMSG->dwMsgLen = (uint16_t)dwTotalLen + OVERHEAD_LEN;
PS_CBGETMSG->pbActualMsg = (uint8_t*)OCP_MALLOC(dwTotalLen + OVERHEAD_LEN);
if(PS_CBGETMSG->pbActualMsg == NULL)
{
i4Status = (int32_t)OCP_ML_MALLOC_FAILURE;
break;
}
//Set to true indicating memory is already allocated
PS_CBGETMSG->bRepeatCall = TRUE;
OCP_MEMCPY(PS_CBGETMSG->pbActualMsg + (OVERHEAD_LEN - MSG_HEADER_LEN),psInOutMsg->prgbStream,(uint16_t)(dwFragLen + MSG_HEADER_LEN));
//Set fragment offset to zero and fragment len to total len
Utility_SetUint24((PS_CBGETMSG->pbActualMsg + (OVERHEAD_LEN - 3)), dwTotalLen);
}
else
{
//copy data from offset
OCP_MEMCPY(PS_CBGETMSG->pbActualMsg + dwOffset + OVERHEAD_LEN, (psInOutMsg->prgbStream + MSG_HEADER_LEN), (uint16_t)dwFragLen);
}
i4Status = CMD_LIB_OK;
}while(FALSE);
/// @cond hidden
#undef OFFSET_MSG_FRAG_LENGTH
#undef OFFSET_MSG_TOTAL_LENGTH
#undef OFFSET_MSG_FRAGMENT_OFFSET
#undef PS_CBGETMSG
/// @endcond
return i4Status;
}
/**
* Provide Handshake message using Command Library.<br>
* Under some erroneous conditions, error codes from Command Library can also be returned.<br>
*
* \param[in] eMsgType Message type of the handshake message to be received from Security Chip
* \param[in] PpsMessageLayer Pointer to structure containing information required for Message Layer
* \param[out] PpsMessage Pointer to sBlob containing the Handshake message
*
* \retval #OCP_ML_OK Successful Execution
* \retval #OCP_ML_ERROR Failure Execution
* \retval #OCP_ML_INVALID_UNIXTIME Invalid unix time provided by user
*/
int32_t MsgLayer_FormMessage(eMsgType_d eMsgType,const sMessageLayer_d* PpsMessageLayer, sbBlob_d* PpsMessage)
{
int32_t i4Status = (int32_t) OCP_ML_ERROR;
sProcMsgData_d sGMsgVector;
sCallBack_d sCallBack;
sCBGetMsg_d sCBGetMsg;
uMsgParams_d uMsgParams;
do
{
//Null Check
if((NULL == PpsMessageLayer) || (NULL == PpsMessage))
{
i4Status = (int32_t)OCP_ML_NULL_PARAM;
break;
}
//Assign the call back function parameters
sCBGetMsg.bRepeatCall = FALSE;
sCBGetMsg.pbActualMsg = NULL;
sCBGetMsg.dwMsgLen = 0;
//Assign call back function to allocate memory
sCallBack.pfAcceptMessage = CallBack_GetMessage;
sCallBack.fvParams = (Void*) &sCBGetMsg;
//Form the Get message command APDU parameters
sGMsgVector.eParam = eMsgType;
sGMsgVector.wSessionKeyOID = PpsMessageLayer->wSessionID;
sGMsgVector.psCallBack = &sCallBack;
sGMsgVector.psBlobInBuffer = NULL;
//sGMsgVector.puMsgParams = &uMsgParams;
sGMsgVector.puMsgParams = NULL;
//Based on the message type set the message specific data
switch((uint8_t)eMsgType)
{
case eClientHello:
if(NULL != PpsMessageLayer->pfGetUnixTIme)
{
sGMsgVector.puMsgParams = &uMsgParams;
//To use the unix time provided
i4Status = PpsMessageLayer->pfGetUnixTIme(&sGMsgVector.puMsgParams->sMsgParamCH_d.dwUnixTime);
if(CALL_BACK_OK != i4Status)
{
i4Status = (int32_t) OCP_ML_INVALID_UNIXTIME;
break;
}
}
break;
case eClientCertificate:
if(0x0000 != PpsMessageLayer->wOIDDevCertificate)
{
sGMsgVector.puMsgParams = &uMsgParams;
sGMsgVector.puMsgParams->sMsgParamCert_d.wCertOID = PpsMessageLayer->wOIDDevCertificate;
}
break;
default:
//lint -e788 suppress "Default values for return are already set.No more operation required here"
//For other messages there is no message specific data
break;
}
if(((int32_t) OCP_ML_INVALID_UNIXTIME == i4Status) || ((int32_t) OCP_ML_INVALID_CERTTYPE == i4Status))
{
break;
}
//Get the Message using Get Message command from the Security Chip
i4Status = CmdLib_GetMessage(&sGMsgVector);
if(CMD_LIB_OK != i4Status)
{
LOG_TRANSPORTDBVAL(i4Status,eInfo);
break;
}
//Allocated memory is assigned the sBlob
PpsMessage->prgbStream = sCBGetMsg.pbActualMsg;
PpsMessage->wLen = sCBGetMsg.dwMsgLen;
i4Status = (int32_t) OCP_ML_OK ;
}while(FALSE);
return i4Status;
}
/**
* Process Handshake message using Command Library.<br>
* Under some erroneous conditions, error codes from Command Library can also be returned. <br>
*
* \param[in] eMsgType Message type of the handshake message to be send to Security Chip
* \param[in] PpsMessageLayer Pointer to structure containing information required for Message Layer
* \param[in] PpsMessage Pointer to sBlob containing the Handshake message
*
* \retval #OCP_ML_OK Successful Execution
* \retval #OCP_ML_ERROR Failure Execution
*/
int32_t MsgLayer_ProcessMessage(eMsgType_d eMsgType,const sMessageLayer_d* PpsMessageLayer, sbBlob_d* PpsMessage)
{
int32_t i4Status = (int32_t) OCP_ML_ERROR;
sProcMsgData_d sPMsgVector ;
do
{
//Null Check
if((NULL == PpsMessageLayer) || (NULL == PpsMessage) || (NULL == PpsMessage->prgbStream))
{
i4Status = (int32_t)OCP_ML_NULL_PARAM;
break;
}
//Length check for input parameters
if(0 == PpsMessage->wLen)
{
i4Status = (int32_t)OCP_ML_ZERO_LEN;
break;
}
//Assign the required parameter(s) for the Put Message command
sPMsgVector.eParam = eMsgType;
sPMsgVector.psBlobInBuffer = PpsMessage;
sPMsgVector.wSessionKeyOID = PpsMessageLayer->wSessionID;
sPMsgVector.puMsgParams = NULL;
sPMsgVector.psCallBack = NULL;
//Invoke the Put Message command API from the command library to send the message to Security Chip to Process
i4Status = CmdLib_PutMessage(&sPMsgVector);
if(CMD_LIB_OK != i4Status)
{
LOG_TRANSPORTDBVAL(i4Status,eInfo);
break;
}
i4Status = (int32_t) OCP_ML_OK;
}while(FALSE);
#undef PhOCPHandle
return i4Status;
}
/**
* @}
*/
#endif /*MODULE_ENABLE_DTLS_MUTUAL_AUTH*/
File diff suppressed because it is too large Load Diff
+123
View File
@@ -0,0 +1,123 @@
/**
* 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
*
* \brief This file implements the Configuration functions for OCP Library.
*
* \addtogroup grMutualAuth
* @{
*/
#include "optiga/dtls/DtlsTransportLayer.h"
#include "optiga/dtls/DtlsHandshakeProtocol.h" //To be put under ifdef
#include "optiga/dtls/DtlsRecordLayer.h"
#include "optiga/dtls/HardwareCrypto.h"
#include "optiga/optiga_dtls.h"
#ifdef MODULE_ENABLE_DTLS_MUTUAL_AUTH
/// @cond hidden
//lint --e{714} suppress "Functions are extern and not reference in header file as
// these function not to be used for external interfaces. Hence suppressed"
Void ConfigHL(fPerformHandshake_d* PpfPerformHandshake,eConfiguration_d PeConfiguration)
{
//Based on input mode assign pointers to PpsAppOCPCntx
switch(PeConfiguration)
{
case eDTLS_12_UDP_HWCRYPTO:
//Assign the Handshake layer function pointer to context data
*PpfPerformHandshake = DtlsHS_Handshake;
break;
case eTLS_12_TCP_HWCRYPTO:
break;
}
}
//lint --e{714} suppress "Functions are extern and not reference in header file as
// these function not to be used for external interfaces. Hence suppressed"
Void ConfigRL(sConfigRL_d* PpsConfigRL,eConfiguration_d PeConfiguration)
{
//Based on input mode assign pointers to psConfigRL
switch(PeConfiguration)
{
case eDTLS_12_UDP_HWCRYPTO:
PpsConfigRL->pfInit = DtlsRL_Init;
PpsConfigRL->pfSend = DtlsRL_Send;
PpsConfigRL->pfRecv = DtlsRL_Recv;
PpsConfigRL->pfClose = DtlsRL_Close;
break;
case eTLS_12_TCP_HWCRYPTO:
break;
}
}
//lint --e{714} suppress "Functions are extern and not reference in header file as
// these function not to be used for external interfaces. Hence suppressed"
Void ConfigTL(sConfigTL_d* PpsConfigTL,eConfiguration_d PeConfiguration)
{
//Based on input mode assign pointers to psConfigTL
switch(PeConfiguration)
{
case eTLS_12_TCP_HWCRYPTO:
break;
case eDTLS_12_UDP_HWCRYPTO:
//Assign function to function pointers
PpsConfigTL->pfInit = DtlsTL_Init;
PpsConfigTL->pfConnect = DtlsTL_Connect;
PpsConfigTL->pfDisconnect = DtlsTL_Disconnect;
PpsConfigTL->pfRecv = DtlsTL_Recv;
PpsConfigTL->pfSend = DtlsTL_Send;
break;
}
}
//lint --e{714} suppress "Functions are extern and not reference in header file as
// these function not to be used for external interfaces. Hence suppressed"
Void ConfigCL(sConfigCL_d* PpsConfigCL,eConfiguration_d PeConfiguration)
{
//Based on input mode assign pointers to psConfigCL
switch(PeConfiguration)
{
case eDTLS_12_UDP_HWCRYPTO:
case eTLS_12_TCP_HWCRYPTO:
PpsConfigCL->pfInit = HWCL_Init;
PpsConfigCL->pfEncrypt = HWCL_Encrypt;
PpsConfigCL->pfDecrypt = HWCL_Decrypt;
PpsConfigCL->pfClose = HWCL_Close;
break;
}
}
/// @endcond
/**
* @}
*/
#endif /*MODULE_ENABLE_DTLS_MUTUAL_AUTH*/