Change compiler flag definition place to fix ASAN build break on ARM
[platform/upstream/nettle.git] / macros.h
1 /* macros.h
2  *
3  */
4
5 /* nettle, low-level cryptographics library
6  *
7  * Copyright (C) 2001, 2010 Niels Möller
8  *  
9  * The nettle library is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or (at your
12  * option) any later version.
13  * 
14  * The nettle library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17  * License for more details.
18  * 
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with the nettle library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22  * MA 02111-1301, USA.
23  */
24
25 #ifndef NETTLE_MACROS_H_INCLUDED
26 #define NETTLE_MACROS_H_INCLUDED
27
28 /* Reads a 64-bit integer, in network, big-endian, byte order */
29 #define READ_UINT64(p)                          \
30 (  (((uint64_t) (p)[0]) << 56)                  \
31  | (((uint64_t) (p)[1]) << 48)                  \
32  | (((uint64_t) (p)[2]) << 40)                  \
33  | (((uint64_t) (p)[3]) << 32)                  \
34  | (((uint64_t) (p)[4]) << 24)                  \
35  | (((uint64_t) (p)[5]) << 16)                  \
36  | (((uint64_t) (p)[6]) << 8)                   \
37  |  ((uint64_t) (p)[7]))
38
39 #define WRITE_UINT64(p, i)                      \
40 do {                                            \
41   (p)[0] = ((i) >> 56) & 0xff;                  \
42   (p)[1] = ((i) >> 48) & 0xff;                  \
43   (p)[2] = ((i) >> 40) & 0xff;                  \
44   (p)[3] = ((i) >> 32) & 0xff;                  \
45   (p)[4] = ((i) >> 24) & 0xff;                  \
46   (p)[5] = ((i) >> 16) & 0xff;                  \
47   (p)[6] = ((i) >> 8) & 0xff;                   \
48   (p)[7] = (i) & 0xff;                          \
49 } while(0)
50
51 /* Reads a 32-bit integer, in network, big-endian, byte order */
52 #define READ_UINT32(p)                          \
53 (  (((uint32_t) (p)[0]) << 24)                  \
54  | (((uint32_t) (p)[1]) << 16)                  \
55  | (((uint32_t) (p)[2]) << 8)                   \
56  |  ((uint32_t) (p)[3]))
57
58 #define WRITE_UINT32(p, i)                      \
59 do {                                            \
60   (p)[0] = ((i) >> 24) & 0xff;                  \
61   (p)[1] = ((i) >> 16) & 0xff;                  \
62   (p)[2] = ((i) >> 8) & 0xff;                   \
63   (p)[3] = (i) & 0xff;                          \
64 } while(0)
65
66 /* Analogous macros, for 24 and 16 bit numbers */
67 #define READ_UINT24(p)                          \
68 (  (((uint32_t) (p)[0]) << 16)                  \
69  | (((uint32_t) (p)[1]) << 8)                   \
70  |  ((uint32_t) (p)[2]))
71
72 #define WRITE_UINT24(p, i)                      \
73 do {                                            \
74   (p)[0] = ((i) >> 16) & 0xff;                  \
75   (p)[1] = ((i) >> 8) & 0xff;                   \
76   (p)[2] = (i) & 0xff;                          \
77 } while(0)
78
79 #define READ_UINT16(p)                          \
80 (  (((uint32_t) (p)[0]) << 8)                   \
81  |  ((uint32_t) (p)[1]))
82
83 #define WRITE_UINT16(p, i)                      \
84 do {                                            \
85   (p)[0] = ((i) >> 8) & 0xff;                   \
86   (p)[1] = (i) & 0xff;                          \
87 } while(0)
88
89 /* And the other, little-endian, byteorder */
90 #define LE_READ_UINT64(p)                       \
91 (  (((uint64_t) (p)[7]) << 56)                  \
92  | (((uint64_t) (p)[6]) << 48)                  \
93  | (((uint64_t) (p)[5]) << 40)                  \
94  | (((uint64_t) (p)[4]) << 32)                  \
95  | (((uint64_t) (p)[3]) << 24)                  \
96  | (((uint64_t) (p)[2]) << 16)                  \
97  | (((uint64_t) (p)[1]) << 8)                   \
98  |  ((uint64_t) (p)[0]))
99
100 #define LE_WRITE_UINT64(p, i)                   \
101 do {                                            \
102   (p)[7] = ((i) >> 56) & 0xff;                  \
103   (p)[6] = ((i) >> 48) & 0xff;                  \
104   (p)[5] = ((i) >> 40) & 0xff;                  \
105   (p)[4] = ((i) >> 32) & 0xff;                  \
106   (p)[3] = ((i) >> 24) & 0xff;                  \
107   (p)[2] = ((i) >> 16) & 0xff;                  \
108   (p)[1] = ((i) >> 8) & 0xff;                   \
109   (p)[0] = (i) & 0xff;                          \
110 } while (0)
111     
112 #define LE_READ_UINT32(p)                       \
113 (  (((uint32_t) (p)[3]) << 24)                  \
114  | (((uint32_t) (p)[2]) << 16)                  \
115  | (((uint32_t) (p)[1]) << 8)                   \
116  |  ((uint32_t) (p)[0]))
117
118 #define LE_WRITE_UINT32(p, i)                   \
119 do {                                            \
120   (p)[3] = ((i) >> 24) & 0xff;                  \
121   (p)[2] = ((i) >> 16) & 0xff;                  \
122   (p)[1] = ((i) >> 8) & 0xff;                   \
123   (p)[0] = (i) & 0xff;                          \
124 } while(0)
125
126 /* Analogous macros, for 16 bit numbers */
127 #define LE_READ_UINT16(p)                       \
128   (  (((uint32_t) (p)[1]) << 8)                 \
129      |  ((uint32_t) (p)[0]))
130
131 #define LE_WRITE_UINT16(p, i)                   \
132   do {                                          \
133     (p)[1] = ((i) >> 8) & 0xff;                 \
134     (p)[0] = (i) & 0xff;                        \
135   } while(0)
136
137 /* Macro to make it easier to loop over several blocks. */
138 #define FOR_BLOCKS(length, dst, src, blocksize) \
139   assert( !((length) % (blocksize)));           \
140   for (; (length); ((length) -= (blocksize),    \
141                   (dst) += (blocksize),         \
142                   (src) += (blocksize)) )
143
144 #define ROTL32(n,x) (((x)<<(n)) | ((x)>>(32-(n))))
145
146 #define ROTL64(n,x) (((x)<<(n)) | ((x)>>(64-(n))))
147
148 /* Requires that size > 0 */
149 #define INCREMENT(size, ctr)                    \
150   do {                                          \
151     unsigned increment_i = (size) - 1;          \
152     if (++(ctr)[increment_i] == 0)              \
153       while (increment_i > 0                    \
154              && ++(ctr)[--increment_i] == 0 )   \
155         ;                                       \
156   } while (0)
157
158
159 /* Helper macro for Merkle-Damgård hash functions. Assumes the context
160    structs includes the following fields:
161
162      xxx count_low, count_high;         // Two word block count
163      uint8_t block[...];                // Buffer holding one block
164      unsigned int index;                // Index into block
165 */
166
167 /* FIXME: Should probably switch to using uint64_t for the count, but
168    due to alignment and byte order that may be an ABI change. */
169
170 #define MD_INCR(ctx) ((ctx)->count_high += !++(ctx)->count_low)
171
172 /* Takes the compression function f as argument. NOTE: also clobbers
173    length and data. */
174 #define MD_UPDATE(ctx, length, data, f, incr)                           \
175   do {                                                                  \
176     if ((ctx)->index)                                                   \
177       {                                                                 \
178         /* Try to fill partial block */                                 \
179         unsigned __md_left = sizeof((ctx)->block) - (ctx)->index;       \
180         if ((length) < __md_left)                                       \
181           {                                                             \
182             memcpy((ctx)->block + (ctx)->index, (data), (length));      \
183             (ctx)->index += (length);                                   \
184             goto __md_done; /* Finished */                              \
185           }                                                             \
186         else                                                            \
187           {                                                             \
188             memcpy((ctx)->block + (ctx)->index, (data), __md_left);     \
189                                                                         \
190             f((ctx), (ctx)->block);                                     \
191             (incr);                                                     \
192                                                                         \
193             (data) += __md_left;                                        \
194             (length) -= __md_left;                                      \
195           }                                                             \
196       }                                                                 \
197     while ((length) >= sizeof((ctx)->block))                            \
198       {                                                                 \
199         f((ctx), (data));                                               \
200         (incr);                                                         \
201                                                                         \
202         (data) += sizeof((ctx)->block);                                 \
203         (length) -= sizeof((ctx)->block);                               \
204       }                                                                 \
205     memcpy ((ctx)->block, (data), (length));                            \
206     (ctx)->index = (length);                                            \
207   __md_done:                                                            \
208     ;                                                                   \
209   } while (0)
210
211 /* Pads the block to a block boundary with the bit pattern 1 0*,
212    leaving size octets for the length field at the end. If needed,
213    compresses the block and starts a new one. */
214 #define MD_PAD(ctx, size, f)                                            \
215   do {                                                                  \
216     unsigned __md_i;                                                    \
217     __md_i = (ctx)->index;                                              \
218                                                                         \
219     /* Set the first char of padding to 0x80. This is safe since there  \
220        is always at least one byte free */                              \
221                                                                         \
222     assert(__md_i < sizeof((ctx)->block));                                      \
223     (ctx)->block[__md_i++] = 0x80;                                              \
224                                                                         \
225     if (__md_i > (sizeof((ctx)->block) - 2*sizeof((ctx)->count_low)))   \
226       { /* No room for length in this block. Process it and             \
227            pad with another one */                                      \
228         memset((ctx)->block + __md_i, 0, sizeof((ctx)->block) - __md_i); \
229                                                                         \
230         f((ctx), (ctx)->block);                                         \
231         __md_i = 0;                                                     \
232       }                                                                 \
233     memset((ctx)->block + __md_i, 0,                                    \
234            sizeof((ctx)->block) - (size) - __md_i);                     \
235                                                                         \
236   } while (0)
237
238 #endif /* NETTLE_MACROS_H_INCLUDED */