Util.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. /**
  2. * MIT License
  3. *
  4. * Copyright (c) 2018 Infineon Technologies AG
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. * SOFTWARE
  23. *
  24. *
  25. *
  26. * \file
  27. *
  28. * \brief This file contains utility functions
  29. *
  30. *
  31. *
  32. */
  33. #ifndef WIN32
  34. #endif
  35. #ifdef WIN32
  36. #include <Windows.h>
  37. #include <stdio.h>
  38. #endif
  39. #include "optiga/common/Util.h"
  40. /**
  41. *
  42. * Compare PprgbBuf1 uint64 data with the PprgbBuf2 uint64 data.<br>
  43. *
  44. * \param[in] PpsSrc1 Pointer to the uint64 structure
  45. * \param[in] PpsSrc2 Pointer to the uint64 structure
  46. *
  47. * \retval GREATER_THAN if PpsSrc1 > PpsSrc2
  48. * \retval LESSER_THAN if PpsSrc1 < PpsSrc2
  49. * \retval EQUAL if PpsSrc1 == PpsSrc2
  50. * \retval UTIL_ERROR for NULL parameter
  51. *
  52. */
  53. int32_t CompareUint64(const sUint64 *PpsSrc1, const sUint64 *PpsSrc2)
  54. {
  55. int32_t i4Retval = (int32_t) UTIL_ERROR;
  56. do
  57. {
  58. #ifdef ENABLE_NULL_CHECKS
  59. if((NULL == PpsSrc1) || (NULL == PpsSrc2))
  60. {
  61. break;
  62. }
  63. #endif
  64. if(PpsSrc1->dwHigherByte == PpsSrc2->dwHigherByte)
  65. {
  66. if(PpsSrc1->dwLowerByte > PpsSrc2->dwLowerByte)
  67. {
  68. i4Retval = GREATER_THAN;
  69. }
  70. else if(PpsSrc1->dwLowerByte < PpsSrc2->dwLowerByte)
  71. {
  72. i4Retval = LESSER_THAN;
  73. }
  74. //PpsSrc1->dwLowerByte == PpsSrc2->dwLowerByte
  75. else
  76. {
  77. i4Retval = EQUAL;
  78. }
  79. }
  80. else
  81. {
  82. if(PpsSrc1->dwHigherByte > PpsSrc2->dwHigherByte)
  83. {
  84. i4Retval = GREATER_THAN;
  85. }
  86. // PpsSrc1->dwHigherByte < PpsSrc2->dwHigherByte
  87. else
  88. {
  89. i4Retval = LESSER_THAN;
  90. }
  91. }
  92. }while(0);
  93. return i4Retval;
  94. }
  95. /**
  96. * Subtraction of PpsSubtrahend uint64 data type from PpsMinuend uint64 data
  97. * PpsMinuend should be greater than PpsSubtrahend else will return error
  98. *
  99. * \param[in] PpsMinuend Minued
  100. * \param[in] PpsSubtrahend Subtrahend
  101. * \param[in] PpsDifference Difference
  102. *
  103. * \retval UTIL_SUCCESS if PpsMinuend > PpsSubtrahend
  104. * \retval UTIL_ERROR if PpsMinuend < PpsSubtrahend and for NULL parameter
  105. */
  106. int32_t SubtractUint64(const sUint64 *PpsMinuend, const sUint64 *PpsSubtrahend,sUint64 *PpsDifference)
  107. {
  108. int32_t i4Retval = (int32_t) UTIL_ERROR;
  109. sUint64 sIntermediateVal;
  110. do
  111. {
  112. #ifdef ENABLE_NULL_CHECKS
  113. if((NULL == PpsMinuend) || (NULL == PpsSubtrahend) || (NULL == PpsDifference))
  114. {
  115. break;
  116. }
  117. #endif
  118. i4Retval = CompareUint64(PpsMinuend, PpsSubtrahend);
  119. //Check if Minuend is greater than Subtrahend to avoid overflow
  120. if((GREATER_THAN != i4Retval) && (EQUAL != i4Retval))
  121. {
  122. i4Retval = (int32_t) UTIL_ERROR;
  123. break;
  124. }
  125. sIntermediateVal.dwLowerByte = PpsMinuend->dwLowerByte - PpsSubtrahend->dwLowerByte;
  126. sIntermediateVal.dwHigherByte = PpsMinuend->dwHigherByte - PpsSubtrahend->dwHigherByte;
  127. if(sIntermediateVal.dwLowerByte > PpsMinuend->dwLowerByte)
  128. {
  129. --sIntermediateVal.dwHigherByte;
  130. }
  131. PpsDifference->dwLowerByte = sIntermediateVal.dwLowerByte;
  132. PpsDifference->dwHigherByte = sIntermediateVal.dwHigherByte;
  133. i4Retval = (int32_t) UTIL_SUCCESS;
  134. }while(0);
  135. return i4Retval;
  136. }
  137. /**
  138. * Shift left the PpsWindow uint64 data for shiftcount times based on the window size
  139. *
  140. */
  141. int32_t ShiftLeftUint64(sUint64 *PpsWindow, sUint64 PsShiftCount, uint8_t PbWindowSize, uint8_t PbMaxWindowSize)
  142. {
  143. int32_t i4Retval = (int32_t) UTIL_ERROR;
  144. uint32_t dwShiftCount = 0;
  145. uint32_t dwMaskShiftCount = MASK_DOUBLE_WORD;
  146. sUint64 sWindowSize = {0} ;
  147. do
  148. {
  149. #ifdef ENABLE_NULL_CHECKS
  150. if(NULL == PpsWindow)
  151. {
  152. break;
  153. }
  154. #endif
  155. sWindowSize.dwLowerByte = (uint32_t) PbWindowSize;
  156. i4Retval = CompareUint64(&PsShiftCount, &sWindowSize);
  157. //If Shift Count size is greater than or equal to window size
  158. if((GREATER_THAN == i4Retval) || (EQUAL == i4Retval))
  159. {
  160. ///Set the window with all bit zero
  161. PpsWindow->dwLowerByte = DEFAULT_LOWBOUND_DOUBLEWORD;
  162. PpsWindow->dwHigherByte = DEFAULT_LOWBOUND_DOUBLEWORD;
  163. i4Retval = (int32_t) UTIL_SUCCESS;
  164. break;
  165. }
  166. //If Shift count is less than the window size
  167. //Set the window shift count
  168. dwShiftCount = PsShiftCount.dwLowerByte;
  169. //Mask the lower byte data
  170. dwMaskShiftCount &= PpsWindow->dwLowerByte ;
  171. //If window size is equal to 32
  172. if(WORD_SIZE == PbWindowSize)
  173. {
  174. ///Shift only higher byte if window size is 32
  175. PpsWindow->dwLowerByte = DEFAULT_LOWBOUND_DOUBLEWORD ;
  176. PpsWindow->dwHigherByte <<= dwShiftCount ;
  177. i4Retval = (int32_t) UTIL_SUCCESS;
  178. break;
  179. }
  180. //Shift count is greater than 32
  181. if(WORD_SIZE <= dwShiftCount)
  182. {
  183. //Set the lower byte to zero which is equal to shift by 32
  184. PpsWindow->dwLowerByte = DEFAULT_LOWBOUND_DOUBLEWORD ;
  185. //Set the Higher byte to zero which is equal to shift by 32
  186. PpsWindow->dwHigherByte = DEFAULT_LOWBOUND_DOUBLEWORD ;
  187. //copy the data of lower byte
  188. PpsWindow->dwHigherByte |= dwMaskShiftCount;
  189. //Remaining shift count to be done
  190. dwShiftCount -= WORD_SIZE;
  191. //Shift the left higher byte data with the remaining count
  192. PpsWindow->dwHigherByte <<= dwShiftCount;
  193. //Reset the outside of window bits
  194. PpsWindow->dwHigherByte &= MASK_DOUBLE_WORD >> (PbMaxWindowSize - PbWindowSize);
  195. i4Retval = (int32_t) UTIL_SUCCESS;
  196. break;
  197. }
  198. //Shift count is lesser than 32
  199. //Shift the lower byte for shift count times
  200. PpsWindow->dwLowerByte <<= dwShiftCount ;
  201. //Shift the higher byte for shift count times
  202. PpsWindow->dwHigherByte <<= dwShiftCount ;
  203. //To mask the data to be copied to higher byte
  204. dwMaskShiftCount >>= WORD_SIZE - dwShiftCount;
  205. //Copy data shifted from lower byte to higher byte
  206. PpsWindow->dwHigherByte |= dwMaskShiftCount;
  207. //Reset the outside of window bits
  208. PpsWindow->dwHigherByte &= MASK_DOUBLE_WORD >> (PbMaxWindowSize - PbWindowSize);
  209. i4Retval = (int32_t) UTIL_SUCCESS;
  210. }while(0);
  211. return i4Retval;
  212. }
  213. /**
  214. * Addition of two uint64 data type
  215. *
  216. */
  217. int32_t AddUint64(const sUint64 *PpsSrc1, const sUint64 *PpsSrc2,sUint64 *PpsDest)
  218. {
  219. int32_t i4Retval = (int32_t) UTIL_ERROR;
  220. sUint64 sIntermediateval;
  221. sIntermediateval.dwLowerByte = PpsSrc1->dwLowerByte + PpsSrc2->dwLowerByte;
  222. sIntermediateval.dwHigherByte = PpsSrc1->dwHigherByte + PpsSrc2->dwHigherByte;
  223. if(sIntermediateval.dwLowerByte < PpsSrc1->dwLowerByte)
  224. {
  225. ++sIntermediateval.dwHigherByte;
  226. }
  227. PpsDest->dwLowerByte = sIntermediateval.dwLowerByte;
  228. PpsDest->dwHigherByte = sIntermediateval.dwHigherByte;
  229. i4Retval = (int32_t) UTIL_SUCCESS;
  230. return i4Retval;
  231. }
  232. int32_t IncrementUint64(sUint64 *PpsSrc1)
  233. {
  234. int32_t i4Retval = (int32_t) UTIL_ERROR;
  235. sUint64 sOne;
  236. sOne.dwHigherByte = 0;
  237. sOne.dwLowerByte = 1;
  238. i4Retval = AddUint64(PpsSrc1,&sOne,PpsSrc1);
  239. return i4Retval;
  240. }
  241. /**
  242. *
  243. * Prepares uint16 [Big endian] type value from the buffer.<br>
  244. *
  245. * \param[in] PprgbData Pointer to the buffer
  246. *
  247. * \retval return 16 bit value
  248. *
  249. */
  250. uint16_t Utility_GetUint16 (const uint8_t* PprgbData)
  251. {
  252. uint16_t wVal;
  253. wVal = (uint16_t)(*PprgbData << 8);
  254. wVal |= (uint16_t)(*(PprgbData+1));
  255. return wVal;
  256. }
  257. /**
  258. *
  259. * Copies LSB 3 bytes of uint32 [Big endian] type value to the buffer and store .<br>
  260. *
  261. * \param[in,out] PprgbData Pointer to the buffer
  262. * \param[in] Pdwvalue 32 bit value
  263. *
  264. */
  265. void Utility_SetUint24 (uint8_t* PprgbData,uint32_t Pdwvalue)
  266. {
  267. #define prgbBuffer PprgbData
  268. *(prgbBuffer) = (uint8_t)(Pdwvalue>>16);
  269. *(prgbBuffer+1) = (uint8_t)(Pdwvalue>>8);
  270. *(prgbBuffer+2) = (uint8_t)(Pdwvalue);
  271. #undef prgbBuffer
  272. }
  273. /**
  274. *
  275. * Prepares uint24 [Big endian] type value from the buffer and store .<br>
  276. *
  277. * \param[in] PprgbData Pointer to the buffer
  278. *
  279. * \retval return 32 bit value
  280. *
  281. */
  282. uint32_t Utility_GetUint24 (const uint8_t* PprgbData)
  283. {
  284. uint32_t dwVal;
  285. dwVal = ((uint32_t)(*PprgbData))<< 16;
  286. dwVal |= ((uint32_t)(*(PprgbData+1)))<<8;
  287. dwVal |= (uint32_t)(*(PprgbData+2));
  288. return dwVal;
  289. }
  290. /**
  291. *
  292. * Prepares uint24 [Big endian] type value from the buffer and store .<br>
  293. *
  294. * \param[in] PprgbData Pointer to the buffer
  295. *
  296. * \retval return 32 bit value
  297. *
  298. */
  299. uint32_t Utility_GetUint32 (const uint8_t* PprgbData)
  300. {
  301. uint32_t dwVal;
  302. dwVal = ((uint32_t)(*PprgbData))<< 24 | ((uint32_t)(*(PprgbData + 1))<< 16 | ((uint32_t)(*(PprgbData + 2)))<< 8 | (uint32_t)(*(PprgbData + 3)));
  303. return dwVal;
  304. }
  305. /**
  306. *
  307. * Copies 2 bytes of uint16 type value to the buffer<br>
  308. *
  309. * \param[in,out] PprgbData Pointer to the buffer
  310. * \param[in] PwValue 16 bit value
  311. *
  312. */
  313. void Utility_SetUint16 (puint8_t PprgbData,uint16_t PwValue)
  314. {
  315. *PprgbData = (uint8_t)(PwValue>>8);
  316. *(PprgbData+1) = (uint8_t)(PwValue);
  317. }
  318. /**
  319. *
  320. * sets the bit position to high in the window frame.<br>
  321. *
  322. * \param[in,out] PprgbData Pointer to the uint64 data
  323. * \param[in] bWindowSize Window size
  324. * \param[in] bBitPosition bit position from low bound of the window(Bit is set at lowbound+bBitPosition )
  325. *
  326. * \retval UTIL_SUCCESS for successful execution
  327. * \retval UTIL_ERROR if execution is failure
  328. */
  329. int32_t Utility_SetBitUint64(sUint64* PprgbData, uint8_t bWindowSize, uint8_t bBitPosition)
  330. {
  331. int32_t i4Retval = (int32_t) UTIL_ERROR;
  332. uint8_t bShiftCount = 0;
  333. do
  334. {
  335. #ifdef ENABLE_NULL_CHECKS
  336. if(NULL == PprgbData)
  337. {
  338. break;
  339. }
  340. #endif
  341. if(bBitPosition > bWindowSize)
  342. {
  343. break;
  344. }
  345. //Window size is equal to bit position
  346. if(bBitPosition == bWindowSize)
  347. {
  348. if(WORD_SIZE == bWindowSize)
  349. {
  350. PprgbData->dwHigherByte |= LEAST_SIGNIFICANT_BIT_HIGH;
  351. i4Retval = (int32_t) UTIL_SUCCESS;
  352. break;
  353. }
  354. PprgbData->dwLowerByte |= LEAST_SIGNIFICANT_BIT_HIGH;
  355. i4Retval = (int32_t) UTIL_SUCCESS;
  356. break;
  357. }
  358. //Bit Position from the Higher bound
  359. bShiftCount = bWindowSize - bBitPosition;
  360. //Window size is equal to 32
  361. if(WORD_SIZE == bWindowSize)
  362. {
  363. PprgbData->dwHigherByte |= LEAST_SIGNIFICANT_BIT_HIGH << (bShiftCount - 1);
  364. i4Retval = (int32_t) UTIL_SUCCESS;
  365. break;
  366. }
  367. //If Bit position from High Bound is greater than 32 then bit set is to be in Higher byte
  368. if(WORD_SIZE < bShiftCount)
  369. {
  370. bShiftCount -= WORD_SIZE;
  371. PprgbData->dwHigherByte |= LEAST_SIGNIFICANT_BIT_HIGH << (bShiftCount - 1);
  372. i4Retval = (int32_t) UTIL_SUCCESS;
  373. break;
  374. }
  375. //If Bit position from High Bound is lesser or equal 32 then bit set is to be in lower byte
  376. PprgbData->dwLowerByte |= LEAST_SIGNIFICANT_BIT_HIGH << (bShiftCount - 1);
  377. i4Retval = (int32_t) UTIL_SUCCESS;
  378. }while(0);
  379. return i4Retval;
  380. }
  381. /**
  382. *
  383. * Copies 4 bytes of uint32 [Big endian] type value to the buffer and store .<br>
  384. *
  385. * \param[in,out] PprgbData Pointer to the buffer
  386. * \param[in] Pdwvalue 32 bit value
  387. *
  388. */
  389. void Utility_SetUint32 (uint8_t* PprgbData,uint32_t Pdwvalue)
  390. {
  391. #define prgbBuffer PprgbData
  392. *(prgbBuffer) = (uint8_t)(Pdwvalue>>24);
  393. *(prgbBuffer + 1) = (uint8_t)(Pdwvalue>>16);
  394. *(prgbBuffer+2) = (uint8_t)(Pdwvalue>>8);
  395. *(prgbBuffer+3) = (uint8_t)(Pdwvalue);
  396. #undef prgbBuffer
  397. }
  398. /**
  399. *
  400. * Copies the data from source buffer to destination buffer.<br>
  401. *
  402. * \param[in,out] PprgbDestBuf Pointer to the destination buffer
  403. * \param[in,out] PprgbSrcBuf Pointer to the source buffer
  404. * \param[in] PwLength Number of bytes to be copied/moved
  405. *
  406. */
  407. void Utility_Memmove(puint8_t PprgbDestBuf, const puint8_t PprgbSrcBuf, uint16_t PwLength)
  408. {
  409. uint16_t wIndex=0;
  410. puint8_t pTempSrcBuf = PprgbSrcBuf;
  411. do
  412. {
  413. //if source and destination are the same buffer. and the buffers overlap
  414. if((PprgbDestBuf > pTempSrcBuf) && (PprgbDestBuf <= (pTempSrcBuf + PwLength - 1)))
  415. {
  416. while(0 < PwLength)
  417. {
  418. PwLength -= 1;
  419. *(PprgbDestBuf + PwLength) = *(pTempSrcBuf + PwLength);
  420. }
  421. }
  422. else
  423. {
  424. while(wIndex < PwLength)
  425. {
  426. *(PprgbDestBuf + wIndex) = *(pTempSrcBuf + wIndex);
  427. wIndex++;
  428. }
  429. }
  430. }while(0);
  431. }