]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/cc_priv.h
0a51e66eec069b9221e7d5c9f0d9fa4296f2a056
[apple/xnu.git] / EXTERNAL_HEADERS / corecrypto / cc_priv.h
1 /*
2 * cc_priv.h
3 * corecrypto
4 *
5 * Created on 12/01/2010
6 *
7 * Copyright (c) 2010,2011,2012,2014,2015 Apple Inc. All rights reserved.
8 *
9 */
10
11 #ifndef _CORECRYPTO_CC_PRIV_H_
12 #define _CORECRYPTO_CC_PRIV_H_
13
14 #include <corecrypto/cc.h>
15 #include <stdint.h>
16
17 /* defines the following macros :
18
19 CC_MEMCPY : optimized memcpy.
20 CC_MEMMOVE : optimized memmove.
21 CC_MEMSET : optimized memset.
22
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.
27
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.
32
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.
37
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.
42
43 CC_BSWAP : byte swap a 32 bits variable.
44
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.
47
48 The following are not defined yet... define them if needed.
49
50 CC_BSWAPc : byte swap a 32 bits constant
51
52 CC_BSWAP64 : byte swap a 64 bits variable
53 CC_BSWAP64c : byte swap a 64 bits constant
54
55 CC_READ_LE32 : read a 32 bits little endian value
56
57 CC_WRITE_LE32 : write a 32 bits little endian value
58 CC_WRITE_LE64 : write a 64 bits little endian value
59
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
62
63 */
64
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))
69
70 // MARK: - Loads and Store
71
72 // MARK: -- 32 bits - little endian
73
74 // MARK: --- Default version
75
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); \
81 } while(0)
82
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)); \
88 } while(0)
89
90 // MARK: -- 64 bits - little endian
91
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); \
101 } while(0)
102
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))); \
112 } while(0)
113
114 // MARK: -- 32 bits - big endian
115 // MARK: --- intel version
116
117 #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
118
119 #define CC_STORE32_BE(x, y) \
120 __asm__ __volatile__ ( \
121 "bswapl %0 \n\t" \
122 "movl %0,(%1)\n\t" \
123 "bswapl %0 \n\t" \
124 ::"r"(x), "r"(y))
125
126 #define CC_LOAD32_BE(x, y) \
127 __asm__ __volatile__ ( \
128 "movl (%1),%0\n\t" \
129 "bswapl %0\n\t" \
130 :"=r"(x): "r"(y))
131
132 #else
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); \
139 } while(0)
140
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)); \
146 } while(0)
147
148 #endif
149
150 // MARK: -- 64 bits - big endian
151
152 // MARK: --- intel 64 bits version
153
154 #if defined(__x86_64__) && !defined (_MSC_VER)
155
156 #define CC_STORE64_BE(x, y) \
157 __asm__ __volatile__ ( \
158 "bswapq %0 \n\t" \
159 "movq %0,(%1)\n\t" \
160 "bswapq %0 \n\t" \
161 ::"r"(x), "r"(y))
162
163 #define CC_LOAD64_BE(x, y) \
164 __asm__ __volatile__ ( \
165 "movq (%1),%0\n\t" \
166 "bswapq %0\n\t" \
167 :"=r"(x): "r"(y))
168
169 #else
170
171 // MARK: --- default version
172
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); \
182 } while(0)
183
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))); \
193 } while(0)
194
195 #endif
196
197 // MARK: - 32-bit Rotates
198
199 #if defined(_MSC_VER)
200 // MARK: -- MSVC version
201
202 #include <stdlib.h>
203 #if !defined(__clang__)
204 #pragma intrinsic(_lrotr,_lrotl)
205 #endif
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)
210
211 #elif (defined(__i386__) || defined(__x86_64__))
212 // MARK: -- intel asm version
213
214 CC_INLINE uint32_t CC_ROL(uint32_t word, int i)
215 {
216 __asm__ ("roll %%cl,%0"
217 :"=r" (word)
218 :"0" (word),"c" (i));
219 return word;
220 }
221
222 CC_INLINE uint32_t CC_ROR(uint32_t word, int i)
223 {
224 __asm__ ("rorl %%cl,%0"
225 :"=r" (word)
226 :"0" (word),"c" (i));
227 return word;
228 }
229
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" \
234 :"=r" (_word) \
235 :"0" (_word),"I" (i)); \
236 _word; \
237 })
238
239
240 #define CC_RORc(word, i) \
241 ({ uint32_t _word=(word); \
242 __asm__ __volatile__ ("rorl %2,%0" \
243 :"=r" (_word) \
244 :"0" (_word),"I" (i)); \
245 _word; \
246 })
247
248 #else
249
250 // MARK: -- default version
251
252 CC_INLINE uint32_t CC_ROL(uint32_t word, int i)
253 {
254 return ( (word<<(i&31)) | (word>>(32-(i&31))) );
255 }
256
257 CC_INLINE uint32_t CC_ROR(uint32_t word, int i)
258 {
259 return ( (word>>(i&31)) | (word<<(32-(i&31))) );
260 }
261
262 #define CC_ROLc(x, y) CC_ROL(x, y)
263 #define CC_RORc(x, y) CC_ROR(x, y)
264
265 #endif
266
267 // MARK: - 64 bits rotates
268
269 #if defined(__x86_64__) && !defined(_MSC_VER) //clang _MSVC doesn't support GNU-style inline assembly
270 // MARK: -- intel 64 asm version
271
272 CC_INLINE uint64_t CC_ROL64(uint64_t word, int i)
273 {
274 __asm__("rolq %%cl,%0"
275 :"=r" (word)
276 :"0" (word),"c" (i));
277 return word;
278 }
279
280 CC_INLINE uint64_t CC_ROR64(uint64_t word, int i)
281 {
282 __asm__("rorq %%cl,%0"
283 :"=r" (word)
284 :"0" (word),"c" (i));
285 return word;
286 }
287
288 /* Need to be a macro here, because 'i' is an immediate (constant) */
289 #define CC_ROL64c(word, i) \
290 ({ \
291 uint64_t _word=(word); \
292 __asm__("rolq %2,%0" \
293 :"=r" (_word) \
294 :"0" (_word),"J" (i)); \
295 _word; \
296 })
297
298 #define CC_ROR64c(word, i) \
299 ({ \
300 uint64_t _word=(word); \
301 __asm__("rorq %2,%0" \
302 :"=r" (_word) \
303 :"0" (_word),"J" (i)); \
304 _word; \
305 })
306
307
308 #else /* Not x86_64 */
309
310 // MARK: -- default C version
311
312 CC_INLINE uint64_t CC_ROL64(uint64_t word, int i)
313 {
314 return ( (word<<(i&63)) | (word>>(64-(i&63))) );
315 }
316
317 CC_INLINE uint64_t CC_ROR64(uint64_t word, int i)
318 {
319 return ( (word>>(i&63)) | (word<<(64-(i&63))) );
320 }
321
322 #define CC_ROL64c(x, y) CC_ROL64(x, y)
323 #define CC_ROR64c(x, y) CC_ROR64(x, y)
324
325 #endif
326
327
328 // MARK: - Byte Swaps
329
330 CC_INLINE uint32_t CC_BSWAP(uint32_t x)
331 {
332 return (
333 ((x>>24)&0x000000FF) |
334 ((x<<24)&0xFF000000) |
335 ((x>>8) &0x0000FF00) |
336 ((x<<8) &0x00FF0000)
337 );
338 }
339
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)))
349
350 #ifdef __LITTLE_ENDIAN__
351 #define CC_H2BE32(x) CC_BSWAP(x)
352 #define CC_H2LE32(x) (x)
353 #else
354 #define CC_H2BE32(x) (x)
355 #define CC_H2LE32(x) CC_BSWAP(x)
356 #endif
357
358 #define CC_READ_LE32(ptr) \
359 ( (uint32_t)( \
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)))
364
365 #define CC_WRITE_LE32(ptr, x) \
366 do { \
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); \
371 } while(0)
372
373 #define CC_WRITE_LE64(ptr, x) \
374 do { \
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); \
383 } while(0)
384
385 /* extract a byte portably */
386 #ifdef _MSC_VER
387 #define cc_byte(x, n) ((unsigned char)((x) >> (8 * (n))))
388 #else
389 #define cc_byte(x, n) (((x) >> (8 * (n))) & 255)
390 #endif
391
392 /* HEAVISIDE_STEP (shifted by one)
393 function f(x): x->0, when x=0
394 x->1, when x>0
395 Can also be seen as a bitwise operation:
396 f(x): x -> y
397 y[0]=(OR x[i]) for all i (all bits)
398 y[i]=0 for all i>0
399 Run in constant time (log2(<bitsize of x>))
400 Useful to run constant time checks
401 */
402 #define HEAVISIDE_STEP_UINT64(r,s) {uint64_t _t=s; \
403 _t=(((_t)>>32) | (_t)); \
404 _t=(0xFFFFFFFF + (_t & 0xFFFFFFFF)); \
405 r=_t >> 32;}
406
407 #define HEAVISIDE_STEP_UINT32(r,s) {uint32_t _t=s; \
408 _t=(((_t)>>16) | (_t)); \
409 _t=(0xFFFF + (_t & 0xFFFF)); \
410 r=_t >> 16;}
411
412 #define HEAVISIDE_STEP_UINT16(r,s) {uint32_t _t=s; \
413 _t=(0xFFFF + ((_t) & 0xFFFF)); \
414 r=_t >> 16;}
415
416 #define HEAVISIDE_STEP_UINT8(r,s) {uint16_t _t=s; \
417 _t=(0xFF + ((_t) & 0xFF)); \
418 r=_t >> 8;}
419
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);} \
426 }
427
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)
431
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)
436
437 //cc_try_abort() is implemented to comply with FIPS 140-2. See radar 19129408
438 void cc_try_abort(const char * msg , ...);
439
440 /*!
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
446 */
447 void *cc_muxp(int s, const void *a, const void *b);
448
449 /*!
450 @brief cc_mux2p
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
457 */
458 void cc_mux2p(int s, void **r_true, void **r_false, const void *a, const void *b);
459
460 /*!
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.
465 @param r output
466 @return r = a, if s is 1 and b if s is 0
467 */
468 #define CC_MUXU(r, s, a, b) \
469 { \
470 __typeof__(r) _cond = ((__typeof__(r))(s)-(__typeof__(r))1); \
471 r = (~_cond&(a))|(_cond&(b)); \
472 }
473
474 /*
475 Unfortunately, since we export this symbol, this declaration needs
476 to be in a public header to satisfy TAPI.
477
478 See fipspost_trace_priv.h for more details.
479 */
480 extern const void *fipspost_trace_vtable;
481
482 #endif /* _CORECRYPTO_CC_PRIV_H_ */