d99da6df3539e7d147e892a379ec685445685250
[crypto.git] / lib / silccrypt / ciphers_def.h
1 /*
2
3   ciphers_def.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1999 - 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #ifndef CIPHERS_DEF_H
21 #define CIPHERS_DEF_H
22
23 /* General definitions for algorithms */
24 typedef unsigned char u1byte;
25 typedef SilcUInt32 u4byte;
26 typedef SilcUInt32 u32;
27 typedef SilcUInt32 uint_32t;
28 typedef SilcUInt8 uint_8t;
29
30 #define rotr(x, nr) silc_ror(x, nr)
31 #define rotl(x, nr) silc_rol(x, nr)
32 #define byte(x, nr) ((x) >> (nr * 8) & 255)
33
34 /* Byte key to words */
35 #define SILC_GET_WORD_KEY(s, d, len)            \
36 do {                                            \
37   int _i;                                       \
38   for (_i = 0; _i < (len / 8) / 4; _i++)        \
39     SILC_GET32_LSB(d[_i], s + (_i * 4));        \
40 } while(0);
41
42 /* CBC mode 128-bit block, LSB, 32-bit block argument must be encrypted */
43
44 #define SILC_CBC_ENC_LSB_128_32(len, iv, block, src, dst, i, enc)       \
45 do {                                                                    \
46   SILC_ASSERT((len & (16 - 1)) == 0);                                   \
47   if (len & (16 - 1))                                                   \
48     return FALSE;                                                       \
49                                                                         \
50   SILC_GET32_LSB(block[0], &iv[0]);                                     \
51   SILC_GET32_LSB(block[1], &iv[4]);                                     \
52   SILC_GET32_LSB(block[2], &iv[8]);                                     \
53   SILC_GET32_LSB(block[3], &iv[12]);                                    \
54                                                                         \
55   for (i = 0; i < len; i += 16) {                                       \
56     SILC_GET32_X_LSB(block[0], &src[0]);                                \
57     SILC_GET32_X_LSB(block[1], &src[4]);                                \
58     SILC_GET32_X_LSB(block[2], &src[8]);                                \
59     SILC_GET32_X_LSB(block[3], &src[12]);                               \
60                                                                         \
61     enc;                                                                \
62                                                                         \
63     SILC_PUT32_LSB(block[0], &dst[0]);                                  \
64     SILC_PUT32_LSB(block[1], &dst[4]);                                  \
65     SILC_PUT32_LSB(block[2], &dst[8]);                                  \
66     SILC_PUT32_LSB(block[3], &dst[12]);                                 \
67                                                                         \
68     dst += 16;                                                          \
69     src += 16;                                                          \
70   }                                                                     \
71                                                                         \
72   SILC_PUT32_LSB(block[0], &iv[0]);                                     \
73   SILC_PUT32_LSB(block[1], &iv[4]);                                     \
74   SILC_PUT32_LSB(block[2], &iv[8]);                                     \
75   SILC_PUT32_LSB(block[3], &iv[12]);                                    \
76 } while(0)
77
78 /* CBC mode 128-bit block, LSB, decrypt block to block_dec. */
79
80 #define SILC_CBC_DEC_LSB_128_32(len, iv, block_prev, block,             \
81                                 block_dec, src, dst, i, dec)            \
82 do {                                                                    \
83   if (!len || len & (16 - 1))                                           \
84     return FALSE;                                                       \
85                                                                         \
86   SILC_GET32_LSB(block_prev[0], &iv[0]);                                \
87   SILC_GET32_LSB(block_prev[1], &iv[4]);                                \
88   SILC_GET32_LSB(block_prev[2], &iv[8]);                                \
89   SILC_GET32_LSB(block_prev[3], &iv[12]);                               \
90                                                                         \
91   for (i = 0; i < len; i += 16) {                                       \
92     SILC_GET32_LSB(block[0], &src[0]);                                  \
93     SILC_GET32_LSB(block[1], &src[4]);                                  \
94     SILC_GET32_LSB(block[2], &src[8]);                                  \
95     SILC_GET32_LSB(block[3], &src[12]);                                 \
96                                                                         \
97     dec;                                                                \
98                                                                         \
99     block_dec[0] ^= block_prev[0];                                      \
100     block_dec[1] ^= block_prev[1];                                      \
101     block_dec[2] ^= block_prev[2];                                      \
102     block_dec[3] ^= block_prev[3];                                      \
103                                                                         \
104     SILC_PUT32_LSB(block_dec[0], &dst[0]);                              \
105     SILC_PUT32_LSB(block_dec[1], &dst[4]);                              \
106     SILC_PUT32_LSB(block_dec[2], &dst[8]);                              \
107     SILC_PUT32_LSB(block_dec[3], &dst[12]);                             \
108                                                                         \
109     block_prev[0] = block[0];                                           \
110     block_prev[1] = block[1];                                           \
111     block_prev[2] = block[2];                                           \
112     block_prev[3] = block[3];                                           \
113                                                                         \
114     dst += 16;                                                          \
115     src += 16;                                                          \
116   }                                                                     \
117                                                                         \
118   SILC_PUT32_LSB(block[0], &iv[0]);                                     \
119   SILC_PUT32_LSB(block[1], &iv[4]);                                     \
120   SILC_PUT32_LSB(block[2], &iv[8]);                                     \
121   SILC_PUT32_LSB(block[3], &iv[12]);                                    \
122 } while(0)
123
124 /* CBC mode 128-bit block, MSB, 32-bit block argument must be encrypted */
125
126 #define SILC_CBC_ENC_MSB_128_32(len, iv, block, src, dst, i, enc)       \
127 do {                                                                    \
128   SILC_ASSERT((len & (16 - 1)) == 0);                                   \
129   if (len & (16 - 1))                                                   \
130     return FALSE;                                                       \
131                                                                         \
132   SILC_GET32_MSB(block[0], &iv[0]);                                     \
133   SILC_GET32_MSB(block[1], &iv[4]);                                     \
134   SILC_GET32_MSB(block[2], &iv[8]);                                     \
135   SILC_GET32_MSB(block[3], &iv[12]);                                    \
136                                                                         \
137   for (i = 0; i < len; i += 16) {                                       \
138     SILC_GET32_X_MSB(block[0], &src[0]);                                \
139     SILC_GET32_X_MSB(block[1], &src[4]);                                \
140     SILC_GET32_X_MSB(block[2], &src[8]);                                \
141     SILC_GET32_X_MSB(block[3], &src[12]);                               \
142                                                                         \
143     enc;                                                                \
144                                                                         \
145     SILC_PUT32_MSB(block[0], &dst[0]);                                  \
146     SILC_PUT32_MSB(block[1], &dst[4]);                                  \
147     SILC_PUT32_MSB(block[2], &dst[8]);                                  \
148     SILC_PUT32_MSB(block[3], &dst[12]);                                 \
149                                                                         \
150     dst += 16;                                                          \
151     src += 16;                                                          \
152   }                                                                     \
153                                                                         \
154   SILC_PUT32_MSB(block[0], &iv[0]);                                     \
155   SILC_PUT32_MSB(block[1], &iv[4]);                                     \
156   SILC_PUT32_MSB(block[2], &iv[8]);                                     \
157   SILC_PUT32_MSB(block[3], &iv[12]);                                    \
158 } while(0)
159
160 /* CBC mode 128-bit block, MSB, decrypt block to block_dec. */
161
162 #define SILC_CBC_DEC_MSB_128_32(len, iv, block_prev, block,             \
163                                 block_dec, src, dst, i, dec)            \
164 do {                                                                    \
165   if (!len || len & (16 - 1))                                           \
166     return FALSE;                                                       \
167                                                                         \
168   SILC_GET32_MSB(block_prev[0], &iv[0]);                                \
169   SILC_GET32_MSB(block_prev[1], &iv[4]);                                \
170   SILC_GET32_MSB(block_prev[2], &iv[8]);                                \
171   SILC_GET32_MSB(block_prev[3], &iv[12]);                               \
172                                                                         \
173   for (i = 0; i < len; i += 16) {                                       \
174     SILC_GET32_MSB(block[0], &src[0]);                                  \
175     SILC_GET32_MSB(block[1], &src[4]);                                  \
176     SILC_GET32_MSB(block[2], &src[8]);                                  \
177     SILC_GET32_MSB(block[3], &src[12]);                                 \
178                                                                         \
179     dec;                                                                \
180                                                                         \
181     block_dec[0] ^= block_prev[0];                                      \
182     block_dec[1] ^= block_prev[1];                                      \
183     block_dec[2] ^= block_prev[2];                                      \
184     block_dec[3] ^= block_prev[3];                                      \
185                                                                         \
186     SILC_PUT32_MSB(block_dec[0], &dst[0]);                              \
187     SILC_PUT32_MSB(block_dec[1], &dst[4]);                              \
188     SILC_PUT32_MSB(block_dec[2], &dst[8]);                              \
189     SILC_PUT32_MSB(block_dec[3], &dst[12]);                             \
190                                                                         \
191     block_prev[0] = block[0];                                           \
192     block_prev[1] = block[1];                                           \
193     block_prev[2] = block[2];                                           \
194     block_prev[3] = block[3];                                           \
195                                                                         \
196     dst += 16;                                                          \
197     src += 16;                                                          \
198   }                                                                     \
199                                                                         \
200   SILC_PUT32_MSB(block[0], &iv[0]);                                     \
201   SILC_PUT32_MSB(block[1], &iv[4]);                                     \
202   SILC_PUT32_MSB(block[2], &iv[8]);                                     \
203   SILC_PUT32_MSB(block[3], &iv[12]);                                    \
204 } while(0)
205
206 /* CBC mode 64-bit block, MSB, 32-bit block argument must be encrypted */
207
208 #define SILC_CBC_ENC_MSB_64_32(len, iv, block, src, dst, i, enc)        \
209 do {                                                                    \
210   SILC_ASSERT((len & (8 - 1)) == 0);                                    \
211   if (len & (8 - 1))                                                    \
212     return FALSE;                                                       \
213                                                                         \
214   SILC_GET32_MSB(block[0], &iv[0]);                                     \
215   SILC_GET32_MSB(block[1], &iv[4]);                                     \
216                                                                         \
217   for (i = 0; i < len; i += 8) {                                        \
218     SILC_GET32_X_MSB(block[0], &src[0]);                                \
219     SILC_GET32_X_MSB(block[1], &src[4]);                                \
220                                                                         \
221     enc;                                                                \
222                                                                         \
223     SILC_PUT32_MSB(block[0], &dst[0]);                                  \
224     SILC_PUT32_MSB(block[1], &dst[4]);                                  \
225                                                                         \
226     dst += 8;                                                           \
227     src += 8;                                                           \
228   }                                                                     \
229                                                                         \
230   SILC_PUT32_MSB(block[0], &iv[0]);                                     \
231   SILC_PUT32_MSB(block[1], &iv[4]);                                     \
232 } while(0)
233
234 /* CBC mode 64-bit block, MSB, decrypt block to block_dec. */
235
236 #define SILC_CBC_DEC_MSB_64_32(len, iv, block_prev, block,              \
237                                block_dec, src, dst, i, dec)             \
238 do {                                                                    \
239   if (!len || len & (8 - 1))                                            \
240     return FALSE;                                                       \
241                                                                         \
242   SILC_GET32_MSB(block_prev[0], &iv[0]);                                \
243   SILC_GET32_MSB(block_prev[1], &iv[4]);                                \
244                                                                         \
245   for (i = 0; i < len; i += 8) {                                        \
246     SILC_GET32_MSB(block[0], &src[0]);                                  \
247     SILC_GET32_MSB(block[1], &src[4]);                                  \
248                                                                         \
249     dec;                                                                \
250                                                                         \
251     block_dec[0] ^= block_prev[0];                                      \
252     block_dec[1] ^= block_prev[1];                                      \
253                                                                         \
254     SILC_PUT32_MSB(block_dec[0], &dst[0]);                              \
255     SILC_PUT32_MSB(block_dec[1], &dst[4]);                              \
256                                                                         \
257     block_prev[0] = block[0];                                           \
258     block_prev[1] = block[1];                                           \
259                                                                         \
260     dst += 8;                                                           \
261     src += 8;                                                           \
262   }                                                                     \
263                                                                         \
264   SILC_PUT32_MSB(block[0], &iv[0]);                                     \
265   SILC_PUT32_MSB(block[1], &iv[4]);                                     \
266 } while(0)
267
268
269 /* CTR mode 128-bit block, MSB, MSB counter, the 8-bit enc_ctr argument must
270    be encrypted */
271
272 #define SILC_CTR_MSB_128_8(iv, ctr, enc_ctr, pad, src, dst, enc)        \
273 do {                                                                    \
274   SILC_GET32_MSB(ctr[0], iv);                                           \
275   SILC_GET32_MSB(ctr[1], iv + 4);                                       \
276   SILC_GET32_MSB(ctr[2], iv + 8);                                       \
277   SILC_GET32_MSB(ctr[3], iv + 12);                                      \
278                                                                         \
279   if (pad == 0)                                                         \
280     pad = 16;                                                           \
281                                                                         \
282   while (len-- > 0) {                                                   \
283     if (pad == 16) {                                                    \
284       if (++ctr[3] == 0)                                                \
285         if (++ctr[2] == 0)                                              \
286           if (++ctr[1] == 0)                                            \
287             ++ctr[0];                                                   \
288                                                                         \
289       SILC_PUT32_MSB(ctr[0], enc_ctr);                                  \
290       SILC_PUT32_MSB(ctr[1], enc_ctr + 4);                              \
291       SILC_PUT32_MSB(ctr[2], enc_ctr + 8);                              \
292       SILC_PUT32_MSB(ctr[3], enc_ctr + 12);                             \
293                                                                         \
294       enc;                                                              \
295       pad = 0;                                                          \
296     }                                                                   \
297     *dst++ = *src++ ^ enc_ctr[pad++];                                   \
298   }                                                                     \
299                                                                         \
300   SILC_PUT32_MSB(ctr[0], iv);                                           \
301   SILC_PUT32_MSB(ctr[1], iv + 4);                                       \
302   SILC_PUT32_MSB(ctr[2], iv + 8);                                       \
303   SILC_PUT32_MSB(ctr[3], iv + 12);                                      \
304 } while(0)
305
306 /* CTR mode 128-bit block, MSB, MSB counter, the 32-bit ctr argument must
307    be encrypted to enc_ctr */
308
309 #define SILC_CTR_MSB_128_32(iv, ctr, enc_ctr, pad, src, dst, enc)       \
310 do {                                                                    \
311   SILC_GET32_MSB(ctr[0], iv);                                           \
312   SILC_GET32_MSB(ctr[1], iv + 4);                                       \
313   SILC_GET32_MSB(ctr[2], iv + 8);                                       \
314   SILC_GET32_MSB(ctr[3], iv + 12);                                      \
315                                                                         \
316   if (pad == 0)                                                         \
317     pad = 16;                                                           \
318                                                                         \
319   while (len-- > 0) {                                                   \
320     if (pad == 16) {                                                    \
321       if (++ctr[3] == 0)                                                \
322         if (++ctr[2] == 0)                                              \
323           if (++ctr[1] == 0)                                            \
324             ++ctr[0];                                                   \
325                                                                         \
326       enc;                                                              \
327       SILC_PUT32_MSB(enc_ctr[0], iv);                                   \
328       SILC_PUT32_MSB(enc_ctr[1], iv + 4);                               \
329       SILC_PUT32_MSB(enc_ctr[2], iv + 8);                               \
330       SILC_PUT32_MSB(enc_ctr[3], iv + 12);                              \
331       pad = 0;                                                          \
332     }                                                                   \
333     *dst++ = *src++ ^ enc_ctr[pad++];                                   \
334   }                                                                     \
335                                                                         \
336   SILC_PUT32_MSB(ctr[0], iv);                                           \
337   SILC_PUT32_MSB(ctr[1], iv + 4);                                       \
338   SILC_PUT32_MSB(ctr[2], iv + 8);                                       \
339   SILC_PUT32_MSB(ctr[3], iv + 12);                                      \
340 } while(0)
341
342 /* CTR mode 128-bit block, LSB, MSB counter, the 32-bit enc_ctr argument
343    must be encrypted */
344
345 #define SILC_CTR_LSB_128_32(iv, ctr, enc_ctr, pad, src, dst, enc)       \
346 do {                                                                    \
347   SILC_GET32_MSB(ctr[0], iv);                                           \
348   SILC_GET32_MSB(ctr[1], iv + 4);                                       \
349   SILC_GET32_MSB(ctr[2], iv + 8);                                       \
350   SILC_GET32_MSB(ctr[3], iv + 12);                                      \
351                                                                         \
352   if (pad == 0)                                                         \
353     pad = 16;                                                           \
354                                                                         \
355   while (len-- > 0) {                                                   \
356     if (pad == 16) {                                                    \
357       if (++ctr[3] == 0)                                                \
358         if (++ctr[2] == 0)                                              \
359           if (++ctr[1] == 0)                                            \
360             ++ctr[0];                                                   \
361                                                                         \
362       enc_ctr[0] = SILC_SWAB_32(ctr[0]);                                \
363       enc_ctr[1] = SILC_SWAB_32(ctr[1]);                                \
364       enc_ctr[2] = SILC_SWAB_32(ctr[2]);                                \
365       enc_ctr[3] = SILC_SWAB_32(ctr[3]);                                \
366                                                                         \
367       enc;                                                              \
368       SILC_PUT32_LSB(enc_ctr[0], iv);                                   \
369       SILC_PUT32_LSB(enc_ctr[1], iv + 4);                               \
370       SILC_PUT32_LSB(enc_ctr[2], iv + 8);                               \
371       SILC_PUT32_LSB(enc_ctr[3], iv + 12);                              \
372       pad = 0;                                                          \
373     }                                                                   \
374     *dst++ = *src++ ^ iv[pad++];                                        \
375   }                                                                     \
376                                                                         \
377   SILC_PUT32_MSB(ctr[0], iv);                                           \
378   SILC_PUT32_MSB(ctr[1], iv + 4);                                       \
379   SILC_PUT32_MSB(ctr[2], iv + 8);                                       \
380   SILC_PUT32_MSB(ctr[3], iv + 12);                                      \
381 } while(0)
382
383 /* CTR mode 64-bit block, MSB, MSB counter, the 32-bit ctr argument must
384    be encrypted to enc_ctr */
385
386 #define SILC_CTR_MSB_64_32(iv, ctr, enc_ctr, pad, src, dst, enc)        \
387 do {                                                                    \
388   SILC_GET32_MSB(ctr[0], iv);                                           \
389   SILC_GET32_MSB(ctr[1], iv + 4);                                       \
390                                                                         \
391   if (pad == 0)                                                         \
392     pad = 8;                                                            \
393                                                                         \
394   while (len-- > 0) {                                                   \
395     if (pad == 8) {                                                     \
396       if (++ctr[1] == 0)                                                \
397         ++ctr[0];                                                       \
398                                                                         \
399       enc;                                                              \
400       SILC_PUT32_MSB(enc_ctr[0], iv);                                   \
401       SILC_PUT32_MSB(enc_ctr[1], iv + 4);                               \
402       pad = 0;                                                          \
403     }                                                                   \
404     *dst++ = *src++ ^ iv[pad++];                                        \
405   }                                                                     \
406                                                                         \
407   SILC_PUT32_MSB(ctr[0], iv);                                           \
408   SILC_PUT32_MSB(ctr[1], iv + 4);                                       \
409 } while(0)
410
411 /* CFB 128-bit block, LSB, the 32-bit cfb argument must be encrypted. */
412
413 #define SILC_CFB_ENC_LSB_128_32(iv, cfb, pad, src, dst, enc)            \
414 do {                                                                    \
415   while (len-- > 0) {                                                   \
416     if (pad == 16) {                                                    \
417       SILC_GET32_LSB(cfb[0], iv);                                       \
418       SILC_GET32_LSB(cfb[1], iv + 4);                                   \
419       SILC_GET32_LSB(cfb[2], iv + 8);                                   \
420       SILC_GET32_LSB(cfb[3], iv + 12);                                  \
421                                                                         \
422       enc;                                                              \
423                                                                         \
424       SILC_PUT32_LSB(cfb[0], iv);                                       \
425       SILC_PUT32_LSB(cfb[1], iv + 4);                                   \
426       SILC_PUT32_LSB(cfb[2], iv + 8);                                   \
427       SILC_PUT32_LSB(cfb[3], iv + 12);                                  \
428       pad = 0;                                                          \
429     }                                                                   \
430     iv[pad] = (*dst = *src ^ iv[pad]);                                  \
431     dst++;                                                              \
432     src++;                                                              \
433     pad++;                                                              \
434   }                                                                     \
435 } while(0)
436
437 /* CFB 128-bit block, LSB, the 32-bit cfb argument must be decrypted. */
438
439 #define SILC_CFB_DEC_LSB_128_32(iv, cfb, pad, src, dst, dec)            \
440 do {                                                                    \
441   unsigned char temp;                                                   \
442   while (len-- > 0) {                                                   \
443     if (pad == 16) {                                                    \
444       SILC_GET32_LSB(cfb[0], iv);                                       \
445       SILC_GET32_LSB(cfb[1], iv + 4);                                   \
446       SILC_GET32_LSB(cfb[2], iv + 8);                                   \
447       SILC_GET32_LSB(cfb[3], iv + 12);                                  \
448                                                                         \
449       dec;                                                              \
450                                                                         \
451       SILC_PUT32_LSB(cfb[0], iv);                                       \
452       SILC_PUT32_LSB(cfb[1], iv + 4);                                   \
453       SILC_PUT32_LSB(cfb[2], iv + 8);                                   \
454       SILC_PUT32_LSB(cfb[3], iv + 12);                                  \
455       pad = 0;                                                          \
456     }                                                                   \
457     temp = *src;                                                        \
458     *dst = temp ^ iv[pad];                                              \
459     iv[pad++] = temp;                                                   \
460     dst++;                                                              \
461     src++;                                                              \
462   }                                                                     \
463 } while(0)
464
465 /* CFB 128-bit block, MSB, the 32-bit cfb argument must be encrypted. */
466
467 #define SILC_CFB_ENC_MSB_128_32(iv, cfb, pad, src, dst, enc)            \
468 do {                                                                    \
469   while (len-- > 0) {                                                   \
470     if (pad == 16) {                                                    \
471       SILC_GET32_MSB(cfb[0], iv);                                       \
472       SILC_GET32_MSB(cfb[1], iv + 4);                                   \
473       SILC_GET32_MSB(cfb[2], iv + 8);                                   \
474       SILC_GET32_MSB(cfb[3], iv + 12);                                  \
475                                                                         \
476       enc;                                                              \
477                                                                         \
478       SILC_PUT32_MSB(cfb[0], iv);                                       \
479       SILC_PUT32_MSB(cfb[1], iv + 4);                                   \
480       SILC_PUT32_MSB(cfb[2], iv + 8);                                   \
481       SILC_PUT32_MSB(cfb[3], iv + 12);                                  \
482       pad = 0;                                                          \
483     }                                                                   \
484     iv[pad] = (*dst = *src ^ iv[pad]);                                  \
485     dst++;                                                              \
486     src++;                                                              \
487     pad++;                                                              \
488   }                                                                     \
489 } while(0)
490
491 /* CFB 128-bit block, MSB, the 32-bit cfb argument must be decrypted. */
492
493 #define SILC_CFB_DEC_MSB_128_32(iv, cfb, pad, src, dst, dec)            \
494 do {                                                                    \
495   unsigned char temp;                                                   \
496   while (len-- > 0) {                                                   \
497     if (pad == 16) {                                                    \
498       SILC_GET32_MSB(cfb[0], iv);                                       \
499       SILC_GET32_MSB(cfb[1], iv + 4);                                   \
500       SILC_GET32_MSB(cfb[2], iv + 8);                                   \
501       SILC_GET32_MSB(cfb[3], iv + 12);                                  \
502                                                                         \
503       dec;                                                              \
504                                                                         \
505       SILC_PUT32_MSB(cfb[0], iv);                                       \
506       SILC_PUT32_MSB(cfb[1], iv + 4);                                   \
507       SILC_PUT32_MSB(cfb[2], iv + 8);                                   \
508       SILC_PUT32_MSB(cfb[3], iv + 12);                                  \
509       pad = 0;                                                          \
510     }                                                                   \
511     temp = *src;                                                        \
512     *dst = temp ^ iv[pad];                                              \
513     iv[pad++] = temp;                                                   \
514     dst++;                                                              \
515     src++;                                                              \
516   }                                                                     \
517 } while(0)
518
519 /* CFB 64-bit block, MSB, the 32-bit cfb argument must be encrypted. */
520
521 #define SILC_CFB_ENC_MSB_64_32(iv, cfb, pad, src, dst, enc)             \
522 do {                                                                    \
523   while (len-- > 0) {                                                   \
524     if (pad == 8) {                                                     \
525       SILC_GET32_MSB(cfb[0], iv);                                       \
526       SILC_GET32_MSB(cfb[1], iv + 4);                                   \
527                                                                         \
528       enc;                                                              \
529                                                                         \
530       SILC_PUT32_MSB(cfb[0], iv);                                       \
531       SILC_PUT32_MSB(cfb[1], iv + 4);                                   \
532       pad = 0;                                                          \
533     }                                                                   \
534     iv[pad] = (*dst = *src ^ iv[pad]);                                  \
535     dst++;                                                              \
536     src++;                                                              \
537     pad++;                                                              \
538   }                                                                     \
539 } while(0)
540
541 /* CFB 64-bit block, MSB, the 32-bit cfb argument must be decrypted. */
542
543 #define SILC_CFB_DEC_MSB_64_32(iv, cfb, pad, src, dst, dec)             \
544 do {                                                                    \
545   unsigned char temp;                                                   \
546   while (len-- > 0) {                                                   \
547     if (pad == 8) {                                                     \
548       SILC_GET32_MSB(cfb[0], iv);                                       \
549       SILC_GET32_MSB(cfb[1], iv + 4);                                   \
550                                                                         \
551       dec;                                                              \
552                                                                         \
553       SILC_PUT32_MSB(cfb[0], iv);                                       \
554       SILC_PUT32_MSB(cfb[1], iv + 4);                                   \
555       pad = 0;                                                          \
556     }                                                                   \
557     temp = *src;                                                        \
558     *dst = temp ^ iv[pad];                                              \
559     iv[pad++] = temp;                                                   \
560     dst++;                                                              \
561     src++;                                                              \
562   }                                                                     \
563 } while(0)
564
565 /* CFB 128-bit block, MSB, the 8-bit iv argument must be encrypted. */
566
567 #define SILC_CFB_ENC_MSB_128_8(iv, pad, src, dst, enc)                  \
568 do {                                                                    \
569   while (len-- > 0) {                                                   \
570     if (pad == 16) {                                                    \
571       enc;                                                              \
572       pad = 0;                                                          \
573     }                                                                   \
574     iv[pad] = (*dst = *src ^ iv[pad]);                                  \
575     dst++;                                                              \
576     src++;                                                              \
577     pad++;                                                              \
578   }                                                                     \
579 } while(0)
580
581 /* CFB 128-bit block, MSB, the 8-bit iv argument must be decrypted. */
582
583 #define SILC_CFB_DEC_MSB_128_8(iv, pad, src, dst, dec)                  \
584 do {                                                                    \
585   unsigned char temp;                                                   \
586   while (len-- > 0) {                                                   \
587     if (pad == 16) {                                                    \
588       dec;                                                              \
589       pad = 0;                                                          \
590     }                                                                   \
591     temp = *src;                                                        \
592     *dst = temp ^ iv[pad];                                              \
593     iv[pad++] = temp;                                                   \
594     dst++;                                                              \
595     src++;                                                              \
596   }                                                                     \
597 } while(0)
598
599 #endif