in source/core_sntp_serializer.c [666:736]
SntpStatus_t Sntp_DeserializeResponse( const SntpTimestamp_t * pRequestTime,
const SntpTimestamp_t * pResponseRxTime,
const void * pResponseBuffer,
size_t bufferSize,
SntpResponseData_t * pParsedResponse )
{
SntpStatus_t status = SntpSuccess;
const SntpPacket_t * pResponsePacket = ( const SntpPacket_t * ) pResponseBuffer;
if( ( pRequestTime == NULL ) || ( pResponseRxTime == NULL ) ||
( pResponseBuffer == NULL ) || ( pParsedResponse == 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;
}
/* Check if the packet represents a server in the "Mode" field. */
else if( ( pResponsePacket->leapVersionMode & SNTP_MODE_BITS_MASK ) != SNTP_MODE_SERVER )
{
status = SntpInvalidResponse;
}
/* Check if any of the timestamps in the response packet are zero, which is invalid.
* Note: This is done to protect against a nuanced server spoofing attack where if the
* SNTP client resets its internal state of "Client transmit timestamp" (OR "originate
* timestamp" from server perspective) to zero as a protection against replay attack, an
* an attacker with this knowledge of the client operation can spoof a server response
* containing the "originate timestamp" as zero. Thus, to protect against such attack,
* a server response packet with any zero timestamp is rejected. */
else if( ( isZeroTimestamp( &pResponsePacket->originTime ) == true ) ||
( isZeroTimestamp( &pResponsePacket->receiveTime ) == true ) ||
( isZeroTimestamp( &pResponsePacket->transmitTime ) == true ) )
{
status = SntpInvalidResponse;
}
/* Validate that the server has sent the client's request timestamp in the
* "originate" timestamp field of the response. */
else if( ( pRequestTime->seconds !=
readWordFromNetworkByteOrderMemory( &pResponsePacket->originTime.seconds ) ) ||
( pRequestTime->fractions !=
readWordFromNetworkByteOrderMemory( &pResponsePacket->originTime.fractions ) ) )
{
status = SntpInvalidResponse;
}
else
{
/* As the response packet is valid, parse more information from it and
* populate the output parameter. */
status = parseValidSntpResponse( pResponsePacket,
pRequestTime,
pResponseRxTime,
pParsedResponse );
}
return status;
}