| 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 | // All mp types have units in little endian unit order. |
| 66 | typedef cc_unit *ccn_t; // n unit long mp |
| 67 | typedef cc_unit *ccnp1_t; // n + 1 unit long mp |
| 68 | typedef cc_unit *cc2n_t; // 2 * n unit long mp |
| 69 | typedef cc_unit *cc2np2_t; // 2 * n + 2 unit long mp |
| 70 | typedef const cc_unit *ccn_in_t; // n unit long mp |
| 71 | typedef const cc_unit *ccnp1_in_t; // n + 1 unit long mp |
| 72 | typedef const cc_unit *cc2n_in_t; // 2 * n unit long mp |
| 73 | typedef const cc_unit *cc2np2_in_t; // 2 * n + 2 unit long mp |
| 74 | |
| 75 | #define CCN_UNIT_BITS (sizeof(cc_unit) * 8) |
| 76 | #define CCN_UNIT_MASK ((cc_unit)~0) |
| 77 | |
| 78 | typedef struct { |
| 79 | cc_unit *start; // First cc_unit of the workspace |
| 80 | cc_unit *end; // address and beyond NOT TO BE TOUCHED |
| 81 | } cc_ws,*cc_ws_t; |
| 82 | |
| 83 | /* Conversions between n sizeof and bits */ |
| 84 | |
| 85 | /* Returns the sizeof a ccn vector of length _n_ units. */ |
| 86 | #define ccn_sizeof_n(_n_) (sizeof(cc_unit) * (_n_)) |
| 87 | |
| 88 | /* Returns the count (n) of a ccn vector that can represent _bits_. */ |
| 89 | #define ccn_nof(_bits_) (((_bits_) + CCN_UNIT_BITS - 1) >> CCN_LOG2_BITS_PER_UNIT) |
| 90 | |
| 91 | /* Returns the sizeof a ccn vector that can represent _bits_. */ |
| 92 | #define ccn_sizeof(_bits_) (ccn_sizeof_n(ccn_nof(_bits_))) |
| 93 | |
| 94 | /* Returns the count (n) of a ccn vector that can represent _size_ bytes. */ |
| 95 | #define ccn_nof_size(_size_) (((_size_) + CCN_UNIT_SIZE - 1) / CCN_UNIT_SIZE) |
| 96 | |
| 97 | #define ccn_nof_sizeof(_expr_) ccn_nof_size(sizeof (_expr_)) |
| 98 | |
| 99 | /* Return the max number of bits a ccn vector of _n_ units can hold. */ |
| 100 | #define ccn_bitsof_n(_n_) ((_n_) * CCN_UNIT_BITS) |
| 101 | |
| 102 | /* Return the max number of bits a ccn vector of _size_ bytes can hold. */ |
| 103 | #define ccn_bitsof_size(_size_) ((_size_) * 8) |
| 104 | |
| 105 | /* Return the size of a ccn of size bytes in bytes. */ |
| 106 | #define ccn_sizeof_size(_size_) ccn_sizeof_n(ccn_nof_size(_size_)) |
| 107 | |
| 108 | /* Returns the value of bit _k_ of _ccn_, both are only evaluated once. */ |
| 109 | #define ccn_bit(_ccn_, _k_) ({__typeof__ (_k_) __k = (_k_); \ |
| 110 | 1 & ((_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] >> (__k & (CCN_UNIT_BITS - 1)));}) |
| 111 | |
| 112 | /* Set the value of bit _k_ of _ccn_ to the value _v_ */ |
| 113 | #define ccn_set_bit(_ccn_, _k_, _v_) ({__typeof__ (_k_) __k = (_k_); \ |
| 114 | if (_v_) \ |
| 115 | (_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] |= CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1)); \ |
| 116 | else \ |
| 117 | (_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] &= ~(CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1))); \ |
| 118 | }) |
| 119 | |
| 120 | /* Macros for making ccn constants. You must use list of CCN64_C() instances |
| 121 | separated by commas, with an optional smaller sized CCN32_C, CCN16_C, or |
| 122 | CCN8_C() instance at the end of the list, when making macros to declare |
| 123 | larger sized constants. */ |
| 124 | #define CCN8_C(a0) CC_UNIT_C(0x##a0) |
| 125 | |
| 126 | #if CCN_UNIT_SIZE >= 2 |
| 127 | #define CCN16_C(a1,a0) CC_UNIT_C(0x##a1##a0) |
| 128 | #define ccn16_v(a0) (a0) |
| 129 | #elif CCN_UNIT_SIZE == 1 |
| 130 | #define CCN16_C(a1,a0) CCN8_C(a0),CCN8_C(a1) |
| 131 | #define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8) |
| 132 | #endif |
| 133 | |
| 134 | #if CCN_UNIT_SIZE >= 4 |
| 135 | #define CCN32_C(a3,a2,a1,a0) CC_UNIT_C(0x##a3##a2##a1##a0) |
| 136 | #define ccn32_v(a0) (a0) |
| 137 | #else |
| 138 | #define CCN32_C(a3,a2,a1,a0) CCN16_C(a1,a0),CCN16_C(a3,a2) |
| 139 | #define ccn32_v(a0) ccn16_v(a0 & UINT16_C(0xffff)),ccn16_v(a0 >> 16) |
| 140 | #endif |
| 141 | |
| 142 | #if CCN_UNIT_SIZE == 8 |
| 143 | #define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CC_UNIT_C(0x##a7##a6##a5##a4##a3##a2##a1##a0) |
| 144 | #define CCN40_C(a4,a3,a2,a1,a0) CC_UNIT_C(0x##a4##a3##a2##a1##a0) |
| 145 | #define ccn64_v(a0) (a0) |
| 146 | //#define ccn64_32(a1,a0) ((a1 << 32) | a0) |
| 147 | //#define ccn_uint64(a,i) (a[i]) |
| 148 | #else |
| 149 | #define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN32_C(a7,a6,a5,a4) |
| 150 | #define CCN40_C(a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN8_C(a4) |
| 151 | #define ccn64_v(a0) ccn32_v((uint64_t)a0 & UINT32_C(0xffffffff)),ccn32_v((uint64_t)a0 >> 32) |
| 152 | //#define ccn64_32(a1,a0) ccn32_v(a0),ccn32_v(a1) |
| 153 | //#define ccn_uint64(a,i) ((uint64_t)ccn_uint32(a, i << 1 + 1) << 32 | (uint64_t)ccn_uint32(a, i << 1)) |
| 154 | #endif |
| 155 | |
| 156 | /* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or |
| 157 | 64 bit units respectively. */ |
| 158 | #if CCN_UNIT_SIZE == 8 |
| 159 | /* #define ccn_uint16(a,i) ((i & 3) == 3 ? ((uint16_t)(a[i >> 2] >> 48)) : \ |
| 160 | (i & 3) == 2 ? ((uint16_t)(a[i >> 2] >> 32) & UINT16_C(0xffff)) : \ |
| 161 | (i & 3) == 1 ? ((uint16_t)(a[i >> 2] >> 16) & UINT16_C(0xffff)) : \ |
| 162 | ((uint16_t)(a[i >> 1] & UINT16_C(0xffff)))) |
| 163 | */ |
| 164 | //#define ccn_uint32(a,i) (i & 1 ? ((uint32_t)(a[i >> 1] >> 32)) : ((uint32_t)(a[i >> 1] & UINT32_C(0xffffffff)))) |
| 165 | #elif CCN_UNIT_SIZE == 4 |
| 166 | //#define ccn16_v(a0) (a0) |
| 167 | //#define ccn32_v(a0) (a0) |
| 168 | //#define ccn_uint16(a,i) (i & 1 ? ((uint16_t)(a[i >> 1] >> 16)) : ((uint16_t)(a[i >> 1] & UINT16_C(0xffff)))) |
| 169 | //#define ccn_uint32(a,i) (a[i]) |
| 170 | #elif CCN_UNIT_SIZE == 2 |
| 171 | //#define ccn16_v(a0) (a0) |
| 172 | //#define ccn32_v(a0,a1) (a1,a0) |
| 173 | //#define ccn_uint16(a,i) (a[i]) |
| 174 | //#define ccn_uint32(a,i) (((uint32_t)a[i << 1 + 1]) << 16 | (uint32_t)a[i << 1])) |
| 175 | #elif CCN_UNIT_SIZE == 1 |
| 176 | //#define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8) |
| 177 | //#define ccn_uint16(a,i) ((uint16_t)((a[i << 1 + 1] << 8) | a[i << 1])) |
| 178 | //#define ccn_uint32(a,i) ((uint32_t)ccn_uint16(a, i << 1 + 1) << 16 | (uint32_t)ccn_uint16(a, i << 1)) |
| 179 | #endif |
| 180 | |
| 181 | /* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or |
| 182 | 64 bit units respectively. */ |
| 183 | #if CCN_UNIT_SIZE == 8 |
| 184 | |
| 185 | #define ccn64_32(a1,a0) (((const cc_unit)a1) << 32 | ((const cc_unit)a0)) |
| 186 | #define ccn32_32(a0) a0 |
| 187 | #if __LITTLE_ENDIAN__ |
| 188 | #define ccn32_32_parse(p,i) (((const uint32_t *)p)[i]) |
| 189 | #else |
| 190 | #define ccn32_32_parse(p,i) (((const uint32_t *)p)[i^1]) |
| 191 | #endif |
| 192 | #define ccn32_32_null 0 |
| 193 | |
| 194 | #define ccn64_64(a0) a0 |
| 195 | #define ccn64_64_parse(p,i) p[i] |
| 196 | #define ccn64_64_null 0 |
| 197 | |
| 198 | #elif CCN_UNIT_SIZE == 4 |
| 199 | |
| 200 | #define ccn32_32(a0) a0 |
| 201 | #define ccn32_32_parse(p,i) p[i] |
| 202 | #define ccn32_32_null 0 |
| 203 | #define ccn64_32(a1,a0) ccn32_32(a0),ccn32_32(a1) |
| 204 | |
| 205 | #define ccn64_64(a1,a0) a0,a1 |
| 206 | #define ccn64_64_parse(p,i) p[1+(i<<1)],p[i<<1] |
| 207 | #define ccn64_64_null 0,0 |
| 208 | |
| 209 | #elif CCN_UNIT_SIZE == 2 |
| 210 | |
| 211 | #define ccn32_32(a1,a0) a0,a1 |
| 212 | #define ccn32_32_parse(p,i) p[1+(i<<1)],p[i<<1] |
| 213 | #define ccn32_32_null 0,0 |
| 214 | #define ccn64_32(a3,a2,a1,a0) ccn32_32(a1,a0),ccn32_32(a3,a2) |
| 215 | |
| 216 | #define ccn64_64(a3,a2,a1,a0) a0,a1,a2,a3 |
| 217 | #define ccn64_64_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2] |
| 218 | #define ccn64_64_null 0,0,0,0 |
| 219 | |
| 220 | #elif CCN_UNIT_SIZE == 1 |
| 221 | |
| 222 | #define ccn32_32(a3,a2,a1,a0) a0,a1,a2,a3 |
| 223 | #define ccn32_32_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2] |
| 224 | #define ccn32_32_null 0,0,0,0 |
| 225 | #define ccn64_32(a7,a6,a5,a4,a3,a2,a1,a0) ccn32_32(a3,a2,a1,a0),ccn32_32(a7,a6,a5,a4) |
| 226 | |
| 227 | #define ccn64_64(a7,a6,a5,a4,a3,a2,a1,a0) a0,a1,a2,a3,a4,a5,a6,a7 |
| 228 | #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] |
| 229 | #define ccn64_64_null 0,0,0,0,0,0,0,0 |
| 230 | |
| 231 | #endif |
| 232 | |
| 233 | |
| 234 | /* Macros to construct fixed size ccn arrays from 64 or 32 bit quantities. */ |
| 235 | #define ccn192_64(a2,a1,a0) ccn64_64(a0),ccn64_64(a1),ccn64_64(a2) |
| 236 | #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) |
| 237 | #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) |
| 238 | #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) |
| 239 | |
| 240 | |
| 241 | #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) \ |
| 242 | CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0),\ |
| 243 | CCN64_C(b7,b6,b5,b4,b3,b2,b1,b0),\ |
| 244 | CCN64_C(c7,c6,c5,c4,c3,c2,c1,c0) |
| 245 | |
| 246 | #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) \ |
| 247 | 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),\ |
| 248 | CCN8_C(d0) |
| 249 | |
| 250 | #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) \ |
| 251 | 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),\ |
| 252 | CCN32_C(d3,d2,d1,d0) |
| 253 | |
| 254 | #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) \ |
| 255 | 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),\ |
| 256 | CCN40_C(d4,d3,d2,d1,d0) |
| 257 | |
| 258 | #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) \ |
| 259 | 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),\ |
| 260 | CCN64_C(d7,d6,d5,d4,d3,d2,d1,d0) |
| 261 | |
| 262 | #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) \ |
| 263 | 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),\ |
| 264 | CCN8_C(e0) |
| 265 | |
| 266 | #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) \ |
| 267 | 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),\ |
| 268 | CCN64_C(e7,e6,e5,e4,e3,e2,e1,e0),\ |
| 269 | CCN64_C(f7,f6,f5,f4,f3,f2,f1,f0) |
| 270 | |
| 271 | #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) \ |
| 272 | 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),\ |
| 273 | CCN8_C(g0) |
| 274 | |
| 275 | #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) \ |
| 276 | 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),\ |
| 277 | 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),\ |
| 278 | CCN16_C(i1,i0) |
| 279 | |
| 280 | #define CCN192_N ccn_nof(192) |
| 281 | #define CCN224_N ccn_nof(224) |
| 282 | #define CCN256_N ccn_nof(256) |
| 283 | #define CCN384_N ccn_nof(384) |
| 284 | #define CCN512_N ccn_nof(512) |
| 285 | #define CCN521_N ccn_nof(521) |
| 286 | |
| 287 | /* Return the number of used units after stripping leading 0 units. */ |
| 288 | CC_PURE CC_NONNULL((2)) |
| 289 | cc_size ccn_n(cc_size n, const cc_unit *s); |
| 290 | |
| 291 | /* s >> k -> r return bits shifted out of least significant word in bits [0, n> |
| 292 | { N bit, scalar -> N bit } N = n * sizeof(cc_unit) * 8 |
| 293 | the _multi version doesn't return the shifted bits, but does support multiple |
| 294 | word shifts. */ |
| 295 | CC_NONNULL((2, 3)) |
| 296 | cc_unit ccn_shift_right(cc_size n, cc_unit *r, const cc_unit *s, size_t k); |
| 297 | |
| 298 | /* s == 0 -> return 0 | s > 0 -> return index (starting at 1) of most |
| 299 | significant bit that is 1. |
| 300 | { N bit } N = n * sizeof(cc_unit) * 8 */ |
| 301 | CC_NONNULL((2)) |
| 302 | size_t ccn_bitlen(cc_size n, const cc_unit *s); |
| 303 | |
| 304 | /* s == 0 -> return true | s != 0 -> return false |
| 305 | { N bit } N = n * sizeof(cc_unit) * 8 */ |
| 306 | #define ccn_is_zero(_n_, _s_) (!ccn_n(_n_, _s_)) |
| 307 | |
| 308 | /* s == 1 -> return true | s != 1 -> return false |
| 309 | { N bit } N = n * sizeof(cc_unit) * 8 */ |
| 310 | #define ccn_is_one(_n_, _s_) (ccn_n(_n_, _s_) == 1 && _s_[0] == 1) |
| 311 | |
| 312 | #define ccn_is_zero_or_one(_n_, _s_) (((_n_)==0) || ((ccn_n(_n_, _s_) <= 1) && (_s_[0] <= 1))) |
| 313 | |
| 314 | /* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1 |
| 315 | { N bit, N bit -> int } N = n * sizeof(cc_unit) * 8 */ |
| 316 | CC_PURE CC_NONNULL((2, 3)) |
| 317 | int ccn_cmp(cc_size n, const cc_unit *s, const cc_unit *t); |
| 318 | |
| 319 | /* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1 |
| 320 | { N bit, M bit -> int } N = ns * sizeof(cc_unit) * 8 M = nt * sizeof(cc_unit) * 8 */ |
| 321 | CC_INLINE CC_NONNULL((2, 4)) |
| 322 | int ccn_cmpn(cc_size ns, const cc_unit *s, |
| 323 | cc_size nt, const cc_unit *t) { |
| 324 | if (ns > nt) { |
| 325 | return 1; |
| 326 | } else if (ns < nt) { |
| 327 | return -1; |
| 328 | } |
| 329 | return ccn_cmp(ns, s, t); |
| 330 | } |
| 331 | |
| 332 | /* s - t -> r return 1 iff t > s |
| 333 | { N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */ |
| 334 | CC_NONNULL((2, 3, 4)) |
| 335 | cc_unit ccn_sub(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t); |
| 336 | |
| 337 | /* s - v -> r return 1 iff v > s return 0 otherwise. |
| 338 | { N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */ |
| 339 | CC_NONNULL((2, 3)) |
| 340 | cc_unit ccn_sub1(cc_size n, cc_unit *r, const cc_unit *s, cc_unit v); |
| 341 | |
| 342 | /* s - t -> r return 1 iff t > s |
| 343 | { N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */ |
| 344 | CC_INLINE |
| 345 | CC_NONNULL((2, 3, 5)) |
| 346 | cc_unit ccn_subn(cc_size n, cc_unit *r, const cc_unit *s, |
| 347 | cc_size nt, const cc_unit *t) { |
| 348 | assert(n >= nt); |
| 349 | return ccn_sub1(n - nt, r + nt, s + nt, ccn_sub(nt, r, s, t)); |
| 350 | } |
| 351 | |
| 352 | |
| 353 | /* s + t -> r return carry if result doesn't fit in n bits. |
| 354 | { N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */ |
| 355 | CC_NONNULL((2, 3, 4)) |
| 356 | cc_unit ccn_add(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t); |
| 357 | |
| 358 | /* s + v -> r return carry if result doesn't fit in n bits. |
| 359 | { N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */ |
| 360 | CC_NONNULL((2, 3)) |
| 361 | cc_unit ccn_add1(cc_size n, cc_unit *r, const cc_unit *s, cc_unit v); |
| 362 | |
| 363 | /* s + t -> r return carry if result doesn't fit in n bits |
| 364 | { N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */ |
| 365 | CC_INLINE |
| 366 | CC_NONNULL((2, 3, 5)) |
| 367 | cc_unit ccn_addn(cc_size n, cc_unit *r, const cc_unit *s, |
| 368 | cc_size nt, const cc_unit *t) { |
| 369 | assert(n >= nt); |
| 370 | return ccn_add1(n - nt, r + nt, s + nt, ccn_add(nt, r, s, t)); |
| 371 | } |
| 372 | |
| 373 | |
| 374 | /* s * t -> r_2n r_2n must not overlap with s nor t |
| 375 | { n bit, n bit -> 2 * n bit } n = count * sizeof(cc_unit) * 8 |
| 376 | { N bit, N bit -> 2N bit } N = ccn_bitsof(n) */ |
| 377 | CC_NONNULL((2, 3, 4)) |
| 378 | void ccn_mul(cc_size n, cc_unit *r_2n, const cc_unit *s, const cc_unit *t); |
| 379 | |
| 380 | /* s[0..n) * v -> r[0..n)+return value |
| 381 | { N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */ |
| 382 | CC_NONNULL((2, 3)) |
| 383 | cc_unit ccn_mul1(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit v); |
| 384 | |
| 385 | /* s[0..n) * v + r[0..n) -> r[0..n)+return value |
| 386 | { N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */ |
| 387 | CC_NONNULL((2, 3)) |
| 388 | cc_unit ccn_addmul1(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit v); |
| 389 | |
| 390 | #if 0 |
| 391 | /* a % d -> n |
| 392 | {2 * n bit, n bit -> n bit } n = count * sizeof(cc_unit) * 8 */ |
| 393 | CC_NONNULL((2, 3, 4)) |
| 394 | void ccn_mod(cc_size n, cc_unit *r, const cc_unit *a_2n, const cc_unit *d); |
| 395 | #endif |
| 396 | |
| 397 | /* r = (data, len) treated as a big endian byte array, return -1 if data |
| 398 | doesn't fit in r, return 0 otherwise. */ |
| 399 | CC_NONNULL((2, 4)) |
| 400 | int ccn_read_uint(cc_size n, cc_unit *r, size_t data_size, const uint8_t *data); |
| 401 | |
| 402 | /* r = (data, len) treated as a big endian byte array, return -1 if data |
| 403 | doesn't fit in r, return 0 otherwise. |
| 404 | ccn_read_uint strips leading zeroes and doesn't care about sign. */ |
| 405 | #define ccn_read_int(n, r, data_size, data) ccn_read_uint(n, r, data_size, data) |
| 406 | |
| 407 | /* Return actual size in bytes needed to serialize s. */ |
| 408 | CC_PURE CC_NONNULL((2)) |
| 409 | size_t ccn_write_uint_size(cc_size n, const cc_unit *s); |
| 410 | |
| 411 | /* Serialize s, to out. |
| 412 | First byte of byte stream is the m.s. byte of s, |
| 413 | regardless of the size of cc_unit. |
| 414 | |
| 415 | No assumption is made about the alignment of out. |
| 416 | |
| 417 | The out_size argument should be the value returned from ccn_write_uint_size, |
| 418 | and is also the exact number of bytes this function will write to out. |
| 419 | If out_size if less than the value returned by ccn_write_uint_size, only the |
| 420 | first out_size non-zero most significant octets of s will be written. */ |
| 421 | CC_NONNULL((2, 4)) |
| 422 | void ccn_write_uint(cc_size n, const cc_unit *s, size_t out_size, void *out); |
| 423 | |
| 424 | |
| 425 | CC_INLINE CC_NONNULL((2, 4)) |
| 426 | cc_size ccn_write_uint_padded(cc_size n, const cc_unit* s, size_t out_size, uint8_t* to) |
| 427 | { |
| 428 | size_t bytesInKey = ccn_write_uint_size(n, s); |
| 429 | cc_size offset = (out_size > bytesInKey) ? out_size - bytesInKey : 0; |
| 430 | |
| 431 | cc_zero(offset, to); |
| 432 | ccn_write_uint(n, s, out_size - offset, to + offset); |
| 433 | |
| 434 | return offset; |
| 435 | } |
| 436 | |
| 437 | |
| 438 | /* Return actual size in bytes needed to serialize s as int |
| 439 | (adding leading zero if high bit is set). */ |
| 440 | CC_PURE CC_NONNULL((2)) |
| 441 | size_t ccn_write_int_size(cc_size n, const cc_unit *s); |
| 442 | |
| 443 | /* Serialize s, to out. |
| 444 | First byte of byte stream is the m.s. byte of s, |
| 445 | regardless of the size of cc_unit. |
| 446 | |
| 447 | No assumption is made about the alignment of out. |
| 448 | |
| 449 | The out_size argument should be the value returned from ccn_write_int_size, |
| 450 | and is also the exact number of bytes this function will write to out. |
| 451 | If out_size if less than the value returned by ccn_write_int_size, only the |
| 452 | first out_size non-zero most significant octets of s will be written. */ |
| 453 | CC_NONNULL((2, 4)) |
| 454 | void ccn_write_int(cc_size n, const cc_unit *s, size_t out_size, void *out); |
| 455 | |
| 456 | /* s -> r |
| 457 | { n bit -> n bit } */ |
| 458 | CC_NONNULL((2, 3)) |
| 459 | void ccn_set(cc_size n, cc_unit *r, const cc_unit *s); |
| 460 | |
| 461 | CC_INLINE CC_NONNULL((2)) |
| 462 | void ccn_zero(cc_size n, cc_unit *r) { |
| 463 | cc_zero(ccn_sizeof_n(n),r); |
| 464 | } |
| 465 | |
| 466 | CC_INLINE CC_NONNULL((2)) |
| 467 | void ccn_clear(cc_size n, cc_unit *r) { |
| 468 | cc_clear(ccn_sizeof_n(n),r); |
| 469 | } |
| 470 | |
| 471 | CC_NONNULL((2)) |
| 472 | void ccn_zero_multi(cc_size n, cc_unit *r, ...); |
| 473 | |
| 474 | CC_INLINE CC_NONNULL((2)) |
| 475 | void ccn_seti(cc_size n, cc_unit *r, cc_unit v) { |
| 476 | /* assert(n > 0); */ |
| 477 | r[0] = v; |
| 478 | ccn_zero(n - 1, r + 1); |
| 479 | } |
| 480 | |
| 481 | CC_INLINE CC_NONNULL((2, 4)) |
| 482 | void ccn_setn(cc_size n, cc_unit *r, const cc_size s_size, const cc_unit *s) { |
| 483 | /* FIXME: assert not available in kernel. |
| 484 | assert(n > 0); |
| 485 | assert(s_size > 0); |
| 486 | assert(s_size <= n); |
| 487 | */ |
| 488 | ccn_set(s_size, r, s); |
| 489 | ccn_zero(n - s_size, r + s_size); |
| 490 | } |
| 491 | |
| 492 | #define CC_SWAP_HOST_BIG_64(x) \ |
| 493 | ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \ |
| 494 | (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \ |
| 495 | (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \ |
| 496 | (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \ |
| 497 | (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \ |
| 498 | (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \ |
| 499 | (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \ |
| 500 | (((uint64_t)(x) & 0x00000000000000ffULL) << 56))) |
| 501 | #define CC_SWAP_HOST_BIG_32(x) \ |
| 502 | ((((x) & 0xff000000) >> 24) | \ |
| 503 | (((x) & 0x00ff0000) >> 8) | \ |
| 504 | (((x) & 0x0000ff00) << 8) | \ |
| 505 | (((x) & 0x000000ff) << 24)) |
| 506 | #define CC_SWAP_HOST_BIG_16(x) \ |
| 507 | ((((x) & 0xff00) >> 8) | \ |
| 508 | (((x) & 0x00ff) << 8)) |
| 509 | |
| 510 | /* This should probably move if we move ccn_swap out of line. */ |
| 511 | #if CCN_UNIT_SIZE == 8 |
| 512 | #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_64(x) |
| 513 | #elif CCN_UNIT_SIZE == 4 |
| 514 | #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_32(x) |
| 515 | #elif CCN_UNIT_SIZE == 2 |
| 516 | #define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_16(x) |
| 517 | #elif CCN_UNIT_SIZE == 1 |
| 518 | #define CC_UNIT_TO_BIG(x) (x) |
| 519 | #else |
| 520 | #error unsupported CCN_UNIT_SIZE |
| 521 | #endif |
| 522 | |
| 523 | /* Swap units in r in place from cc_unit vector byte order to big endian byte order (or back). */ |
| 524 | CC_INLINE CC_NONNULL((2)) |
| 525 | void ccn_swap(cc_size n, cc_unit *r) { |
| 526 | cc_unit *e; |
| 527 | for (e = r + n - 1; r < e; ++r, --e) { |
| 528 | cc_unit t = CC_UNIT_TO_BIG(*r); |
| 529 | *r = CC_UNIT_TO_BIG(*e); |
| 530 | *e = t; |
| 531 | } |
| 532 | if (n & 1) |
| 533 | *r = CC_UNIT_TO_BIG(*r); |
| 534 | } |
| 535 | |
| 536 | CC_INLINE CC_NONNULL((2, 3, 4)) |
| 537 | void ccn_xor(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t) { |
| 538 | while (n--) { |
| 539 | r[n] = s[n] ^ t[n]; |
| 540 | } |
| 541 | } |
| 542 | |
| 543 | /* Debugging */ |
| 544 | CC_NONNULL((2)) |
| 545 | void ccn_print(cc_size n, const cc_unit *s); |
| 546 | CC_NONNULL((3)) |
| 547 | void ccn_lprint(cc_size n, const char *label, const cc_unit *s); |
| 548 | |
| 549 | /* Forward declaration so we don't depend on ccrng.h. */ |
| 550 | struct ccrng_state; |
| 551 | |
| 552 | #if 0 |
| 553 | CC_INLINE CC_NONNULL((2, 3)) |
| 554 | int ccn_random(cc_size n, cc_unit *r, struct ccrng_state *rng) { |
| 555 | return (RNG)->generate((RNG), ccn_sizeof_n(n), (unsigned char *)r); |
| 556 | } |
| 557 | #else |
| 558 | #define ccn_random(_n_,_r_,_ccrng_ctx_) \ |
| 559 | ccrng_generate(_ccrng_ctx_, ccn_sizeof_n(_n_), (unsigned char *)_r_) |
| 560 | #endif |
| 561 | |
| 562 | /* Make a ccn of size ccn_nof(nbits) units with up to nbits sized random value. */ |
| 563 | CC_NONNULL((2, 3)) |
| 564 | int ccn_random_bits(cc_size nbits, cc_unit *r, struct ccrng_state *rng); |
| 565 | |
| 566 | CC_NONNULL((6, 8)) |
| 567 | 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); |
| 568 | |
| 569 | #define ccn_div(nq, q, na, a, nd, d) ccn_div_euclid(nq, q, 0, NULL, na, a, nd, d) |
| 570 | #define ccn_mod(nr, r, na, a, nd, d) ccn_div_euclid(0 , NULL, nr, r, na, a, nd, d) |
| 571 | |
| 572 | #endif /* _CORECRYPTO_CCN_H_ */ |
| 573 | |