in source/core_sntp_serializer.c [601:663]
SntpStatus_t Sntp_SerializeRequest( SntpTimestamp_t * pRequestTime,
uint32_t randomNumber,
void * pBuffer,
size_t bufferSize )
{
SntpStatus_t status = SntpSuccess;
if( pRequestTime == NULL )
{
status = SntpErrorBadParameter;
}
else if( pBuffer == NULL )
{
status = SntpErrorBadParameter;
}
else if( bufferSize < SNTP_PACKET_BASE_SIZE )
{
status = SntpErrorBufferTooSmall;
}
/* Zero timestamps for client request time is not allowed to protect against
* attack spoofing server response containing zero value for "originate timestamp".
* Note: In SNTP/NTP communication, the "originate timestamp" of a valid server response
* matches the "transmit timestamp" in corresponding client request packet. */
else if( isZeroTimestamp( pRequestTime ) == true )
{
status = SntpErrorBadParameter;
}
else
{
SntpPacket_t * pRequestPacket = ( SntpPacket_t * ) pBuffer;
/* Fill the buffer with zero as most fields are zero for a standard SNTP
* request packet.*/
( void ) memset( pBuffer, 0, sizeof( SntpPacket_t ) );
/* Set the first byte of the request packet for "Version" and "Mode" fields */
pRequestPacket->leapVersionMode = 0U /* Leap Indicator */ |
( SNTP_VERSION << SNTP_VERSION_LSB_POSITION ) /* Version Number */ |
SNTP_MODE_CLIENT /* Mode */;
/* Add passed random number to non-significant bits of the fractions part
* of the transmit timestamp.
* This is suggested by the SNTPv4 (and NTPv4) specification(s)
* to protect against replay attacks. Refer to RFC 4330 Section 3 for
* more information.
* Adding random bits to the least significant 16 bits of the fractions
* part of the timestamp affects only ~15 microseconds of information
* (calculated as 0xFFFF * 232 picoseconds).
*/
pRequestTime->fractions = ( pRequestTime->fractions
| ( randomNumber >> 16 ) );
/* Update the request buffer with request timestamp in network byte order. */
fillWordMemoryInNetworkOrder( &pRequestPacket->transmitTime.seconds,
pRequestTime->seconds );
fillWordMemoryInNetworkOrder( &pRequestPacket->transmitTime.fractions,
pRequestTime->fractions );
}
return status;
}