5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1999 - 2008 Pekka Riikonen
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.
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.
26 /* General definitions for algorithms */
27 typedef unsigned char u1byte;
28 typedef SilcUInt32 u4byte;
29 typedef SilcUInt32 u32;
30 typedef SilcUInt32 uint_32t;
31 typedef SilcUInt8 uint_8t;
33 #define rotr(x, nr) silc_ror(x, nr)
34 #define rotl(x, nr) silc_rol(x, nr)
35 #define byte(x, nr) ((x) >> (nr * 8) & 255)
37 /* Byte key to words */
38 #define SILC_GET_WORD_KEY(s, d, len) \
41 for (_i = 0; _i < (len / 8) / 4; _i++) \
42 SILC_GET32_LSB(d[_i], s + (_i * 4)); \
45 /* CBC mode 128-bit block, LSB, 8-bit iv argument must be encrypted */
47 #ifndef WORDS_BIGENDIAN
50 #define SILC_CBC_ENC_MSB_128_8(len, iv, src, dst, i, enc) \
52 SILC_ASSERT((len & (16 - 1)) == 0); \
56 for (i = 0; i < len; i += 16) { \
57 *(SilcUInt64 *)iv ^= *(SilcUInt64 *)src; \
58 *(SilcUInt64 *)(iv + 8) ^= *(SilcUInt64 *)(src + 8); \
62 *(SilcUInt64 *)dst = *(SilcUInt64 *)iv; \
63 *(SilcUInt64 *)(dst + 8) = *(SilcUInt64 *)(iv + 8); \
69 #else /* !SILC_X86_64 */
71 #define SILC_CBC_ENC_MSB_128_8(len, iv, src, dst, i, enc) \
73 SILC_ASSERT((len & (16 - 1)) == 0); \
77 for (i = 0; i < len; i += 16) { \
78 *(SilcUInt32 *)iv ^= *(SilcUInt32 *)src; \
79 *(SilcUInt32 *)(iv + 4) ^= *(SilcUInt32 *)(src + 4); \
80 *(SilcUInt32 *)(iv + 8) ^= *(SilcUInt32 *)(src + 8); \
81 *(SilcUInt32 *)(iv + 12) ^= *(SilcUInt32 *)(src + 12); \
85 memcpy(dst, iv, 16); \
90 #endif /* SILC_X86_64 */
91 #else /* WORDS_BIGENDIAN */
92 /* big-endian machines */
93 #define SILC_CBC_ENC_MSB_128_8(len, iv, src, dst, i, enc) \
95 SilcUInt32 tmp[4], tmp2[4]; \
97 SILC_ASSERT((len & (16 - 1)) == 0); \
101 for (i = 0; i < len; i += 16) { \
102 SILC_GET32_MSB(tmp[0], &iv[0]); \
103 SILC_GET32_MSB(tmp[1], &iv[4]); \
104 SILC_GET32_MSB(tmp[2], &iv[8]); \
105 SILC_GET32_MSB(tmp[3], &iv[12]); \
107 SILC_GET32_MSB(tmp2[0], &src[0]); \
108 SILC_GET32_MSB(tmp2[1], &src[4]); \
109 SILC_GET32_MSB(tmp2[2], &src[8]); \
110 SILC_GET32_MSB(tmp2[3], &src[12]); \
112 tmp[0] = tmp[0] ^ tmp2[0]; \
113 tmp[1] = tmp[1] ^ tmp2[1]; \
114 tmp[2] = tmp[2] ^ tmp2[2]; \
115 tmp[3] = tmp[3] ^ tmp2[3]; \
117 SILC_PUT32_MSB(tmp[0], &iv[0]); \
118 SILC_PUT32_MSB(tmp[1], &iv[4]); \
119 SILC_PUT32_MSB(tmp[2], &iv[8]); \
120 SILC_PUT32_MSB(tmp[3], &iv[12]); \
124 memcpy(dst, iv, 16); \
129 #endif /* !WORDS_BIGENDIAN */
131 /* CBC mode 128-bit block, MSB, 32-bit block argument must be encrypted */
133 #define SILC_CBC_ENC_LSB_128_32(len, iv, block, src, dst, i, enc) \
135 SILC_ASSERT((len & (16 - 1)) == 0); \
136 if (len & (16 - 1)) \
139 SILC_GET32_LSB(block[0], &iv[0]); \
140 SILC_GET32_LSB(block[1], &iv[4]); \
141 SILC_GET32_LSB(block[2], &iv[8]); \
142 SILC_GET32_LSB(block[3], &iv[12]); \
144 for (i = 0; i < len; i += 16) { \
145 SILC_GET32_X_LSB(block[0], &src[0]); \
146 SILC_GET32_X_LSB(block[1], &src[4]); \
147 SILC_GET32_X_LSB(block[2], &src[8]); \
148 SILC_GET32_X_LSB(block[3], &src[12]); \
152 SILC_PUT32_LSB(block[0], &dst[0]); \
153 SILC_PUT32_LSB(block[1], &dst[4]); \
154 SILC_PUT32_LSB(block[2], &dst[8]); \
155 SILC_PUT32_LSB(block[3], &dst[12]); \
161 SILC_PUT32_LSB(block[0], &iv[0]); \
162 SILC_PUT32_LSB(block[1], &iv[4]); \
163 SILC_PUT32_LSB(block[2], &iv[8]); \
164 SILC_PUT32_LSB(block[3], &iv[12]); \
167 /* CBC mode 128-bit block, LSB, decrypt block to block_dec. */
169 #define SILC_CBC_DEC_LSB_128_32(len, iv, block_prev, block, \
170 block_dec, src, dst, i, dec) \
172 if (!len || len & (16 - 1)) \
175 SILC_GET32_LSB(block_prev[0], &iv[0]); \
176 SILC_GET32_LSB(block_prev[1], &iv[4]); \
177 SILC_GET32_LSB(block_prev[2], &iv[8]); \
178 SILC_GET32_LSB(block_prev[3], &iv[12]); \
180 for (i = 0; i < len; i += 16) { \
181 SILC_GET32_LSB(block[0], &src[0]); \
182 SILC_GET32_LSB(block[1], &src[4]); \
183 SILC_GET32_LSB(block[2], &src[8]); \
184 SILC_GET32_LSB(block[3], &src[12]); \
188 block_dec[0] ^= block_prev[0]; \
189 block_dec[1] ^= block_prev[1]; \
190 block_dec[2] ^= block_prev[2]; \
191 block_dec[3] ^= block_prev[3]; \
193 SILC_PUT32_LSB(block_dec[0], &dst[0]); \
194 SILC_PUT32_LSB(block_dec[1], &dst[4]); \
195 SILC_PUT32_LSB(block_dec[2], &dst[8]); \
196 SILC_PUT32_LSB(block_dec[3], &dst[12]); \
198 block_prev[0] = block[0]; \
199 block_prev[1] = block[1]; \
200 block_prev[2] = block[2]; \
201 block_prev[3] = block[3]; \
207 SILC_PUT32_LSB(block[0], &iv[0]); \
208 SILC_PUT32_LSB(block[1], &iv[4]); \
209 SILC_PUT32_LSB(block[2], &iv[8]); \
210 SILC_PUT32_LSB(block[3], &iv[12]); \
213 /* CBC mode 128-bit block, MSB, 32-bit block argument must be encrypted */
215 #define SILC_CBC_ENC_MSB_128_32(len, iv, block, src, dst, i, enc) \
217 SILC_ASSERT((len & (16 - 1)) == 0); \
218 if (len & (16 - 1)) \
221 SILC_GET32_MSB(block[0], &iv[0]); \
222 SILC_GET32_MSB(block[1], &iv[4]); \
223 SILC_GET32_MSB(block[2], &iv[8]); \
224 SILC_GET32_MSB(block[3], &iv[12]); \
226 for (i = 0; i < len; i += 16) { \
227 SILC_GET32_X_MSB(block[0], &src[0]); \
228 SILC_GET32_X_MSB(block[1], &src[4]); \
229 SILC_GET32_X_MSB(block[2], &src[8]); \
230 SILC_GET32_X_MSB(block[3], &src[12]); \
234 SILC_PUT32_MSB(block[0], &dst[0]); \
235 SILC_PUT32_MSB(block[1], &dst[4]); \
236 SILC_PUT32_MSB(block[2], &dst[8]); \
237 SILC_PUT32_MSB(block[3], &dst[12]); \
243 SILC_PUT32_MSB(block[0], &iv[0]); \
244 SILC_PUT32_MSB(block[1], &iv[4]); \
245 SILC_PUT32_MSB(block[2], &iv[8]); \
246 SILC_PUT32_MSB(block[3], &iv[12]); \
249 /* CBC mode 128-bit block, LSB, 8-bit src argument must be decrypted
252 #ifndef WORDS_BIGENDIAN
255 #define SILC_CBC_DEC_MSB_128_8(len, iv, prev, src, dst, i, dec) \
257 SILC_ASSERT((len & (16 - 1)) == 0); \
258 if (len & (16 - 1)) \
261 for (i = 0; i < len; i += 16) { \
262 *(SilcUInt64 *)prev = *(SilcUInt64 *)src; \
263 *(SilcUInt64 *)(prev + 8) = *(SilcUInt64 *)(src + 8); \
267 *(SilcUInt64 *)dst ^= *(SilcUInt64 *)iv; \
268 *(SilcUInt64 *)(dst + 8) ^= *(SilcUInt64 *)(iv + 8); \
269 *(SilcUInt64 *)iv = *(SilcUInt64 *)prev; \
270 *(SilcUInt64 *)(iv + 8) = *(SilcUInt64 *)(prev + 8); \
276 #else /* !SILC_X86_64 */
278 #define SILC_CBC_DEC_MSB_128_8(len, iv, prev, src, dst, i, dec) \
280 SILC_ASSERT((len & (16 - 1)) == 0); \
281 if (len & (16 - 1)) \
284 for (i = 0; i < len; i += 16) { \
285 memcpy(prev, src, 16); \
289 *(SilcUInt32 *)dst ^= *(SilcUInt32 *)iv; \
290 *(SilcUInt32 *)(dst + 4) ^= *(SilcUInt32 *)(iv + 4); \
291 *(SilcUInt32 *)(dst + 8) ^= *(SilcUInt32 *)(iv + 8); \
292 *(SilcUInt32 *)(dst + 12) ^= *(SilcUInt32 *)(iv + 12); \
293 memcpy(iv, prev, 16); \
299 #endif /* SILC_X86_64 */
300 #else /* WORDS_BIGENDIAN */
301 /* big-endian machines */
302 #define SILC_CBC_DEC_MSB_128_8(len, iv, prev, src, dst, i, dec) \
304 SilcUInt32 tmp2[4], tmp3[4]; \
306 SILC_ASSERT((len & (16 - 1)) == 0); \
307 if (len & (16 - 1)) \
310 for (i = 0; i < len; i += 16) { \
311 memcpy(prev, src, 16); \
315 SILC_GET32_MSB(tmp2[0], &iv[0]); \
316 SILC_GET32_MSB(tmp2[1], &iv[4]); \
317 SILC_GET32_MSB(tmp2[2], &iv[8]); \
318 SILC_GET32_MSB(tmp2[3], &iv[12]); \
320 SILC_GET32_MSB(tmp3[0], &dst[0]); \
321 SILC_GET32_MSB(tmp3[1], &dst[4]); \
322 SILC_GET32_MSB(tmp3[2], &dst[8]); \
323 SILC_GET32_MSB(tmp3[3], &dst[12]); \
325 tmp2[0] = tmp3[0] ^ tmp2[0]; \
326 tmp2[1] = tmp3[1] ^ tmp2[1]; \
327 tmp2[2] = tmp3[2] ^ tmp2[2]; \
328 tmp2[3] = tmp3[3] ^ tmp2[3]; \
330 SILC_PUT32_MSB(tmp2[0], &dst[0]); \
331 SILC_PUT32_MSB(tmp2[1], &dst[4]); \
332 SILC_PUT32_MSB(tmp2[2], &dst[8]); \
333 SILC_PUT32_MSB(tmp2[3], &dst[12]); \
335 memcpy(iv, prev, 16); \
341 #endif /* !WORDS_BIGENDIAN */
343 /* CBC mode 128-bit block, MSB, decrypt block to block_dec. */
345 #define SILC_CBC_DEC_MSB_128_32(len, iv, block_prev, block, \
346 block_dec, src, dst, i, dec) \
348 if (!len || len & (16 - 1)) \
351 SILC_GET32_MSB(block_prev[0], &iv[0]); \
352 SILC_GET32_MSB(block_prev[1], &iv[4]); \
353 SILC_GET32_MSB(block_prev[2], &iv[8]); \
354 SILC_GET32_MSB(block_prev[3], &iv[12]); \
356 for (i = 0; i < len; i += 16) { \
357 SILC_GET32_MSB(block[0], &src[0]); \
358 SILC_GET32_MSB(block[1], &src[4]); \
359 SILC_GET32_MSB(block[2], &src[8]); \
360 SILC_GET32_MSB(block[3], &src[12]); \
364 block_dec[0] ^= block_prev[0]; \
365 block_dec[1] ^= block_prev[1]; \
366 block_dec[2] ^= block_prev[2]; \
367 block_dec[3] ^= block_prev[3]; \
369 SILC_PUT32_MSB(block_dec[0], &dst[0]); \
370 SILC_PUT32_MSB(block_dec[1], &dst[4]); \
371 SILC_PUT32_MSB(block_dec[2], &dst[8]); \
372 SILC_PUT32_MSB(block_dec[3], &dst[12]); \
374 block_prev[0] = block[0]; \
375 block_prev[1] = block[1]; \
376 block_prev[2] = block[2]; \
377 block_prev[3] = block[3]; \
383 SILC_PUT32_MSB(block[0], &iv[0]); \
384 SILC_PUT32_MSB(block[1], &iv[4]); \
385 SILC_PUT32_MSB(block[2], &iv[8]); \
386 SILC_PUT32_MSB(block[3], &iv[12]); \
389 /* CBC mode 64-bit block, MSB, 32-bit block argument must be encrypted */
391 #define SILC_CBC_ENC_MSB_64_32(len, iv, block, src, dst, i, enc) \
393 SILC_ASSERT((len & (8 - 1)) == 0); \
397 SILC_GET32_MSB(block[0], &iv[0]); \
398 SILC_GET32_MSB(block[1], &iv[4]); \
400 for (i = 0; i < len; i += 8) { \
401 SILC_GET32_X_MSB(block[0], &src[0]); \
402 SILC_GET32_X_MSB(block[1], &src[4]); \
406 SILC_PUT32_MSB(block[0], &dst[0]); \
407 SILC_PUT32_MSB(block[1], &dst[4]); \
413 SILC_PUT32_MSB(block[0], &iv[0]); \
414 SILC_PUT32_MSB(block[1], &iv[4]); \
417 /* CBC mode 64-bit block, MSB, decrypt block to block_dec. */
419 #define SILC_CBC_DEC_MSB_64_32(len, iv, block_prev, block, \
420 block_dec, src, dst, i, dec) \
422 if (!len || len & (8 - 1)) \
425 SILC_GET32_MSB(block_prev[0], &iv[0]); \
426 SILC_GET32_MSB(block_prev[1], &iv[4]); \
428 for (i = 0; i < len; i += 8) { \
429 SILC_GET32_MSB(block[0], &src[0]); \
430 SILC_GET32_MSB(block[1], &src[4]); \
434 block_dec[0] ^= block_prev[0]; \
435 block_dec[1] ^= block_prev[1]; \
437 SILC_PUT32_MSB(block_dec[0], &dst[0]); \
438 SILC_PUT32_MSB(block_dec[1], &dst[4]); \
440 block_prev[0] = block[0]; \
441 block_prev[1] = block[1]; \
447 SILC_PUT32_MSB(block[0], &iv[0]); \
448 SILC_PUT32_MSB(block[1], &iv[4]); \
451 #ifndef WORDS_BIGENDIAN
453 /* CTR mode 128-bit block, MSB, MSB counter, the 8-bit ctr argument must
454 be encrypted to enc_ctr */
456 #define SILC_CTR_MSB_128_8(ctr, enc_ctr, pad, src, dst, enc) \
460 for (i = 15; i >= 0; i--) \
467 *(SilcUInt64 *)dst = *(SilcUInt64 *)src ^ *(SilcUInt64 *)enc_ctr; \
468 *(SilcUInt64 *)(dst + 8) = *(SilcUInt64 *)(src + 8) ^ \
469 *(SilcUInt64 *)(enc_ctr + 8); \
473 silc_prefetch((void *)src, 0, 0); \
478 *dst++ = *src++ ^ enc_ctr[pad++]; \
483 #else /* WORDS_BIGENDIAN */
485 #define SILC_CTR_MSB_128_8(ctr, enc_ctr, pad, src, dst, enc) \
487 while (len-- > 0) { \
489 for (i = 15; i >= 0; i--) \
496 *dst++ = *src++ ^ enc_ctr[pad++]; \
500 #endif /* !WORDS_BIGENDIAN */
502 /* CTR mode 128-bit block, LSB, MSB counter, the 32-bit tmp argument
503 must be encrypted, enc_ctr must have the encrypted data too. */
505 #define SILC_CTR_LSB_128_32(ctr, tmp, enc_ctr, pad, src, dst, enc) \
507 while (len-- > 0) { \
509 for (i = 15; i >= 0; i--) \
513 SILC_GET32_LSB(tmp[0], ctr); \
514 SILC_GET32_LSB(tmp[1], ctr + 4); \
515 SILC_GET32_LSB(tmp[2], ctr + 8); \
516 SILC_GET32_LSB(tmp[3], ctr + 12); \
518 SILC_PUT32_LSB(tmp[0], enc_ctr); \
519 SILC_PUT32_LSB(tmp[1], enc_ctr + 4); \
520 SILC_PUT32_LSB(tmp[2], enc_ctr + 8); \
521 SILC_PUT32_LSB(tmp[3], enc_ctr + 12); \
524 *dst++ = *src++ ^ enc_ctr[pad++]; \
528 /* CTR mode 128-bit block, LSB, MSB counter, the 32-bit tmp argument
529 must be encrypted, enc_ctr must have the encrypted data too. */
531 #define SILC_CTR_MSB_64_32(ctr, tmp, enc_ctr, pad, src, dst, enc) \
533 while (len-- > 0) { \
535 for (i = 7; i >= 0; i--) \
539 SILC_GET32_MSB(tmp[0], ctr); \
540 SILC_GET32_MSB(tmp[1], ctr + 4); \
542 SILC_PUT32_MSB(tmp[0], enc_ctr); \
543 SILC_PUT32_MSB(tmp[1], enc_ctr + 4); \
546 *dst++ = *src++ ^ enc_ctr[pad++]; \
550 /* CFB 128-bit block, LSB, the 32-bit cfb argument must be encrypted. */
552 #define SILC_CFB_ENC_LSB_128_32(iv, cfb, pad, src, dst, enc) \
554 while (len-- > 0) { \
556 SILC_GET32_LSB(cfb[0], iv); \
557 SILC_GET32_LSB(cfb[1], iv + 4); \
558 SILC_GET32_LSB(cfb[2], iv + 8); \
559 SILC_GET32_LSB(cfb[3], iv + 12); \
563 SILC_PUT32_LSB(cfb[0], iv); \
564 SILC_PUT32_LSB(cfb[1], iv + 4); \
565 SILC_PUT32_LSB(cfb[2], iv + 8); \
566 SILC_PUT32_LSB(cfb[3], iv + 12); \
569 iv[pad] = (*dst = *src ^ iv[pad]); \
576 /* CFB 128-bit block, LSB, the 32-bit cfb argument must be decrypted. */
578 #define SILC_CFB_DEC_LSB_128_32(iv, cfb, pad, src, dst, dec) \
580 unsigned char temp; \
581 while (len-- > 0) { \
583 SILC_GET32_LSB(cfb[0], iv); \
584 SILC_GET32_LSB(cfb[1], iv + 4); \
585 SILC_GET32_LSB(cfb[2], iv + 8); \
586 SILC_GET32_LSB(cfb[3], iv + 12); \
590 SILC_PUT32_LSB(cfb[0], iv); \
591 SILC_PUT32_LSB(cfb[1], iv + 4); \
592 SILC_PUT32_LSB(cfb[2], iv + 8); \
593 SILC_PUT32_LSB(cfb[3], iv + 12); \
597 *dst = temp ^ iv[pad]; \
604 /* CFB 128-bit block, MSB, the 32-bit cfb argument must be encrypted. */
606 #define SILC_CFB_ENC_MSB_128_32(iv, cfb, pad, src, dst, enc) \
608 while (len-- > 0) { \
610 SILC_GET32_MSB(cfb[0], iv); \
611 SILC_GET32_MSB(cfb[1], iv + 4); \
612 SILC_GET32_MSB(cfb[2], iv + 8); \
613 SILC_GET32_MSB(cfb[3], iv + 12); \
617 SILC_PUT32_MSB(cfb[0], iv); \
618 SILC_PUT32_MSB(cfb[1], iv + 4); \
619 SILC_PUT32_MSB(cfb[2], iv + 8); \
620 SILC_PUT32_MSB(cfb[3], iv + 12); \
623 iv[pad] = (*dst = *src ^ iv[pad]); \
630 /* CFB 128-bit block, MSB, the 32-bit cfb argument must be decrypted. */
632 #define SILC_CFB_DEC_MSB_128_32(iv, cfb, pad, src, dst, dec) \
634 unsigned char temp; \
635 while (len-- > 0) { \
637 SILC_GET32_MSB(cfb[0], iv); \
638 SILC_GET32_MSB(cfb[1], iv + 4); \
639 SILC_GET32_MSB(cfb[2], iv + 8); \
640 SILC_GET32_MSB(cfb[3], iv + 12); \
644 SILC_PUT32_MSB(cfb[0], iv); \
645 SILC_PUT32_MSB(cfb[1], iv + 4); \
646 SILC_PUT32_MSB(cfb[2], iv + 8); \
647 SILC_PUT32_MSB(cfb[3], iv + 12); \
651 *dst = temp ^ iv[pad]; \
658 /* CFB 64-bit block, MSB, the 32-bit cfb argument must be encrypted. */
660 #define SILC_CFB_ENC_MSB_64_32(iv, cfb, pad, src, dst, enc) \
662 while (len-- > 0) { \
664 SILC_GET32_MSB(cfb[0], iv); \
665 SILC_GET32_MSB(cfb[1], iv + 4); \
669 SILC_PUT32_MSB(cfb[0], iv); \
670 SILC_PUT32_MSB(cfb[1], iv + 4); \
673 iv[pad] = (*dst = *src ^ iv[pad]); \
680 /* CFB 64-bit block, MSB, the 32-bit cfb argument must be decrypted. */
682 #define SILC_CFB_DEC_MSB_64_32(iv, cfb, pad, src, dst, dec) \
684 unsigned char temp; \
685 while (len-- > 0) { \
687 SILC_GET32_MSB(cfb[0], iv); \
688 SILC_GET32_MSB(cfb[1], iv + 4); \
692 SILC_PUT32_MSB(cfb[0], iv); \
693 SILC_PUT32_MSB(cfb[1], iv + 4); \
697 *dst = temp ^ iv[pad]; \
704 /* CFB 128-bit block, MSB, the 8-bit iv argument must be encrypted. */
706 #define SILC_CFB_ENC_MSB_128_8(iv, pad, src, dst, enc) \
708 while (len-- > 0) { \
713 iv[pad] = (*dst = *src ^ iv[pad]); \
720 /* CFB 128-bit block, MSB, the 8-bit iv argument must be decrypted. */
722 #define SILC_CFB_DEC_MSB_128_8(iv, pad, src, dst, dec) \
724 unsigned char temp; \
725 while (len-- > 0) { \
731 *dst = temp ^ iv[pad]; \