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