Skip to content

Commit

Permalink
helpers-sntp: Add helper library for time synchronisation
Browse files Browse the repository at this point in the history
This helper library shall be used with any FRI application
to add real clock time synchronisation for the target.

This addition is needed to fix AWS TLS Expired Server Cert
test which is part of AWS Device Advisor Validation tests as
this test requires the device under test to have synchronised
real time clock to be able to detect that the server's certificate
is expired and reject it.

Signed-off-by: Ahmed Ismail <[email protected]>
  • Loading branch information
AhmedIsmail02 committed Mar 1, 2024
1 parent c46bd2e commit cc91a29
Show file tree
Hide file tree
Showing 5 changed files with 1,987 additions and 0 deletions.
1 change: 1 addition & 0 deletions applications/helpers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ add_subdirectory(device_advisor)
add_subdirectory(events)
add_subdirectory(logging)
add_subdirectory(provisioning)
add_subdirectory(sntp)
26 changes: 26 additions & 0 deletions applications/helpers/sntp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2024 Arm Limited and/or its affiliates
# <[email protected]>
# SPDX-License-Identifier: MIT

add_library(helpers-sntp
src/sntp_client_task.c
)

target_include_directories(helpers-sntp
PUBLIC
inc
)

target_include_directories(coresntp-config
INTERFACE
inc
)

target_link_libraries(helpers-sntp
backoff-algorithm
connectivity-stack
corepkcs11
coresntp
helpers-logging
mbedtls
)
188 changes: 188 additions & 0 deletions applications/helpers/sntp/inc/core_sntp_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
/*
* FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <[email protected]>
*
* 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
*
*/
#ifndef CORE_SNTP_CONFIG_H
#define CORE_SNTP_CONFIG_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 SNTP.
* 3. Include the header file "logging_stack.h", if logging is enabled for SNTP.
*/

#include "logging_levels.h"

/* Logging configuration for the SNTP library. */
#ifndef LIBRARY_LOG_NAME
#define LIBRARY_LOG_NAME "SNTP"
#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"
/************ End of logging configuration ****************/

/**
* @brief The time period between consecutive time polling requests that are sent by the
* SNTP client in the demo application.
*
* @note According to the SNTPv4 specification, the polling interval MUST NOT be less
* than 15 seconds for responsible use of time servers by SNTP clients.
*
*
*/
#define democonfigSNTP_CLIENT_POLLING_INTERVAL_SECONDS ( 16 )

/**
* @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 Even though this demo shows the use of AES-128-CMAC, a symmetric-key cryptographic based
* solution, for authenticating SNTP communication between the demo (SNTP client) and
* SNTP/NTP server, we instead RECOMMEND that production devices use the most secure authentication
* mechanism alternative available with the Network Time Security (NTS) protocol, an asymmetric-key
* cryptographic protocol. For more information, refer to the NTS specification here:
* https://datatracker.ietf.org/doc/html/rfc8915
*
* @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 democonfigLIST_OF_AUTHENTICATION_SYMMETRIC_KEYS 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 democonfigLIST_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

/**
* @brief The year to bake in the demo application for initializing the system clock with.
* The demo initializes the system clock time for the starting second of the 1st January of
* the configured year. So for example, with a configuration of year 2021, the demo will
* initialize the system clock time as 1st January 2021 00h:00m:00s.
*
* @note The coreSNTP library REQUIRES that the client system time is within ~68 years of internet
* time. Thus, for systems that do not have an Real-Time Clock module, this demo shows how
* a starting time can be baked in the device firmware to keep the starting time of the system
* close to actual time on the first boot-up of device.
* For such systems without Real-Time Clock module, all device boot ups from subsequent device resets
* or power cycles can continue to carry close to correct time by EITHER
* * (RECOMMENDED) Saving the most recent time in non-volatile memory
* OR
* * Using the same firmware baked-in starting time of device for every boot-up.
*/
#define democonfigSYSTEM_START_YEAR ( 2024 )

/**
* @brief The timeout (in milliseconds) for the time response to a time request made to a
* time server.
*/
#define democonfigSERVER_RESPONSE_TIMEOUT_MS ( 5000 )

/**
* @brief The maximum block time (in milliseconds) for an attempt to send time request over the network
* to a time server when through the Sntp_SendTimeRequest API.
*/
#define democonfigSEND_TIME_REQUEST_TIMEOUT_MS ( 50 )

/**
* @brief The maximum block time (in milliseconds) for an attempt to read server response (to a time request)
* from the network through the Sntp_ReceiveTimeResponse API.
*
* @note This value MAY BE less than the server response timeout (configured in democonfigSERVER_RESPONSE_TIMEOUT_MS)
* to support use-cases when application DOES NOT want to block for the entire server response timeout period.
* In such a case, the Sntp_ReceiveTimeResponse API can be called multiple times (with block time duration
* that is orders of degree shorter than the response timeout value) to check whether an expected server response
* has been received as well as performing other application logic in the same thread context.
*/
#define democonfigRECEIVE_SERVER_RESPONSE_BLOCK_TIME_MS ( 200 )

/**
* @brief Set the stack size of the main demo task.
*
* In the Windows port, this stack only holds a structure. The actual
* stack is created by an operating system thread.
*/
#define democonfigDEMO_STACKSIZE configMINIMAL_STACK_SIZE

#define democonfigDEMO_PRIORITY tskIDLE_PRIORITY

#endif /* ifndef CORE_SNTP_CONFIG_H */
83 changes: 83 additions & 0 deletions applications/helpers/sntp/inc/sntp_client_task.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* FreeRTOS V202212.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <[email protected]>
*
* 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
*
*/
#ifndef SNTP_CLIENT_TASK_H
#define SNTP_CLIENT_TASK_H

#include "mbedtls/platform_time.h"

/**
* @brief Utility macro to convert milliseconds to the fractions value of an SNTP timestamp.
* @note The fractions value MUST be less than 1000 as duration of seconds is not represented
* as fractions part of SNTP timestamp.
*/
#define MILLISECONDS_TO_SNTP_FRACTIONS( ms ) ( ms * 1000 * SNTP_FRACTION_VALUE_PER_MICROSECOND )

/**
* @brief Type representing system time in Coordinated Universal Time (UTC)
* zone as time since 1st January 1970 00h:00m:00s.
*
* @note This task uses RAM-based mathematical model to represent UTC time
* in system.
*/
typedef struct UTCTime
{
uint32_t secs;
uint32_t msecs;
} UTCTime_t;

/**
* @brief Utility function to print the system time as human-readable time (in the
* YYYY-MM-DD dd:mm:ss format).
*
* @param[in] pTime The system time to be printed.
*/
void vPrintTime( const mbedtls_time_t * pTime );

/**
* @brief Initializes the system clock with the first second of the year (i.e. at midnight
* of 1st January) that is configured in the democonfigSYSTEM_START_YEAR config of
* core_sntp_config.h file.
*/
void initializeSystemClock( void );

/**
* @brief Used by application to query wall-clock
* time as unsigned integer seconds from the system.
*
* @param[out] mbedtls_time_t This will be populated with the current time
* in the system as total time since 1st January 1900 00h:00m:00s.
*/
mbedtls_time_t systemGetWallClockTime( mbedtls_time_t * pTime );

/**
* @brief Sntp Client Task that is responsible for synchronizing system time with the time servers
* periodically.
*/
void vStartSntpClientTask( void );

#endif /* SNTP_CLIENT_TASK_H */
Loading

0 comments on commit cc91a29

Please sign in to comment.