1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 
8 
9 /********************** Include Files **********************************/
10 
11 #include "cc_common_math.h"
12 #include "cc_common_error.h"
13 
14 /************************ Defines **************************************/
15 
16 /************************ Enums ****************************************/
17 
18 /************************ Typedefs *************************************/
19 
20 /************************ Global Data **********************************/
21 
22 /************* Private function prototype ******************************/
23 
24 /************************ Public Functions *****************************/
25 
26 #ifndef DX_OEM_FW
27 /********************************************************************************
28  * @brief This function adds a value to a large counter presented in a buffer.
29  *        The MSB of the counter is stored in the first cell in the array.
30  *
31  *        for example:
32  *
33  *        a counter of 64 bit : the value is :
34  *
35  *        byte[0] << 56 | byte[1] << 48 ............ byte[6] << 8 | byte[7]
36  *
37  * @param[in] CounterBuff_ptr - The buffer containing the counter.
38  * @param[in] Val             - this value to add.
39  * @param[in] CounterSize      - the counter size in 32bit words.
40  *
41  * @return CCError_t - On success CC_OK is returned, on failure a
42  *                        value MODULE_* as defined in ...
43  */
44 
CC_CommonIncMsbUnsignedCounter(uint32_t * CounterBuff_ptr,uint32_t Val,uint32_t CounterSize)45 void CC_CommonIncMsbUnsignedCounter( uint32_t     *CounterBuff_ptr ,
46                     uint32_t      Val,
47                     uint32_t      CounterSize )
48 {
49     /* FUNCTION LOCAL DECLERATIONS */
50 
51     /* a value for storing the current counter word value */
52     uint32_t curretCounterWordVal;
53 
54     /* loop variable */
55     uint32_t i;
56 
57     /* FUNCTION LOGIC */
58 
59     /* .. inversing the counters bytes to a word in little endian format. */
60     /* ------------------------------------------------------------------ */
61     for (i = 0 ; i < CounterSize ; i++)
62         CounterBuff_ptr[i] = CC_COMMON_REVERSE32( CounterBuff_ptr[i] );
63 
64     /* .................... initialize local variables .................. */
65     /* ------------------------------------------------------------------ */
66 
67     /* initialize the current local counter value to the first word */
68     curretCounterWordVal = CounterBuff_ptr[CounterSize-1];
69 
70     /* .................... adding the value to the LSW ................. */
71     /* ------------------------------------------------------------------ */
72 
73     /* adding the value to the word */
74     CounterBuff_ptr[CounterSize-1] += Val;
75 
76     /* .................... adding the carry to the higher words ........ */
77     /* ------------------------------------------------------------------ */
78 
79     /* if there is overflow on the word then handle the upper words */
80     if (curretCounterWordVal > CounterBuff_ptr[CounterSize-1]) {
81         /* adding the carry to the counter loop */
82         i = CounterSize - 2;
83         while (1) {
84             /* set the current word value */
85             curretCounterWordVal = CounterBuff_ptr[i];
86 
87             /* adding the carry to the current word */
88             CounterBuff_ptr[i]++;
89 
90             /* if there is no overflow on the current word after adding the value
91                exit the loop */
92             if ((curretCounterWordVal < CounterBuff_ptr[i]) || (i == 0)){
93                 break;
94             }
95             i--;
96 
97         }/* end of adding the carry loop */
98 
99     }/* end of setting the carrier on the upper words */
100 
101     /* .. restore the counters bytes order */
102     /* ----------------------------------- */
103 
104     for (i = 0 ; i < CounterSize ; i++)
105         CounterBuff_ptr[i] = CC_COMMON_REVERSE32( CounterBuff_ptr[i] );
106 
107 
108     return;
109 
110 }/* END OF CC_CommonIncMsbUnsignedCounter */
111 
112 /********************************************************************************
113  * @brief This function adds a value to a large counter presented in a buffer.
114  *        The LS word of the counter is stored in the first cell in the array.
115  *
116  *        for example: a counter of 64 bit : the value is :
117  *        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]
118  *
119  * @param[in] pCounterBuff - The buffer containing the counter.
120  * @param[in] val          - this value to add.
121  * @param[in] counterSize  - the counter size in 32bit words.
122  *
123  * @return Carry from MS word if occurs
124  *
125  */
CC_CommonIncLsbUnsignedCounter(uint32_t * pCounterBuff,uint32_t val,uint32_t counterSize)126 uint32_t CC_CommonIncLsbUnsignedCounter(
127                       uint32_t     *pCounterBuff,
128                       uint32_t      val,
129                       uint32_t      counterSize )
130 {
131     /* FUNCTION LOCAL DECLARATIONS */
132 
133     /* a value for storing the current counter word value */
134     uint32_t currCounterVal;
135     /* loop variable */
136     uint32_t i;
137 
138     for (i = 0; i < counterSize; i++) {
139         currCounterVal = pCounterBuff[i];
140         pCounterBuff[i] += val;
141         val = (currCounterVal > pCounterBuff[i]) ? 1 : 0;
142     }
143 
144     return val;
145 
146 }/* END OF CC_CommonIncLsbUnsignedCounter */
147 
148 
149 /********************************************************************************
150  * @brief This function subtracts a value from a large counter presented in a first
151  *        buffer and sets result in a second buffer. The first and the second
152  *        buffers may be the same.
153  *        The LSB of the counter is stored in the first cell in the array,
154  *
155  * @param[in]  CounterBuff_ptr - the buffer containing the counter.
156  * @param[in]  Val             - the value to subtract.
157  * @param[in]  CounterSize      - the counter size in 32bit words.
158  *
159  * @return CCError_t - On success CC_OK is returned, on failure a
160  *                        value MODULE_* as defined in ...
161  */
162 
CC_CommonDecrLsbUnsignedCounter(uint32_t * CounterBuff_ptr,uint32_t Val,uint32_t CounterSizeInWords)163 void CC_CommonDecrLsbUnsignedCounter( uint32_t     *CounterBuff_ptr,
164                      uint32_t      Val,
165                      uint32_t      CounterSizeInWords )
166 {
167     /* FUNCTION LOCAL DECLERATIONS */
168 
169     /* borrow and temp word */
170     uint32_t borrow, temp;
171 
172     /* loop variable */
173     uint32_t i;
174 
175     /* FUNCTION LOGIC */
176 
177     /* .................... initialize local variables .................. */
178     /* ------------------------------------------------------------------ */
179 
180     /* initialize the borrow to Val */
181     borrow = Val;
182 
183     /* Subtracting loop */
184     for (i = 0 ; i < CounterSizeInWords ; i++) {
185         temp = CounterBuff_ptr[i];
186 
187         CounterBuff_ptr[i] = CounterBuff_ptr[i] - borrow;
188 
189         if (CounterBuff_ptr[i] > temp)
190             borrow = 1;
191         else
192             break;
193     }
194 
195     return;
196 
197 }/* END OF CC_CommonDecrLsbUnsignedCounter */
198 
199 
200 /********************************************************************************
201  * @brief This function compares a value of 2 large counters presented in a byte buffer.
202  *        The MSB of the counter is stored in the first cell in the array.
203  *
204  *        for example:
205  *
206  *        a counter of 64 bit : the value is :
207  *
208  *        byte[0] << 56 | byte[1] << 48 ............ byte[6] << 8 | byte[7]
209  *
210  *
211  * @param[in] CounterBuff1_ptr - The first counter buffer.
212  * @param[in] Counter1Size     - the first counter size in bytes.
213  * @param[in] CounterBuff2_ptr - The second counter buffer.
214  * @param[in] Counter2Size     - the second counter size in bytes.
215  * @param[in] SizeUnit         - the size units. 0 - bits , 1 - bytes
216  *
217  * @return result - an enum with the compare result:
218  *                                0 - both counters are identical
219  *                                1 - counter 1 is larger.
220  *                                2 - counter 2 is larger.
221  * @note This code executes in constant time, regardless of the arguments.
222  */
223 
CC_CommonCmpMsbUnsignedCounters(const uint8_t * CounterBuff1_ptr,uint32_t Counter1Size,const uint8_t * CounterBuff2_ptr,uint32_t Counter2Size)224 CCCommonCmpCounter_t CC_CommonCmpMsbUnsignedCounters( const uint8_t  *CounterBuff1_ptr,
225                                  uint32_t  Counter1Size,
226                                  const uint8_t  *CounterBuff2_ptr,
227                                  uint32_t Counter2Size )
228 {
229 
230     /* FUNCTION LOCAL DECLERATIONS */
231 
232     /* loop variable */
233     int32_t StartInd1,StartInd2;
234     uint32_t i;
235 
236     /* the result after comparing the bytes */
237     CCCommonCmpCounter_t Result;
238 
239     /* the final result */
240     CCCommonCmpCounter_t FinalResult;
241 
242     /* FUNCTION LOGIC */
243 
244     /* ........ initialize local variables ............................................ */
245     /* -------------------------------------------------------------------------------- */
246 
247     /* the default is that the result is the same */
248     Result = CC_COMMON_CmpCounter1AndCounter2AreIdentical;
249     FinalResult = CC_COMMON_CmpCounter1AndCounter2AreIdentical; /* just to avoid compilers warnings */
250 
251     /* ........ calculate the effective size ( decrementing the zeros at the MS bytes ) */
252     /* -------------------------------------------------------------------------------- */
253 
254     StartInd1=0,StartInd2=0;
255     /* a loop for adjusting the counter 1 size by neglecting the zeros */
256     while (Counter1Size && (CounterBuff1_ptr[StartInd1] == 0)) {
257         StartInd1++;
258         Counter1Size--;
259     }
260     /* a loop for adjusting the counter 2 size by neglecting the zeros */
261     while (Counter2Size && (CounterBuff2_ptr[StartInd2] == 0)) {
262         StartInd2++;
263         Counter2Size--;
264     }
265 
266     /* ....... step 1 : comparing the counters assuming the effective counter size is the same .......... */
267     /* -------------------------------------------------------------------------------------------------- */
268 
269     /* for security reasons we shall execute this loop as the minimum between the counter sizes
270        the result will be neglected in steps 2,3 if the actual size is different */
271 
272     /* we shall compare all of the bytes from the MSB , the first one that is different
273        will determine which counter is larger , if all of the bytes are equal then the counters are equal */
274 
275     /* loop for checking all of the bytes */
276     for (i=0 ; i < CC_MIN(Counter1Size, Counter2Size) ; i++) {
277         /* if the counter 1 byte is grater then counter 2 byte - return counter 1 is bigger */
278         if ((CounterBuff1_ptr[StartInd1 + i] > CounterBuff2_ptr[StartInd2 + i]) && Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical)
279 
280             Result = CC_COMMON_CmpCounter1GreaterThenCounter2;
281 
282         /* if the counter 2 byte is grater then counter 1 byte - return counter 2 is bigger */
283         if ((CounterBuff2_ptr[StartInd2 + i] > CounterBuff1_ptr[StartInd1 + i]) && Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical)
284 
285             Result = CC_COMMON_CmpCounter2GreaterThenCounter1;
286 
287     }/* end of searching all of the bytes loop */
288 
289     /* ....... STEP 2 : the counter 1 effective size is bigger then counter 2 effective size */
290     /* ------------------------------------------------------------------------------------- */
291 
292     /* on this case the final result is then counter 1 is larger then counter 2 - neglecting the
293        result calculated in step 1 */
294     if (Counter1Size > Counter2Size)
295 
296         FinalResult = CC_COMMON_CmpCounter1GreaterThenCounter2;
297 
298     /* ....... STEP 3 : the counter 2 effective size is bigger then counter 1 effective size */
299     /* ------------------------------------------------------------------------------------- */
300 
301     /* on this case the final result is then counter 2 is larger then counter 1 - neglecting the
302       result calculated in step 1 */
303     if (Counter2Size > Counter1Size)
304 
305         FinalResult = CC_COMMON_CmpCounter2GreaterThenCounter1;
306 
307     /* ....... STEP 4 : the counter 1 effective size is the same as the counter 2 effective size */
308     /* ----------------------------------------------------------------------------------------- */
309 
310     /* on this case the final result is the one calculated in STEP 1 */
311     if (Counter2Size == Counter1Size)
312 
313         FinalResult = Result;
314 
315     /* return the final result */
316 
317     return FinalResult;
318 
319 } /* end CC_CommonCmpMsbUnsignedCounters */
320 
321 
322 #endif
323 
324 
325 /********************************************************************************
326  * @brief This function compares a value of 2 large counter presented in a byte buffer.
327  *        The LSB of the counter is stored in the first cell in the array.
328  *
329  *        for example:
330  *
331  *        a counter of 64 bit : the value is :
332  *
333  *        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]
334  *
335  * @param[in] CounterBuff1_ptr - The first counter buffer.
336  * @param[in] Counter1Size     - the first counter size in bytes.
337  * @param[in] CounterBuff2_ptr - The second counter buffer.
338  * @param[in] Counter2Size     - the second counter size in bytes.
339  *
340  * @return result - an enum with the compare result:
341  *                                0 - both counters are identical
342  *                                1 - counter 1 is larger.
343  *                                2 - counter 2 is larger.
344  */
345 
CC_CommonCmpLsbUnsignedCounters(const uint8_t * CounterBuff1_ptr,size_t Counter1Size,const uint8_t * CounterBuff2_ptr,size_t Counter2Size)346 CCCommonCmpCounter_t CC_CommonCmpLsbUnsignedCounters( const uint8_t  *CounterBuff1_ptr,
347                                  size_t  Counter1Size,
348                                  const uint8_t  *CounterBuff2_ptr,
349                                  size_t Counter2Size )
350 {
351     /* FUNCTION LOCAL DECLERATIONS */
352 
353     /* loop variable */
354     int32_t i;
355 
356     /* the result after comparing the bytes */
357     CCCommonCmpCounter_t Result;
358 
359     /* the final result */
360     CCCommonCmpCounter_t FinalResult;
361 
362     /* FUNCTION LOGIC */
363 
364     /* ........ initialize local variables ............................................ */
365     /* -------------------------------------------------------------------------------- */
366 
367     /* the default is that the result is the same */
368     Result = CC_COMMON_CmpCounter1AndCounter2AreIdentical;
369     FinalResult = CC_COMMON_CmpCounter1AndCounter2AreIdentical; /* just to avoid compilers warnings */
370 
371     /* STEP 1 : calculate the effective size (decrementing the zeros at the MS bytes) */
372     /* ------------------------------------------------------------------------------ */
373 
374     /* a loop for adjusting the counter 1 size by neglecting the zeros */
375     while (Counter1Size != 0) {
376         if (CounterBuff1_ptr[Counter1Size - 1] == 0)
377             Counter1Size--;
378         else
379             break;
380     }
381 
382 
383     /* a loop for adjusting the counter 2 size by neglecting the zeros */
384     while (Counter2Size != 0) {
385         if (CounterBuff2_ptr[Counter2Size - 1] == 0)
386             Counter2Size--;
387         else
388             break;
389     }
390 
391     /* check the sizes */
392     if (Counter1Size == 0 && Counter2Size == 0)
393         return CC_COMMON_CmpCounter1AndCounter2AreIdentical;
394     else if (Counter1Size > Counter2Size)
395         return CC_COMMON_CmpCounter1GreaterThenCounter2;
396     else if (Counter2Size > Counter1Size)
397         return CC_COMMON_CmpCounter2GreaterThenCounter1;
398 
399     /* step 2 : comparing the counters assuming the effective counter size is the same */
400     /* ------------------------------------------------------------------------------- */
401 
402     /* for security reasons we shall execute this loop as the minimum between the counter sizes
403       the result will be neglected in steps 2,3 if the actual size is different */
404 
405     /* we shall compare all of the bytes from the MSB , the first one that is different
406        will determine which counter is larger , if all of the bytes are equal then the counters are equal */
407 
408     /* loop for checking all of the bytes */
409     for (i = CC_MIN(Counter1Size - 1,Counter2Size - 1) ; i >= 0 ; i--) {
410         /* if the counter 1 byte is grater then counter 2 byte - return counter 1 is bigger */
411         if ((CounterBuff1_ptr[i] > CounterBuff2_ptr[i]) && Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical)
412             Result = CC_COMMON_CmpCounter1GreaterThenCounter2;
413 
414         /* if the counter 2 byte is grater then counter 1 byte - return counter 2 is bigger */
415         if ((CounterBuff2_ptr[i] > CounterBuff1_ptr[i]) && Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical)
416             Result = CC_COMMON_CmpCounter2GreaterThenCounter1;
417 
418     }/* end of searching all of the bytes loop */
419 
420     /* STEP 3 : the counter 1 effective size is bigger then counter 2 effective size */
421     /* ----------------------------------------------------------------------------- */
422 
423     /* on this case the final result is then counter 1 is larger then counter 2 - neglecting the
424        result calculated in step 1 */
425     if (Counter1Size > Counter2Size)
426         FinalResult = CC_COMMON_CmpCounter1GreaterThenCounter2;
427 
428     /* STEP 4 : the counter 2 effective size is bigger then counter 1 effective size */
429     /* ----------------------------------------------------------------------------- */
430 
431     /* on this case the final result is then counter 2 is larger then counter 1 - neglecting the
432       result calculated in step 1 */
433     if (Counter2Size > Counter1Size)
434         FinalResult = CC_COMMON_CmpCounter2GreaterThenCounter1;
435 
436     /* ....... STEP 4 : the counter 1 effective size is the same as the counter 2 effective size */
437     /* ----------------------------------------------------------------------------------------- */
438 
439     /* on this case the final result is the one calculated in STEP 1 */
440     if (Counter2Size == Counter1Size)
441         FinalResult = Result;
442 
443     /* return the final result */
444     return FinalResult;
445 
446 }/* END OF CC_CommonCmpLsbUnsignedCounters */
447 
448 
449 
450 /**************************************************************************
451  *           CC_CommonCmpLsWordsUnsignedCounters function         *
452  **************************************************************************/
453 /**
454  * @brief This function compares a value of 2 large counter presented in a word buffer.
455  *        The LSWord of the counters is stored in the first cell in the array.
456  *
457  *
458  * @param[in] CounterBuff1_ptr - The first counter buffer.
459  * @param[in] Counter1SizeWords     - the first counter size in Words.
460  * @param[in] CounterBuff2_ptr - The second counter buffer.
461  * @param[in] Counter2SizeWords     - the second counter size in Words.
462  *
463  * @return result - an enum with the compare result:
464  *                                0 - both counters are identical
465  *                                1 - counter 1 is larger.
466  *                                2 - counter 2 is larger.
467  */
CC_CommonCmpLsWordsUnsignedCounters(const uint32_t * CounterBuff1_ptr,uint32_t Counter1SizeWords,const uint32_t * CounterBuff2_ptr,uint32_t Counter2SizeWords)468 CCCommonCmpCounter_t CC_CommonCmpLsWordsUnsignedCounters(const uint32_t  *CounterBuff1_ptr,
469                                 uint32_t   Counter1SizeWords,
470                                 const uint32_t  *CounterBuff2_ptr,
471                                 uint32_t   Counter2SizeWords)
472 {
473     /* FUNCTION LOCAL DECLARATIONS */
474 
475     /* loop variable */
476     int32_t i;
477 
478     /* the result after comparing the bytes */
479     CCCommonCmpCounter_t Result;
480 
481     /* the final result */
482     CCCommonCmpCounter_t FinalResult;
483 
484     /* FUNCTION LOGIC */
485 
486     /* ........ initialize local variables ............................................ */
487     /* -------------------------------------------------------------------------------- */
488 
489     /* the default is that the result is the same */
490     Result = CC_COMMON_CmpCounter1AndCounter2AreIdentical;
491     FinalResult = CC_COMMON_CmpCounter1AndCounter2AreIdentical; /* just to avoid compilers warnings */
492 
493     /* ........ calculate the effective size ( decrementing the zeros at the MS bytes ) */
494     /* -------------------------------------------------------------------------------- */
495 
496     /* a loop for adjusting the counter 1 size by neglecting the zeros */
497     while (Counter1SizeWords != 0) {
498         if (CounterBuff1_ptr[Counter1SizeWords - 1] == 0)
499             Counter1SizeWords--;
500         else
501             break;
502     }
503 
504     /* a loop for adjusting the counter 2 size by neglecting the zeros */
505     while (Counter2SizeWords != 0) {
506         if (CounterBuff2_ptr[Counter2SizeWords - 1] == 0)
507             Counter2SizeWords--;
508         else
509             break;
510     }
511 
512     /* check the sizes */
513     if (Counter1SizeWords == 0 && Counter2SizeWords == 0)
514         return CC_COMMON_CmpCounter1AndCounter2AreIdentical;
515     else if (Counter1SizeWords > Counter2SizeWords)
516         return CC_COMMON_CmpCounter1GreaterThenCounter2;
517     else if (Counter2SizeWords > Counter1SizeWords)
518         return CC_COMMON_CmpCounter2GreaterThenCounter1;
519 
520     /* ....... step 1 : comparing the counters assuming the effective counter size is the same .......... */
521     /* -------------------------------------------------------------------------------------------------- */
522 
523     /* for security reasons we shall execute this loop as the minimum between the counter sizes
524        the result will be neglected in steps 2,3 if the actual size is different */
525 
526     /* we shall compare all of the bytes from the MSB , the first one that is different
527        will determine which counter is larger , if all of the bytes are equal then the counters are equal */
528 
529     /* loop for checking all of the bytes */
530     for (i = CC_MIN(Counter1SizeWords - 1, Counter2SizeWords - 1) ; i >= 0 ; i--) {
531         /* if the counter 1 byte is grater then counter 2 byte - return counter 1 is bigger */
532         if ((CounterBuff1_ptr[i] > CounterBuff2_ptr[i]) && (Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical))
533             Result = CC_COMMON_CmpCounter1GreaterThenCounter2;
534 
535         /* if the counter 2 byte is grater then counter 1 byte - return counter 2 is bigger */
536         if ((CounterBuff2_ptr[i] > CounterBuff1_ptr[i]) && (Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical))
537             Result = CC_COMMON_CmpCounter2GreaterThenCounter1;
538 
539     }/* end of searching all of the bytes loop */
540 
541     /* ....... STEP 2 : the counter 1 effective size is bigger then counter 2 effective size */
542     /* ------------------------------------------------------------------------------------- */
543 
544     /* on this case the final result is then counter 1 is larger then counter 2 - neglecting the
545        result calculated in step 1 */
546     if (Counter1SizeWords > Counter2SizeWords)
547         FinalResult = CC_COMMON_CmpCounter1GreaterThenCounter2;
548 
549     /* ....... STEP 3 : the counter 2 effective size is bigger then counter 1 effective size */
550     /* ------------------------------------------------------------------------------------- */
551 
552     /* on this case the final result is then counter 2 is larger then counter 1 - neglecting the
553       result calculated in step 1 */
554     if (Counter2SizeWords > Counter1SizeWords)
555         FinalResult = CC_COMMON_CmpCounter2GreaterThenCounter1;
556 
557     /* ....... STEP 4 : the counter 1 effective size is the same as the counter 2 effective size */
558     /* ----------------------------------------------------------------------------------------- */
559 
560     /* on this case the final result is the one calculated in STEP 1 */
561     if (Counter2SizeWords == Counter1SizeWords)
562         FinalResult = Result;
563 
564     /* return the final result */
565     return FinalResult;
566 
567 }
568 
569 
570 
571 /*******************************************************************************
572  *             CC_CommonGetBytesCounterEffectiveSizeInBits                  *
573  *******************************************************************************
574  *
575  * @brief This function returns the effective number of bits in the byte stream counter
576  *        ( searching the highest '1' in the counter )
577  *
578  *        The function has one implementations: for little and big endian machines.
579  *
580  *        Assumed, that LSB of the counter is stored in the first cell in the array.
581  *         For example, the value of the 8-Bytes counter B is :
582  *             B[7]<<56 | B[6]<<48 ............ B[1]<<8 | B[0] .
583  *
584  *
585  * @param[in] CounterBuff_ptr -  The counter buffer.
586  * @param[in] CounterSize     -  the counter size in bytes.
587  *
588  * @return result - The effective counters size in bits.
589  */
590 
CC_CommonGetBytesCounterEffectiveSizeInBits(const uint8_t * CounterBuff_ptr,uint32_t CounterSize)591 uint32_t CC_CommonGetBytesCounterEffectiveSizeInBits( const uint8_t  *CounterBuff_ptr,
592                              uint32_t  CounterSize )
593 {
594     /* FUNCTION LOCAL DECLERATIONS */
595 
596     /* loop variable */
597     int32_t i;
598 
599     /* the effective size in bits */
600     uint32_t CounterEffectiveSizeInBits;
601 
602     /* the effective MS byte ( the one that is not zero ) */
603     uint8_t EffectiveMsByteVal;
604 
605     /* FUNCTION LOGIC */
606 
607     /* STEP1 : a loop for adjusting the counter size by neglecting the MSB zeros */
608     while (CounterSize != 0) {
609         if (CounterBuff_ptr[CounterSize - 1] == 0)
610             CounterSize--;
611         else
612             break;
613     }
614 
615     /* STEP2 : if counter size is 0 - return 0 */
616     if (CounterSize == 0)
617         return 0;
618 
619     /* set the effective MS byte */
620     EffectiveMsByteVal = CounterBuff_ptr[CounterSize - 1];
621 
622     /* initialize the effective size as the counters size ( with MSB zeros ) */
623     CounterEffectiveSizeInBits = CounterSize * 8;
624 
625     /* STEP 3 : adjusting the effective size in bits */
626     for (i = 0; i < 8 ; i++) {
627         if (EffectiveMsByteVal & 0x80)
628             break;
629 
630         CounterEffectiveSizeInBits--;
631         EffectiveMsByteVal <<= 1;
632 
633     }/* end of adjusting the effective size in bits loop */
634 
635     return CounterEffectiveSizeInBits;
636 
637 }/* END OF CC_CommonGetBytesCounterEffectiveSizeInBits */
638 
639 
640 #ifndef DX_OEM_FW
641 
642 /*******************************************************************************
643  *             CC_CommonGetWordsCounterEffectiveSizeInBits                  *
644  *******************************************************************************
645  *
646  * @brief This function returns the effective number of bits in the words array
647  *        ( searching the highest '1' in the counter )
648  *
649  *        The function may works on little and big endian machines.
650  *
651  *        Assumed, that the words in array are ordered from LS word to MS word.
652  *        For LITTLE Endian machines assumed, that LSB of the each word is stored in the first
653  *        cell in the word. For example, the value of the 8-Bytes (B) counter is :
654  *             B[7]<<56 | B[6]<<48 ............ B[1]<<8 | B[0]
655  *
656  *        For BIG Endian machines assumed, that MS byte of each word is stored in the first
657  *        cell, LS byte is stored in the last place of the word.
658  *        For example, the value of the 64 bit counter is :
659  *         B[3] << 56 | B[2] << 48 B[1] << 8 | B[0],  B[7]<<56 | B[6]<<48 | B[5]<<8 | B[4]
660  *
661  *     NOTE !!: 1. For BIG Endian the counter buffer and its size must be aligned to 4-bytes word.
662  *
663  * @param[in] CounterBuff_ptr   -  The counter buffer.
664  * @param[in] CounterSizeWords  -  The counter size in words.
665  *
666  * @return result - The effective counters size in bits.
667  *
668  */
CC_CommonGetWordsCounterEffectiveSizeInBits(const uint32_t * CounterBuff_ptr,uint32_t CounterSizeWords)669 uint32_t CC_CommonGetWordsCounterEffectiveSizeInBits( const uint32_t  *CounterBuff_ptr,
670                              uint32_t   CounterSizeWords)
671 {
672 
673     /* FUNCTION LOCAL DECLARATIONS */
674 
675     /* loop variable */
676     int32_t i;
677 
678     /* the effective size in bits */
679     uint32_t CounterEffectiveSizeInBits = 0;
680 
681     /* the  MS word ( the first, that is not zero ) */
682     uint32_t MsWordVal = 0;
683 
684 
685     /* FUNCTION LOGIC */
686 
687     /* STEP1 : a loop for adjusting the counter size by neglecting the MSW zeros */
688     while (CounterSizeWords != 0) {
689         if (CounterBuff_ptr[CounterSizeWords - 1] == 0)
690             CounterSizeWords--;
691         else
692             break;
693     }
694 
695     /* STEP2 : if counter size is 0 - return 0 */
696     if (CounterSizeWords == 0)
697         return 0;
698 
699     /* set the effective MS word and bit-size */
700     MsWordVal = CounterBuff_ptr[CounterSizeWords - 1];
701     CounterEffectiveSizeInBits = 32*CounterSizeWords;
702 
703     /* STEP 3 : adjusting the effective size in bits */
704     for (i = 0; i < 32 ; i++) {
705         if (MsWordVal & 0x80000000)
706             break;
707 
708         CounterEffectiveSizeInBits--;
709         MsWordVal <<= 1;
710 
711     }/* end of adjusting the effective size in bits loop */
712 
713 
714     return CounterEffectiveSizeInBits;
715 
716 }/* END OF CC_CommonGetWordsCounterEffectiveSizeInBits */
717 
718 
719 /********************************************************************************
720  * @brief This function divides a vector by 2 - in a secured way
721  *
722  *        The LSB of the vector is stored in the first cell in the array.
723  *
724  *        for example:
725  *
726  *        a vector of 128 bit : the value is :
727  *
728  *        word[3] << 96 | word[2] << 64 ............ word[1] << 32 | word[0]
729  *
730  * @param[in] VecBuff_ptr     -  The vector buffer.
731  * @param[in] SizeInWords     -  the counter size in words.
732  *
733  * @return result - no return value.
734  */
735 
CC_CommonDivideVectorBy2(uint32_t * VecBuff_ptr,uint32_t SizeInWords)736 void CC_CommonDivideVectorBy2(uint32_t *VecBuff_ptr,uint32_t SizeInWords)
737 {
738     /* FUNCTION LOCAL DECLERATIONS */
739 
740     uint32_t i;
741     uint32_t Temp;
742 
743     /* FUNCTION LOGIC */
744 
745     /* for loop for dividing the vectors arrays by 2 */
746     for (i=0;i < (SizeInWords)-1 ;i++) {
747         VecBuff_ptr[i]=VecBuff_ptr[i] >> 1;
748         Temp=VecBuff_ptr[i+1]&1UL;
749         VecBuff_ptr[i]=VecBuff_ptr[i] | Temp<<(32-1);
750     }
751 
752     /* dividing the MS word */
753     VecBuff_ptr[SizeInWords-1]=VecBuff_ptr[SizeInWords-1]>>1;
754 
755     return;
756 
757 }/* END OF CC_CommonDivideVectorBy2 */
758 
759 
760 /********************************************************************************
761  * @brief This function shifts left a big endian vector by Shift - bits (Shift < 8).
762  *
763  *        The MSB of the vector is stored in the first cell in the array,
764  *
765  *        For example, a vector of 128 bit is :
766  *
767  *        byte[n-1] | byte[n-2] ... byte[1] | byte[0]
768  *
769  * @param[in] VecBuff_ptr     -  The vector buffer.
770  * @param[in] SizeInBytes     -  The counter size in bytes.
771  * @param[in] Shift           -  The number of shift left bits, must be < 8.
772  * @return no return value.
773  */
774 
CC_CommonShiftLeftBigEndVector(uint8_t * VecBuff_ptr,uint32_t SizeInBytes,int8_t Shift)775 void CC_CommonShiftLeftBigEndVector(uint8_t *VecBuff_ptr,uint32_t SizeInBytes, int8_t Shift)
776 {
777     /* FUNCTION LOCAL DECLARATIONS */
778 
779     uint32_t i;
780     uint32_t Temp = 0;
781 
782 
783     /* FUNCTION LOGIC */
784 
785     if (SizeInBytes == 0 || Shift == 0)
786         return;
787 
788     /* loop for shifting the vector by Shift bits left */
789     for (i=0;i < SizeInBytes - 1 ;i++) {
790         VecBuff_ptr[i] = (uint8_t)(VecBuff_ptr[i] << Shift);
791         Temp = VecBuff_ptr[i+1] & 0xFF ;
792         VecBuff_ptr[i] = VecBuff_ptr[i] | (uint8_t)(Temp >> (8 - Shift));
793     }
794 
795     /* shifting the LS byte */
796     VecBuff_ptr[SizeInBytes - 1] = (uint8_t)(VecBuff_ptr[SizeInBytes - 1] << Shift);
797 
798     return;
799 
800 }/* END OF CC_CommonShiftLeftBigEndVector */
801 
802 
803 /*******************************************************************************
804  *                      CC_CommonShiftRightVector                           *
805  *******************************************************************************
806  * @brief This function shifts right a vector by Shift - bits (Shift < 8).
807  *
808  *        The LSB of the vector is stored in the first cell in the array.
809  *        For example, a vector of 128 bit is :
810  *
811  *        byte[n-1] | byte[n-2] ... byte[1] | byte[0]
812  *
813  * @param[in] VecBuff_ptr     -  The vector buffer.
814  * @param[in] SizeInBytes     -  The counter size in bytes.
815  * @param[in] Shift           -  The number of shift left bits, must be < 8.
816  * @return no return value.
817  */
CC_CommonShiftRightVector(uint8_t * VecBuff_ptr,uint32_t SizeInBytes,int8_t Shift)818 void CC_CommonShiftRightVector(uint8_t *VecBuff_ptr,uint32_t SizeInBytes, int8_t Shift)
819 {
820     /* FUNCTION LOCAL DECLARATIONS */
821 
822     uint32_t i;
823     uint32_t Temp = 0;
824 
825 
826     /* FUNCTION LOGIC */
827 
828     if (SizeInBytes == 0 || Shift == 0)
829         return;
830 
831     /* loop for shifting the vector by Shift bits right */
832     for (i=0;i < SizeInBytes - 1 ;i++) {
833         VecBuff_ptr[i] = (uint8_t)(VecBuff_ptr[i] >> Shift);
834         Temp = VecBuff_ptr[i+1] & 0xFF ;
835         VecBuff_ptr[i] = VecBuff_ptr[i] | (uint8_t)(Temp << (8 - Shift));
836     }
837 
838     /* shifting the MS byte */
839     VecBuff_ptr[SizeInBytes - 1] = (uint8_t)(VecBuff_ptr[SizeInBytes - 1] >> Shift);
840 
841     return;
842 
843 }/* END OF CC_CommonShiftRightVector */
844 
845 
846 /********************************************************************************
847  * @brief This function adds 2 vectors ( A+B).
848  *
849  * @param[in] A_ptr       -  input vector A.
850  * @param[in] B_ptr       -  input vector B.
851  * @param[in] SizeInWords - The size in words
852  * @param[in] Res_ptr     - The result pointer
853  *
854  * @return - Carry from high words addition.
855  */
856 
CC_CommonAdd2vectors(uint32_t * A_ptr,uint32_t * B_ptr,uint32_t SizeInWords,uint32_t * Res_ptr)857 uint32_t CC_CommonAdd2vectors ( uint32_t *A_ptr, uint32_t *B_ptr,uint32_t SizeInWords, uint32_t *Res_ptr )
858 {
859     /* FUNCTION LOCAL DECLARATIONS */
860 
861     uint16_t  i;
862     uint32_t temp;
863     uint32_t Carry, PrevCarry=0;
864     uint32_t currentWordRes;
865 
866     /* FUNCTION LOGIC */
867 
868     for (i=0;i < SizeInWords;i++) {
869         /* execute the addition */
870         currentWordRes = A_ptr[i]+B_ptr[i];
871 
872         /* check if carry */
873         Carry = ((currentWordRes < A_ptr[i]) || (currentWordRes < B_ptr[i]));
874 
875         /* add previous carry */
876         Res_ptr[i] = currentWordRes + PrevCarry;
877 
878         /*  Solve 4 problems: 1.if result > 32 bits ==> Carry to the next word.
879                               2.if the result=32 bits exactly ==> the result is = 0 but carry=1 to the next word.
880                           3.if the result=32 bit-1 and because of PrevCarry the result come to 0 ==> Carry to the next word.
881                           4.if the result=0 because the exercise is 0+0. */
882 
883         /* a dummy initialization for temp */
884         temp = 2;
885 
886         if (!(Res_ptr[i]))
887 
888             temp = 1;
889 
890         if (Res_ptr[i])
891 
892             temp = 0;
893 
894         PrevCarry = Carry | ( PrevCarry & temp & 0x1);
895 
896     }/* end of adding the vectors */
897 
898     return PrevCarry;
899 
900 }/* END OF CC_CommonAdd2vectors */
901 
902 
903 
904 /*******************************************************************************
905  *                      CC_CommonSubtractUintArrays                         *
906  *******************************************************************************
907 
908  * @brief This function subtracts two little endian word arrays (length SizeInWords):
909  *        Res = (A - B) and returns borrow from subtracting of high words.
910  *
911  * @param[in] A_ptr       -  Pointer to input vector A.
912  * @param[in] B_ptr       -  Pointer to input vector B.
913  * @param[in] SizeInWords -  Size in words of each of vectors
914  * @param[in] Res_ptr     -  result pointer
915  *
916  * @return  Borrow from high words subtracting.
917  */
918 
CC_CommonSubtractUintArrays(const uint32_t * A_ptr,uint32_t * B_ptr,uint32_t SizeInWords,uint32_t * Res_ptr)919 uint32_t CC_CommonSubtractUintArrays(const uint32_t *A_ptr,
920                     uint32_t *B_ptr,
921                     uint32_t  SizeInWords,
922                     uint32_t *Res_ptr )
923 {
924     /* FUNCTION LOCAL DECLARATIONS */
925 
926     uint32_t temp, i;
927 
928     uint32_t Borrow = 0;
929 
930     /* FUNCTION LOGIC */
931 
932     for (i=0; i < SizeInWords; i++) {
933         /* subtract previous borrow */
934         temp = A_ptr[i] - Borrow;
935 
936         /* check if borrow */
937         if (temp > A_ptr[i])
938 
939             Borrow = 1;
940 
941         else Borrow = 0;
942 
943         /* subtract B */
944         Res_ptr[i] = temp - B_ptr[i];
945 
946         /* check if borrow */
947         if (Res_ptr[i] > temp)
948 
949             Borrow ++;
950 
951 
952     }/* end of subtracting */
953 
954     return Borrow;
955 
956 }/* END OF CC_CommonSubtractUintArrays */
957 
958 
959 /*******************************************************************************
960  *                      CC_CommonSubtractMSBUint8Arrays                     *
961  *******************************************************************************
962 
963  * @brief This function subtracts two big endian byte arrays.
964  *
965  *   Assuming:  SizeA >= SizeB.
966  *              Size of result buffer is not less, than sizeA.
967  *
968  * @param[in] A_ptr       -  Pointer to input vector A.
969  * @param[in] sizeA       -  Size in bytes of each of vector A.
970  * @param[in] B_ptr       -  Pointer to input vector B.
971  * @param[in] sizeB       -  Size in bytes of each of vector B.
972  * @param[in] Res_ptr     -  result pointer
973  *
974  * @return  Borrow from high byte of vector A.
975  */
CC_CommonSubtractMSBUint8Arrays(uint8_t * A_ptr,uint32_t sizeA,uint8_t * B_ptr,uint32_t sizeB,uint8_t * Res_ptr)976 uint8_t CC_CommonSubtractMSBUint8Arrays(
977                       uint8_t  *A_ptr,
978                       uint32_t  sizeA,
979                       uint8_t  *B_ptr,
980                       uint32_t  sizeB,
981                       uint8_t  *Res_ptr )
982 {
983     /* FUNCTION LOCAL DECLARATIONS */
984 
985     uint8_t temp;
986 
987     uint8_t Borrow = 0;
988 
989     int32_t difSizes, i;
990 
991 
992     /* FUNCTION LOGIC */
993 
994     difSizes = sizeA - sizeB;
995 
996     for (i = sizeA - 1; i > 0; i--) {
997         /* subtract previous borrow */
998         temp = A_ptr[i] - Borrow;
999 
1000         /* check if borrow */
1001         if (temp > A_ptr[i])
1002 
1003             Borrow = 1;
1004 
1005         else Borrow = 0;
1006 
1007         /* subtract B */
1008         if (i - difSizes >= 0)
1009             Res_ptr[i] = temp - B_ptr[i - difSizes];
1010         else
1011             Res_ptr[i] = temp;
1012 
1013         /* check if borrow */
1014         if (Res_ptr[i] > temp)
1015 
1016             Borrow ++;
1017 
1018     }/* end of subtracting */
1019 
1020     return Borrow;
1021 
1022 }/* END OF CC_CommonSubtractUintArrays */
1023 
1024 
1025 #endif
1026