1 | /* Copyright (c) (2010-2022) Apple Inc. All rights reserved. |
2 | * |
3 | * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which |
4 | * is contained in the License.txt file distributed with corecrypto) and only to |
5 | * people who accept that license. IMPORTANT: Any license rights granted to you by |
6 | * Apple Inc. (if any) are limited to internal use within your organization only on |
7 | * devices and computers you own or control, for the sole purpose of verifying the |
8 | * security characteristics and correct functioning of the Apple Software. You may |
9 | * not, directly or indirectly, redistribute the Apple Software or any portions thereof. |
10 | */ |
11 | |
12 | #ifndef _CORECRYPTO_CCN_H_ |
13 | #define _CORECRYPTO_CCN_H_ |
14 | |
15 | #include <corecrypto/cc.h> |
16 | |
17 | CC_PTRCHECK_CAPABLE_HEADER() |
18 | |
19 | typedef size_t cc_size; |
20 | |
21 | #if CCN_UNIT_SIZE == 8 |
22 | typedef uint64_t cc_unit; // 64 bit unit |
23 | typedef int64_t cc_int; |
24 | #define CCN_LOG2_BITS_PER_UNIT 6 // 2^6 = 64 bits |
25 | #define CC_UNIT_C(x) UINT64_C(x) |
26 | #elif CCN_UNIT_SIZE == 4 |
27 | typedef uint32_t cc_unit; // 32 bit unit |
28 | typedef int32_t cc_int; |
29 | #define CCN_LOG2_BITS_PER_UNIT 5 // 2^5 = 32 bits |
30 | #define CC_UNIT_C(x) UINT32_C(x) |
31 | |
32 | #else |
33 | #error Unsupported CCN_UNIT_SIZE |
34 | #endif |
35 | |
36 | #define CCN_UNIT_BITS (sizeof(cc_unit) * 8) |
37 | #define CCN_UNIT_MASK ((cc_unit)~0) |
38 | #define CCN_UNIT_LOWER_HALF_MASK ((CCN_UNIT_MASK) >> (CCN_UNIT_BITS/2)) |
39 | #define CCN_UNIT_UPPER_HALF_MASK (~CCN_UNIT_LOWER_HALF_MASK) |
40 | #define CCN_UNIT_HALF_BITS (CCN_UNIT_BITS / 2) |
41 | |
42 | /* Conversions between n sizeof and bits */ |
43 | |
44 | /* Returns the sizeof a ccn vector of length _n_ units. */ |
45 | #define ccn_sizeof_n(_n_) (sizeof(cc_unit) * (_n_)) |
46 | |
47 | /* Returns the count (n) of a ccn vector that can represent _bits_. */ |
48 | #define ccn_nof(_bits_) (((_bits_) + CCN_UNIT_BITS - 1) >> CCN_LOG2_BITS_PER_UNIT) |
49 | |
50 | /* Returns the sizeof a ccn vector that can represent _bits_. */ |
51 | #define ccn_sizeof(_bits_) (ccn_sizeof_n(ccn_nof(_bits_))) |
52 | |
53 | /* Returns the count (n) of a ccn vector that can represent _size_ bytes. */ |
54 | #define ccn_nof_size(_size_) (((_size_) + sizeof(cc_unit) - 1) / sizeof(cc_unit)) |
55 | |
56 | #define ccn_nof_sizeof(_expr_) ccn_nof_size(sizeof(_expr_)) |
57 | |
58 | /* Return the max number of bits a ccn vector of _n_ units can hold. */ |
59 | #define ccn_bitsof_n(_n_) ((_n_) * CCN_UNIT_BITS) |
60 | |
61 | /* Return the max number of bits a ccn vector of _size_ bytes can hold. */ |
62 | #define ccn_bitsof_size(_size_) ((_size_) * 8) |
63 | |
64 | /* Return the size of a ccn of size bytes in bytes. */ |
65 | #define ccn_sizeof_size(_size_) ccn_sizeof_n(ccn_nof_size(_size_)) |
66 | |
67 | /*! |
68 | @function ccn_set_bit |
69 | @param x The input cc_unit |
70 | @param k The index to set |
71 | @param v The value to set |
72 | */ |
73 | CC_NONNULL_ALL |
74 | void ccn_set_bit(cc_unit *cc_indexable x, size_t k, cc_unit v); |
75 | |
76 | /* Macros for making ccn constants. You must use list of CCN64_C() instances |
77 | separated by commas, with an optional smaller sized CCN32_C, CCN16_C, or |
78 | CCN8_C() instance at the end of the list, when making macros to declare |
79 | larger sized constants. */ |
80 | #define CCN8_C(a0) CC_UNIT_C(0x##a0) |
81 | |
82 | #define CCN16_C(a1,a0) CC_UNIT_C(0x##a1##a0) |
83 | #define ccn16_v(a0) (a0) |
84 | |
85 | #define CCN32_C(a3,a2,a1,a0) CC_UNIT_C(0x##a3##a2##a1##a0) |
86 | #define ccn32_v(a0) (a0) |
87 | |
88 | #if CCN_UNIT_SIZE == 8 |
89 | #define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CC_UNIT_C(0x##a7##a6##a5##a4##a3##a2##a1##a0) |
90 | #define CCN40_C(a4,a3,a2,a1,a0) CC_UNIT_C(0x##a4##a3##a2##a1##a0) |
91 | #define ccn64_v(a0) (a0) |
92 | #else |
93 | #define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN32_C(a7,a6,a5,a4) |
94 | #define CCN40_C(a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN8_C(a4) |
95 | #define ccn64_v(a0) ccn32_v((uint64_t)a0 & UINT32_C(0xffffffff)),ccn32_v((uint64_t)a0 >> 32) |
96 | #endif |
97 | |
98 | /* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or |
99 | 64 bit units respectively. */ |
100 | #if CCN_UNIT_SIZE == 8 |
101 | |
102 | #define ccn64_32(a1,a0) (((const cc_unit)a1) << 32 | ((const cc_unit)a0)) |
103 | #define ccn32_32(a0) a0 |
104 | #if __LITTLE_ENDIAN__ |
105 | #define ccn32_32_parse(p,i) (((const uint32_t *)p)[i]) |
106 | #else |
107 | #define ccn32_32_parse(p,i) (((const uint32_t *)p)[i^1]) |
108 | #endif |
109 | #define ccn32_32_null 0 |
110 | |
111 | #define ccn64_64(a0) a0 |
112 | #define ccn64_64_parse(p,i) p[i] |
113 | #define ccn64_64_null 0 |
114 | |
115 | #elif CCN_UNIT_SIZE == 4 |
116 | |
117 | #define ccn32_32(a0) a0 |
118 | #define ccn32_32_parse(p,i) p[i] |
119 | #define ccn32_32_null 0 |
120 | #define ccn64_32(a1,a0) ccn32_32(a0),ccn32_32(a1) |
121 | |
122 | #define ccn64_64(a1,a0) a0,a1 |
123 | #define ccn64_64_parse(p,i) p[1+(i<<1)],p[i<<1] |
124 | #define ccn64_64_null 0,0 |
125 | |
126 | #endif |
127 | |
128 | |
129 | /* Macros to construct fixed size ccn arrays from 64 or 32 bit quantities. */ |
130 | #define ccn192_64(a2,a1,a0) ccn64_64(a0),ccn64_64(a1),ccn64_64(a2) |
131 | #define ccn192_32(a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4) |
132 | #define ccn224_32(a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn32_32(a6) |
133 | #define ccn256_32(a7,a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn64_32(a7,a6) |
134 | #define ccn384_32(a11,a10,a9,a8,a7,a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn64_32(a7,a6),ccn64_32(a9,a8),ccn64_32(a11,a10) |
135 | |
136 | |
137 | #define CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
138 | CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0),\ |
139 | CCN64_C(b7,b6,b5,b4,b3,b2,b1,b0),\ |
140 | CCN64_C(c7,c6,c5,c4,c3,c2,c1,c0) |
141 | |
142 | #define CCN200_C(d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
143 | CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
144 | CCN8_C(d0) |
145 | |
146 | #define CCN224_C(d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
147 | CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
148 | CCN32_C(d3,d2,d1,d0) |
149 | |
150 | #define CCN232_C(d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
151 | CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
152 | CCN40_C(d4,d3,d2,d1,d0) |
153 | |
154 | #define CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
155 | CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
156 | CCN64_C(d7,d6,d5,d4,d3,d2,d1,d0) |
157 | |
158 | #define CCN384_C(f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
159 | CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
160 | CCN64_C(e7,e6,e5,e4,e3,e2,e1,e0),\ |
161 | CCN64_C(f7,f6,f5,f4,f3,f2,f1,f0) |
162 | |
163 | #define CCN448_C(g7,g6,g5,g4,g3,g2,g1,g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
164 | CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
165 | CCN192_C(g7,g6,g5,g4,g3,g2,g1,g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0) |
166 | |
167 | #define CCN528_C(i1,i0,h7,h6,h5,h4,h3,h2,h1,h0,g7,g6,g5,g4,g3,g2,g1,g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \ |
168 | CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\ |
169 | CCN256_C(h7,h6,h5,h4,h3,h2,h1,h0,g7,g6,g5,g4,g3,g2,g1,g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0),\ |
170 | CCN16_C(i1,i0) |
171 | |
172 | #define CCN192_N ccn_nof(192) |
173 | #define CCN224_N ccn_nof(224) |
174 | #define CCN256_N ccn_nof(256) |
175 | #define CCN384_N ccn_nof(384) |
176 | #define CCN448_N ccn_nof(448) |
177 | #define CCN512_N ccn_nof(512) |
178 | #define CCN521_N ccn_nof(521) |
179 | |
180 | /* s == 0 -> return 0 | s > 0 -> return index (starting at 1) of most |
181 | * significant bit that is 1. |
182 | * { N bit } N = n * sizeof(cc_unit) * 8 |
183 | * |
184 | * Runs in constant time, independent of the value of `s`. |
185 | */ |
186 | CC_NONNULL((2)) |
187 | size_t ccn_bitlen(cc_size n, const cc_unit *cc_counted_by(n) s); |
188 | |
189 | /* s == 0 -> return true | s != 0 -> return false |
190 | { N bit } N = n * sizeof(cc_unit) * 8 */ |
191 | #define ccn_is_zero(_n_, _s_) (!ccn_n((_n_), (_s_))) |
192 | |
193 | /* s == 1 -> return true | s != 1 -> return false |
194 | { N bit } N = n * sizeof(cc_unit) * 8 */ |
195 | #define ccn_is_one(_n_, _s_) (ccn_n((_n_), (_s_)) == 1 && (_s_)[0] == 1) |
196 | |
197 | #define ccn_is_zero_or_one(_n_, _s_) (((_n_)==0) || ((ccn_n((_n_), (_s_)) <= 1) && ((_s_)[0] <= 1))) |
198 | |
199 | /* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1 |
200 | { N bit, N bit -> int } N = n * sizeof(cc_unit) * 8 */ |
201 | CC_PURE CC_NONNULL((2, 3)) |
202 | int ccn_cmp(cc_size n, const cc_unit *cc_counted_by(n) s, const cc_unit *cc_counted_by(n) t) __asm__("_ccn_cmp" ); |
203 | |
204 | /*! @function ccn_cmpn |
205 | @abstract Compares the values of two big ints of different lengths. |
206 | |
207 | @discussion The execution time does not depend on the values of either s or t. |
208 | The function does not hide ns, nt, or whether ns > nt. |
209 | |
210 | @param ns Length of s |
211 | @param s First integer |
212 | @param nt Length of t |
213 | @param t Second integer |
214 | |
215 | @return 1 if s > t, -1 if s < t, 0 otherwise. |
216 | */ |
217 | CC_NONNULL_ALL |
218 | int ccn_cmpn(cc_size ns, const cc_unit *cc_counted_by(ns) s, cc_size nt, const cc_unit *cc_counted_by(nt) t); |
219 | |
220 | /* s - t -> r return 1 iff t > s |
221 | { N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */ |
222 | CC_NONNULL((2, 3, 4)) |
223 | cc_unit ccn_sub(cc_size n, cc_unit *cc_counted_by(n) r, const cc_unit *cc_counted_by(n) s, const cc_unit *cc_counted_by(n) t) __asm__("_ccn_sub" ); |
224 | |
225 | /* s + t -> r return carry if result doesn't fit in n bits. |
226 | { N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */ |
227 | CC_NONNULL((2, 3, 4)) |
228 | cc_unit ccn_add(cc_size n, cc_unit *cc_counted_by(n) r, const cc_unit *cc_counted_by(n) s, const cc_unit *cc_counted_by(n) t) __asm__("_ccn_add" ); |
229 | |
230 | /* s + v -> r return carry if result doesn't fit in n bits. |
231 | { N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */ |
232 | CC_NONNULL((2, 3)) |
233 | cc_unit ccn_add1(cc_size n, cc_unit *cc_counted_by(n) r, const cc_unit *cc_counted_by(n) s, cc_unit v); |
234 | |
235 | /*! |
236 | @function ccn_read_uint |
237 | @abstract Copy big endian integer and represent it in cc_units |
238 | |
239 | @param n Input allocated size of the cc_unit output array r |
240 | @param r Ouput cc_unit array for unsigned integer |
241 | @param data_nbytes Input byte size of data |
242 | @param data Input unsigned integer represented in big endian |
243 | |
244 | @result r is initialized with the big unsigned number |
245 | |
246 | @return 0 if no error, !=0 if the big number cannot be represented in the allocated cc_unit array. |
247 | |
248 | @discussion The execution pattern of this function depends on both n and data_nbytes but not on data values except the handling |
249 | of the error case. |
250 | */ |
251 | |
252 | CC_NONNULL((2, 4)) |
253 | int ccn_read_uint(cc_size n, cc_unit *cc_counted_by(n) r, size_t data_nbytes, const uint8_t *cc_sized_by(data_nbytes) data); |
254 | |
255 | /* r = (data, len) treated as a big endian byte array, return -1 if data |
256 | doesn't fit in r, return 0 otherwise. |
257 | ccn_read_uint strips leading zeroes and doesn't care about sign. */ |
258 | #define ccn_read_int(n, r, data_size, data) ccn_read_uint(n, r, data_size, data) |
259 | |
260 | /*! |
261 | @function ccn_write_uint_size |
262 | @abstract Compute the minimum size required to store an big integer |
263 | |
264 | @param n Input size of the cc_unit array representing the input |
265 | @param s Input cc_unit array |
266 | |
267 | @result Return value is the exact byte size of the big integer |
268 | |
269 | @discussion |
270 | The execution flow is independent on the value of the big integer. |
271 | However, the use of the returned value may leak the position of the most significant byte |
272 | */ |
273 | CC_PURE CC_NONNULL((2)) size_t ccn_write_uint_size(cc_size n, const cc_unit *cc_counted_by(n) s); |
274 | |
275 | /*! |
276 | @function ccn_write_uint |
277 | @abstract Serialize the big integer into a big endian byte buffer |
278 | |
279 | @param n Input size of the cc_unit array representing the input |
280 | @param s Input cc_unit array |
281 | @param out_size Size of the output buffer |
282 | @param out Output byte array of size at least out_size |
283 | |
284 | @discussion This function writes exactly |
285 | MIN(out_size,ccn_write_uint_size(n,s)) bytes truncating to keep the |
286 | most significant bytes when out_size<ccn_write_uint_size(n,s). The |
287 | execution flow of function is based on the position of the most |
288 | significant byte as well as input sizes. |
289 | |
290 | */ |
291 | |
292 | CC_NONNULL((2, 4)) |
293 | void ccn_write_uint(cc_size n, const cc_unit *cc_counted_by(n) s, size_t out_size, void *cc_sized_by(out_size) out); |
294 | |
295 | /*! |
296 | @function ccn_write_uint_padded_ct |
297 | @abstract Serialize the big integer into a big endian byte buffer |
298 | |
299 | @param n Input size of the cc_unit array representing the input |
300 | @param s Input cc_unit array |
301 | @param out_size Size of the output buffer |
302 | @param out Output byte array of size at least out_size |
303 | |
304 | @return number of leading zero bytes in case of success, a negative error value in case of failure |
305 | |
306 | @result This function writes exactly out_size byte, padding with zeroes when necessary. |
307 | This function DOES NOT support truncation and returns an error if out_size < ccn_write_uint_size |
308 | |
309 | @discussion The execution flow of function is independent on the value of the big integer |
310 | However, the processing of the return value by the caller may expose the position of |
311 | the most significant byte |
312 | */ |
313 | CC_NONNULL((2, 4)) |
314 | int ccn_write_uint_padded_ct(cc_size n, const cc_unit *cc_sized_by(n) s, size_t out_size, uint8_t *cc_counted_by(out_size) out); |
315 | |
316 | /*! |
317 | @function ccn_write_uint_padded |
318 | @abstract Serialize the big integer into a big endian byte buffer |
319 | Not recommended, for most cases ccn_write_uint_padded_ct is more appropriate |
320 | Sensitive big integers are exposed since the processing expose the position of the MS byte |
321 | |
322 | @param n Input size of the cc_unit array representing the input |
323 | @param s Input cc_unit array |
324 | @param out_size Size of the output buffer |
325 | @param out Output byte array of size at least out_size |
326 | |
327 | @return number of leading zero bytes |
328 | |
329 | @result This function writes exactly out_size byte, padding with zeroes when necessary. |
330 | This function DOES support truncation when out_size<ccn_write_uint_size() |
331 | |
332 | @discussion The execution flow of this function DEPENDS on the position of the most significant byte in |
333 | case truncation is required. |
334 | */ |
335 | |
336 | CC_NONNULL((2, 4)) |
337 | size_t ccn_write_uint_padded(cc_size n, const cc_unit *cc_counted_by(n) s, size_t out_size, uint8_t *cc_sized_by(out_size) out); |
338 | |
339 | |
340 | /* Return actual size in bytes needed to serialize s as int |
341 | (adding leading zero if high bit is set). */ |
342 | CC_PURE CC_NONNULL((2)) |
343 | size_t ccn_write_int_size(cc_size n, const cc_unit *cc_counted_by(n) s); |
344 | |
345 | /* Serialize s, to out. |
346 | First byte of byte stream is the m.s. byte of s, |
347 | regardless of the size of cc_unit. |
348 | |
349 | No assumption is made about the alignment of out. |
350 | |
351 | The out_size argument should be the value returned from ccn_write_int_size, |
352 | and is also the exact number of bytes this function will write to out. |
353 | If out_size if less than the value returned by ccn_write_int_size, only the |
354 | first out_size non-zero most significant octets of s will be written. */ |
355 | CC_NONNULL((2, 4)) |
356 | void ccn_write_int(cc_size n, const cc_unit *cc_counted_by(n) s, size_t out_size, void *cc_sized_by(out_size) out); |
357 | |
358 | CC_NONNULL((2)) |
359 | void ccn_zero(cc_size n, cc_unit *cc_sized_by(n) r); |
360 | |
361 | CC_NONNULL((2)) |
362 | void ccn_seti(cc_size n, cc_unit *cc_counted_by(n) r, cc_unit v); |
363 | |
364 | #define CC_SWAP_HOST_BIG_64(x) \ |
365 | ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \ |
366 | (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \ |
367 | (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \ |
368 | (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \ |
369 | (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \ |
370 | (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \ |
371 | (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \ |
372 | (((uint64_t)(x) & 0x00000000000000ffULL) << 56))) |
373 | #define CC_SWAP_HOST_BIG_32(x) \ |
374 | ((((x) & 0xff000000) >> 24) | \ |
375 | (((x) & 0x00ff0000) >> 8) | \ |
376 | (((x) & 0x0000ff00) << 8) | \ |
377 | (((x) & 0x000000ff) << 24)) |
378 | #define CC_SWAP_HOST_BIG_16(x) \ |
379 | ((((x) & 0xff00) >> 8) | \ |
380 | (((x) & 0x00ff) << 8)) |
381 | |
382 | /* This should probably move if we move ccn_swap out of line. */ |
383 | #if CCN_UNIT_SIZE == 8 |
384 | #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_64(x) |
385 | #elif CCN_UNIT_SIZE == 4 |
386 | #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_32(x) |
387 | #else |
388 | #error Unsupported CCN_UNIT_SIZE |
389 | #endif |
390 | |
391 | /*! |
392 | @function ccn_swap |
393 | @discussion Swaps r inplace from cc_unit vector byte order to big endian byte order (or back) |
394 | */ |
395 | CC_NONNULL((2)) |
396 | void ccn_swap(cc_size n, cc_unit *cc_counted_by(n) r); |
397 | |
398 | CC_NONNULL((2, 3, 4)) |
399 | void ccn_xor(cc_size n, cc_unit *cc_counted_by(n) r, const cc_unit *cc_counted_by(n) s, const cc_unit *cc_counted_by(n) t); |
400 | |
401 | /* Debugging */ |
402 | CC_NONNULL((2)) |
403 | void ccn_print(cc_size n, const cc_unit *cc_counted_by(n) s); |
404 | CC_NONNULL((3)) |
405 | void ccn_lprint(cc_size n, const char *cc_cstring label, const cc_unit *cc_counted_by(n) s); |
406 | |
407 | /* Forward declaration so we don't depend on ccrng.h. */ |
408 | struct ccrng_state; |
409 | |
410 | #define ccn_random(_n_,_r_,_ccrng_ctx_) \ |
411 | ccrng_generate(_ccrng_ctx_, ccn_sizeof_n(_n_), (unsigned char *)_r_) |
412 | |
413 | #endif /* _CORECRYPTO_CCN_H_ */ |
414 | |