-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmisc.h
200 lines (166 loc) · 6.98 KB
/
misc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
* A bunch of helper macros and functions for internal use.
*/
#ifndef CRY_MISC_H_
#define CRY_MISC_H_
#include <stdint.h>
#include <stdarg.h>
/** Nop to prevent some warnings */
#define NOP do {} while (0)
#define CRY_UNUSED(v) (void)(v)
/** Statically get array number of elements */
#define CRY_ARRAY_LEN(ar) (sizeof(ar)/sizeof((ar)[0]))
/** Macro used to compute the minimum of two integral values. */
#define CRY_MIN(a, b) (((a) < (b)) ? (a) : (b))
/** Macro used to compute the maximum of two integral values. */
#define CRY_MAX(a, b) (((a) > (b)) ? (a) : (b))
/**
* Increments a big endian value of a give size.
* Used to directly increment a value within a buffer.
*/
#define CRY_INCREMENT_BE(val_ptr, val_size) do { \
size_t __i = (val_size) - 1; \
if (++(val_ptr)[__i] == 0) \
while (++(val_ptr)[--__i] == 0 && __i > 0); \
} while (0)
/** Architecture independent little endian 16 bit value write. */
#define CRY_WRITE16_LE(val, dst) do { \
((uint8_t *) (dst))[1] = (uint8_t) (((val) >> 8) & 0xff); \
((uint8_t *) (dst))[0] = (uint8_t) (((val) >> 0) & 0xff); \
} while (0)
/** Architecture independent big endian 16 bit value write. */
#define CRY_WRITE16_BE(val, dst) do { \
((uint8_t *) (dst))[0] = (uint8_t) (((val) >> 8) & 0xff); \
((uint8_t *) (dst))[1] = (uint8_t) (((val) >> 0) & 0xff); \
} while (0)
/** Architecture independent little endian 16 bit value read. */
#define CRY_READ16_LE(val, src) \
((val) = ((((uint16_t) (src)[1]) << 8) | \
(((uint16_t) (src)[0]) << 0)))
/** Architecture independent big endian 16 bit value read. */
#define CRY_READ16_BE(val, src) \
((val) = ((((uint16_t) (src)[0]) << 8) | \
(((uint16_t) (src)[1]) << 0)))
/** Architecture independent little endian 32 bit value write. */
#define CRY_WRITE32_LE(val, dst) do { \
((uint8_t *) (dst))[3] = (uint8_t) (((val) >> 24) & 0xff); \
((uint8_t *) (dst))[2] = (uint8_t) (((val) >> 16) & 0xff); \
((uint8_t *) (dst))[1] = (uint8_t) (((val) >> 8) & 0xff); \
((uint8_t *) (dst))[0] = (uint8_t) (((val) >> 0) & 0xff); \
} while (0)
/** Architecture independent big endian 32 bit value write. */
#define CRY_WRITE32_BE(val, dst) do { \
((uint8_t *) (dst))[0] = (uint8_t) (((val) >> 24) & 0xff); \
((uint8_t *) (dst))[1] = (uint8_t) (((val) >> 16) & 0xff); \
((uint8_t *) (dst))[2] = (uint8_t) (((val) >> 8) & 0xff); \
((uint8_t *) (dst))[3] = (uint8_t) (((val) >> 0) & 0xff); \
} while (0)
/** Architecture independent little endian 32 bit value read. */
#define CRY_READ32_LE(val, src) \
((val) = ((((uint32_t) (src)[3]) << 24) | \
(((uint32_t) (src)[2]) << 16) | \
(((uint32_t) (src)[1]) << 8) | \
(((uint32_t) (src)[0]) << 0)))
/** Architecture independent big endian 32 bit value read. */
#define CRY_READ32_BE(val, src) \
((val) = ((((uint32_t) (src)[0]) << 24) | \
(((uint32_t) (src)[1]) << 16) | \
(((uint32_t) (src)[2]) << 8) | \
(((uint32_t) (src)[3]) << 0)))
/** Architecture independent little endian 64 bit value write. */
#define CRY_WRITE64_LE(val, dst) do { \
((uint8_t *) (dst))[7] = (uint8_t) (((val) >> 56) & 0xff); \
((uint8_t *) (dst))[6] = (uint8_t) (((val) >> 48) & 0xff); \
((uint8_t *) (dst))[5] = (uint8_t) (((val) >> 40) & 0xff); \
((uint8_t *) (dst))[4] = (uint8_t) (((val) >> 32) & 0xff); \
((uint8_t *) (dst))[3] = (uint8_t) (((val) >> 24) & 0xff); \
((uint8_t *) (dst))[2] = (uint8_t) (((val) >> 16) & 0xff); \
((uint8_t *) (dst))[1] = (uint8_t) (((val) >> 8) & 0xff); \
((uint8_t *) (dst))[0] = (uint8_t) (((val) >> 0) & 0xff); \
} while (0)
/** Architecture independent big endian 64 bit value write. */
#define CRY_WRITE64_BE(val, dst) do { \
((uint8_t *) (dst))[0] = (uint8_t) (((val) >> 56) & 0xff); \
((uint8_t *) (dst))[1] = (uint8_t) (((val) >> 48) & 0xff); \
((uint8_t *) (dst))[2] = (uint8_t) (((val) >> 40) & 0xff); \
((uint8_t *) (dst))[3] = (uint8_t) (((val) >> 32) & 0xff); \
((uint8_t *) (dst))[4] = (uint8_t) (((val) >> 24) & 0xff); \
((uint8_t *) (dst))[5] = (uint8_t) (((val) >> 16) & 0xff); \
((uint8_t *) (dst))[6] = (uint8_t) (((val) >> 8) & 0xff); \
((uint8_t *) (dst))[7] = (uint8_t) (((val) >> 0) & 0xff); \
} while (0)
/** Architecture independent little endian 64 bit value read. */
#define CRY_READ64_LE(val, src) \
((val) = ((((uint64_t) (src)[7]) << 56) | \
(((uint64_t) (src)[6]) << 48) | \
(((uint64_t) (src)[5]) << 40) | \
(((uint64_t) (src)[4]) << 32) | \
(((uint64_t) (src)[3]) << 24) | \
(((uint64_t) (src)[2]) << 16) | \
(((uint64_t) (src)[1]) << 8) | \
(((uint64_t) (src)[0]) << 0)))
/** Architecture independent big endian 64 bit value read. */
#define CRY_READ64_BE(val, src) \
((val) = ((((uint64_t) (src)[0]) << 56) | \
(((uint64_t) (src)[1]) << 48) | \
(((uint64_t) (src)[2]) << 40) | \
(((uint64_t) (src)[3]) << 32) | \
(((uint64_t) (src)[4]) << 24) | \
(((uint64_t) (src)[5]) << 16) | \
(((uint64_t) (src)[6]) << 8) | \
(((uint64_t) (src)[7]) << 0)))
/** In-place swap macro */
#define CRY_SWAP(v1, v2) do { \
(v1) ^= (v2); \
(v2) ^= (v1); \
(v1) ^= (v2); \
} while (0)
/** Rotate the bits left */
#define CRY_ROTL(val, bits, size) \
((val) << bits | ((val) >> ((size) - (bits))))
/** Rotate the bits right */
#define CRY_ROTR(val, bits, size) \
((val) >> bits | ((val) << ((size) - (bits))))
#define CRY_ROTL32(val, bits) CRY_ROTL(val, bits, 32)
#define CRY_ROTR32(val, bits) CRY_ROTR(val, bits, 32)
#define CRY_ROTL64(val, bits) CRY_ROTL(val, bits, 64)
#define CRY_ROTR64(val, bits) CRY_ROTR(val, bits, 64)
/**
* Modular inverse using Euclid algorithm.
*
* @param val Value.
* @param mod Module.
* @return On success returns the positive modular inverse.
* If the value is not invertible returns 0.
*/
unsigned long cry_long_inv(unsigned long val, unsigned long mod);
/**
* Secure memset.
*
* Implementation that should never be optimized out by the compiler.
*
* @param dst Destination buffer pointer.
* @param val Constant filling value.
* @param len Destination buffer size.
*/
#define cry_memset(dst, val, len) do { \
volatile unsigned char *__p = (unsigned char*)(dst); \
size_t __n = (len); \
while (__n--) \
*__p++ = (val); \
} while (0)
/**
* Check CRY operation result.
* If not zero result jump to label.
*/
#define CRY_CHK(expr, label) do { \
if ((expr) != 0) \
goto label; \
} while (0)
typedef int (*cry_list_elem_init_f)(void *elem, ...);
typedef void (*cry_list_elem_clear_f)(void *elem, ...);
int cry_list_init(cry_list_elem_init_f init, cry_list_elem_clear_f clear,
void *first, va_list arg);
void cry_list_clear(cry_list_elem_clear_f clear,
void *first, va_list args);
#endif /* CRY_MISC_H_ */