491 lines
14 KiB
C
491 lines
14 KiB
C
/**
|
|
* 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 contains utility functions
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
#ifndef WIN32
|
|
|
|
#endif
|
|
#ifdef WIN32
|
|
#include <Windows.h>
|
|
#include <stdio.h>
|
|
#endif
|
|
#include "optiga/common/Util.h"
|
|
|
|
|
|
/**
|
|
*
|
|
* Compare PprgbBuf1 uint64 data with the PprgbBuf2 uint64 data.<br>
|
|
*
|
|
* \param[in] PpsSrc1 Pointer to the uint64 structure
|
|
* \param[in] PpsSrc2 Pointer to the uint64 structure
|
|
*
|
|
* \retval GREATER_THAN if PpsSrc1 > PpsSrc2
|
|
* \retval LESSER_THAN if PpsSrc1 < PpsSrc2
|
|
* \retval EQUAL if PpsSrc1 == PpsSrc2
|
|
* \retval UTIL_ERROR for NULL parameter
|
|
*
|
|
*/
|
|
int32_t CompareUint64(const sUint64 *PpsSrc1, const sUint64 *PpsSrc2)
|
|
{
|
|
int32_t i4Retval = (int32_t) UTIL_ERROR;
|
|
|
|
do
|
|
{
|
|
#ifdef ENABLE_NULL_CHECKS
|
|
if((NULL == PpsSrc1) || (NULL == PpsSrc2))
|
|
{
|
|
break;
|
|
}
|
|
#endif
|
|
if(PpsSrc1->dwHigherByte == PpsSrc2->dwHigherByte)
|
|
{
|
|
if(PpsSrc1->dwLowerByte > PpsSrc2->dwLowerByte)
|
|
{
|
|
i4Retval = GREATER_THAN;
|
|
}
|
|
else if(PpsSrc1->dwLowerByte < PpsSrc2->dwLowerByte)
|
|
{
|
|
i4Retval = LESSER_THAN;
|
|
}
|
|
//PpsSrc1->dwLowerByte == PpsSrc2->dwLowerByte
|
|
else
|
|
{
|
|
i4Retval = EQUAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(PpsSrc1->dwHigherByte > PpsSrc2->dwHigherByte)
|
|
{
|
|
i4Retval = GREATER_THAN;
|
|
}
|
|
// PpsSrc1->dwHigherByte < PpsSrc2->dwHigherByte
|
|
else
|
|
{
|
|
i4Retval = LESSER_THAN;
|
|
}
|
|
}
|
|
}while(0);
|
|
|
|
return i4Retval;
|
|
}
|
|
|
|
/**
|
|
* Subtraction of PpsSubtrahend uint64 data type from PpsMinuend uint64 data
|
|
* PpsMinuend should be greater than PpsSubtrahend else will return error
|
|
*
|
|
* \param[in] PpsMinuend Minued
|
|
* \param[in] PpsSubtrahend Subtrahend
|
|
* \param[in] PpsDifference Difference
|
|
*
|
|
* \retval UTIL_SUCCESS if PpsMinuend > PpsSubtrahend
|
|
* \retval UTIL_ERROR if PpsMinuend < PpsSubtrahend and for NULL parameter
|
|
*/
|
|
int32_t SubtractUint64(const sUint64 *PpsMinuend, const sUint64 *PpsSubtrahend,sUint64 *PpsDifference)
|
|
{
|
|
int32_t i4Retval = (int32_t) UTIL_ERROR;
|
|
sUint64 sIntermediateVal;
|
|
|
|
do
|
|
{
|
|
#ifdef ENABLE_NULL_CHECKS
|
|
if((NULL == PpsMinuend) || (NULL == PpsSubtrahend) || (NULL == PpsDifference))
|
|
{
|
|
break;
|
|
}
|
|
#endif
|
|
i4Retval = CompareUint64(PpsMinuend, PpsSubtrahend);
|
|
|
|
//Check if Minuend is greater than Subtrahend to avoid overflow
|
|
if((GREATER_THAN != i4Retval) && (EQUAL != i4Retval))
|
|
{
|
|
i4Retval = (int32_t) UTIL_ERROR;
|
|
break;
|
|
}
|
|
|
|
sIntermediateVal.dwLowerByte = PpsMinuend->dwLowerByte - PpsSubtrahend->dwLowerByte;
|
|
sIntermediateVal.dwHigherByte = PpsMinuend->dwHigherByte - PpsSubtrahend->dwHigherByte;
|
|
|
|
if(sIntermediateVal.dwLowerByte > PpsMinuend->dwLowerByte)
|
|
{
|
|
--sIntermediateVal.dwHigherByte;
|
|
}
|
|
|
|
PpsDifference->dwLowerByte = sIntermediateVal.dwLowerByte;
|
|
PpsDifference->dwHigherByte = sIntermediateVal.dwHigherByte;
|
|
|
|
i4Retval = (int32_t) UTIL_SUCCESS;
|
|
|
|
}while(0);
|
|
return i4Retval;
|
|
}
|
|
|
|
/**
|
|
* Shift left the PpsWindow uint64 data for shiftcount times based on the window size
|
|
*
|
|
*/
|
|
int32_t ShiftLeftUint64(sUint64 *PpsWindow, sUint64 PsShiftCount, uint8_t PbWindowSize, uint8_t PbMaxWindowSize)
|
|
{
|
|
int32_t i4Retval = (int32_t) UTIL_ERROR;
|
|
uint32_t dwShiftCount = 0;
|
|
uint32_t dwMaskShiftCount = MASK_DOUBLE_WORD;
|
|
sUint64 sWindowSize = {0} ;
|
|
|
|
do
|
|
{
|
|
#ifdef ENABLE_NULL_CHECKS
|
|
if(NULL == PpsWindow)
|
|
{
|
|
break;
|
|
}
|
|
#endif
|
|
sWindowSize.dwLowerByte = (uint32_t) PbWindowSize;
|
|
|
|
i4Retval = CompareUint64(&PsShiftCount, &sWindowSize);
|
|
|
|
//If Shift Count size is greater than or equal to window size
|
|
if((GREATER_THAN == i4Retval) || (EQUAL == i4Retval))
|
|
{
|
|
///Set the window with all bit zero
|
|
PpsWindow->dwLowerByte = DEFAULT_LOWBOUND_DOUBLEWORD;
|
|
PpsWindow->dwHigherByte = DEFAULT_LOWBOUND_DOUBLEWORD;
|
|
i4Retval = (int32_t) UTIL_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
//If Shift count is less than the window size
|
|
|
|
//Set the window shift count
|
|
dwShiftCount = PsShiftCount.dwLowerByte;
|
|
//Mask the lower byte data
|
|
dwMaskShiftCount &= PpsWindow->dwLowerByte ;
|
|
|
|
//If window size is equal to 32
|
|
if(WORD_SIZE == PbWindowSize)
|
|
{
|
|
///Shift only higher byte if window size is 32
|
|
PpsWindow->dwLowerByte = DEFAULT_LOWBOUND_DOUBLEWORD ;
|
|
|
|
PpsWindow->dwHigherByte <<= dwShiftCount ;
|
|
i4Retval = (int32_t) UTIL_SUCCESS;
|
|
break;
|
|
}
|
|
//Shift count is greater than 32
|
|
if(WORD_SIZE <= dwShiftCount)
|
|
{
|
|
//Set the lower byte to zero which is equal to shift by 32
|
|
PpsWindow->dwLowerByte = DEFAULT_LOWBOUND_DOUBLEWORD ;
|
|
//Set the Higher byte to zero which is equal to shift by 32
|
|
PpsWindow->dwHigherByte = DEFAULT_LOWBOUND_DOUBLEWORD ;
|
|
//copy the data of lower byte
|
|
PpsWindow->dwHigherByte |= dwMaskShiftCount;
|
|
//Remaining shift count to be done
|
|
dwShiftCount -= WORD_SIZE;
|
|
//Shift the left higher byte data with the remaining count
|
|
PpsWindow->dwHigherByte <<= dwShiftCount;
|
|
//Reset the outside of window bits
|
|
PpsWindow->dwHigherByte &= MASK_DOUBLE_WORD >> (PbMaxWindowSize - PbWindowSize);
|
|
|
|
i4Retval = (int32_t) UTIL_SUCCESS;
|
|
break;
|
|
}
|
|
//Shift count is lesser than 32
|
|
|
|
//Shift the lower byte for shift count times
|
|
PpsWindow->dwLowerByte <<= dwShiftCount ;
|
|
//Shift the higher byte for shift count times
|
|
PpsWindow->dwHigherByte <<= dwShiftCount ;
|
|
//To mask the data to be copied to higher byte
|
|
dwMaskShiftCount >>= WORD_SIZE - dwShiftCount;
|
|
//Copy data shifted from lower byte to higher byte
|
|
PpsWindow->dwHigherByte |= dwMaskShiftCount;
|
|
//Reset the outside of window bits
|
|
PpsWindow->dwHigherByte &= MASK_DOUBLE_WORD >> (PbMaxWindowSize - PbWindowSize);
|
|
|
|
i4Retval = (int32_t) UTIL_SUCCESS;
|
|
|
|
}while(0);
|
|
return i4Retval;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Addition of two uint64 data type
|
|
*
|
|
*/
|
|
int32_t AddUint64(const sUint64 *PpsSrc1, const sUint64 *PpsSrc2,sUint64 *PpsDest)
|
|
{
|
|
int32_t i4Retval = (int32_t) UTIL_ERROR;
|
|
sUint64 sIntermediateval;
|
|
|
|
sIntermediateval.dwLowerByte = PpsSrc1->dwLowerByte + PpsSrc2->dwLowerByte;
|
|
sIntermediateval.dwHigherByte = PpsSrc1->dwHigherByte + PpsSrc2->dwHigherByte;
|
|
|
|
if(sIntermediateval.dwLowerByte < PpsSrc1->dwLowerByte)
|
|
{
|
|
++sIntermediateval.dwHigherByte;
|
|
}
|
|
|
|
PpsDest->dwLowerByte = sIntermediateval.dwLowerByte;
|
|
PpsDest->dwHigherByte = sIntermediateval.dwHigherByte;
|
|
i4Retval = (int32_t) UTIL_SUCCESS;
|
|
return i4Retval;
|
|
}
|
|
|
|
int32_t IncrementUint64(sUint64 *PpsSrc1)
|
|
{
|
|
int32_t i4Retval = (int32_t) UTIL_ERROR;
|
|
sUint64 sOne;
|
|
sOne.dwHigherByte = 0;
|
|
sOne.dwLowerByte = 1;
|
|
i4Retval = AddUint64(PpsSrc1,&sOne,PpsSrc1);
|
|
return i4Retval;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Prepares uint16 [Big endian] type value from the buffer.<br>
|
|
*
|
|
* \param[in] PprgbData Pointer to the buffer
|
|
*
|
|
* \retval return 16 bit value
|
|
*
|
|
*/
|
|
uint16_t Utility_GetUint16 (const uint8_t* PprgbData)
|
|
{
|
|
uint16_t wVal;
|
|
|
|
wVal = (uint16_t)(*PprgbData << 8);
|
|
wVal |= (uint16_t)(*(PprgbData+1));
|
|
|
|
return wVal;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Copies LSB 3 bytes of uint32 [Big endian] type value to the buffer and store .<br>
|
|
*
|
|
* \param[in,out] PprgbData Pointer to the buffer
|
|
* \param[in] Pdwvalue 32 bit value
|
|
*
|
|
*/
|
|
void Utility_SetUint24 (uint8_t* PprgbData,uint32_t Pdwvalue)
|
|
{
|
|
#define prgbBuffer PprgbData
|
|
|
|
*(prgbBuffer) = (uint8_t)(Pdwvalue>>16);
|
|
*(prgbBuffer+1) = (uint8_t)(Pdwvalue>>8);
|
|
*(prgbBuffer+2) = (uint8_t)(Pdwvalue);
|
|
|
|
#undef prgbBuffer
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Prepares uint24 [Big endian] type value from the buffer and store .<br>
|
|
*
|
|
* \param[in] PprgbData Pointer to the buffer
|
|
*
|
|
* \retval return 32 bit value
|
|
*
|
|
*/
|
|
uint32_t Utility_GetUint24 (const uint8_t* PprgbData)
|
|
{
|
|
uint32_t dwVal;
|
|
dwVal = ((uint32_t)(*PprgbData))<< 16;
|
|
dwVal |= ((uint32_t)(*(PprgbData+1)))<<8;
|
|
dwVal |= (uint32_t)(*(PprgbData+2));
|
|
|
|
return dwVal;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Prepares uint24 [Big endian] type value from the buffer and store .<br>
|
|
*
|
|
* \param[in] PprgbData Pointer to the buffer
|
|
*
|
|
* \retval return 32 bit value
|
|
*
|
|
*/
|
|
uint32_t Utility_GetUint32 (const uint8_t* PprgbData)
|
|
{
|
|
uint32_t dwVal;
|
|
dwVal = ((uint32_t)(*PprgbData))<< 24 | ((uint32_t)(*(PprgbData + 1))<< 16 | ((uint32_t)(*(PprgbData + 2)))<< 8 | (uint32_t)(*(PprgbData + 3)));
|
|
|
|
return dwVal;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Copies 2 bytes of uint16 type value to the buffer<br>
|
|
*
|
|
* \param[in,out] PprgbData Pointer to the buffer
|
|
* \param[in] PwValue 16 bit value
|
|
*
|
|
*/
|
|
void Utility_SetUint16 (puint8_t PprgbData,uint16_t PwValue)
|
|
{
|
|
*PprgbData = (uint8_t)(PwValue>>8);
|
|
*(PprgbData+1) = (uint8_t)(PwValue);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* sets the bit position to high in the window frame.<br>
|
|
*
|
|
* \param[in,out] PprgbData Pointer to the uint64 data
|
|
* \param[in] bWindowSize Window size
|
|
* \param[in] bBitPosition bit position from low bound of the window(Bit is set at lowbound+bBitPosition )
|
|
*
|
|
* \retval UTIL_SUCCESS for successful execution
|
|
* \retval UTIL_ERROR if execution is failure
|
|
*/
|
|
int32_t Utility_SetBitUint64(sUint64* PprgbData, uint8_t bWindowSize, uint8_t bBitPosition)
|
|
{
|
|
int32_t i4Retval = (int32_t) UTIL_ERROR;
|
|
uint8_t bShiftCount = 0;
|
|
|
|
do
|
|
{
|
|
#ifdef ENABLE_NULL_CHECKS
|
|
if(NULL == PprgbData)
|
|
{
|
|
break;
|
|
}
|
|
#endif
|
|
if(bBitPosition > bWindowSize)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//Window size is equal to bit position
|
|
if(bBitPosition == bWindowSize)
|
|
{
|
|
if(WORD_SIZE == bWindowSize)
|
|
{
|
|
PprgbData->dwHigherByte |= LEAST_SIGNIFICANT_BIT_HIGH;
|
|
i4Retval = (int32_t) UTIL_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
PprgbData->dwLowerByte |= LEAST_SIGNIFICANT_BIT_HIGH;
|
|
i4Retval = (int32_t) UTIL_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
//Bit Position from the Higher bound
|
|
bShiftCount = bWindowSize - bBitPosition;
|
|
//Window size is equal to 32
|
|
if(WORD_SIZE == bWindowSize)
|
|
{
|
|
PprgbData->dwHigherByte |= LEAST_SIGNIFICANT_BIT_HIGH << (bShiftCount - 1);
|
|
i4Retval = (int32_t) UTIL_SUCCESS;
|
|
break;
|
|
}
|
|
//If Bit position from High Bound is greater than 32 then bit set is to be in Higher byte
|
|
if(WORD_SIZE < bShiftCount)
|
|
{
|
|
bShiftCount -= WORD_SIZE;
|
|
|
|
PprgbData->dwHigherByte |= LEAST_SIGNIFICANT_BIT_HIGH << (bShiftCount - 1);
|
|
|
|
i4Retval = (int32_t) UTIL_SUCCESS;
|
|
break;
|
|
}
|
|
|
|
//If Bit position from High Bound is lesser or equal 32 then bit set is to be in lower byte
|
|
PprgbData->dwLowerByte |= LEAST_SIGNIFICANT_BIT_HIGH << (bShiftCount - 1);
|
|
|
|
i4Retval = (int32_t) UTIL_SUCCESS;
|
|
|
|
}while(0);
|
|
return i4Retval;
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* Copies 4 bytes of uint32 [Big endian] type value to the buffer and store .<br>
|
|
*
|
|
* \param[in,out] PprgbData Pointer to the buffer
|
|
* \param[in] Pdwvalue 32 bit value
|
|
*
|
|
*/
|
|
void Utility_SetUint32 (uint8_t* PprgbData,uint32_t Pdwvalue)
|
|
{
|
|
#define prgbBuffer PprgbData
|
|
|
|
*(prgbBuffer) = (uint8_t)(Pdwvalue>>24);
|
|
*(prgbBuffer + 1) = (uint8_t)(Pdwvalue>>16);
|
|
*(prgbBuffer+2) = (uint8_t)(Pdwvalue>>8);
|
|
*(prgbBuffer+3) = (uint8_t)(Pdwvalue);
|
|
|
|
#undef prgbBuffer
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Copies the data from source buffer to destination buffer.<br>
|
|
*
|
|
* \param[in,out] PprgbDestBuf Pointer to the destination buffer
|
|
* \param[in,out] PprgbSrcBuf Pointer to the source buffer
|
|
* \param[in] PwLength Number of bytes to be copied/moved
|
|
*
|
|
*/
|
|
void Utility_Memmove(puint8_t PprgbDestBuf, const puint8_t PprgbSrcBuf, uint16_t PwLength)
|
|
{
|
|
uint16_t wIndex=0;
|
|
puint8_t pTempSrcBuf = PprgbSrcBuf;
|
|
|
|
do
|
|
{
|
|
//if source and destination are the same buffer. and the buffers overlap
|
|
if((PprgbDestBuf > pTempSrcBuf) && (PprgbDestBuf <= (pTempSrcBuf + PwLength - 1)))
|
|
{
|
|
while(0 < PwLength)
|
|
{
|
|
PwLength -= 1;
|
|
*(PprgbDestBuf + PwLength) = *(pTempSrcBuf + PwLength);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while(wIndex < PwLength)
|
|
{
|
|
*(PprgbDestBuf + wIndex) = *(pTempSrcBuf + wIndex);
|
|
wIndex++;
|
|
}
|
|
}
|
|
}while(0);
|
|
}
|