xref: /xnu-11417.140.69/EXTERNAL_HEADERS/corecrypto/ccn.h (revision 43a90889846e00bfb5cf1d255cdc0a701a1e05a4)
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