3 Copyright (C) 2001, 2010 Niels Möller
5 This file is part of GNU Nettle.
7 GNU Nettle is free software: you can redistribute it and/or
8 modify it under the terms of either:
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.
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.
20 or both in parallel, as here.
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.
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/.
32 #ifndef NETTLE_MACROS_H_INCLUDED
33 #define NETTLE_MACROS_H_INCLUDED
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]))
46 #define WRITE_UINT64(p, i) \
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; \
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]))
65 #define WRITE_UINT32(p, i) \
67 (p)[0] = ((i) >> 24) & 0xff; \
68 (p)[1] = ((i) >> 16) & 0xff; \
69 (p)[2] = ((i) >> 8) & 0xff; \
70 (p)[3] = (i) & 0xff; \
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]))
79 #define WRITE_UINT24(p, i) \
81 (p)[0] = ((i) >> 16) & 0xff; \
82 (p)[1] = ((i) >> 8) & 0xff; \
83 (p)[2] = (i) & 0xff; \
86 #define READ_UINT16(p) \
87 ( (((uint32_t) (p)[0]) << 8) \
88 | ((uint32_t) (p)[1]))
90 #define WRITE_UINT16(p, i) \
92 (p)[0] = ((i) >> 8) & 0xff; \
93 (p)[1] = (i) & 0xff; \
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]))
107 #define LE_WRITE_UINT64(p, i) \
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; \
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]))
125 #define LE_WRITE_UINT32(p, i) \
127 (p)[3] = ((i) >> 24) & 0xff; \
128 (p)[2] = ((i) >> 16) & 0xff; \
129 (p)[1] = ((i) >> 8) & 0xff; \
130 (p)[0] = (i) & 0xff; \
133 /* Analogous macros, for 16 bit numbers */
134 #define LE_READ_UINT16(p) \
135 ( (((uint32_t) (p)[1]) << 8) \
136 | ((uint32_t) (p)[0]))
138 #define LE_WRITE_UINT16(p, i) \
140 (p)[1] = ((i) >> 8) & 0xff; \
141 (p)[0] = (i) & 0xff; \
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)) )
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))))
156 #define ROTL64(n,x) (((x)<<(n)) | ((x)>>((-(n))&63)))
158 /* Requires that size > 0 */
159 #define INCREMENT(size, ctr) \
161 unsigned increment_i = (size) - 1; \
162 if (++(ctr)[increment_i] == 0) \
163 while (increment_i > 0 \
164 && ++(ctr)[--increment_i] == 0 ) \
169 /* Helper macro for Merkle-Damgård hash functions. Assumes the context
170 structs includes the following fields:
172 uint8_t block[...]; // Buffer holding one block
173 unsigned int index; // Index into block
176 /* Currently used by sha512 (and sha384) only. */
177 #define MD_INCR(ctx) ((ctx)->count_high += !++(ctx)->count_low)
179 /* Takes the compression function f as argument. NOTE: also clobbers
181 #define MD_UPDATE(ctx, length, data, f, incr) \
185 /* Try to fill partial block */ \
186 unsigned __md_left = sizeof((ctx)->block) - (ctx)->index; \
187 if ((length) < __md_left) \
189 memcpy((ctx)->block + (ctx)->index, (data), (length)); \
190 (ctx)->index += (length); \
191 goto __md_done; /* Finished */ \
195 memcpy((ctx)->block + (ctx)->index, (data), __md_left); \
197 f((ctx), (ctx)->block); \
200 (data) += __md_left; \
201 (length) -= __md_left; \
204 while ((length) >= sizeof((ctx)->block)) \
209 (data) += sizeof((ctx)->block); \
210 (length) -= sizeof((ctx)->block); \
212 memcpy ((ctx)->block, (data), (length)); \
213 (ctx)->index = (length); \
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) \
224 __md_i = (ctx)->index; \
226 /* Set the first char of padding to 0x80. This is safe since there \
227 is always at least one byte free */ \
229 assert(__md_i < sizeof((ctx)->block)); \
230 (ctx)->block[__md_i++] = 0x80; \
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); \
237 f((ctx), (ctx)->block); \
240 memset((ctx)->block + __md_i, 0, \
241 sizeof((ctx)->block) - (size) - __md_i); \
245 #endif /* NETTLE_MACROS_H_INCLUDED */