]> git.saurik.com Git - apple/xnu.git/blob - EXTERNAL_HEADERS/corecrypto/ccn.h
xnu-6153.41.3.tar.gz
[apple/xnu.git] / EXTERNAL_HEADERS / corecrypto / ccn.h
1 /*
2 * ccn.h
3 * corecrypto
4 *
5 * Created on 11/16/2010
6 *
7 * Copyright (c) 2010,2011,2012,2013,2014,2015 Apple Inc. All rights reserved.
8 *
9 */
10
11 #ifndef _CORECRYPTO_CCN_H_
12 #define _CORECRYPTO_CCN_H_
13
14 #include <corecrypto/cc.h>
15 #include <stdint.h>
16 #include <stdarg.h>
17
18 typedef uint8_t cc_byte;
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 #if CCN_UINT128_SUPPORT_FOR_64BIT_ARCH
27 typedef unsigned cc_dunit __attribute__((mode(TI))); // 128 bit double width unit
28 typedef signed cc_dint __attribute__((mode(TI)));
29 #else
30 typedef struct cc_dunit {
31 uint64_t l; //do not change the order of the variables. cc_dunit must be little endian
32 uint64_t h;
33 } cc_dunit;
34
35 typedef struct cc_dint {
36 uint64_t l;
37 uint64_t h;
38 } cc_dint;
39 #endif
40
41 #elif CCN_UNIT_SIZE == 4
42 typedef uint32_t cc_unit; // 32 bit unit
43 typedef uint64_t cc_dunit; // 64 bit double width unit
44 typedef int64_t cc_dint;
45 typedef int32_t cc_int;
46 #define CCN_LOG2_BITS_PER_UNIT 5 // 2^5 = 32 bits
47 #define CC_UNIT_C(x) UINT32_C(x)
48
49 #elif CCN_UNIT_SIZE == 2
50 typedef uint16_t cc_unit; // 16 bit unit
51 typedef uint32_t cc_dunit; // 32 bit double width unit
52 #define CCN_LOG2_BITS_PER_UNIT 4 // 2^4 = 16 bits
53 #define CC_UNIT_C(x) UINT16_C(x)
54
55 #elif CCN_UNIT_SIZE == 1
56 typedef uint8_t cc_unit; // 8 bit unit
57 typedef uint16_t cc_dunit; // 16 bit double width unit
58 #define CCN_LOG2_BITS_PER_UNIT 3 // 2^3 = 8 bits
59 #define CC_UNIT_C(x) UINT8_C(x)
60
61 #else
62 #error invalid CCN_UNIT_SIZE
63 #endif
64
65 #define CCN_UNIT_BITS (sizeof(cc_unit) * 8)
66 #define CCN_UNIT_MASK ((cc_unit)~0)
67 #define CCN_UNIT_LOWER_HALF_MASK ((CCN_UNIT_MASK) >> (CCN_UNIT_BITS/2))
68 #define CCN_UNIT_UPPER_HALF_MASK (~CCN_UNIT_LOWER_HALF_MASK)
69
70 typedef struct {
71 cc_unit *start; // First cc_unit of the workspace
72 cc_unit *end; // address and beyond NOT TO BE TOUCHED
73 } cc_ws,*cc_ws_t;
74
75 /* Conversions between n sizeof and bits */
76
77 /* Returns the sizeof a ccn vector of length _n_ units. */
78 #define ccn_sizeof_n(_n_) (sizeof(cc_unit) * (_n_))
79
80 /* Returns the count (n) of a ccn vector that can represent _bits_. */
81 #define ccn_nof(_bits_) (((_bits_) + CCN_UNIT_BITS - 1) >> CCN_LOG2_BITS_PER_UNIT)
82
83 /* Returns the sizeof a ccn vector that can represent _bits_. */
84 #define ccn_sizeof(_bits_) (ccn_sizeof_n(ccn_nof(_bits_)))
85
86 /* Returns the count (n) of a ccn vector that can represent _size_ bytes. */
87 #define ccn_nof_size(_size_) (((_size_) + CCN_UNIT_SIZE - 1) / CCN_UNIT_SIZE)
88
89 #define ccn_nof_sizeof(_expr_) ccn_nof_size(sizeof (_expr_))
90
91 /* Return the max number of bits a ccn vector of _n_ units can hold. */
92 #define ccn_bitsof_n(_n_) ((_n_) * CCN_UNIT_BITS)
93
94 /* Return the max number of bits a ccn vector of _size_ bytes can hold. */
95 #define ccn_bitsof_size(_size_) ((_size_) * 8)
96
97 /* Return the size of a ccn of size bytes in bytes. */
98 #define ccn_sizeof_size(_size_) ccn_sizeof_n(ccn_nof_size(_size_))
99
100 /* Returns the value of bit _k_ of _ccn_, both are only evaluated once. */
101 #define ccn_bit(_ccn_, _k_) ({__typeof__ (_k_) __k = (_k_); \
102 1 & ((_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] >> (__k & (CCN_UNIT_BITS - 1)));})
103
104 /* Set the value of bit _k_ of _ccn_ to the value _v_ */
105 #define ccn_set_bit(_ccn_, _k_, _v_) ({__typeof__ (_k_) __k = (_k_); \
106 if (_v_) \
107 (_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] |= CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1)); \
108 else \
109 (_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] &= ~(CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1))); \
110 })
111
112 /* Macros for making ccn constants. You must use list of CCN64_C() instances
113 separated by commas, with an optional smaller sized CCN32_C, CCN16_C, or
114 CCN8_C() instance at the end of the list, when making macros to declare
115 larger sized constants. */
116 #define CCN8_C(a0) CC_UNIT_C(0x##a0)
117
118 #if CCN_UNIT_SIZE >= 2
119 #define CCN16_C(a1,a0) CC_UNIT_C(0x##a1##a0)
120 #define ccn16_v(a0) (a0)
121 #elif CCN_UNIT_SIZE == 1
122 #define CCN16_C(a1,a0) CCN8_C(a0),CCN8_C(a1)
123 #define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8)
124 #endif
125
126 #if CCN_UNIT_SIZE >= 4
127 #define CCN32_C(a3,a2,a1,a0) CC_UNIT_C(0x##a3##a2##a1##a0)
128 #define ccn32_v(a0) (a0)
129 #else
130 #define CCN32_C(a3,a2,a1,a0) CCN16_C(a1,a0),CCN16_C(a3,a2)
131 #define ccn32_v(a0) ccn16_v(a0 & UINT16_C(0xffff)),ccn16_v(a0 >> 16)
132 #endif
133
134 #if CCN_UNIT_SIZE == 8
135 #define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CC_UNIT_C(0x##a7##a6##a5##a4##a3##a2##a1##a0)
136 #define CCN40_C(a4,a3,a2,a1,a0) CC_UNIT_C(0x##a4##a3##a2##a1##a0)
137 #define ccn64_v(a0) (a0)
138 //#define ccn64_32(a1,a0) ((a1 << 32) | a0)
139 //#define ccn_uint64(a,i) (a[i])
140 #else
141 #define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN32_C(a7,a6,a5,a4)
142 #define CCN40_C(a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN8_C(a4)
143 #define ccn64_v(a0) ccn32_v((uint64_t)a0 & UINT32_C(0xffffffff)),ccn32_v((uint64_t)a0 >> 32)
144 //#define ccn64_32(a1,a0) ccn32_v(a0),ccn32_v(a1)
145 //#define ccn_uint64(a,i) ((uint64_t)ccn_uint32(a, i << 1 + 1) << 32 | (uint64_t)ccn_uint32(a, i << 1))
146 #endif
147
148 /* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or
149 64 bit units respectively. */
150 #if CCN_UNIT_SIZE == 8
151 /* #define ccn_uint16(a,i) ((i & 3) == 3 ? ((uint16_t)(a[i >> 2] >> 48)) : \
152 (i & 3) == 2 ? ((uint16_t)(a[i >> 2] >> 32) & UINT16_C(0xffff)) : \
153 (i & 3) == 1 ? ((uint16_t)(a[i >> 2] >> 16) & UINT16_C(0xffff)) : \
154 ((uint16_t)(a[i >> 1] & UINT16_C(0xffff))))
155 */
156 //#define ccn_uint32(a,i) (i & 1 ? ((uint32_t)(a[i >> 1] >> 32)) : ((uint32_t)(a[i >> 1] & UINT32_C(0xffffffff))))
157 #elif CCN_UNIT_SIZE == 4
158 //#define ccn16_v(a0) (a0)
159 //#define ccn32_v(a0) (a0)
160 //#define ccn_uint16(a,i) (i & 1 ? ((uint16_t)(a[i >> 1] >> 16)) : ((uint16_t)(a[i >> 1] & UINT16_C(0xffff))))
161 //#define ccn_uint32(a,i) (a[i])
162 #elif CCN_UNIT_SIZE == 2
163 //#define ccn16_v(a0) (a0)
164 //#define ccn32_v(a0,a1) (a1,a0)
165 //#define ccn_uint16(a,i) (a[i])
166 //#define ccn_uint32(a,i) (((uint32_t)a[i << 1 + 1]) << 16 | (uint32_t)a[i << 1]))
167 #elif CCN_UNIT_SIZE == 1
168 //#define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8)
169 //#define ccn_uint16(a,i) ((uint16_t)((a[i << 1 + 1] << 8) | a[i << 1]))
170 //#define ccn_uint32(a,i) ((uint32_t)ccn_uint16(a, i << 1 + 1) << 16 | (uint32_t)ccn_uint16(a, i << 1))
171 #endif
172
173 /* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or
174 64 bit units respectively. */
175 #if CCN_UNIT_SIZE == 8
176
177 #define ccn64_32(a1,a0) (((const cc_unit)a1) << 32 | ((const cc_unit)a0))
178 #define ccn32_32(a0) a0
179 #if __LITTLE_ENDIAN__
180 #define ccn32_32_parse(p,i) (((const uint32_t *)p)[i])
181 #else
182 #define ccn32_32_parse(p,i) (((const uint32_t *)p)[i^1])
183 #endif
184 #define ccn32_32_null 0
185
186 #define ccn64_64(a0) a0
187 #define ccn64_64_parse(p,i) p[i]
188 #define ccn64_64_null 0
189
190 #elif CCN_UNIT_SIZE == 4
191
192 #define ccn32_32(a0) a0
193 #define ccn32_32_parse(p,i) p[i]
194 #define ccn32_32_null 0
195 #define ccn64_32(a1,a0) ccn32_32(a0),ccn32_32(a1)
196
197 #define ccn64_64(a1,a0) a0,a1
198 #define ccn64_64_parse(p,i) p[1+(i<<1)],p[i<<1]
199 #define ccn64_64_null 0,0
200
201 #elif CCN_UNIT_SIZE == 2
202
203 #define ccn32_32(a1,a0) a0,a1
204 #define ccn32_32_parse(p,i) p[1+(i<<1)],p[i<<1]
205 #define ccn32_32_null 0,0
206 #define ccn64_32(a3,a2,a1,a0) ccn32_32(a1,a0),ccn32_32(a3,a2)
207
208 #define ccn64_64(a3,a2,a1,a0) a0,a1,a2,a3
209 #define ccn64_64_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2]
210 #define ccn64_64_null 0,0,0,0
211
212 #elif CCN_UNIT_SIZE == 1
213
214 #define ccn32_32(a3,a2,a1,a0) a0,a1,a2,a3
215 #define ccn32_32_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2]
216 #define ccn32_32_null 0,0,0,0
217 #define ccn64_32(a7,a6,a5,a4,a3,a2,a1,a0) ccn32_32(a3,a2,a1,a0),ccn32_32(a7,a6,a5,a4)
218
219 #define ccn64_64(a7,a6,a5,a4,a3,a2,a1,a0) a0,a1,a2,a3,a4,a5,a6,a7
220 #define ccn64_64_parse(p,i) p[7+(i<<3)],p[6+(i<<3)],p[5+(i<<3)],p[4+(i<<3)],p[3+(i<<3)],p[2+(i<<3)],p[1+(i<<3)],p[i<<3]
221 #define ccn64_64_null 0,0,0,0,0,0,0,0
222
223 #endif
224
225
226 /* Macros to construct fixed size ccn arrays from 64 or 32 bit quantities. */
227 #define ccn192_64(a2,a1,a0) ccn64_64(a0),ccn64_64(a1),ccn64_64(a2)
228 #define ccn192_32(a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4)
229 #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)
230 #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)
231 #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)
232
233
234 #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) \
235 CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0),\
236 CCN64_C(b7,b6,b5,b4,b3,b2,b1,b0),\
237 CCN64_C(c7,c6,c5,c4,c3,c2,c1,c0)
238
239 #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) \
240 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),\
241 CCN8_C(d0)
242
243 #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) \
244 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),\
245 CCN32_C(d3,d2,d1,d0)
246
247 #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) \
248 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),\
249 CCN40_C(d4,d3,d2,d1,d0)
250
251 #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) \
252 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),\
253 CCN64_C(d7,d6,d5,d4,d3,d2,d1,d0)
254
255 #define CCN264_C(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) \
256 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),\
257 CCN8_C(e0)
258
259 #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) \
260 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),\
261 CCN64_C(e7,e6,e5,e4,e3,e2,e1,e0),\
262 CCN64_C(f7,f6,f5,f4,f3,f2,f1,f0)
263
264 #define CCN392_C(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) \
265 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),\
266 CCN8_C(g0)
267
268 #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) \
269 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),\
270 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),\
271 CCN16_C(i1,i0)
272
273 #define CCN192_N ccn_nof(192)
274 #define CCN224_N ccn_nof(224)
275 #define CCN256_N ccn_nof(256)
276 #define CCN384_N ccn_nof(384)
277 #define CCN512_N ccn_nof(512)
278 #define CCN521_N ccn_nof(521)
279
280 /* Return the number of used units after stripping leading 0 units. */
281 CC_PURE CC_NONNULL((2))
282 cc_size ccn_n(cc_size n, const cc_unit *s) __asm__("_ccn_n");
283
284 /* s >> k -> r return bits shifted out of least significant word in the higest order bits of
285 the retuned value. For example if CCN_UNIT_SIZE == 1, then (0b1101 1110)>>4 returns (0b1110 0000)
286 and sets r==(0b0000 1101).
287 { N bit, scalar -> N bit } N = n * sizeof(cc_unit) * 8
288 the _multi version doesn't return the shifted bits, but does support multiple
289 word shifts. */
290 CC_NONNULL((2, 3))
291 cc_unit ccn_shift_right(cc_size n, cc_unit *r, const cc_unit *s, size_t k) __asm__("_ccn_shift_right");
292
293 /* s == 0 -> return 0 | s > 0 -> return index (starting at 1) of most
294 * significant bit that is 1.
295 * { N bit } N = n * sizeof(cc_unit) * 8
296 *
297 * Runs in constant time, independent of the value of `s`.
298 */
299 CC_NONNULL((2))
300 size_t ccn_bitlen(cc_size n, const cc_unit *s);
301
302 /* s == 0 -> return true | s != 0 -> return false
303 { N bit } N = n * sizeof(cc_unit) * 8 */
304 #define ccn_is_zero(_n_, _s_) (!ccn_n(_n_, _s_))
305
306 /* s == 1 -> return true | s != 1 -> return false
307 { N bit } N = n * sizeof(cc_unit) * 8 */
308 #define ccn_is_one(_n_, _s_) (ccn_n(_n_, _s_) == 1 && _s_[0] == 1)
309
310 #define ccn_is_zero_or_one(_n_, _s_) (((_n_)==0) || ((ccn_n(_n_, _s_) <= 1) && (_s_[0] <= 1)))
311
312 /* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1
313 { N bit, N bit -> int } N = n * sizeof(cc_unit) * 8 */
314 CC_PURE CC_NONNULL((2, 3))
315 int ccn_cmp(cc_size n, const cc_unit *s, const cc_unit *t) __asm__("_ccn_cmp");
316
317 /* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1
318 { N bit, M bit -> int } N = ns * sizeof(cc_unit) * 8 M = nt * sizeof(cc_unit) * 8 */
319 CC_INLINE CC_NONNULL((2, 4))
320 int ccn_cmpn(cc_size ns, const cc_unit *s,
321 cc_size nt, const cc_unit *t) {
322 if (ns > nt) {
323 return 1;
324 } else if (ns < nt) {
325 return -1;
326 }
327 return ccn_cmp(ns, s, t);
328 }
329
330 /* s - t -> r return 1 iff t > s
331 { N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */
332 CC_NONNULL((2, 3, 4))
333 cc_unit ccn_sub(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t) __asm__("_ccn_sub");
334
335 /* s - v -> r return 1 iff v > s return 0 otherwise.
336 { N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */
337 CC_NONNULL((2, 3))
338 cc_unit ccn_sub1(cc_size n, cc_unit *r, const cc_unit *s, cc_unit v);
339
340 /* s - t -> r return 1 iff t > s
341 { N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */
342 CC_INLINE
343 CC_NONNULL((2, 3, 5))
344 cc_unit ccn_subn(cc_size n, cc_unit *r, const cc_unit *s,
345 cc_size nt, const cc_unit *t) {
346 assert(n >= nt);
347 return ccn_sub1(n - nt, r + nt, s + nt, ccn_sub(nt, r, s, t));
348 }
349
350
351 /* s + t -> r return carry if result doesn't fit in n bits.
352 { N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */
353 CC_NONNULL((2, 3, 4))
354 cc_unit ccn_add(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t) __asm__("_ccn_add");
355
356 /* s + v -> r return carry if result doesn't fit in n bits.
357 { N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */
358 CC_NONNULL((2, 3))
359 cc_unit ccn_add1(cc_size n, cc_unit *r, const cc_unit *s, cc_unit v);
360
361 /* s + t -> r return carry if result doesn't fit in n bits
362 { N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */
363 CC_INLINE
364 CC_NONNULL((2, 3, 5))
365 cc_unit ccn_addn(cc_size n, cc_unit *r, const cc_unit *s,
366 cc_size nt, const cc_unit *t) {
367 assert(n >= nt);
368 return ccn_add1(n - nt, r + nt, s + nt, ccn_add(nt, r, s, t));
369 }
370
371
372 /* s * t -> r_2n r_2n must not overlap with s nor t
373 { n bit, n bit -> 2 * n bit } n = count * sizeof(cc_unit) * 8
374 { N bit, N bit -> 2N bit } N = ccn_bitsof(n) */
375 CC_NONNULL((2, 3, 4))
376 void ccn_mul(cc_size n, cc_unit *r_2n, const cc_unit *s, const cc_unit *t) __asm__("_ccn_mul");
377
378 /* s[0..n) * v -> r[0..n)+return value
379 { N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */
380 CC_NONNULL((2, 3))
381 cc_unit ccn_mul1(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit v);
382
383 /* s[0..n) * v + r[0..n) -> r[0..n)+return value
384 { N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */
385 CC_NONNULL((2, 3))
386 cc_unit ccn_addmul1(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit v);
387
388
389 /*!
390 @function ccn_read_uint
391 @abstract Copy big endian integer and represent it in cc_units
392
393 @param n Input allocated size of the cc_unit output array r
394 @param r Ouput cc_unit array for unsigned integer
395 @param data_nbytes Input byte size of data
396 @param data Input unsigned integer represented in big endian
397
398 @result r is initialized with the big unsigned number
399
400 @return 0 if no error, !=0 if the big number cannot be represented in the allocated cc_unit array.
401
402 @discussion The execution pattern of this function depends on both n and data_nbytes but not on data values except the handling
403 of the error case.
404 */
405
406 CC_NONNULL((2, 4))
407 int ccn_read_uint(cc_size n, cc_unit *r, size_t data_nbytes, const uint8_t *data);
408
409 /* r = (data, len) treated as a big endian byte array, return -1 if data
410 doesn't fit in r, return 0 otherwise.
411 ccn_read_uint strips leading zeroes and doesn't care about sign. */
412 #define ccn_read_int(n, r, data_size, data) ccn_read_uint(n, r, data_size, data)
413
414 /*!
415 @function ccn_write_uint_size
416 @abstract Compute the minimum size required to store an big integer
417
418 @param n Input size of the cc_unit array representing the input
419 @param s Input cc_unit array
420
421 @result Return value is the exact byte size of the big integer
422
423 @discussion
424 The execution flow is independent on the value of the big integer.
425 However, the use of the returned value may leak the position of the most significant byte
426 */
427 CC_PURE CC_NONNULL((2)) size_t ccn_write_uint_size(cc_size n, const cc_unit *s);
428
429 /*!
430 @function ccn_write_uint
431 @abstract Serialize the big integer into a big endian byte buffer
432
433 @param n Input size of the cc_unit array representing the input
434 @param s Input cc_unit array
435 @param out_size Size of the output buffer
436 @param out Output byte array of size at least out_size
437
438 @discussion This function writes exactly
439 MIN(out_size,ccn_write_uint_size(n,s)) bytes truncating to keep the
440 most significant bytes when out_size<ccn_write_uint_size(n,s). The
441 execution flow of function is based on the position of the most
442 significant byte as well as input sizes.
443
444 */
445
446 CC_NONNULL((2, 4))
447 void ccn_write_uint(cc_size n, const cc_unit *s, size_t out_size, void *out);
448
449 /*!
450 @function ccn_write_uint_padded_ct
451 @abstract Serialize the big integer into a big endian byte buffer
452
453 @param n Input size of the cc_unit array representing the input
454 @param s Input cc_unit array
455 @param out_size Size of the output buffer
456 @param out Output byte array of size at least out_size
457
458 @return number of leading zero bytes in case of success, a negative error value in case of failure
459
460 @result This function writes exactly out_size byte, padding with zeroes when necessary.
461 This function DOES NOT support truncation and returns an error if out_size < ccn_write_uint_size
462
463 @discussion The execution flow of function is independent on the value of the big integer
464 However, the processing of the return value by the caller may expose the position of
465 the most significant byte
466 */
467 CC_NONNULL((2, 4))
468 int ccn_write_uint_padded_ct(cc_size n, const cc_unit *s, size_t out_size, uint8_t *out);
469
470 /*!
471 @function ccn_write_uint_padded
472 @abstract Serialize the big integer into a big endian byte buffer
473 Not recommended, for most cases ccn_write_uint_padded_ct is more appropriate
474 Sensitive big integers are exposed since the processing expose the position of the MS byte
475
476 @param n Input size of the cc_unit array representing the input
477 @param s Input cc_unit array
478 @param out_size Size of the output buffer
479 @param out Output byte array of size at least out_size
480
481 @return number of leading zero bytes
482
483 @result This function writes exactly out_size byte, padding with zeroes when necessary.
484 This function DOES support truncation when out_size<ccn_write_uint_size()
485
486 @discussion The execution flow of this function DEPENDS on the position of the most significant byte in
487 case truncation is required.
488 */
489
490 CC_INLINE CC_NONNULL((2, 4)) size_t ccn_write_uint_padded(cc_size n, const cc_unit *s, size_t out_size, uint8_t *out)
491 {
492 size_t offset = 0;
493 // Try first the non-truncation case
494 int offset_int = ccn_write_uint_padded_ct(n, s, out_size, out);
495 if (offset_int >= 0) {
496 // It worked
497 offset = (size_t)offset_int;
498 } else {
499 // Truncation case, execution depends on the position of the MSByte
500 ccn_write_uint(n, s, out_size, out);
501 }
502 return offset;
503 }
504
505
506 /* Return actual size in bytes needed to serialize s as int
507 (adding leading zero if high bit is set). */
508 CC_PURE CC_NONNULL((2))
509 size_t ccn_write_int_size(cc_size n, const cc_unit *s);
510
511 /* Serialize s, to out.
512 First byte of byte stream is the m.s. byte of s,
513 regardless of the size of cc_unit.
514
515 No assumption is made about the alignment of out.
516
517 The out_size argument should be the value returned from ccn_write_int_size,
518 and is also the exact number of bytes this function will write to out.
519 If out_size if less than the value returned by ccn_write_int_size, only the
520 first out_size non-zero most significant octets of s will be written. */
521 CC_NONNULL((2, 4))
522 void ccn_write_int(cc_size n, const cc_unit *s, size_t out_size, void *out);
523
524 /* s -> r
525 { n bit -> n bit } */
526 CC_NONNULL((2, 3))
527 void ccn_set(cc_size n, cc_unit *r, const cc_unit *s) __asm__("_ccn_set");
528
529 CC_INLINE CC_NONNULL((2))
530 void ccn_zero(cc_size n, cc_unit *r) {
531 cc_clear(ccn_sizeof_n(n),r);
532 }
533
534 CC_INLINE CC_NONNULL((2))
535 void ccn_clear(cc_size n, cc_unit *r) {
536 cc_clear(ccn_sizeof_n(n),r);
537 }
538
539 CC_NONNULL((2))
540 void ccn_zero_multi(cc_size n, cc_unit *r, ...);
541
542 CC_INLINE CC_NONNULL((2))
543 void ccn_seti(cc_size n, cc_unit *r, cc_unit v) {
544 /* assert(n > 0); */
545 r[0] = v;
546 ccn_zero(n - 1, r + 1);
547 }
548
549 CC_INLINE CC_NONNULL((2, 4))
550 void ccn_setn(cc_size n, cc_unit *r, const cc_size s_size, const cc_unit *s) {
551 /* FIXME: assert not available in kernel.
552 assert(n > 0);
553 assert(s_size > 0);
554 assert(s_size <= n);
555 */
556 ccn_set(s_size, r, s);
557 ccn_zero(n - s_size, r + s_size);
558 }
559
560 #define CC_SWAP_HOST_BIG_64(x) \
561 ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
562 (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
563 (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
564 (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
565 (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
566 (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
567 (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
568 (((uint64_t)(x) & 0x00000000000000ffULL) << 56)))
569 #define CC_SWAP_HOST_BIG_32(x) \
570 ((((x) & 0xff000000) >> 24) | \
571 (((x) & 0x00ff0000) >> 8) | \
572 (((x) & 0x0000ff00) << 8) | \
573 (((x) & 0x000000ff) << 24))
574 #define CC_SWAP_HOST_BIG_16(x) \
575 ((((x) & 0xff00) >> 8) | \
576 (((x) & 0x00ff) << 8))
577
578 /* This should probably move if we move ccn_swap out of line. */
579 #if CCN_UNIT_SIZE == 8
580 #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_64(x)
581 #elif CCN_UNIT_SIZE == 4
582 #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_32(x)
583 #elif CCN_UNIT_SIZE == 2
584 #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_16(x)
585 #elif CCN_UNIT_SIZE == 1
586 #define CC_UNIT_TO_BIG(x) (x)
587 #else
588 #error unsupported CCN_UNIT_SIZE
589 #endif
590
591 /* Swap units in r in place from cc_unit vector byte order to big endian byte order (or back). */
592 CC_INLINE CC_NONNULL((2))
593 void ccn_swap(cc_size n, cc_unit *r) {
594 cc_unit *e;
595 for (e = r + n - 1; r < e; ++r, --e) {
596 cc_unit t = CC_UNIT_TO_BIG(*r);
597 *r = CC_UNIT_TO_BIG(*e);
598 *e = t;
599 }
600 if (n & 1)
601 *r = CC_UNIT_TO_BIG(*r);
602 }
603
604 CC_INLINE CC_NONNULL((2, 3, 4))
605 void ccn_xor(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t) {
606 while (n--) {
607 r[n] = s[n] ^ t[n];
608 }
609 }
610
611 /* Debugging */
612 CC_NONNULL((2))
613 void ccn_print(cc_size n, const cc_unit *s);
614 CC_NONNULL((3))
615 void ccn_lprint(cc_size n, const char *label, const cc_unit *s);
616
617 /* Forward declaration so we don't depend on ccrng.h. */
618 struct ccrng_state;
619
620 #if 0
621 CC_INLINE CC_NONNULL((2, 3))
622 int ccn_random(cc_size n, cc_unit *r, struct ccrng_state *rng) {
623 return (RNG)->generate((RNG), ccn_sizeof_n(n), (unsigned char *)r);
624 }
625 #else
626 #define ccn_random(_n_,_r_,_ccrng_ctx_) \
627 ccrng_generate(_ccrng_ctx_, ccn_sizeof_n(_n_), (unsigned char *)_r_)
628 #endif
629
630 /* Make a ccn of size ccn_nof(nbits) units with up to nbits sized random value. */
631 CC_NONNULL((2, 3))
632 int ccn_random_bits(cc_size nbits, cc_unit *r, struct ccrng_state *rng);
633
634 CC_NONNULL((6, 8))
635 int ccn_div_euclid(cc_size nq, cc_unit *q, cc_size nr, cc_unit *r, cc_size na, const cc_unit *a, cc_size nd, const cc_unit *d);
636
637 #define ccn_div(nq, q, na, a, nd, d) ccn_div_euclid(nq, q, 0, NULL, na, a, nd, d)
638 #define ccn_mod(nr, r, na, a, nd, d) ccn_div_euclid(0 , NULL, nr, r, na, a, nd, d)
639
640 #endif /* _CORECRYPTO_CCN_H_ */