/** * 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 #include #endif #include "optiga/common/Util.h" /** * * Compare PprgbBuf1 uint64 data with the PprgbBuf2 uint64 data.
* * \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.
* * \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 .
* * \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 .
* * \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 .
* * \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
* * \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.
* * \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 .
* * \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.
* * \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); }