diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/DemoTasks/SNTPClientTask.c b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/DemoTasks/SNTPClientTask.c index e0501dc82..3525fd461 100755 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/DemoTasks/SNTPClientTask.c +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/DemoTasks/SNTPClientTask.c @@ -45,6 +45,7 @@ #include #include #include +#include /* Kernel includes. */ #include "FreeRTOS.h" @@ -64,6 +65,11 @@ #include "FreeRTOS_UDP_IP.h" #include "FreeRTOS_Sockets.h" +/* PKCS11 includes. */ +#include "core_pki_utils.h" +#include "core_pkcs11_config.h" +#include "core_pkcs11.h" + /*-----------------------------------------------------------*/ /* Compile time error for undefined configs. */ @@ -72,6 +78,14 @@ #error "Define the democonfigLIST_OF_TIME_SERVERS config by following the instructions in demo_config.h file." #endif +#ifndef democonfigLIST_OF_AUTHENTICATION_SYMMETRIC_KEYS + #error "Define the democonfigLIST_OF_AUTHENTICATION_SYMMETRIC_KEYS config by following the instructions in demo_config.h file." +#endif + +#ifndef democonfigLIST_OF_AUTHENTICATION_KEY_IDS + #error "Define the democonfigLIST_OF_AUTHENTICATION_KEY_IDS config by following the instructions in demo_config.h file." +#endif + #ifndef democonfigDESIRED_CLOCK_ACCURACY_MS #error "Define the democonfigDESIRED_CLOCK_ACCURACY_MS config by following instructions in demo_config.h file." #endif @@ -98,7 +112,7 @@ * @note The size of the buffer MUST be large enough to hold an entire SNTP packet, which includes the standard SNTP * packet data of 48 bytes and authentication data for security mechanism, if used, in communication with time server. */ -#define SNTP_CONTEXT_NETWORK_BUFFER_SIZE ( SNTP_PACKET_BASE_SIZE ) +#define SNTP_CONTEXT_NETWORK_BUFFER_SIZE ( SNTP_PACKET_BASE_SIZE ) /** * @brief The constant for storing the number of milliseconds per FreeRTOS tick in the system. @@ -107,7 +121,46 @@ * internet time or UTC time. Thus, the actual time duration value per tick of the system will be * larger from the perspective of internet time. */ -#define MILLISECONDS_PER_TICK ( 1000 / configTICK_RATE_HZ ) +#define MILLISECONDS_PER_TICK ( 1000 / configTICK_RATE_HZ ) + +/** + * @brief The fixed size of the key for the AES-128-CMAC algorithm used for authenticating communication + * between the time server and the client. + */ +#define AES_CMAC_AUTHENTICATION_KEY_SIZE ( 16 ) + +/** + * @brief The size of the "Key Identifier" field in the SNTP packet when symmetric key authentication mode as + * security mechanism in communicating with time server. + * + * The "Key Identifier" field appears immediately after the 48 bytes of standard SNTP packet created by the coreSNTP + * library. For more information, refer to the SNTPv4 specification: https://datatracker.ietf.org/doc/html/rfc4330#page-8 + * + * @note This demo uses the "Key Identifier" field to communicate with time servers that support authentication mechanism. + * This field is stored with the Key ID of the AES-128-CMAC based authentication key stored in the time server. + */ +#define SNTP_PACKET_SYMMETRIC_KEY_ID_LENGTH 4 + +/** + * @brief The offset for the starting byte of the "Key Identifier" field in an SNTPv4/NTPv4 packet. + * This field is only used when symmetric key authentication mode is used for communicating with time server. + * + * For more information of the SNTP packet format, refer to the SNTPv4 specification + * https://datatracker.ietf.org/doc/html/rfc4330#page-8 + */ +#define SNTP_PACKET_SYMMETRIC_KEY_ID_OFFSET SNTP_PACKET_BASE_SIZE + +/** + * @brief The total size of an SNTP packet (which remains same for both client request and server response in SNTP communication) + * when using symmetric key based authentication mechanism. + * + * This value includes size of the 48 bytes of standard SNTP packet, and the "Key Identifier" and "Message Digest" fields + * that are used for authentication information in SNTP communication between client and server. + * + * For more information of the SNTP packet format, refer to the SNTPv4 specification + * https://datatracker.ietf.org/doc/html/rfc4330#page-8 + */ +#define SNTP_PACKET_AUTHENTICATED_MODE_SIZE ( SNTP_PACKET_BASE_SIZE + SNTP_PACKET_SYMMETRIC_KEY_ID_LENGTH + pkcs11AES_CMAC_SIGNATURE_LENGTH ) /*-----------------------------------------------------------*/ @@ -118,13 +171,28 @@ * * @note The context is used in the @ref UdpTransportInterface_t interface required * by the coreSNTP library. - * */ struct NetworkContext { Socket_t socket; }; +/** + * @brief The definition of the @ref SntpAuthContext_t structure for the demo. + * This structure represents the symmetric key for the AES-128-CMAC algorithm based + * authentication mechanism shown in the demo for securing SNTP communication + * between client and time server. + * + * @note The context is used in the @ref SntpAuthInterface_t interface required + * by the coreSNTP library for enabling authentication. + */ +struct SntpAuthContext +{ + const char * pServer; + int32_t keyId; + uint8_t pAuthKey[ AES_CMAC_AUTHENTICATION_KEY_SIZE ]; +}; + /** * @brief Structure aggregating state variables for RAM-based wall-clock time * in Coordinated Universal Time (UTC) for system. @@ -169,6 +237,25 @@ static SystemClock_t systemClock; static SemaphoreHandle_t xMutex = NULL; static StaticSemaphore_t xSemaphoreMutex; + +/* + * @brief Stores the configured time servers in an array. + */ +static const char * pTimeServers[] = { democonfigLIST_OF_TIME_SERVERS }; +const size_t numOfServers = sizeof( pTimeServers ) / sizeof( char * ); + +/** + * @brief Stores the list of configured AES-128-CMAC symmetric keys for authentication + * mechanism for corresponding time servers in democonfigLIST_OF_TIME_SERVERS. + */ +static const char * pAESCMACAuthKeys[] = { democonfigLIST_OF_AUTHENTICATION_SYMMETRIC_KEYS }; + +/** + * @brief Stores list of Key IDs corresponding to the authentication keys configured + * in democonfigLIST_OF_TIME_SERVERS. + */ +static const int32_t pAuthKeyIds[] = { democonfigLIST_OF_AUTHENTICATION_KEY_IDS }; + /*-----------------------------------------------------------*/ /** @@ -229,7 +316,8 @@ static bool initializeSntpClient( SntpContext_t * pContext, size_t numOfServers, uint8_t * pContextBuffer, size_t contextBufferSize, - NetworkContext_t * pUdpContext ); + NetworkContext_t * pUdpContext, + SntpAuthContext_t * pAuthContext ); /** * @brief The demo implementation of the @ref SntpResolveDns_t interface to @@ -337,6 +425,129 @@ static void sntpClient_SetTime( const SntpServerInfo_t * pTimeServer, int32_t clockOffsetSec, SntpLeapSecondInfo_t leapSecondInfo ); +/** + * @brief Utility function to create a PKCS11 session and a PKCS11 object, and obtain the PKCS11 + * global function list for performing 128 bit AES-CMAC operations. + * This function is called by the definitions of both the authentication interface functions, + * @ref SntpGenerateAuthCode_t and @ref SntpValidateServerAuth_t, in this demo for the + * AES-CMAC operations. + * + * @param[in] pAuthContext The context representing the symmetric key for the AES-CMAC operation. + * @param[out] pPkcs11Session This is populated with the created PKCS11 session. + * @param[out] pFunctionList This is populated with the function list obtained from the created + * PKCS11 session. + * @param[out] pCmacKey This is populated with the created PKCS11 object handle for AES-CMAC + * operations. + * + * @return The return status code of PKCS11 API calls. + */ +static CK_RV setupPkcs11ObjectForAesCmac( const SntpAuthContext_t * pAuthContext, + CK_SESSION_HANDLE * pPkcs11Session, + CK_FUNCTION_LIST_PTR * pFunctionList, + CK_OBJECT_HANDLE * pCmacKey ); + +/** + * @brief Utility function for filling the authentication context with the time server and + * its associated authentication key information from the democonfigLIST_OF_AUTHENTICATION_SYMMETRIC_KEYS + * and democonfigLIST_OF_AUTHENTICATION_KEY_IDS configuration lists. + * + * The authentication context represents the server and its authentication key information being + * used by the SNTP client at a time for time query. This function is called to update the context + * at the time of SNTP client initialization as well as whenever the SNTP client rotates the time + * server of use. + * + * @param[in] pServer The time server whose information is filled in the context. + * @param[out] pAuthContext The authentication context to update with information about the @p pServer. + */ +static bool populateAuthContextForServer( const char * pServer, + SntpAuthContext_t * pAuthContext ); + +/** + * @brief The demo implementation of the @ref SntpGenerateClientAuth_t function of the authentication + * interface required by the coreSNTP library to execute functionality of generating client-side + * message authentication code and appending it to the time request before sending to a time server. + * + * This function first determines whether the passed time server has an authentication key configured + * in the demo. If the time server supports authentication, the function utilizes the corePKCS11 library + * to generate the client authentication code as a signature using the AES-128-CMAC algorithm, and append + * it to the passed SNTP request packet buffer, @p pRequestBuffer. + * + * @note If the time server supports authentication, this function writes the "Key Identifier" and "Message + * Digest" fields of an SNTP packet. + * + * @param[in, out] pAuthContext The authentication context representing the time server and its authentication + * credentials. If the coreSNTP library rotated the time server of use, then this function updates the context + * to carry authentication information for the new server. + * @param[in] pTimeServer The current time server being used for sending time queries by the SNTP client. + * This is used to determine whether the @p pAuthContext carries stale information of a previously used server, + * and thus, needs to be updated with information of the current server, @p pTimeServer. + * @param[in, out] pRequestBuffer The buffer representing the SNTP request packet, which is already populated with + * the standard 48 bytes of packet data. If the time server supports authentication, then the 48 bytes of data + * and the authentication key are used to generated AES-128-CMAC signature, and the "Key Identifier" and "Message + * Digest" fields of the packet are filled in the buffer. + * @param[in] bufferSize The total buffer size of the @p pRequestBuffer for the SNTP request packet. + * @param[out] pAuthCodeSize This will be populated with the total bytes for authentication data written to the + * @p pRequestBuffer when + * + * @return Returns one of the following: + * - SntpSuccess if EITHER no authentication key information has been configured for the time + * server, and thus, no AES-CMAC operation was performed OR the time server supports authentication and + * the corePKCS11 operations are successful in generating and appending authentication information to the + * @p pRequestBuffer. + * - SntpErrorAuthFailure if there is failure in PKCS#11 operations in generating and appending the AES-128-CMAC + * signature as the authentication code to the @p pRequestBuffer. + */ +static SntpStatus_t addClientAuthCode( SntpAuthContext_t * pAuthContext, + const SntpServerInfo_t * pTimeServer, + void * pRequestBuffer, + size_t bufferSize, + size_t * pAuthCodeSize ); + + +/** + * @brief The demo implementation of the @ref SntpValidateServerAuth_t function of the authentication + * interface required by the coreSNTP library to execute validation of server as the source of the + * received SNTP response by verifying the authentication information present in the packet. + * + * This function first checks whether the passed time server has authentication key information configured + * in the demo to determine if the server supports authentication. If the time server supports authentication, + * the function utilizes the corePKCS11 library to verify the AES-128-CMAC signature in the packet, @p pResponseData + * that represents the server authentication code. + * + * @param[in] pAuthContext The authentication context representing the time server of use and its authentication + * credentials. + * @param[in] pTimeServer The current time server of use from which the response data, @p pResponseData has been + * received by the SNTP client. This SHOULD match the time server information carried by the authentication context. + * @param[in] pResponseData The buffer representing the SNTP response packet, received from the server, @p pTimeServer, + * which contains the server authentication code, if the server supports authentication. The authentication code, if present, + * is verified using corePKCS11 to be the expected AES-128-CMAC signature using the standard 48 bytes of SNTP packet data + * present in the buffer and the secret symmetric key configured for the server. + * @param[in] responseSize The total buffer size of the @p pResponseData for the SNTP response packet. + * + * @return Returns one of the following: + * - SntpSuccess if EITHER no authentication key information has been configured for the time server, and thus, + * no AES-CMAC validation operation is performed OR the time server supports authentication and the authentication + * code has been successfully validated @p pBuffer. + * - SntpErrorAuthFailure if there is internal failure in PKCS#11 operations in validating the server authentication code as + * as the AES-128-CMAC for the information present in the response packet, @p pResponseData. + * - SntpServerNotAuthenticated if the server is not validated from the response due to the authentication code not matching + * the expected AES-128-CMAC signature. + */ +static SntpStatus_t validateServerAuth( SntpAuthContext_t * pAuthContext, + const SntpServerInfo_t * pTimeServer, + const void * pResponseData, + size_t responseSize ); + +/** + * @brief Generates a random number using PKCS#11. + * + * @note It is RECOMMENDED to generate a random number for the call to Sntp_SendTimeRequest API + * of coreSNTP library to protect against server response spoofing attacks from "network off-path" + * attackers. + * + * @return The generated random number. + */ +static uint32_t generateRandomNumber(); /*------------------------------------------------------------------------------*/ @@ -607,6 +818,371 @@ static void sntpClient_SetTime( const SntpServerInfo_t * pTimeServer, xSemaphoreGive( xMutex ); } +/**************************** Authentication Utilities and Interface Functions ***********************************************/ +static bool populateAuthContextForServer( const char * pServer, + SntpAuthContext_t * pAuthContext ) + +{ + size_t index = 0; + + /* Look for the server in the list of configured servers to determine the + * index position of the server so that the server's corresponding information of credentials + * can be found from democonfigLIST_OF_AUTHENTICATION_SYMMETRIC_KEYS and democonfigLIST_OF_AUTHENTICATION_KEY_IDS + * lists. */ + for( index = 0; index < numOfServers; index++ ) + { + if( ( strlen( pServer ) == strlen( pTimeServers[ index ] ) ) && ( strncmp( pServer, pTimeServers[ index ], strlen( pServer ) ) == 0 ) ) + { + /* The records for server in the demo configuration lists have been found. */ + break; + } + } + + /* Make sure that record for server has been found. */ + configASSERT( index != numOfServers ); + + /* Fill the time server in the authentication context. */ + pAuthContext->pServer = pServer; + + /* Determine if the time server has been configured to use authentication mechanism. */ + if( ( pAESCMACAuthKeys[ index ] != NULL ) && ( pAuthKeyIds[ index ] != -1 ) ) + { + const char * pKeyHexString = pAESCMACAuthKeys[ index ]; + + /* Verify that the configured authentication key is 128 bits or 16 bytes in size. As + * the input format is a hex string, the string length should be 32 bytes. */ + configASSERT( strlen( pKeyHexString ) == 2 * AES_CMAC_AUTHENTICATION_KEY_SIZE ); + + /* Set the key ID in the context. */ + pAuthContext->keyId = pAuthKeyIds[ index ]; + + /* Store the configured AES-128-CMAC key for authentication in the SntpAuthContext_t context + * after converting it from hex string to binary. */ + for( index = 0; index < strlen( pKeyHexString ); index += 2 ) + { + char byteString[ 3 ] = { pKeyHexString[ index ], pKeyHexString[ index + 1 ], '\0' }; + uint8_t byteVal = strtoul( byteString, NULL, 16 ); + pAuthContext->pAuthKey[ index / 2 ] = byteVal; + } + } + else + { + /* No key information has been configured for the time server. Thus, communication with the time + * server will not use authentication mechanism. */ + memset( pAuthContext->pAuthKey, 0, sizeof( pAuthContext->pAuthKey ) ); + pAuthContext->keyId = -1; + } +} + +static CK_RV setupPkcs11ObjectForAesCmac( const SntpAuthContext_t * pAuthContext, + CK_SESSION_HANDLE * pPkcs11Session, + CK_FUNCTION_LIST_PTR * pFunctionList, + CK_OBJECT_HANDLE * pCmacKey ) +{ + CK_RV result; + + static CK_BYTE label[] = pkcs11configLABEL_CMAC_KEY; + static CK_KEY_TYPE cmacKeyType = CKK_AES; + static CK_OBJECT_CLASS cmacKeyClass = CKO_SECRET_KEY; + static CK_BBOOL trueObject = CK_TRUE; + + static CK_ATTRIBUTE aes_cmac_template[] = + { + { CKA_CLASS, &cmacKeyClass, sizeof( CK_OBJECT_CLASS ) }, + { CKA_KEY_TYPE, &cmacKeyType, sizeof( CK_KEY_TYPE ) }, + { CKA_LABEL, label, sizeof( label ) - 1 }, + { CKA_TOKEN, &trueObject, sizeof( CK_BBOOL ) }, + { CKA_SIGN, &trueObject, sizeof( CK_BBOOL ) }, + { CKA_VERIFY, &trueObject, sizeof( CK_BBOOL ) }, + { CKA_VALUE, NULL, 0 } + }; + + /* Update the attributes array with the key of AES-CMAC operation. */ + aes_cmac_template[ 6 ].pValue = pAuthContext->pAuthKey; + aes_cmac_template[ 6 ].ulValueLen = sizeof( pAuthContext->pAuthKey ); + + result = xInitializePkcs11Session( pPkcs11Session ); + + if( result != CKR_OK ) + { + LogError( ( "Failed to open PKCS #11 session." ) ); + } + + if( result == CKR_OK ) + { + result = C_GetFunctionList( pFunctionList ); + + if( result != CKR_OK ) + { + LogError( ( "Failed to get PKCS #11 function list." ) ); + } + } + + if( result == CKR_OK ) + { + /* Create the template objects */ + result = ( *pFunctionList )->C_CreateObject( *pPkcs11Session, + ( CK_ATTRIBUTE_PTR ) &aes_cmac_template, + sizeof( aes_cmac_template ) / sizeof( CK_ATTRIBUTE ), + pCmacKey ); + + if( result != CKR_OK ) + { + LogError( ( "Failed to create AES CMAC object." ) ); + } + + configASSERT( *pCmacKey != CK_INVALID_HANDLE ); + } + + return result; +} + +SntpStatus_t addClientAuthCode( SntpAuthContext_t * pAuthContext, + const SntpServerInfo_t * pTimeServer, + void * pRequestBuffer, + size_t bufferSize, + size_t * pAuthCodeSize ) +{ + CK_RV result = CKR_OK; + CK_FUNCTION_LIST_PTR functionList; + CK_SESSION_HANDLE pkcs11Session = 0; + + CK_OBJECT_HANDLE cMacKey; + size_t macBytesWritten = pkcs11AES_CMAC_SIGNATURE_LENGTH; + + CK_MECHANISM mechanism = + { + CKM_AES_CMAC, NULL_PTR, 0 + }; + + /* Determine whether the authentication context information needs to be updated to match + * the passed time server that is to be used for querying time. + * Note: The coreSNTP library will rotate the time server of use for communication to the next + * in the list if either the time server rejects a time request OR times out in its response to the + * time request. In such a case of rotating time server, the application (or user of the coreSNTP + * library) is required to necessary updates to the authentication context to reflect the new + * time server being used for SNTP communication by the SNTP client.*/ + if( ( strlen( pTimeServer->pServerName ) != strlen( pAuthContext->pServer ) ) || + ( strncmp( pTimeServer->pServerName, pAuthContext->pServer, strlen( pAuthContext->pServer ) ) != 0 ) ) + { + /* Update the authentication context to represent the new time server of usage for + * time requests. */ + populateAuthContextForServer( pTimeServer->pServerName, pAuthContext ); + } + + /* Check if the time server supports AES-128-CMAC authentication scheme in communication. + * If the time server supports authentication, then proceed with operation of generating client + * authentication code from the SNTP request packet and appending it to the request buffer. */ + if( pAuthContext->keyId != -1 ) + { + /* Ensure that the buffer is large enough to hold the "Key Identifier" and "Message Digest" fields + * for authentication information of the SNTP time request packet. */ + configASSERT( bufferSize >= SNTP_PACKET_AUTHENTICATED_MODE_SIZE ); + + result = setupPkcs11ObjectForAesCmac( pAuthContext, + &pkcs11Session, + &functionList, + &cMacKey ); + + if( result == CKR_OK ) + { + /* Test SignInit and Sign */ + result = functionList->C_SignInit( pkcs11Session, &mechanism, cMacKey ); + + if( result != CKR_OK ) + { + LogError( ( "Failed to C_SignInit AES CMAC." ) ); + } + } + + /* Append the Key ID of the signing key before appending the signature to the buffer. */ + *( uint32_t * ) ( ( uint8_t * ) pRequestBuffer + SNTP_PACKET_SYMMETRIC_KEY_ID_OFFSET ) = FreeRTOS_htonl( pAuthContext->keyId ); + + /* Generate the authentication code as the signature of the time request packet + * with the configured key. */ + if( result == CKR_OK ) + { + result = functionList->C_Sign( pkcs11Session, + ( CK_BYTE_PTR ) pRequestBuffer, + SNTP_PACKET_BASE_SIZE, + ( CK_BYTE_PTR ) pRequestBuffer + SNTP_PACKET_BASE_SIZE + SNTP_PACKET_SYMMETRIC_KEY_ID_LENGTH, + &macBytesWritten ); + + if( result != CKR_OK ) + { + LogError( ( "Failed to generate client auth code: Failed to generate AES-128-CMAC signature of SNTP request packet." ) ); + } + } + + /* Close the PKCS #11 session as the AES-CMAC operation is completed. */ + if( result == CKR_OK ) + { + result = functionList->C_CloseSession( pkcs11Session ); + configASSERT( result == CKR_OK ); + + result = functionList->C_Finalize( NULL ); + configASSERT( result == CKR_OK ); + } + + if( result == CKR_OK ) + { + *pAuthCodeSize = SNTP_PACKET_SYMMETRIC_KEY_ID_LENGTH + pkcs11AES_CMAC_SIGNATURE_LENGTH; + } + } + else + { + /* Server has not been configured with authentication key information, thus, no data was appended to the + * request packet buffer. */ + *pAuthCodeSize = 0; + } + + return ( result == CKR_OK ) ? SntpSuccess : SntpErrorAuthFailure; +} + +SntpStatus_t validateServerAuth( SntpAuthContext_t * pAuthContext, + const SntpServerInfo_t * pTimeServer, + const void * pResponseData, + size_t responseSize ) +{ + CK_RV result = CKR_OK; + CK_FUNCTION_LIST_PTR functionList; + CK_SESSION_HANDLE pkcs11Session = 0; + SntpStatus_t returnStatus = SntpSuccess; + + CK_OBJECT_HANDLE cMacKey; + size_t macBytesWritten = pkcs11AES_CMAC_SIGNATURE_LENGTH; + + CK_MECHANISM mechanism = + { + CKM_AES_CMAC, NULL_PTR, 0 + }; + + /* The time server information in the authentication context, managed by this demo application, and the + * pTimeServer parameter, passed by the coreSNTP library, MUST be the same. + * Note: The addClientAuthCode() function + * is responsible for updating the authentication context to represent the time server being currently used + * by the coreSNTP library for time querying. */ + configASSERT( ( strlen( pTimeServer->pServerName ) == strlen( pAuthContext->pServer ) ) && + ( strncmp( pTimeServer->pServerName, pAuthContext->pServer, strlen( pAuthContext->pServer ) ) == 0 ) ); + + /* Check if the time server supports AES-128-CMAC authentication scheme in communication. + * If the time server supports authentication, then proceed with operation of validating server + * from the authentication code in the response payload. */ + if( pAuthContext->keyId != -1 ) + { + /* As the server supports authentication mode of communication, the server response size + * SHOULD contain the authentication code. */ + configASSERT( responseSize >= ( SNTP_PACKET_AUTHENTICATED_MODE_SIZE ) ); + + result = setupPkcs11ObjectForAesCmac( pAuthContext, + &pkcs11Session, + &functionList, + &cMacKey ); + + if( result == CKR_OK ) + { + /* Test SignInit and Sign */ + result = functionList->C_VerifyInit( pkcs11Session, &mechanism, cMacKey ); + + if( result != CKR_OK ) + { + returnStatus = SntpErrorAuthFailure; + LogError( ( "Failed to C_VerifyInit AES CMAC." ) ); + } + } + else + { + returnStatus = SntpErrorAuthFailure; + } + + /* Generate the authentication code as the signature of the time request packet + * with the configured key. */ + if( result == CKR_OK ) + { + result = functionList->C_Verify( pkcs11Session, + ( CK_BYTE_PTR ) pResponseData, + SNTP_PACKET_BASE_SIZE, + ( CK_BYTE_PTR ) pResponseData + SNTP_PACKET_SYMMETRIC_KEY_ID_OFFSET + SNTP_PACKET_SYMMETRIC_KEY_ID_LENGTH, + pkcs11AES_CMAC_SIGNATURE_LENGTH ); + + if( result != CKR_OK ) + { + returnStatus = SntpServerNotAuthenticated; + LogError( ( "Server cannot be validated from received response: AES-128-CMAC signature in response packet does not match expected." ) ); + } + } + + /* Close the PKCS #11 session as the AES-CMAC operation is completed. */ + if( result == CKR_OK ) + { + result = functionList->C_CloseSession( pkcs11Session ); + configASSERT( result == CKR_OK ); + + result = functionList->C_Finalize( NULL ); + configASSERT( result == CKR_OK ); + } + } + + return returnStatus; +} + + +/*************************************************************************************/ + +static uint32_t generateRandomNumber() +{ + CK_RV pkcs11Status = CKR_OK; + CK_FUNCTION_LIST_PTR pFunctionList = NULL; + CK_SESSION_HANDLE session = CK_INVALID_HANDLE; + uint32_t randomNum = 0; + + /* Get list of functions supported by the PKCS #11 port. */ + pkcs11Status = C_GetFunctionList( &pFunctionList ); + + if( pkcs11Status != CKR_OK ) + { + configASSERT( pFunctionList != NULL ); + LogError( ( "Failed to generate random number. " + "PKCS #11 API, C_GetFunctionList, failed." ) ); + } + + if( pkcs11Status == CKR_OK ) + { + /* Initialize PKCS #11 module and create a new session. */ + pkcs11Status = xInitializePkcs11Session( &session ); + + if( pkcs11Status != CKR_OK ) + { + configASSERT( session != CK_INVALID_HANDLE ); + + LogError( ( "Failed to generate random number. " + "Failed to initialize PKCS #11 session." ) ); + } + } + + if( pkcs11Status == CKR_OK ) + { + if( pFunctionList->C_GenerateRandom( session, + &randomNum, + sizeof( randomNum ) ) != CKR_OK ) + { + LogError( ( "Failed to generate random number. " + "PKCS #11 API, C_GenerateRandom, failed to generate random number." ) ); + } + } + + if( pkcs11Status == CKR_OK ) + { + if( pFunctionList->C_CloseSession( session ) != CKR_OK ) + { + LogError( ( " Failed to close PKCS #11 session after generating random number." ) ); + } + } + + return randomNum; +} + + /*************************************************************************************/ void initializeSystemClock( void ) @@ -636,7 +1212,8 @@ static bool initializeSntpClient( SntpContext_t * pContext, size_t numOfServers, uint8_t * pContextBuffer, size_t contextBufferSize, - NetworkContext_t * pUdpContext ) + NetworkContext_t * pUdpContext, + SntpAuthContext_t * pAuthContext ) { bool initStatus = false; @@ -649,7 +1226,7 @@ static bool initializeSntpClient( SntpContext_t * pContext, } else { - for( int8_t index = 0; index < numOfServers; index++ ) + for( uint8_t index = 0; index < numOfServers; index++ ) { pServers[ index ].pServerName = pTimeServers[ index ]; pServers[ index ].port = SNTP_DEFAULT_SERVER_PORT; @@ -675,6 +1252,7 @@ static bool initializeSntpClient( SntpContext_t * pContext, { struct freertos_sockaddr bindAddress; UdpTransportInterface_t udpTransportIntf; + SntpAuthenticationInterface_t symmetricKeyAuthIntf; bindAddress.sin_port = FreeRTOS_htons( SNTP_DEFAULT_SERVER_PORT ); @@ -689,6 +1267,11 @@ static bool initializeSntpClient( SntpContext_t * pContext, udpTransportIntf.sendTo = UdpTransport_Send; udpTransportIntf.recvFrom = UdpTransport_Recv; + /* Set the authentication interface object. */ + symmetricKeyAuthIntf.pAuthContext = pAuthContext; + symmetricKeyAuthIntf.generateClientAuth = addClientAuthCode; + symmetricKeyAuthIntf.validateServerAuth = validateServerAuth; + /* Initialize context. */ Sntp_Init( pContext, pServers, @@ -700,7 +1283,7 @@ static bool initializeSntpClient( SntpContext_t * pContext, sntpClient_GetTime, sntpClient_SetTime, &udpTransportIntf, - NULL ); + &symmetricKeyAuthIntf ); initStatus = true; } @@ -715,27 +1298,45 @@ void sntpTask( void * pParameters ) { SntpContext_t clientContext; bool initStatus = false; + CK_RV pkcs11Status; + + /* Validate that the configured lists of time servers, authentication keys and key IDs + * are of the same length. */ + configASSERT( numOfServers == ( sizeof( pAESCMACAuthKeys ) / sizeof( pAESCMACAuthKeys[ 0 ] ) ) ); + configASSERT( numOfServers == sizeof( pAuthKeyIds ) / sizeof( pAuthKeyIds[ 0 ] ) ); /* Variable representing the SNTP client context. */ static SntpContext_t context; /* Memory for the SNTP packet buffer in the SNTP context. */ - static uint8_t contextBuffer[ SNTP_CONTEXT_NETWORK_BUFFER_SIZE ]; + static uint8_t contextBuffer[ SNTP_PACKET_AUTHENTICATED_MODE_SIZE ]; /* Memory for the network context representing the UDP socket that will be * passed to the SNTP client context. */ static NetworkContext_t udpContext; - /* Store the configured time servers in an array. */ - static const char * pTimeServers[] = { democonfigLIST_OF_TIME_SERVERS }; - const size_t numOfServers = sizeof( pTimeServers ) / sizeof( char * ); + /* Initialize PKCS11 module for cryptographic operations of AES-128-CMAC show + * shown in this demo for authentication mechanism in SNTP communication with server. */ + pkcs11Status = xInitializePKCS11(); + configASSERT( pkcs11Status == CKR_OK ); + + /* Memory for authentication context that will be passed to the SNTP client context through + * the authentication interface. This represents a combination of the time server and + * its authentication key information that will be utilized for authentication communication + * between client and server, if the server supports authentication. */ + static SntpAuthContext_t authContext; + + /* Initialize the authentication context for information for the first time server and its + * keys configured in the demo. */ + populateAuthContextForServer( pTimeServers[ 0 ], &authContext ); initStatus = initializeSntpClient( &clientContext, pTimeServers, numOfServers, contextBuffer, sizeof( contextBuffer ), - &udpContext ); + &udpContext, + &authContext ); if( initStatus == true ) { @@ -753,9 +1354,13 @@ void sntpTask( void * pParameters ) /* SNTP Client loop of sending and receiving SNTP packets for time synchronization at poll intervals */ while( 1 ) { - /* TODO - Generate random number with corePKCS11. */ - status = Sntp_SendTimeRequest( &clientContext, 100 ); - configASSERT( status == SntpSuccess ); + status = Sntp_SendTimeRequest( &clientContext, generateRandomNumber() ); + + /*configASSERT( status == SntpSuccess ); */ + if( status != SntpSuccess ) + { + continue; + } /* Wait till the server response is not received. */ do diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/WIN32.vcxproj b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/WIN32.vcxproj old mode 100644 new mode 100755 index 602de1d0f..17cdea642 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/WIN32.vcxproj +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/WIN32.vcxproj @@ -58,8 +58,8 @@ Disabled - ..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\Common\WinPCap;..\..\..\FreeRTOS\Source\include;..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\Source\Application-Protocols\coreSNTP\source\include;.;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\..\Source\Utilities\mbedtls_freertos;..\..\..\Source\FreeRTOS-Plus-Trace\Include;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\include;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;..\..\..\FreeRTOS-Plus\Source\Utilities\logging;..\Common\WinPCap;..\..\..\FreeRTOS\Source\include;..\..\..\FreeRTOS-Plus\Source\corePKCS11\source\include;..\..\..\FreeRTOS-Plus\Source\corePKCS11\source\dependency\3rdparty\pkcs11;..\..\ThirdParty\mbedtls\include;..\..\..\FreeRTOS-Plus\Source\corePKCS11\source\dependency\3rdparty\mbedtls_utils;..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\Source\Application-Protocols\coreSNTP\source\include;.;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;MBEDTLS_CONFIG_FILE="mbedtls_config.h";CONFIG_MEDTLS_USE_AFR_MEMORY;%(PreprocessorDefinitions) false EnableFastChecks MultiThreadedDLL @@ -88,7 +88,7 @@ .\Debug/WIN32.pdb Console MachineX86 - wpcap.lib;%(AdditionalDependencies) + wpcap.lib;Bcrypt.lib;%(AdditionalDependencies) ..\Common\WinPCap false false @@ -130,7 +130,7 @@ Console MachineX86 ..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap - wpcap.lib;%(AdditionalDependencies) + wpcap.lib;Bcrypt.lib;%(AdditionalDependencies) true @@ -146,6 +146,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -188,11 +279,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - @@ -200,6 +386,9 @@ + + + diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/WIN32.vcxproj.filters b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/WIN32.vcxproj.filters old mode 100644 new mode 100755 index 1e7f6386e..e1a445c3f --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/WIN32.vcxproj.filters +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/WIN32.vcxproj.filters @@ -41,27 +41,30 @@ {6ad56e6d-c330-4830-8f4b-c75b05dfa866} - - {84613aa2-91dc-4e1a-a3b3-823b6d7bf0e0} - - - {70524181-23e5-4dde-a3fb-6afc11d6df04} - - - {6e7ee4cd-b54c-4f67-9b70-8c1e9fe80b92} - {59d75faa-e4df-4d85-bf56-67e9cc801004} - - {212f58ea-e09c-4778-9935-31b4e95538ee} - - - {2e22b7fe-a180-47a1-b459-6a3451c7a4ee} - {1407130d-da4c-4bcc-8ca0-4cf77f4cf97f} + + {78a81f37-e1f1-4ef1-b067-bb23c8e1dfe2} + + + {38512398-609b-4a9b-bc1a-67cab17720ae} + + + {6a7d78a6-4f09-4a5f-a692-ce4791240881} + + + {e32be358-792b-45ab-b1c5-f87e64315cd3} + + + {e88d4eab-3fad-4755-a5a4-41c6e4f59089} + + + {817c6143-0ae9-4cac-828f-08f0da380f99} + @@ -121,18 +124,288 @@ FreeRTOS\Source - - + + FreeRTOS\Source + + DemoTasks + DemoTasks - - FreeRTOS+\FreeRTOS IoT Libraries\standard\coreSNTP + + FreeRTOS+\mbedtls - - FreeRTOS+\FreeRTOS IoT Libraries\standard\coreSNTP + + FreeRTOS+\mbedtls + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\mbedtls + + + FreeRTOS+\FreeRTOS IoT Libraries\standard\corePKCS11 + + + FreeRTOS+\FreeRTOS IoT Libraries\standard\corePKCS11 + + + FreeRTOS+\FreeRTOS IoT Libraries\standard\corePKCS11 + + + FreeRTOS+\FreeRTOS IoT Libraries\standard\corePKCS11 + + + FreeRTOS+\FreeRTOS IoT Libraries\platform\mbedtls + + + FreeRTOS+\FreeRTOS IoT Libraries\platform\mbedtls + + + + @@ -204,21 +477,6 @@ FreeRTOS\Source\include - - FreeRTOS+\FreeRTOS IoT Libraries\standard\coreSNTP\include - - - FreeRTOS+\FreeRTOS IoT Libraries\standard\coreSNTP\include - - - FreeRTOS+\FreeRTOS+TCP\include - - - FreeRTOS+\FreeRTOS IoT Libraries\standard\coreSNTP\include - - - FreeRTOS+\FreeRTOS IoT Libraries\platform\backoff_algorithm\include - FreeRTOS+\FreeRTOS IoT Libraries\platform\logging @@ -243,5 +501,264 @@ Config + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\mbedtls\include + + + FreeRTOS+\FreeRTOS IoT Libraries\platform\mbedtls + + + FreeRTOS+\FreeRTOS IoT Libraries\standard\corePKCS11\3rdparty\pkcs11 + + + FreeRTOS+\FreeRTOS IoT Libraries\standard\corePKCS11\3rdparty\pkcs11 + + + FreeRTOS+\FreeRTOS IoT Libraries\standard\corePKCS11\3rdparty\pkcs11 + + + FreeRTOS+\FreeRTOS IoT Libraries\standard\corePKCS11\include + + + FreeRTOS+\FreeRTOS IoT Libraries\standard\corePKCS11\include + + + FreeRTOS+\FreeRTOS IoT Libraries\standard\corePKCS11\include + + + + + \ No newline at end of file diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/core_pkcs11_config.h b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/core_pkcs11_config.h new file mode 100644 index 000000000..d92a50217 --- /dev/null +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/core_pkcs11_config.h @@ -0,0 +1,192 @@ +/* + * FreeRTOS V202104.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/** + * @file core_pkcs11_config.h + * @brief PCKS#11 config options. + */ + + +#ifndef _CORE_PKCS11_CONFIG_H_ +#define _CORE_PKCS11_CONFIG_H_ + +#include "FreeRTOS.h" + +/**************************************************/ +/******* DO NOT CHANGE the following order ********/ +/**************************************************/ + +/* Include logging header files and define logging macros in the following order: + * 1. Include the header file "logging_levels.h". + * 2. Define the LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL macros depending on + * the logging configuration for PKCS #11. + * 3. Include the header file "logging_stack.h", if logging is enabled for PKCS #11. + */ + +#include "logging_levels.h" + +/* Logging configuration for the PKCS #11 library. */ +#ifndef LIBRARY_LOG_NAME + #define LIBRARY_LOG_NAME "PKCS11" +#endif + +#ifndef LIBRARY_LOG_LEVEL + #define LIBRARY_LOG_LEVEL LOG_ERROR +#endif + +/* Prototype for the function used to print to console on Windows simulator + * of FreeRTOS. + * The function prints to the console before the network is connected; + * then a UDP port after the network has connected. */ +extern void vLoggingPrintf( const char * pcFormatString, + ... ); + +/* Map the SdkLog macro to the logging function to enable logging + * on Windows simulator. */ +#ifndef SdkLog + #define SdkLog( message ) vLoggingPrintf message +#endif + +#include "logging_stack.h" + +/** + * @brief Malloc API used by core_pkcs11.h + */ +#define PKCS11_MALLOC pvPortMalloc + +/** + * @brief Free API used by core_pkcs11.h + */ +#define PKCS11_FREE vPortFree + +/** + * @brief PKCS #11 default user PIN. + * + * The PKCS #11 standard specifies the presence of a user PIN. That feature is + * sensible for applications that have an interactive user interface and memory + * protections. However, since typical microcontroller applications lack one or + * both of those, the user PIN is assumed to be used herein for interoperability + * purposes only, and not as a security feature. + * + * Note: Do not cast this to a pointer! The library calls sizeof to get the length + * of this string. + */ +#define configPKCS11_DEFAULT_USER_PIN "0000" + +/** + * @brief Maximum length (in characters) for a PKCS #11 CKA_LABEL + * attribute. + */ +#define pkcs11configMAX_LABEL_LENGTH 32 + +/** + * @brief Maximum number of token objects that can be stored + * by the PKCS #11 module. + */ +#define pkcs11configMAX_NUM_OBJECTS 6 + +/** + * @brief Maximum number of sessions that can be stored + * by the PKCS #11 module. + */ +#define pkcs11configMAX_SESSIONS 10 + +/** + * @brief Set to 1 if a PAL destroy object is implemented. + * + * If set to 0, no PAL destroy object is implemented, and this functionality + * is implemented in the common PKCS #11 layer. + */ +#define pkcs11configPAL_DESTROY_SUPPORTED 0 + +/** + * @brief Set to 1 if OTA image verification via PKCS #11 module is supported. + * + * If set to 0, OTA code signing certificate is built in via + * aws_ota_codesigner_certificate.h. + */ +#define pkcs11configOTA_SUPPORTED 0 + +/** + * @brief Set to 1 if PAL supports storage for JITP certificate, + * code verify certificate, and trusted server root certificate. + * + * If set to 0, PAL does not support storage mechanism for these, and + * they are accessed via headers compiled into the code. + */ +#define pkcs11configJITP_CODEVERIFY_ROOT_CERT_SUPPORTED 0 + +/** + * @brief The PKCS #11 label for device private key. + * + * Private key for connection to AWS IoT endpoint. The corresponding + * public key should be registered with the AWS IoT endpoint. + */ +#define pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS "Device Priv TLS Key" + +/** + * @brief The PKCS #11 label for device public key. + * + * The public key corresponding to pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS. + */ +#define pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS "Device Pub TLS Key" + +/** + * @brief The PKCS #11 label for the device certificate. + * + * Device certificate corresponding to pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS. + */ +#define pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS "Device Cert" + +/** + * @brief The PKCS #11 label for the object to be used for CMAC operations. + */ +#define pkcs11configLABEL_CMAC_KEY "CMAC Key" + +/** + * @brief The PKCS #11 label for the object to be used for code verification. + * + * Used by over-the-air update code to verify an incoming signed image. + */ +#define pkcs11configLABEL_CODE_VERIFICATION_KEY "Code Verify Key" + +/** + * @brief The PKCS #11 label for Just-In-Time-Provisioning. + * + * The certificate corresponding to the issuer of the device certificate + * (pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS) when using the JITR or + * JITP flow. + */ +#define pkcs11configLABEL_JITP_CERTIFICATE "JITP Cert" + +/** + * @brief The PKCS #11 label for the AWS Trusted Root Certificate. + * + * @see aws_default_root_certificates.h + */ +#define pkcs11configLABEL_ROOT_CERTIFICATE "Root Cert" + +#endif /* _CORE_PKCS11_CONFIG_H_ */ diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/demo_config.h b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/demo_config.h index 75fbd1418..d306cab29 100755 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/demo_config.h +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/demo_config.h @@ -90,8 +90,49 @@ extern void vLoggingPrintf( const char * pcFormatString, * @brief The set of time servers, in decreasing order of priority, for configuring the SNTP client. * The servers SHOULD be listed as comma-separated list of strings. For example, the following * can be a configuration used: + * + * #define democonfigLIST_OF_TIME_SERVERS "", "", "pool.ntp.org" + */ + +/** + * @brief The list of 128-bit (or 16 bytes) symmetric keys for authenticating communication with the NTP/SNTP time servers + * corresponding to the list in democonfigLIST_OF_TIME_SERVERS. A symmetric key is used for generating authentication code + * in client request to related NTP/SNTP server as well as validating server from the time response received. + * + * This demo shows use of AES-128-CMAC algorithm for a mutual authentication mechanism in the SNTP communication + * between the NTP/SNTP server and client. The demo generates a Message Authentication Code (MAC) using + * the algorithm and appends it to the client request packet before the coreSNTP library sends it over + * the network to the server. The server validates the client from the request from the authentication code + * present in the request packet. Similarly, this demo validates the server from the response received on + * the network by verifying the authentication code present in the response packet. + * + * It is RECOMMENDED to use an authentication mechanism for protecting devices against server spoofing + * attacks. + * + * @note Please provide the 128-bit keys as comma separated list of hexadecimal strings in the order matching + * the list of time servers configured in democonfigLIST_OF_TIME_SERVERS configuration. If a time server does + * not support authentication, then NULL should be used to indicate use of no authentication mechanism for the + * time server. + * + * @note Use of the AES-128-CMAC based authentication scheme in the demo requires that the symmetric key + * is shared safely between the time server and the client device. + * + * #define democonfigAES_CMAC_AUTHENTICATION_SYMMETRIC_KEY "", "", NULL + */ + +/** + * @brief The list of key IDs of the shared @ref democonfigLIST_OF_AUTHENTICATION_SYMMETRIC_KEYS keys between + * the client and the corresponding NTP/SNTP servers, in democonfigLIST_OF_TIME_SERVERS, for authenticating + * the SNTP communication between the client and server. + * + * The ID for a key usually represents the ID used to reference the symmetric key in the NTP/SNTP server system. + * + * @note This Key IDs should be configured as a comma-separated list of integer Key IDs that match the order of + * keys in democonfigdemoconfigLIST_OF_AUTHENTICATION_SYMMETRIC_KEYS. If there is a NULL (or no key) in the list + * of keys, then -1 can be used as the corresponding key ID. + * + * #define democonfigLIST_OF_AUTHENTICATION_KEY_IDS , , -1 */ -#define democonfigLIST_OF_TIME_SERVERS "time.cloudflare.com", "pool.ntp.org" /** * @brief The year to bake in the demo application for initializing the system clock with. diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/main.c index 7a8a666e0..17e017225 100755 --- a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/main.c +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/main.c @@ -47,6 +47,11 @@ /* Demo logging includes. */ #include "logging.h" +/* mbedTLS include for configuring + * threading functions. */ +#include "mbedtls/threading.h" +#include "threading_alt.h" + /* Demo Specific configs. */ #include "demo_config.h" #include "common_demo_include.h" @@ -150,6 +155,12 @@ void vStartSntpDemo( void ) { initializeSystemClock(); + /* Configure mbedTLS to use FreeRTOS specific threading function. */ + mbedtls_threading_set_alt( mbedtls_platform_mutex_init, + mbedtls_platform_mutex_free, + mbedtls_platform_mutex_lock, + mbedtls_platform_mutex_unlock ); + /* Create the SNTP client task that is responsible for synchronizing system time with the time servers * periodically. This is created as a high priority task to keep the SNTP client operation unhindered. */ xTaskCreate( sntpTask, /* Function that implements the task. */ diff --git a/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/mbedtls_config.h b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/mbedtls_config.h new file mode 100755 index 000000000..fb75ed540 --- /dev/null +++ b/FreeRTOS-Plus/Demo/coreSNTP_Windows_Simulator/mbedtls_config.h @@ -0,0 +1,137 @@ +/* + * FreeRTOS V202104.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* This file configures mbed TLS for FreeRTOS. */ + +#ifndef MBEDTLS_CONFIG_H_ +#define MBEDTLS_CONFIG_H_ + +/* FreeRTOS include. */ +#include "FreeRTOS.h" + +/* Generate errors if deprecated functions are used. */ +#define MBEDTLS_DEPRECATED_REMOVED + +/* Place AES tables in ROM. */ +#define MBEDTLS_AES_ROM_TABLES + +/* Enable the following cipher modes. */ +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_CIPHER_MODE_CFB +#define MBEDTLS_CIPHER_MODE_CTR + +/* Enable CMAC mode for authentication code generation. */ +#define MBEDTLS_CMAC_C + +/* Enable the following cipher padding modes. */ +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS +#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN +#define MBEDTLS_CIPHER_PADDING_ZEROS + +/* Cipher suite configuration. */ +#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_NIST_OPTIM +#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +/* Enable all SSL alert messages. */ +#define MBEDTLS_SSL_ALL_ALERT_MESSAGES + +/* Enable the following SSL features. */ +#define MBEDTLS_SSL_ENCRYPT_THEN_MAC +#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET +#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +#define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_ALPN +#define MBEDTLS_SSL_SERVER_NAME_INDICATION + +/* Check certificate key usage. */ +#define MBEDTLS_X509_CHECK_KEY_USAGE +#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE + +/* Disable platform entropy functions. */ +#define MBEDTLS_NO_PLATFORM_ENTROPY + +/* Enable the following mbed TLS features. */ +#define MBEDTLS_AES_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_BASE64_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_CTR_DRBG_C +#define MBEDTLS_ECDH_C +#define MBEDTLS_ECDSA_C +#define MBEDTLS_ECP_C +#define MBEDTLS_ENTROPY_C +#define MBEDTLS_ENTROPY_HARDWARE_ALT + +#define MBEDTLS_GCM_C +#define MBEDTLS_MD_C +#define MBEDTLS_OID_C +#define MBEDTLS_PEM_PARSE_C +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PK_WRITE_C +#define MBEDTLS_PKCS1_V15 +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_RSA_C +#define MBEDTLS_SHA1_C +#define MBEDTLS_SHA256_C +#define MBEDTLS_SSL_CLI_C +#define MBEDTLS_SSL_TLS_C +#define MBEDTLS_THREADING_ALT +#define MBEDTLS_THREADING_C +#define MBEDTLS_X509_USE_C +#define MBEDTLS_X509_CRT_PARSE_C + +/* Set the memory allocation functions on FreeRTOS. */ +void * mbedtls_platform_calloc( size_t nmemb, + size_t size ); +void mbedtls_platform_free( void * ptr ); +#define MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_PLATFORM_CALLOC_MACRO mbedtls_platform_calloc +#define MBEDTLS_PLATFORM_FREE_MACRO mbedtls_platform_free + +/* The network send and receive functions on FreeRTOS. */ +int mbedtls_platform_send( void * ctx, + const unsigned char * buf, + size_t len ); +int mbedtls_platform_recv( void * ctx, + unsigned char * buf, + size_t len ); + +/* The entropy poll function. */ +int mbedtls_platform_entropy_poll( void * data, + unsigned char * output, + size_t len, + size_t * olen ); + +#include "mbedtls/check_config.h" + +#endif /* ifndef MBEDTLS_CONFIG_H_ */ diff --git a/lexicon.txt b/lexicon.txt index cb69f36f5..98f665f69 100644 --- a/lexicon.txt +++ b/lexicon.txt @@ -7,6 +7,7 @@ aclk acm adc adcclk +addclientauthcode adden addfaketaskwaitingtoreceivefromqueue addfaketaskwaitingtosendtoqueue @@ -151,6 +152,7 @@ bss btimer btn buf +buffersize bufsize burtc burtcclkdiv @@ -441,6 +443,7 @@ dap dat datashee datasheet +datatracker dbe dcdc dclr @@ -811,6 +814,7 @@ het hetbase hetport hetreg +hexstring hfclk hfrco hfxo @@ -1396,6 +1400,8 @@ passsed passwordsize pasv pathlen +pauthcodesize +pauthcontext payloadlength pb pbasetime @@ -1445,6 +1451,7 @@ pclientcert pclk pclkb pclwipappsblockinggettxbuffer +pcmackey pcmethod pcmyreply pcname @@ -1511,6 +1518,7 @@ pfm pfr pfs pfswe +pfunctionlist phostname php phy @@ -1609,11 +1617,13 @@ preceivedcommand predivide prefen premain +prequestbuffer prescale prescaled prescaler presense presigned +presponsedata prev printc printf @@ -1812,6 +1822,7 @@ ps psc pscheckvariable psel +pserver pserverinfo psignature psl @@ -2048,6 +2059,7 @@ resetart resetprg resoltion resp +responsesize resubscribe resubscribes resync @@ -2214,6 +2226,9 @@ sni snprintf sntp sntpclienttask +sntperrorauthfailure +sntpservernotauthenticated +sntpsuccess sntptask soc sockaddr @@ -2370,6 +2385,7 @@ tim timeguard timertest timertimer +timeserver tls tmr tmrdemoone