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
48The 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 { \
84x = ((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 { \
104x = (((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 { \
142x = ((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 { \
185x = (((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
214CC_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
222CC_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
252CC_INLINE uint32_t CC_ROL(uint32_t word, int i)
253{
254 return ( (word<<(i&31)) | (word>>(32-(i&31))) );
255}
256
257CC_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
272CC_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
280CC_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
312CC_INLINE uint64_t CC_ROL64(uint64_t word, int i)
313{
314 return ( (word<<(i&63)) | (word>>(64-(i&63))) );
315}
316
317CC_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
330CC_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) \
366do { \
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) \
374do { \
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
438void 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 */
447void *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 */
458void 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*/
480extern const void *fipspost_trace_vtable;
481
482#endif /* _CORECRYPTO_CC_PRIV_H_ */
483