+/* CTR mode 128-bit block, MSB, MSB counter, the 8-bit ctr argument must
+ be encrypted to enc_ctr */
+
+#define SILC_CTR_MSB_128_8(ctr, enc_ctr, pad, src, dst, enc) \
+do { \
+ while (len > 0) { \
+ if (pad == 16) { \
+ for (i = 15; i >= 0; i--) \
+ if (++ctr[i]) \
+ break; \
+ \
+ enc; \
+ \
+ if (len >= 16) { \
+ *(SilcUInt64 *)dst = *(SilcUInt64 *)src ^ *(SilcUInt64 *)enc_ctr; \
+ *(SilcUInt64 *)(dst + 8) = *(SilcUInt64 *)(src + 8) ^ \
+ *(SilcUInt64 *)(enc_ctr + 8); \
+ src += 16; \
+ dst += 16; \
+ len -= 16; \
+ silc_prefetch((void *)src, 0, 0); \
+ continue; \
+ } \
+ pad = 0; \
+ } \
+ *dst++ = *src++ ^ enc_ctr[pad++]; \
+ len--; \
+ } \
+} while(0)
+
+#else /* WORDS_BIGENDIAN */
+
+#define SILC_CTR_MSB_128_8(ctr, enc_ctr, pad, src, dst, enc) \
+do { \
+ while (len-- > 0) { \
+ if (pad == 16) { \
+ for (i = 15; i >= 0; i--) \
+ if (++ctr[i]) \
+ break; \
+ \
+ enc; \
+ pad = 0; \
+ } \
+ *dst++ = *src++ ^ enc_ctr[pad++]; \
+ } \
+} while(0)
+
+#endif /* !WORDS_BIGENDIAN */
+
+/* CTR mode 128-bit block, LSB, MSB counter, the 32-bit tmp argument
+ must be encrypted, enc_ctr must have the encrypted data too. */
+
+#define SILC_CTR_LSB_128_32(ctr, tmp, enc_ctr, pad, src, dst, enc) \
+do { \
+ while (len-- > 0) { \
+ if (pad == 16) { \
+ for (i = 15; i >= 0; i--) \
+ if (++ctr[i]) \
+ break; \
+ \
+ SILC_GET32_LSB(tmp[0], ctr); \
+ SILC_GET32_LSB(tmp[1], ctr + 4); \
+ SILC_GET32_LSB(tmp[2], ctr + 8); \
+ SILC_GET32_LSB(tmp[3], ctr + 12); \
+ enc; \
+ SILC_PUT32_LSB(tmp[0], enc_ctr); \
+ SILC_PUT32_LSB(tmp[1], enc_ctr + 4); \
+ SILC_PUT32_LSB(tmp[2], enc_ctr + 8); \
+ SILC_PUT32_LSB(tmp[3], enc_ctr + 12); \
+ pad = 0; \
+ } \
+ *dst++ = *src++ ^ enc_ctr[pad++]; \
+ } \
+} while(0)
+
+/* CTR mode 128-bit block, LSB, MSB counter, the 32-bit tmp argument
+ must be encrypted, enc_ctr must have the encrypted data too. */
+
+#define SILC_CTR_MSB_64_32(ctr, tmp, enc_ctr, pad, src, dst, enc) \
+do { \
+ while (len-- > 0) { \
+ if (pad == 8) { \
+ for (i = 7; i >= 0; i--) \
+ if (++ctr[i]) \
+ break; \
+ \
+ SILC_GET32_MSB(tmp[0], ctr); \
+ SILC_GET32_MSB(tmp[1], ctr + 4); \
+ enc; \
+ SILC_PUT32_MSB(tmp[0], enc_ctr); \
+ SILC_PUT32_MSB(tmp[1], enc_ctr + 4); \
+ pad = 0; \
+ } \
+ *dst++ = *src++ ^ enc_ctr[pad++]; \
+ } \
+} while(0)
+
+/* CFB 128-bit block, LSB, the 32-bit cfb argument must be encrypted. */
+
+#define SILC_CFB_ENC_LSB_128_32(iv, cfb, pad, src, dst, enc) \
+do { \
+ while (len-- > 0) { \
+ if (pad == 16) { \
+ SILC_GET32_LSB(cfb[0], iv); \
+ SILC_GET32_LSB(cfb[1], iv + 4); \
+ SILC_GET32_LSB(cfb[2], iv + 8); \
+ SILC_GET32_LSB(cfb[3], iv + 12); \
+ \
+ enc; \
+ \
+ SILC_PUT32_LSB(cfb[0], iv); \
+ SILC_PUT32_LSB(cfb[1], iv + 4); \
+ SILC_PUT32_LSB(cfb[2], iv + 8); \
+ SILC_PUT32_LSB(cfb[3], iv + 12); \
+ pad = 0; \
+ } \
+ iv[pad] = (*dst = *src ^ iv[pad]); \
+ dst++; \
+ src++; \
+ pad++; \
+ } \
+} while(0)
+
+/* CFB 128-bit block, LSB, the 32-bit cfb argument must be decrypted. */
+
+#define SILC_CFB_DEC_LSB_128_32(iv, cfb, pad, src, dst, dec) \
+do { \
+ unsigned char temp; \
+ while (len-- > 0) { \
+ if (pad == 16) { \
+ SILC_GET32_LSB(cfb[0], iv); \
+ SILC_GET32_LSB(cfb[1], iv + 4); \
+ SILC_GET32_LSB(cfb[2], iv + 8); \
+ SILC_GET32_LSB(cfb[3], iv + 12); \
+ \
+ dec; \
+ \
+ SILC_PUT32_LSB(cfb[0], iv); \
+ SILC_PUT32_LSB(cfb[1], iv + 4); \
+ SILC_PUT32_LSB(cfb[2], iv + 8); \
+ SILC_PUT32_LSB(cfb[3], iv + 12); \
+ pad = 0; \
+ } \
+ temp = *src; \
+ *dst = temp ^ iv[pad]; \
+ iv[pad++] = temp; \
+ dst++; \
+ src++; \
+ } \
+} while(0)
+
+/* CFB 128-bit block, MSB, the 32-bit cfb argument must be encrypted. */
+
+#define SILC_CFB_ENC_MSB_128_32(iv, cfb, pad, src, dst, enc) \
+do { \
+ while (len-- > 0) { \
+ if (pad == 16) { \
+ SILC_GET32_MSB(cfb[0], iv); \
+ SILC_GET32_MSB(cfb[1], iv + 4); \
+ SILC_GET32_MSB(cfb[2], iv + 8); \
+ SILC_GET32_MSB(cfb[3], iv + 12); \
+ \
+ enc; \
+ \
+ SILC_PUT32_MSB(cfb[0], iv); \
+ SILC_PUT32_MSB(cfb[1], iv + 4); \
+ SILC_PUT32_MSB(cfb[2], iv + 8); \
+ SILC_PUT32_MSB(cfb[3], iv + 12); \
+ pad = 0; \
+ } \
+ iv[pad] = (*dst = *src ^ iv[pad]); \
+ dst++; \
+ src++; \
+ pad++; \
+ } \
+} while(0)
+
+/* CFB 128-bit block, MSB, the 32-bit cfb argument must be decrypted. */
+
+#define SILC_CFB_DEC_MSB_128_32(iv, cfb, pad, src, dst, dec) \
+do { \
+ unsigned char temp; \
+ while (len-- > 0) { \
+ if (pad == 16) { \
+ SILC_GET32_MSB(cfb[0], iv); \
+ SILC_GET32_MSB(cfb[1], iv + 4); \
+ SILC_GET32_MSB(cfb[2], iv + 8); \
+ SILC_GET32_MSB(cfb[3], iv + 12); \
+ \
+ dec; \
+ \
+ SILC_PUT32_MSB(cfb[0], iv); \
+ SILC_PUT32_MSB(cfb[1], iv + 4); \
+ SILC_PUT32_MSB(cfb[2], iv + 8); \
+ SILC_PUT32_MSB(cfb[3], iv + 12); \
+ pad = 0; \
+ } \
+ temp = *src; \
+ *dst = temp ^ iv[pad]; \
+ iv[pad++] = temp; \
+ dst++; \
+ src++; \
+ } \
+} while(0)
+
+/* CFB 64-bit block, MSB, the 32-bit cfb argument must be encrypted. */
+
+#define SILC_CFB_ENC_MSB_64_32(iv, cfb, pad, src, dst, enc) \
+do { \
+ while (len-- > 0) { \
+ if (pad == 8) { \
+ SILC_GET32_MSB(cfb[0], iv); \
+ SILC_GET32_MSB(cfb[1], iv + 4); \
+ \
+ enc; \
+ \
+ SILC_PUT32_MSB(cfb[0], iv); \
+ SILC_PUT32_MSB(cfb[1], iv + 4); \
+ pad = 0; \
+ } \
+ iv[pad] = (*dst = *src ^ iv[pad]); \
+ dst++; \
+ src++; \
+ pad++; \
+ } \
+} while(0)
+
+/* CFB 64-bit block, MSB, the 32-bit cfb argument must be decrypted. */
+
+#define SILC_CFB_DEC_MSB_64_32(iv, cfb, pad, src, dst, dec) \
+do { \
+ unsigned char temp; \
+ while (len-- > 0) { \
+ if (pad == 8) { \
+ SILC_GET32_MSB(cfb[0], iv); \
+ SILC_GET32_MSB(cfb[1], iv + 4); \
+ \
+ dec; \
+ \
+ SILC_PUT32_MSB(cfb[0], iv); \
+ SILC_PUT32_MSB(cfb[1], iv + 4); \
+ pad = 0; \
+ } \
+ temp = *src; \
+ *dst = temp ^ iv[pad]; \
+ iv[pad++] = temp; \
+ dst++; \
+ src++; \
+ } \
+} while(0)
+
+/* CFB 128-bit block, MSB, the 8-bit iv argument must be encrypted. */
+
+#define SILC_CFB_ENC_MSB_128_8(iv, pad, src, dst, enc) \
+do { \
+ while (len-- > 0) { \
+ if (pad == 16) { \
+ enc; \
+ pad = 0; \
+ } \
+ iv[pad] = (*dst = *src ^ iv[pad]); \
+ dst++; \
+ src++; \
+ pad++; \
+ } \
+} while(0)
+
+/* CFB 128-bit block, MSB, the 8-bit iv argument must be decrypted. */
+
+#define SILC_CFB_DEC_MSB_128_8(iv, pad, src, dst, dec) \
+do { \
+ unsigned char temp; \
+ while (len-- > 0) { \
+ if (pad == 16) { \
+ dec; \
+ pad = 0; \
+ } \
+ temp = *src; \
+ *dst = temp ^ iv[pad]; \
+ iv[pad++] = temp; \
+ dst++; \
+ src++; \
+ } \
+} while(0)