初始版本

This commit is contained in:
xiaozhengsheng
2025-08-19 09:49:41 +08:00
parent 10f1ddf1c1
commit 6df0f7d96e
2974 changed files with 1712873 additions and 54 deletions

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

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*/

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*/

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

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*/

1212
external/infineon/optiga/dtls/OCP.c vendored Normal file

File diff suppressed because it is too large Load Diff

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*/