]>
git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/cc_priv.h
0a51e66eec069b9221e7d5c9f0d9fa4296f2a056
5 * Created on 12/01/2010
7 * Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
11 #ifndef _CORECRYPTO_CC_PRIV_H_
12 #define _CORECRYPTO_CC_PRIV_H_
14 #include <corecrypto/cc.h>
17 /* defines the following macros :
19 CC_MEMCPY : optimized memcpy.
20 CC_MEMMOVE : optimized memmove.
21 CC_MEMSET : optimized memset.
23 CC_STORE32_BE : store 32 bit value in big endian in unaligned buffer.
24 CC_STORE32_LE : store 32 bit value in little endian in unaligned buffer.
25 CC_STORE64_BE : store 64 bit value in big endian in unaligned buffer.
26 CC_STORE64_LE : store 64 bit value in little endian in unaligned buffer.
28 CC_LOAD32_BE : load 32 bit value in big endian from unaligned buffer.
29 CC_LOAD32_LE : load 32 bit value in little endian from unaligned buffer.
30 CC_LOAD64_BE : load 64 bit value in big endian from unaligned buffer.
31 CC_LOAD64_LE : load 64 bit value in little endian from unaligned buffer.
33 CC_ROR : Rotate Right 32 bits. Rotate count can be a variable.
34 CC_ROL : Rotate Left 32 bits. Rotate count can be a variable.
35 CC_RORc : Rotate Right 32 bits. Rotate count must be a constant.
36 CC_ROLc : Rotate Left 32 bits. Rotate count must be a constant.
38 CC_ROR64 : Rotate Right 64 bits. Rotate count can be a variable.
39 CC_ROL64 : Rotate Left 64 bits. Rotate count can be a variable.
40 CC_ROR64c : Rotate Right 64 bits. Rotate count must be a constant.
41 CC_ROL64c : Rotate Left 64 bits. Rotate count must be a constant.
43 CC_BSWAP : byte swap a 32 bits variable.
45 CC_H2BE32 : convert a 32 bits value between host and big endian order.
46 CC_H2LE32 : convert a 32 bits value between host and little endian order.
48 The following are not defined yet... define them if needed.
50 CC_BSWAPc : byte swap a 32 bits constant
52 CC_BSWAP64 : byte swap a 64 bits variable
53 CC_BSWAP64c : byte swap a 64 bits constant
55 CC_READ_LE32 : read a 32 bits little endian value
57 CC_WRITE_LE32 : write a 32 bits little endian value
58 CC_WRITE_LE64 : write a 64 bits little endian value
60 CC_H2BE64 : convert a 64 bits value between host and big endian order
61 CC_H2LE64 : convert a 64 bits value between host and little endian order
65 /* TODO: optimized versions */
66 #define CC_MEMCPY(D,S,L) memcpy((D),(S),(L))
67 #define CC_MEMMOVE(D,S,L) memmove((D),(S),(L))
68 #define CC_MEMSET(D,V,L) memset((D),(V),(L))
70 // MARK: - Loads and Store
72 // MARK: -- 32 bits - little endian
74 // MARK: --- Default version
76 #define CC_STORE32_LE(x, y) do { \
77 ((unsigned char *)(y))[3] = (unsigned char)(((x)>>24)&255); \
78 ((unsigned char *)(y))[2] = (unsigned char)(((x)>>16)&255); \
79 ((unsigned char *)(y))[1] = (unsigned char)(((x)>>8)&255); \
80 ((unsigned char *)(y))[0] = (unsigned char)((x)&255); \
83 #define CC_LOAD32_LE(x, y) do { \
84 x = ((uint32_t)(((const unsigned char *)(y))[3] & 255)<<24) | \
85 ((uint32_t)(((const unsigned char *)(y))[2] & 255)<<16) | \
86 ((uint32_t)(((const unsigned char *)(y))[1] & 255)<<8) | \
87 ((uint32_t)(((const unsigned char *)(y))[0] & 255)); \
90 // MARK: -- 64 bits - little endian
92 #define CC_STORE64_LE(x, y) do { \
93 ((unsigned char *)(y))[7] = (unsigned char)(((x)>>56)&255); \
94 ((unsigned char *)(y))[6] = (unsigned char)(((x)>>48)&255); \
95 ((unsigned char *)(y))[5] = (unsigned char)(((x)>>40)&255); \
96 ((unsigned char *)(y))[4] = (unsigned char)(((x)>>32)&255); \
97 ((unsigned char *)(y))[3] = (unsigned char)(((x)>>24)&255); \
98 ((unsigned char *)(y))[2] = (unsigned char)(((x)>>16)&255); \
99 ((unsigned char *)(y))[1] = (unsigned char)(((x)>>8)&255); \
100 ((unsigned char *)(y))[0] = (unsigned char)((x)&255); \
103 #define CC_LOAD64_LE(x, y) do { \
104 x = (((uint64_t)(((const unsigned char *)(y))[7] & 255))<<56) | \
105 (((uint64_t)(((const unsigned char *)(y))[6] & 255))<<48) | \
106 (((uint64_t)(((const unsigned char *)(y))[5] & 255))<<40) | \
107 (((uint64_t)(((const unsigned char *)(y))[4] & 255))<<32) | \
108 (((uint64_t)(((const unsigned char *)(y))[3] & 255))<<24) | \
109 (((uint64_t)(((const unsigned char *)(y))[2] & 255))<<16) | \
110 (((uint64_t)(((const unsigned char *)(y))[1] & 255))<<8) | \
111 (((uint64_t)(((const unsigned char *)(y))[0] & 255))); \
114 // MARK: -- 32 bits - big endian
115 // MARK: --- intel version
117 #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
119 #define CC_STORE32_BE(x, y) \
120 __asm__ __volatile__ ( \
126 #define CC_LOAD32_BE(x, y) \
127 __asm__ __volatile__ ( \
133 // MARK: --- default version
134 #define CC_STORE32_BE(x, y) do { \
135 ((unsigned char *)(y))[0] = (unsigned char)(((x)>>24)&255); \
136 ((unsigned char *)(y))[1] = (unsigned char)(((x)>>16)&255); \
137 ((unsigned char *)(y))[2] = (unsigned char)(((x)>>8)&255); \
138 ((unsigned char *)(y))[3] = (unsigned char)((x)&255); \
141 #define CC_LOAD32_BE(x, y) do { \
142 x = ((uint32_t)(((const unsigned char *)(y))[0] & 255)<<24) | \
143 ((uint32_t)(((const unsigned char *)(y))[1] & 255)<<16) | \
144 ((uint32_t)(((const unsigned char *)(y))[2] & 255)<<8) | \
145 ((uint32_t)(((const unsigned char *)(y))[3] & 255)); \
150 // MARK: -- 64 bits - big endian
152 // MARK: --- intel 64 bits version
154 #if defined(__x86_64__) && !defined (_MSC_VER)
156 #define CC_STORE64_BE(x, y) \
157 __asm__ __volatile__ ( \
163 #define CC_LOAD64_BE(x, y) \
164 __asm__ __volatile__ ( \
171 // MARK: --- default version
173 #define CC_STORE64_BE(x, y) do { \
174 ((unsigned char *)(y))[0] = (unsigned char)(((x)>>56)&255); \
175 ((unsigned char *)(y))[1] = (unsigned char)(((x)>>48)&255); \
176 ((unsigned char *)(y))[2] = (unsigned char)(((x)>>40)&255); \
177 ((unsigned char *)(y))[3] = (unsigned char)(((x)>>32)&255); \
178 ((unsigned char *)(y))[4] = (unsigned char)(((x)>>24)&255); \
179 ((unsigned char *)(y))[5] = (unsigned char)(((x)>>16)&255); \
180 ((unsigned char *)(y))[6] = (unsigned char)(((x)>>8)&255); \
181 ((unsigned char *)(y))[7] = (unsigned char)((x)&255); \
184 #define CC_LOAD64_BE(x, y) do { \
185 x = (((uint64_t)(((const unsigned char *)(y))[0] & 255))<<56) | \
186 (((uint64_t)(((const unsigned char *)(y))[1] & 255))<<48) | \
187 (((uint64_t)(((const unsigned char *)(y))[2] & 255))<<40) | \
188 (((uint64_t)(((const unsigned char *)(y))[3] & 255))<<32) | \
189 (((uint64_t)(((const unsigned char *)(y))[4] & 255))<<24) | \
190 (((uint64_t)(((const unsigned char *)(y))[5] & 255))<<16) | \
191 (((uint64_t)(((const unsigned char *)(y))[6] & 255))<<8) | \
192 (((uint64_t)(((const unsigned char *)(y))[7] & 255))); \
197 // MARK: - 32-bit Rotates
199 #if defined(_MSC_VER)
200 // MARK: -- MSVC version
203 #if !defined(__clang__)
204 #pragma intrinsic(_lrotr,_lrotl)
206 #define CC_ROR(x,n) _lrotr(x,n)
207 #define CC_ROL(x,n) _lrotl(x,n)
208 #define CC_RORc(x,n) _lrotr(x,n)
209 #define CC_ROLc(x,n) _lrotl(x,n)
211 #elif (defined(__i386__) || defined(__x86_64__))
212 // MARK: -- intel asm version
214 CC_INLINE
uint32_t CC_ROL ( uint32_t word
, int i
)
216 __asm__ ( "roll % %c l, %0 "
218 : "0" ( word
), "c" ( i
));
222 CC_INLINE
uint32_t CC_ROR ( uint32_t word
, int i
)
224 __asm__ ( "rorl % %c l, %0 "
226 : "0" ( word
), "c" ( i
));
230 /* Need to be a macro here, because 'i' is an immediate (constant) */
231 #define CC_ROLc(word, i) \
232 ({ uint32_t _word=(word); \
233 __asm__ __volatile__ ( "roll %2 , %0 " \
235 : "0" (_word), "I" (i)); \
240 #define CC_RORc(word, i) \
241 ({ uint32_t _word=(word); \
242 __asm__ __volatile__ ( "rorl %2 , %0 " \
244 : "0" (_word), "I" (i)); \
250 // MARK: -- default version
252 CC_INLINE
uint32_t CC_ROL ( uint32_t word
, int i
)
254 return ( ( word
<<( i
& 31 )) | ( word
>>( 32 -( i
& 31 ))) );
257 CC_INLINE
uint32_t CC_ROR ( uint32_t word
, int i
)
259 return ( ( word
>>( i
& 31 )) | ( word
<<( 32 -( i
& 31 ))) );
262 #define CC_ROLc(x, y) CC_ROL(x, y)
263 #define CC_RORc(x, y) CC_ROR(x, y)
267 // MARK: - 64 bits rotates
269 #if defined(__x86_64__) && !defined(_MSC_VER) //clang _MSVC doesn't support GNU-style inline assembly
270 // MARK: -- intel 64 asm version
272 CC_INLINE
uint64_t CC_ROL64 ( uint64_t word
, int i
)
274 __asm__ ( "rolq % %c l, %0 "
276 : "0" ( word
), "c" ( i
));
280 CC_INLINE
uint64_t CC_ROR64 ( uint64_t word
, int i
)
282 __asm__ ( "rorq % %c l, %0 "
284 : "0" ( word
), "c" ( i
));
288 /* Need to be a macro here, because 'i' is an immediate (constant) */
289 #define CC_ROL64c(word, i) \
291 uint64_t _word=(word); \
292 __asm__( "rolq %2 , %0 " \
294 : "0" (_word), "J" (i)); \
298 #define CC_ROR64c(word, i) \
300 uint64_t _word=(word); \
301 __asm__( "rorq %2 , %0 " \
303 : "0" (_word), "J" (i)); \
308 #else /* Not x86_64 */
310 // MARK: -- default C version
312 CC_INLINE
uint64_t CC_ROL64 ( uint64_t word
, int i
)
314 return ( ( word
<<( i
& 63 )) | ( word
>>( 64 -( i
& 63 ))) );
317 CC_INLINE
uint64_t CC_ROR64 ( uint64_t word
, int i
)
319 return ( ( word
>>( i
& 63 )) | ( word
<<( 64 -( i
& 63 ))) );
322 #define CC_ROL64c(x, y) CC_ROL64(x, y)
323 #define CC_ROR64c(x, y) CC_ROR64(x, y)
328 // MARK: - Byte Swaps
330 CC_INLINE
uint32_t CC_BSWAP ( uint32_t x
)
333 (( x
>> 24 )& 0x000000FF ) |
334 (( x
<< 24 )& 0xFF000000 ) |
335 (( x
>> 8 ) & 0x0000FF00 ) |
340 #define CC_BSWAP64(x) \
341 ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
342 (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
343 (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
344 (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
345 (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
346 (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
347 (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
348 (((uint64_t)(x) & 0x00000000000000ffULL) << 56)))
350 #ifdef __LITTLE_ENDIAN__
351 #define CC_H2BE32(x) CC_BSWAP(x)
352 #define CC_H2LE32(x) (x)
354 #define CC_H2BE32(x) (x)
355 #define CC_H2LE32(x) CC_BSWAP(x)
358 #define CC_READ_LE32(ptr) \
360 ((uint32_t)((const uint8_t *)(ptr))[0]) | \
361 (((uint32_t)((const uint8_t *)(ptr))[1]) << 8) | \
362 (((uint32_t)((const uint8_t *)(ptr))[2]) << 16) | \
363 (((uint32_t)((const uint8_t *)(ptr))[3]) << 24)))
365 #define CC_WRITE_LE32(ptr, x) \
367 ((uint8_t *)(ptr))[0] = (uint8_t)( (x) & 0xFF); \
368 ((uint8_t *)(ptr))[1] = (uint8_t)(((x) >> 8) & 0xFF); \
369 ((uint8_t *)(ptr))[2] = (uint8_t)(((x) >> 16) & 0xFF); \
370 ((uint8_t *)(ptr))[3] = (uint8_t)(((x) >> 24) & 0xFF); \
373 #define CC_WRITE_LE64(ptr, x) \
375 ((uint8_t *)(ptr))[0] = (uint8_t)( (x) & 0xFF); \
376 ((uint8_t *)(ptr))[1] = (uint8_t)(((x) >> 8) & 0xFF); \
377 ((uint8_t *)(ptr))[2] = (uint8_t)(((x) >> 16) & 0xFF); \
378 ((uint8_t *)(ptr))[3] = (uint8_t)(((x) >> 24) & 0xFF); \
379 ((uint8_t *)(ptr))[4] = (uint8_t)(((x) >> 32) & 0xFF); \
380 ((uint8_t *)(ptr))[5] = (uint8_t)(((x) >> 40) & 0xFF); \
381 ((uint8_t *)(ptr))[6] = (uint8_t)(((x) >> 48) & 0xFF); \
382 ((uint8_t *)(ptr))[7] = (uint8_t)(((x) >> 56) & 0xFF); \
385 /* extract a byte portably */
387 #define cc_byte(x, n) ((unsigned char)((x) >> (8 * (n))))
389 #define cc_byte(x, n) (((x) >> (8 * (n))) & 255)
392 /* HEAVISIDE_STEP (shifted by one)
393 function f(x): x->0, when x=0
395 Can also be seen as a bitwise operation:
397 y[0]=(OR x[i]) for all i (all bits)
399 Run in constant time (log2(<bitsize of x>))
400 Useful to run constant time checks
402 #define HEAVISIDE_STEP_UINT64(r,s) {uint64_t _t=s; \
403 _t=(((_t)>>32) | (_t)); \
404 _t=(0xFFFFFFFF + (_t & 0xFFFFFFFF)); \
407 #define HEAVISIDE_STEP_UINT32(r,s) {uint32_t _t=s; \
408 _t=(((_t)>>16) | (_t)); \
409 _t=(0xFFFF + (_t & 0xFFFF)); \
412 #define HEAVISIDE_STEP_UINT16(r,s) {uint32_t _t=s; \
413 _t=(0xFFFF + ((_t) & 0xFFFF)); \
416 #define HEAVISIDE_STEP_UINT8(r,s) {uint16_t _t=s; \
417 _t=(0xFF + ((_t) & 0xFF)); \
420 #define CC_HEAVISIDE_STEP(r,s) { \
421 if (sizeof(s) == 1) {HEAVISIDE_STEP_UINT8(r,s);} \
422 else if (sizeof(s) == 2) {HEAVISIDE_STEP_UINT16(r,s);} \
423 else if (sizeof(s) == 4) {HEAVISIDE_STEP_UINT32(r,s);} \
424 else if (sizeof(s) == 8) {HEAVISIDE_STEP_UINT64(r,s);} \
425 else {r=(((s)==0)?0:1);} \
428 /* Return 1 if x mod 4 =1,2,3, 0 otherwise */
429 #define CC_CARRY_2BITS(x) (((x>>1) | x) & 0x1)
430 #define CC_CARRY_3BITS(x) (((x>>2) | (x>>1) | x) & 0x1)
432 /* Set a variable to the biggest power of 2 which can be represented */
433 #define MAX_POWER_OF_2(x) ((__typeof__(x))1<<(8*sizeof(x)-1))
434 #define cc_ceiling(a,b) (((a)+((b)-1))/(b))
435 #define CC_BITLEN_TO_BYTELEN(x) cc_ceiling((x), 8)
437 //cc_try_abort() is implemented to comply with FIPS 140-2. See radar 19129408
438 void cc_try_abort ( const char * msg
, ...);
441 @brief cc_muxp(s, a, b) is equivalent to z = s ? a : b, but it executes in constant time
442 @param a input pointer
443 @param b input pointer
444 @param s The selection parameter s must be 0 or 1. if s is integer 1 a is returned. If s is integer 0, b is returned. Otherwise, the output is undefined.
445 @return Returns a, if s is 1 and b if s is 0
447 void * cc_muxp ( int s
, const void * a
, const void * b
);
451 @param a input pointer
452 @param b input pointer
453 @param r_true output pointer: if s is integer 1 r_true=a is returned, otherwise r_true=b
454 @param r_false output pointer: if s is integer 1 r_false=b is returned, otherwise r_false=a
455 @param s The selection parameter s must be 0 or 1.
456 @discussion Executes in constant time
458 void cc_mux2p ( int s
, void ** r_true
, void ** r_false
, const void * a
, const void * b
);
461 @brief CC_MUXU(s, a, b) is equivalent to z = s ? a : b, but it executes in constant time
462 @param a input unsigned type
463 @param b input unsigned type
464 @param s The selection parameter s must be 0 or 1. if s is integer 1 a is returned. If s is integer 0, b is returned. Otherwise, the output is undefined.
466 @return r = a, if s is 1 and b if s is 0
468 #define CC_MUXU(r, s, a, b) \
470 __typeof__(r) _cond = ((__typeof__(r))(s)-(__typeof__(r))1); \
471 r = (~_cond&(a))|(_cond&(b)); \
475 Unfortunately, since we export this symbol, this declaration needs
476 to be in a public header to satisfy TAPI.
478 See fipspost_trace_priv.h for more details.
480 extern const void * fipspost_trace_vtable
;
482 #endif /* _CORECRYPTO_CC_PRIV_H_ */