| 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 | |