1 /* 2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef _CC_COMMON_MATH_H 8 #define _CC_COMMON_MATH_H 9 10 #include "cc_common_error.h" 11 12 13 #ifdef __cplusplus 14 extern "C" 15 { 16 #endif 17 18 19 /************************ Defines ******************************/ 20 21 /************************ Macros *******************************/ 22 #ifndef IS_ALIGNED 23 #define IS_ALIGNED(val, align) \ 24 (((CCVirtAddr_t)(val) & ((align) - 1)) == 0) 25 #endif 26 /* converts size given in bits to size in 32-bit words, rounded up */ 27 #define BIT_SIZE_UP_TO_32BIT_WORDS(x) (((x)>>5UL) + (((x)&31)!=0)) 28 29 /* rotate right 32-bits word by n bits */ 30 #define CC_COMMON_ROTR32(x, n) ( ((x) >> (n)) | ((x) << ( 32 - (n) )) ) 31 /* rotate 32-bits word by 16 bits */ 32 #define CC_COMMON_ROT32(x) ( (x) >> 16 | (x) << 16 ) 33 34 /* inverse the bytes order in a word */ 35 #define CC_COMMON_REVERSE32(x) ( ((CC_COMMON_ROT32((x)) & 0xff00ff00UL) >> 8) | ((CC_COMMON_ROT32((x)) & 0x00ff00ffUL) << 8) ) 36 37 #define SHIFT_LEFT(x, nBits) ( (x) >> (nBits) ) 38 #define SHIFT_RIGHT(x, nBits) ( (x) << (nBits) ) 39 #define CONVERT_LE_2_CPU_E(x) (x) 40 #define CONVERT_CPU_E_2_BE(x) CC_COMMON_REVERSE32(x) 41 42 /* inverse the bytes order in words of array */ 43 #define CC_COMMON_INVERSE_UINT32_IN_ARRAY( Array, SizeWords ) \ 44 { \ 45 uint32_t ii2; \ 46 for( ii2 = 0; ii2 < (SizeWords); ii2++ ) \ 47 { \ 48 (Array)[ii2] = CC_COMMON_REVERSE32( (Array)[ii2] ); \ 49 } \ 50 } 51 52 #ifndef BIG__ENDIAN 53 /* define word endiannes*/ 54 #define CC_SET_WORD_ENDIANESS 55 #else 56 #define CC_SET_WORD_ENDIANESS(val) CC_COMMON_REVERSE32(val) 57 #endif 58 59 #ifdef BIG__ENDIAN 60 #define CC_COMMON_CONVERT_TO_LE32(in32_ptr, out32_ptr, size_words) \ 61 { \ 62 uint32_t i; \ 63 for (i = 0; i < size_words; i++) { \ 64 (out32_ptr)[i] = CC_COMMON_REVERSE32((in32_ptr)[i]); \ 65 } \ 66 } 67 #else 68 #define CC_COMMON_CONVERT_TO_LE32(in32_ptr, out32_ptr, size_words) \ 69 { \ 70 uint32_t i; \ 71 if((in32_ptr) != (out32_ptr)) { \ 72 for (i = 0; i < size_words; i++) { \ 73 (out32_ptr)[i] = (in32_ptr)[i]; \ 74 } \ 75 } \ 76 } 77 #endif 78 79 /* get a bit val from a word array */ 80 #define CC_COMMON_GET_BIT_VAL_FROM_WORD_ARRAY( ptr , bit_pos ) \ 81 (((ptr)[(bit_pos)>>5] >> ((bit_pos) & 0x1FUL)) & 1UL) 82 83 /* exchange a bit on a word array */ 84 #define CC_COMMON_EXCHANGE_BIT_ON_WORD_ARRAY(ptr,bit_pos) ((ptr)[(bit_pos)>>5] ^= (1UL << ((bit_pos) & 0x1FUL))) 85 86 /* macros for copying 4 words to non aligned output according to macine endianness. 87 Note: output is given by aligned down pointer and alignment of output data in bits, 88 input must be aligned to 4 bytes */ 89 #ifdef BIG__ENDIAN 90 91 #define CC_COMMON_COPY_4WORDS_TO_BYTES( out32_ptr, outAlign, in32_ptr ) \ 92 if( outAlign != 0 ) \ 93 { \ 94 (out32_ptr)[0] = ((out32_ptr)[0] & (0xFFFFFFFF << (32-(outAlign)))) | \ 95 CC_COMMON_REVERSE32((in32_ptr)[0]) >> (outAlign); \ 96 (out32_ptr)[1] = CC_COMMON_REVERSE32((in32_ptr)[0]) << (32-(outAlign)) | \ 97 CC_COMMON_REVERSE32((in32_ptr)[1]) >> (outAlign); \ 98 (out32_ptr)[2] = CC_COMMON_REVERSE32((in32_ptr)[1]) << (32-(outAlign)) | \ 99 CC_COMMON_REVERSE32((in32_ptr)[2]) >> (outAlign); \ 100 (out32_ptr)[3] = CC_COMMON_REVERSE32((in32_ptr)[2]) << (32-(outAlign)) | \ 101 CC_COMMON_REVERSE32((in32_ptr)[3]) >> (outAlign); \ 102 (out32_ptr)[4] = ((out32_ptr)[4] & (0xFFFFFFFF >> (outAlign))) | \ 103 CC_COMMON_REVERSE32((in32_ptr)[3]) << (32-(outAlign)); \ 104 } \ 105 else \ 106 { \ 107 (out32_ptr)[0] = CC_COMMON_REVERSE32((in32_ptr)[0]); \ 108 (out32_ptr)[1] = CC_COMMON_REVERSE32((in32_ptr)[1]); \ 109 (out32_ptr)[2] = CC_COMMON_REVERSE32((in32_ptr)[2]); \ 110 (out32_ptr)[3] = CC_COMMON_REVERSE32((in32_ptr)[3]); \ 111 } 112 113 #else /* LITTLE_ENDIAN */ 114 #define CC_COMMON_COPY_4WORDS_TO_BYTES( out32_ptr, outAlign, in32_ptr ) \ 115 if( outAlign != 0 ) \ 116 { \ 117 (out32_ptr)[0] = ((out32_ptr)[0] & (0xFFFFFFFF >> (32-(outAlign)))) | (in32_ptr)[0] << (outAlign); \ 118 (out32_ptr)[1] = (in32_ptr)[0] >> (32-(outAlign)) | (in32_ptr)[1] << (outAlign); \ 119 (out32_ptr)[2] = (in32_ptr)[1] >> (32-(outAlign)) | (in32_ptr)[2] << (outAlign); \ 120 (out32_ptr)[3] = (in32_ptr)[2] >> (32-(outAlign)) | (in32_ptr)[3] << (outAlign); \ 121 (out32_ptr)[4] = ((out32_ptr)[4] & (0xFFFFFFFF << (outAlign))) | (in32_ptr)[3] >> (32-(outAlign)); \ 122 } \ 123 else \ 124 { \ 125 (out32_ptr)[0] = (in32_ptr)[0]; \ 126 (out32_ptr)[1] = (in32_ptr)[1]; \ 127 (out32_ptr)[2] = (in32_ptr)[2]; \ 128 (out32_ptr)[3] = (in32_ptr)[3]; \ 129 } 130 #endif 131 132 133 /* macros for copying 16 bytes from non aligned input into aligned output according to machine endianness. 134 Note: input is given by aligned down pointer and alignment of input data in bits, 135 output must be aligned to 4 bytes */ 136 137 #ifdef BIG__ENDIAN 138 139 #define CC_COMMON_COPY_16BYTES_TO_WORDS( in32_ptr, inAlign, out32_ptr ) \ 140 if( inAlign != 0 ) \ 141 { \ 142 (out32_ptr)[0] = CC_COMMON_REVERSE32( (in32_ptr)[0] << (inAlign) | (in32_ptr)[1] >> (32-(inAlign)) ); \ 143 (out32_ptr)[1] = CC_COMMON_REVERSE32( (in32_ptr)[1] << (inAlign) | (in32_ptr)[2] >> (32-(inAlign)) ); \ 144 (out32_ptr)[2] = CC_COMMON_REVERSE32( (in32_ptr)[2] << (inAlign) | (in32_ptr)[3] >> (32-(inAlign)) ); \ 145 (out32_ptr)[3] = CC_COMMON_REVERSE32( (in32_ptr)[3] << (inAlign) | (in32_ptr)[4] >> (32-(inAlign)) ); \ 146 } \ 147 else \ 148 { \ 149 (out32_ptr)[0] = CC_COMMON_REVERSE32((in32_ptr)[0]); \ 150 (out32_ptr)[1] = CC_COMMON_REVERSE32((in32_ptr)[1]); \ 151 (out32_ptr)[2] = CC_COMMON_REVERSE32((in32_ptr)[2]); \ 152 (out32_ptr)[3] = CC_COMMON_REVERSE32((in32_ptr)[3]); \ 153 } 154 155 #else /* LITTLE_ENDIAN */ 156 157 #define CC_COMMON_COPY_16BYTES_TO_WORDS( in32_ptr, inAlign, out32_ptr ) \ 158 if( inAlign != 0 ) \ 159 { \ 160 (out32_ptr)[0] = (in32_ptr)[0] >> (inAlign) | (in32_ptr)[1] << (32-(inAlign)); \ 161 (out32_ptr)[1] = (in32_ptr)[1] >> (inAlign) | (in32_ptr)[2] << (32-(inAlign)); \ 162 (out32_ptr)[2] = (in32_ptr)[2] >> (inAlign) | (in32_ptr)[3] << (32-(inAlign)); \ 163 (out32_ptr)[3] = (in32_ptr)[3] >> (inAlign) | (in32_ptr)[4] << (32-(inAlign)); \ 164 } \ 165 else \ 166 { \ 167 (out32_ptr)[0] = (in32_ptr)[0]; \ 168 (out32_ptr)[1] = (in32_ptr)[1]; \ 169 (out32_ptr)[2] = (in32_ptr)[2]; \ 170 (out32_ptr)[3] = (in32_ptr)[3]; \ 171 } 172 #endif 173 174 175 /************************ Enums ********************************/ 176 177 /* the counter comperation result enum */ 178 typedef enum { 179 CC_COMMON_CmpCounter1AndCounter2AreIdentical = 0, 180 CC_COMMON_CmpCounter1GreaterThenCounter2 = 1, 181 CC_COMMON_CmpCounter2GreaterThenCounter1 = 2, 182 183 CC_COMMON_CmpCounterLast = 0x7FFFFFFF, 184 185 } CCCommonCmpCounter_t; 186 187 188 /************************ Typedefs *****************************/ 189 190 /************************ Structs ******************************/ 191 192 /************************ Public Variables **********************/ 193 194 /************************ Public Functions **********************/ 195 196 /***************************************************************** 197 * @brief This function adds a value to a large counter presented in a buffer. 198 * The MSB of the counter is stored in the first cell in the array. 199 * 200 * for example: 201 * 202 * a counter of 64 bit : the value is : 203 * 204 * byte[0] << 56 | byte[1] << 48 ............ byte[6] << 8 | byte[7] 205 * 206 * @param[in] CounterBuff_ptr - The buffer containing the counter. 207 * @param[in] Val - this value to add. 208 * @param[in] CounterSize - the counter size in 32bit words. 209 * 210 * @return CCError_t - On success CC_OK is returned, on failure a 211 * value MODULE_* as defined in ... 212 */ 213 214 void CC_CommonIncMsbUnsignedCounter( uint32_t *CounterBuff_ptr , 215 uint32_t Val, 216 uint32_t CounterSize); 217 218 219 /******************************************************************************** 220 * @brief This function adds a value to a large counter presented in a buffer. 221 * The LSB of the counter is stored in the first cell in the array. 222 * 223 * for example: 224 * 225 * a counter of 64 bit : the value is : 226 * 227 * byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0] 228 * 229 * @param[in] CounterBuff_ptr - The buffer containing the counter. 230 * @param[in] Val - this value to add. 231 * @param[in] CounterSize - the counter size in 32bit words. 232 * 233 * @return carry bit from MS word if carry occur 234 * 235 */ 236 237 uint32_t CC_CommonIncLsbUnsignedCounter( 238 uint32_t *CounterBuff_ptr , 239 uint32_t Val, 240 uint32_t CounterSize); 241 242 243 /******************************************************************************** 244 * @brief This function subtracts a value from a large counter presented in a buffer. 245 * The LSB of the counter is stored in the first cell in the array. 246 * 247 * for example: 248 * 249 * a counter of 64 bit : the value is : 250 * 251 * byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0] 252 * 253 * @param[in] CounterBuff_ptr - the buffer containing the counter. 254 * @param[in] Val - the value to subtract. 255 * @param[in] CounterSize - the counter size in 32bit words. 256 * 257 * @return CCError_t - On success CC_OK is returned, on failure a 258 * value MODULE_* as defined in ... 259 */ 260 261 void CC_CommonDecrLsbUnsignedCounter( uint32_t *CounterBuff_ptr, 262 uint32_t Val, 263 uint32_t CounterSizeInWords); 264 265 266 /************************************************************** 267 * @brief This function compares a value of 2 large counter presented in a byte buffer. 268 * The MSB of the counter is stored in the first cell in the array. 269 * 270 * for example: 271 * 272 * a counter of 64 bit : the value is : 273 * 274 * byte[0] << 56 | byte[1] << 48 ............ byte[6] << 8 | byte[7] 275 * 276 * 277 * @param[in] CounterBuff1_ptr - The first counter buffer. 278 * @param[in] Counter1Size - the first counter size in bytes. 279 * @param[in] CounterBuff2_ptr - The second counter buffer. 280 * @param[in] Counter2Size - the second counter size in bytes. 281 * @param[in] SizeUnit - the size units. 0 - bits , 1 - bytes 282 * 283 * @return result - an enum with the compare result: 284 * 0 - both counters are identical 285 * 1 - counter 1 is larger. 286 * 2 - counter 2 is larger. 287 * @note This code executes in constant time, regardless of the arguments. 288 */ 289 290 CCCommonCmpCounter_t CC_CommonCmpMsbUnsignedCounters( const uint8_t *CounterBuff1_ptr, 291 uint32_t Counter1Size, 292 const uint8_t *CounterBuff2_ptr, 293 uint32_t Counter2Size ); 294 295 296 297 /************************************************************** 298 * @brief This function compares a value of 2 large counter presented in a byte buffer. 299 * The LSB of the counter is stored in the first cell in the array. 300 * 301 * for example: 302 * 303 * a counter of 64 bit : the value is : 304 * 305 * byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0] 306 * 307 * @param[in] CounterBuff1_ptr - The first counter buffer. 308 * @param[in] Counter1Size - the first counter size in bytes. 309 * @param[in] CounterBuff2_ptr - The second counter buffer. 310 * @param[in] Counter2Size - the second counter size in bytes. 311 * 312 * @return result - an enum with the compare result: 313 * 0 - both counters are identical 314 * 1 - counter 1 is larger. 315 * 2 - counter 2 is larger. 316 */ 317 318 CCCommonCmpCounter_t CC_CommonCmpLsbUnsignedCounters( const uint8_t *CounterBuff1_ptr, 319 size_t Counter1Size, 320 const uint8_t *CounterBuff2_ptr, 321 size_t Counter2Size ); 322 323 324 325 /************************************************************************** 326 * CC_CommonCmpLsWordsUnsignedCounters function * 327 **************************************************************************/ 328 /** 329 * @brief This function compares a value of 2 large counter presented in a word buffer. 330 * The LSWord of the counters is stored in the first cell in the array. 331 * 332 * 333 * @param[in] CounterBuff1_ptr - The first counter buffer. 334 * @param[in] Counter1SizeWords - the first counter size in Words. 335 * @param[in] CounterBuff2_ptr - The second counter buffer. 336 * @param[in] Counter2SizeWords - the second counter size in Words. 337 * 338 * @return result - an enum with the compare result: 339 * 0 - both counters are identical 340 * 1 - counter 1 is larger. 341 * 2 - counter 2 is larger. 342 */ 343 CCCommonCmpCounter_t CC_CommonCmpLsWordsUnsignedCounters(const uint32_t *CounterBuff1_ptr, 344 uint32_t Counter1SizeWords, 345 const uint32_t *CounterBuff2_ptr, 346 uint32_t Counter2SizeWords); 347 348 /******************************************************************************** 349 * 350 * @brief This function returns the effective number of bits in the byte stream counter 351 * ( searching the highest '1' in the counter ) 352 * 353 * The function has one implementations: for little and big endian machines. 354 * 355 * Assumed, that LSB of the counter is stored in the first cell in the array. 356 * For example, the value of the 8-Bytes counter B is : 357 * B[7]<<56 | B[6]<<48 ............ B[1]<<8 | B[0] . 358 * 359 * 360 * @param[in] CounterBuff_ptr - The counter buffer. 361 * @param[in] CounterSize - the counter size in bytes. 362 * 363 * @return result - The effective counters size in bits. 364 */ 365 366 uint32_t CC_CommonGetBytesCounterEffectiveSizeInBits( const uint8_t *CounterBuff_ptr, 367 uint32_t CounterSize ); 368 369 /******************************************************************************* 370 * CC_CommonGetWordsCounterEffectiveSizeInBits * 371 ******************************************************************************* 372 * 373 * @brief This function returns the effective number of bits in the words array 374 * ( searching the highest '1' in the counter ) 375 * 376 * The function may works on little and big endian machines. 377 * 378 * Assumed, that the words in array are ordered from LS word to MS word. 379 * For LITTLE Endian machines assumed, that LSB of the each word is stored in the first 380 * cell in the word. For example, the value of the 8-Bytes (B) counter is : 381 * B[7]<<56 | B[6]<<48 ............ B[1]<<8 | B[0] 382 * 383 * For BIG Endian machines assumed, that MS byte of each word is stored in the first 384 * cell, LS byte is stored in the last place of the word. 385 * For example, the value of the 64 bit counter is : 386 * B[3] << 56 | B[2] << 48 B[1] << 8 | B[0], B[7]<<56 | B[6]<<48 | B[5]<<8 | B[4] 387 * 388 * NOTE !!: 1. For BIG Endian the counter buffer and its size must be aligned to 4-bytes word. 389 * 390 * @param[in] CounterBuff_ptr - The counter buffer. 391 * @param[in] CounterSizeWords - The counter size in words. 392 * 393 * @return result - The effective counters size in bits. 394 * 395 */ 396 uint32_t CC_CommonGetWordsCounterEffectiveSizeInBits( const uint32_t *CounterBuff_ptr, 397 uint32_t CounterSizeWords); 398 399 /******************************************************************************** 400 * @brief This function divides a vector by 2 - in a secured way 401 * 402 * The LSB of the vector is stored in the first cell in the array. 403 * 404 * for example: 405 * 406 * a vector of 128 bit : the value is : 407 * 408 * word[3] << 96 | word[2] << 64 ............ word[1] << 32 | word[0] 409 * 410 * @param[in] VecBuff_ptr - The vector buffer. 411 * @param[in] SizeInWords - the counter size in words. 412 * 413 * @return result - no return value. 414 */ 415 void CC_CommonDivideVectorBy2(uint32_t *VecBuff_ptr,uint32_t SizeInWords); 416 417 418 /******************************************************************************** 419 * @brief This function shifts left a big endian vector by Shift - bits (Shift < 8). 420 * 421 * The MSB of the vector is stored in the first cell in the array, 422 * 423 * For example, a vector of 128 bit is : 424 * 425 * byte[n-1] | byte[n-2] ... byte[1] | byte[0] 426 * 427 * @param[in] VecBuff_ptr - The vector buffer. 428 * @param[in] SizeInBytes - The counter size in bytes. 429 * @param[in] Shift - The number of shift left bits, must be < 8. 430 * @return no return value. 431 */ 432 433 void CC_CommonShiftLeftBigEndVector(uint8_t *VecBuff_ptr,uint32_t SizeInBytes, int8_t Shift); 434 435 436 /******************************************************************************* 437 * CC_CommonShiftRightVector * 438 ******************************************************************************* 439 * @brief This function shifts right a vector by Shift - bits (Shift < 8). 440 * 441 * The LSB of the vector is stored in the first cell in the array. 442 * For example, a vector of 128 bit is : 443 * 444 * byte[n-1] | byte[n-2] ... byte[1] | byte[0] 445 * 446 * @param[in] VecBuff_ptr - The vector buffer. 447 * @param[in] SizeInBytes - The counter size in bytes. 448 * @param[in] Shift - The number of shift left bits, must be < 8. 449 * @return no return value. 450 */ 451 void CC_CommonShiftRightVector(uint8_t *VecBuff_ptr, uint32_t SizeInBytes, int8_t Shift); 452 453 454 /****************************************************************************** 455 * CC_CommonShiftLeftVector * 456 ****************************************************************************** 457 * @brief This function shifts left a vector by Shift - bits (Shift < 8). 458 * 459 * The LSB of the vector is stored in the first cell in the array. 460 * For example, a vector of 128 bit is : 461 * 462 * byte[n-1] | byte[n-2] ... byte[1] | byte[0] 463 * 464 * @param[in] VecBuff_ptr - The vector buffer. 465 * @param[in] SizeInBytes - The counter size in bytes. 466 * @param[in] Shift - The number of shift left bits, must be < 8. 467 * @return no return value. 468 */ 469 void CC_CommonShiftLeftVector(uint8_t *VecBuff_ptr,uint32_t SizeInBytes, int8_t Shift); 470 471 472 /************************************************************** 473 * @brief This function adds 2 vectors ( A+B). 474 * 475 * @param[in] A_ptr - input vector A. 476 * @param[in] B_ptr - input vector B. 477 * @param[in] SizeInWords - The size in words 478 * @param[in] Res_ptr - The result pointer 479 * 480 * @return result - Carry from high words addition. 481 */ 482 483 uint32_t CC_CommonAdd2vectors ( 484 uint32_t *A_ptr, 485 uint32_t *B_ptr, 486 uint32_t SizeInWords, 487 uint32_t *Res_ptr ); 488 489 490 /******************************************************************************* 491 * CC_CommonSubtractUintArrays * 492 ******************************************************************************* 493 494 * @brief This function subtracts two little endian words arrays of length 495 SizeInWords: Res = (A - B) and returns Borrow from subtracting of high 496 words. 497 * 498 * @param[in] A_ptr - input vector A. 499 * @param[in] B_ptr - input vector B. 500 * @param[in] SizeInWords - size in words 501 * @param[in] Res_ptr - result pointer 502 * 503 * @return Borrow from high words subtracting. 504 */ 505 506 uint32_t CC_CommonSubtractUintArrays(const uint32_t *A_ptr, 507 uint32_t *B_ptr, 508 uint32_t SizeInWords, 509 uint32_t *Res_ptr ); 510 511 /******************************************************************************* 512 * CC_CommonAddTwoLsbUint8Vectors * 513 ******************************************************************************* 514 * 515 * @brief This function adds two little endian vectors Res = (A + B) and returns carry. 516 * 517 * 518 * @param[in] A_ptr - input vector A. 519 * @param[in] B_ptr - input vector B. 520 * @param[in] SizeInWords - size in words 521 * @param[in] Res_ptr - result pointer 522 * 523 * @return - carry from adding of two high bytes. 524 */ 525 526 uint32_t CC_CommonAddTwoLsbUint8Vectors( 527 uint8_t *A_ptr, 528 uint8_t *B_ptr, 529 uint32_t VectSizeInBytes, 530 uint8_t *Res_ptr ); 531 532 533 /******************************************************************************* 534 * CC_CommonSubtractMSBUint8Arrays * 535 ******************************************************************************* 536 537 * @brief This function subtracts two big endian byte arrays. 538 * 539 * Assuming: SizeA >= SizeB. 540 * Size of result buffer is not less, than sizeA. 541 * 542 * @param[in] A_ptr - Pointer to input vector A. 543 * @param[in] sizeA - Size in bytes of each of vector A. 544 * @param[in] B_ptr - Pointer to input vector B. 545 * @param[in] sizeB - Size in bytes of each of vector B. 546 * @param[in] Res_ptr - result pointer 547 * 548 * @return Borrow from high byte of vector A. 549 */ 550 uint8_t CC_CommonSubtractMSBUint8Arrays( 551 uint8_t *A_ptr, 552 uint32_t sizeA, 553 uint8_t *B_ptr, 554 uint32_t sizeB, 555 uint8_t *Res_ptr ); 556 557 558 559 #ifdef __cplusplus 560 } 561 #endif 562 563 #endif 564 565 566 567