X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccrypt%2Fciphers_def.h;h=cf6c6d51382e5d4a5967a4ca793a3086f37e3738;hb=9cb3b70fbb028d0bc059a3e5af3c4ea532a2b2f5;hp=19716f4805f6802ec99e0b7579a9b07b088af17d;hpb=c145f2f7712489b6530438b18bd71e5d1e6ec642;p=crypto.git diff --git a/lib/silccrypt/ciphers_def.h b/lib/silccrypt/ciphers_def.h index 19716f48..cf6c6d51 100644 --- a/lib/silccrypt/ciphers_def.h +++ b/lib/silccrypt/ciphers_def.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1999 - 2007 Pekka Riikonen + Copyright (C) 1999 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,6 +20,9 @@ #ifndef CIPHERS_DEF_H #define CIPHERS_DEF_H + +#include "silclog.h" + /* General definitions for algorithms */ typedef unsigned char u1byte; typedef SilcUInt32 u4byte; @@ -27,8 +30,8 @@ typedef SilcUInt32 u32; typedef SilcUInt32 uint_32t; typedef SilcUInt8 uint_8t; -#define rotr(x, nr) (((x) >> ((int)(nr))) | ((x) << (32 - (int)(nr)))) -#define rotl(x, nr) (((x) << ((int)(nr))) | ((x) >> (32 - (int)(nr)))) +#define rotr(x, nr) silc_ror(x, nr) +#define rotl(x, nr) silc_rol(x, nr) #define byte(x, nr) ((x) >> (nr * 8) & 255) /* Byte key to words */ @@ -39,7 +42,93 @@ do { \ SILC_GET32_LSB(d[_i], s + (_i * 4)); \ } while(0); -/* CBC mode 128-bit block, LSB, 32-bit block argument must be encrypted */ +/* CBC mode 128-bit block, LSB, 8-bit iv argument must be encrypted */ + +#ifndef WORDS_BIGENDIAN +#ifdef SILC_X86_64 +/* x86-64 */ +#define SILC_CBC_ENC_MSB_128_8(len, iv, src, dst, i, enc) \ +do { \ + SILC_ASSERT((len & (16 - 1)) == 0); \ + if (len & (16 - 1)) \ + return FALSE; \ + \ + for (i = 0; i < len; i += 16) { \ + *(SilcUInt64 *)iv ^= *(SilcUInt64 *)src; \ + *(SilcUInt64 *)(iv + 8) ^= *(SilcUInt64 *)(src + 8); \ + \ + enc; \ + \ + *(SilcUInt64 *)dst = *(SilcUInt64 *)iv; \ + *(SilcUInt64 *)(dst + 8) = *(SilcUInt64 *)(iv + 8); \ + \ + dst += 16; \ + src += 16; \ + } \ +} while(0) +#else /* !SILC_X86_64 */ +/* x86 */ +#define SILC_CBC_ENC_MSB_128_8(len, iv, src, dst, i, enc) \ +do { \ + SILC_ASSERT((len & (16 - 1)) == 0); \ + if (len & (16 - 1)) \ + return FALSE; \ + \ + for (i = 0; i < len; i += 16) { \ + *(SilcUInt32 *)iv ^= *(SilcUInt32 *)src; \ + *(SilcUInt32 *)(iv + 4) ^= *(SilcUInt32 *)(src + 4); \ + *(SilcUInt32 *)(iv + 8) ^= *(SilcUInt32 *)(src + 8); \ + *(SilcUInt32 *)(iv + 12) ^= *(SilcUInt32 *)(src + 12); \ + \ + enc; \ + \ + memcpy(dst, iv, 16); \ + dst += 16; \ + src += 16; \ + } \ +} while(0) +#endif /* SILC_X86_64 */ +#else /* WORDS_BIGENDIAN */ +/* big-endian machines */ +#define SILC_CBC_ENC_MSB_128_8(len, iv, src, dst, i, enc) \ +do { \ + SilcUInt32 tmp[4], tmp2[4]; \ + \ + SILC_ASSERT((len & (16 - 1)) == 0); \ + if (len & (16 - 1)) \ + return FALSE; \ + \ + for (i = 0; i < len; i += 16) { \ + SILC_GET32_MSB(tmp[0], &iv[0]); \ + SILC_GET32_MSB(tmp[1], &iv[4]); \ + SILC_GET32_MSB(tmp[2], &iv[8]); \ + SILC_GET32_MSB(tmp[3], &iv[12]); \ + \ + SILC_GET32_MSB(tmp2[0], &src[0]); \ + SILC_GET32_MSB(tmp2[1], &src[4]); \ + SILC_GET32_MSB(tmp2[2], &src[8]); \ + SILC_GET32_MSB(tmp2[3], &src[12]); \ + \ + tmp[0] = tmp[0] ^ tmp2[0]; \ + tmp[1] = tmp[1] ^ tmp2[1]; \ + tmp[2] = tmp[2] ^ tmp2[2]; \ + tmp[3] = tmp[3] ^ tmp2[3]; \ + \ + SILC_PUT32_MSB(tmp[0], &iv[0]); \ + SILC_PUT32_MSB(tmp[1], &iv[4]); \ + SILC_PUT32_MSB(tmp[2], &iv[8]); \ + SILC_PUT32_MSB(tmp[3], &iv[12]); \ + \ + enc; \ + \ + memcpy(dst, iv, 16); \ + dst += 16; \ + src += 16; \ + } \ +} while(0) +#endif /* !WORDS_BIGENDIAN */ + +/* CBC mode 128-bit block, MSB, 32-bit block argument must be encrypted */ #define SILC_CBC_ENC_LSB_128_32(len, iv, block, src, dst, i, enc) \ do { \ @@ -80,7 +169,7 @@ do { \ #define SILC_CBC_DEC_LSB_128_32(len, iv, block_prev, block, \ block_dec, src, dst, i, dec) \ do { \ - if (len & (16 - 1)) \ + if (!len || len & (16 - 1)) \ return FALSE; \ \ SILC_GET32_LSB(block_prev[0], &iv[0]); \ @@ -157,12 +246,106 @@ do { \ SILC_PUT32_MSB(block[3], &iv[12]); \ } while(0) +/* CBC mode 128-bit block, LSB, 8-bit src argument must be decrypted + to dst. */ + +#ifndef WORDS_BIGENDIAN +#ifdef SILC_X86_64 +/* x86-64 */ +#define SILC_CBC_DEC_MSB_128_8(len, iv, prev, src, dst, i, dec) \ +{ \ + SILC_ASSERT((len & (16 - 1)) == 0); \ + if (len & (16 - 1)) \ + return FALSE; \ + \ + for (i = 0; i < len; i += 16) { \ + *(SilcUInt64 *)prev = *(SilcUInt64 *)src; \ + *(SilcUInt64 *)(prev + 8) = *(SilcUInt64 *)(src + 8); \ + \ + dec; \ + \ + *(SilcUInt64 *)dst ^= *(SilcUInt64 *)iv; \ + *(SilcUInt64 *)(dst + 8) ^= *(SilcUInt64 *)(iv + 8); \ + *(SilcUInt64 *)iv = *(SilcUInt64 *)prev; \ + *(SilcUInt64 *)(iv + 8) = *(SilcUInt64 *)(prev + 8); \ + \ + dst += 16; \ + src += 16; \ + } \ +} while(0) +#else /* !SILC_X86_64 */ +/* x86 */ +#define SILC_CBC_DEC_MSB_128_8(len, iv, prev, src, dst, i, dec) \ +do { \ + SILC_ASSERT((len & (16 - 1)) == 0); \ + if (len & (16 - 1)) \ + return FALSE; \ + \ + for (i = 0; i < len; i += 16) { \ + memcpy(prev, src, 16); \ + \ + dec; \ + \ + *(SilcUInt32 *)dst ^= *(SilcUInt32 *)iv; \ + *(SilcUInt32 *)(dst + 4) ^= *(SilcUInt32 *)(iv + 4); \ + *(SilcUInt32 *)(dst + 8) ^= *(SilcUInt32 *)(iv + 8); \ + *(SilcUInt32 *)(dst + 12) ^= *(SilcUInt32 *)(iv + 12); \ + memcpy(iv, prev, 16); \ + \ + dst += 16; \ + src += 16; \ + } \ +} while(0) +#endif /* SILC_X86_64 */ +#else /* WORDS_BIGENDIAN */ +/* big-endian machines */ +#define SILC_CBC_DEC_MSB_128_8(len, iv, prev, src, dst, i, dec) \ +do { \ + SilcUInt32 tmp2[4], tmp3[4]; \ + \ + SILC_ASSERT((len & (16 - 1)) == 0); \ + if (len & (16 - 1)) \ + return FALSE; \ + \ + for (i = 0; i < len; i += 16) { \ + memcpy(prev, src, 16); \ + \ + dec; \ + \ + SILC_GET32_MSB(tmp2[0], &iv[0]); \ + SILC_GET32_MSB(tmp2[1], &iv[4]); \ + SILC_GET32_MSB(tmp2[2], &iv[8]); \ + SILC_GET32_MSB(tmp2[3], &iv[12]); \ + \ + SILC_GET32_MSB(tmp3[0], &dst[0]); \ + SILC_GET32_MSB(tmp3[1], &dst[4]); \ + SILC_GET32_MSB(tmp3[2], &dst[8]); \ + SILC_GET32_MSB(tmp3[3], &dst[12]); \ + \ + tmp2[0] = tmp3[0] ^ tmp2[0]; \ + tmp2[1] = tmp3[1] ^ tmp2[1]; \ + tmp2[2] = tmp3[2] ^ tmp2[2]; \ + tmp2[3] = tmp3[3] ^ tmp2[3]; \ + \ + SILC_PUT32_MSB(tmp2[0], &dst[0]); \ + SILC_PUT32_MSB(tmp2[1], &dst[4]); \ + SILC_PUT32_MSB(tmp2[2], &dst[8]); \ + SILC_PUT32_MSB(tmp2[3], &dst[12]); \ + \ + memcpy(iv, prev, 16); \ + \ + dst += 16; \ + src += 16; \ + } \ +} while(0) +#endif /* !WORDS_BIGENDIAN */ + /* CBC mode 128-bit block, MSB, decrypt block to block_dec. */ #define SILC_CBC_DEC_MSB_128_32(len, iv, block_prev, block, \ block_dec, src, dst, i, dec) \ do { \ - if (len & (16 - 1)) \ + if (!len || len & (16 - 1)) \ return FALSE; \ \ SILC_GET32_MSB(block_prev[0], &iv[0]); \ @@ -236,7 +419,7 @@ do { \ #define SILC_CBC_DEC_MSB_64_32(len, iv, block_prev, block, \ block_dec, src, dst, i, dec) \ do { \ - if (len & (8 - 1)) \ + if (!len || len & (8 - 1)) \ return FALSE; \ \ SILC_GET32_MSB(block_prev[0], &iv[0]); \ @@ -265,147 +448,103 @@ do { \ SILC_PUT32_MSB(block[1], &iv[4]); \ } while(0) +#ifndef WORDS_BIGENDIAN -/* CTR mode 128-bit block, MSB, MSB counter, the 8-bit enc_ctr argument must - be encrypted */ +/* 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(iv, ctr, enc_ctr, pad, src, dst, enc) \ +#define SILC_CTR_MSB_128_8(ctr, enc_ctr, pad, src, dst, enc) \ do { \ - SILC_GET32_MSB(ctr[0], iv); \ - SILC_GET32_MSB(ctr[1], iv + 4); \ - SILC_GET32_MSB(ctr[2], iv + 8); \ - SILC_GET32_MSB(ctr[3], iv + 12); \ - \ - if (pad == 0) \ - pad = 16; \ - \ - while (len-- > 0) { \ + while (len > 0) { \ if (pad == 16) { \ - if (++ctr[3] == 0) \ - if (++ctr[2] == 0) \ - if (++ctr[1] == 0) \ - ++ctr[0]; \ - \ - SILC_PUT32_MSB(ctr[0], enc_ctr); \ - SILC_PUT32_MSB(ctr[1], enc_ctr + 4); \ - SILC_PUT32_MSB(ctr[2], enc_ctr + 8); \ - SILC_PUT32_MSB(ctr[3], enc_ctr + 12); \ + 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--; \ } \ - \ - SILC_PUT32_MSB(ctr[0], iv); \ - SILC_PUT32_MSB(ctr[1], iv + 4); \ - SILC_PUT32_MSB(ctr[2], iv + 8); \ - SILC_PUT32_MSB(ctr[3], iv + 12); \ } while(0) -/* CTR mode 128-bit block, MSB, MSB counter, the 32-bit ctr argument must - be encrypted to enc_ctr */ +#else /* WORDS_BIGENDIAN */ -#define SILC_CTR_MSB_128_32(iv, ctr, enc_ctr, pad, src, dst, enc) \ +#define SILC_CTR_MSB_128_8(ctr, enc_ctr, pad, src, dst, enc) \ do { \ - SILC_GET32_MSB(ctr[0], iv); \ - SILC_GET32_MSB(ctr[1], iv + 4); \ - SILC_GET32_MSB(ctr[2], iv + 8); \ - SILC_GET32_MSB(ctr[3], iv + 12); \ - \ - if (pad == 0) \ - pad = 16; \ - \ while (len-- > 0) { \ if (pad == 16) { \ - if (++ctr[3] == 0) \ - if (++ctr[2] == 0) \ - if (++ctr[1] == 0) \ - ++ctr[0]; \ + for (i = 15; i >= 0; i--) \ + if (++ctr[i]) \ + break; \ \ enc; \ - SILC_PUT32_MSB(enc_ctr[0], iv); \ - SILC_PUT32_MSB(enc_ctr[1], iv + 4); \ - SILC_PUT32_MSB(enc_ctr[2], iv + 8); \ - SILC_PUT32_MSB(enc_ctr[3], iv + 12); \ pad = 0; \ } \ *dst++ = *src++ ^ enc_ctr[pad++]; \ } \ - \ - SILC_PUT32_MSB(ctr[0], iv); \ - SILC_PUT32_MSB(ctr[1], iv + 4); \ - SILC_PUT32_MSB(ctr[2], iv + 8); \ - SILC_PUT32_MSB(ctr[3], iv + 12); \ } while(0) -/* CTR mode 128-bit block, LSB, MSB counter, the 32-bit enc_ctr argument - must be encrypted */ +#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(iv, ctr, enc_ctr, pad, src, dst, enc) \ +#define SILC_CTR_LSB_128_32(ctr, tmp, enc_ctr, pad, src, dst, enc) \ do { \ - SILC_GET32_MSB(ctr[0], iv); \ - SILC_GET32_MSB(ctr[1], iv + 4); \ - SILC_GET32_MSB(ctr[2], iv + 8); \ - SILC_GET32_MSB(ctr[3], iv + 12); \ - \ - if (pad == 0) \ - pad = 16; \ - \ while (len-- > 0) { \ if (pad == 16) { \ - if (++ctr[3] == 0) \ - if (++ctr[2] == 0) \ - if (++ctr[1] == 0) \ - ++ctr[0]; \ - \ - enc_ctr[0] = SILC_SWAB_32(ctr[0]); \ - enc_ctr[1] = SILC_SWAB_32(ctr[1]); \ - enc_ctr[2] = SILC_SWAB_32(ctr[2]); \ - enc_ctr[3] = SILC_SWAB_32(ctr[3]); \ + 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(enc_ctr[0], iv); \ - SILC_PUT32_LSB(enc_ctr[1], iv + 4); \ - SILC_PUT32_LSB(enc_ctr[2], iv + 8); \ - SILC_PUT32_LSB(enc_ctr[3], iv + 12); \ + 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++ ^ iv[pad++]; \ + *dst++ = *src++ ^ enc_ctr[pad++]; \ } \ - \ - SILC_PUT32_MSB(ctr[0], iv); \ - SILC_PUT32_MSB(ctr[1], iv + 4); \ - SILC_PUT32_MSB(ctr[2], iv + 8); \ - SILC_PUT32_MSB(ctr[3], iv + 12); \ } while(0) -/* CTR mode 64-bit block, MSB, MSB counter, the 32-bit ctr argument must - be encrypted to enc_ctr */ +/* 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(iv, ctr, enc_ctr, pad, src, dst, enc) \ +#define SILC_CTR_MSB_64_32(ctr, tmp, enc_ctr, pad, src, dst, enc) \ do { \ - SILC_GET32_MSB(ctr[0], iv); \ - SILC_GET32_MSB(ctr[1], iv + 4); \ - \ - if (pad == 0) \ - pad = 8; \ - \ while (len-- > 0) { \ if (pad == 8) { \ - if (++ctr[1] == 0) \ - ++ctr[0]; \ + 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(enc_ctr[0], iv); \ - SILC_PUT32_MSB(enc_ctr[1], iv + 4); \ + SILC_PUT32_MSB(tmp[0], enc_ctr); \ + SILC_PUT32_MSB(tmp[1], enc_ctr + 4); \ pad = 0; \ } \ - *dst++ = *src++ ^ iv[pad++]; \ + *dst++ = *src++ ^ enc_ctr[pad++]; \ } \ - \ - SILC_PUT32_MSB(ctr[0], iv); \ - SILC_PUT32_MSB(ctr[1], iv + 4); \ } while(0) /* CFB 128-bit block, LSB, the 32-bit cfb argument must be encrypted. */ @@ -438,6 +577,7 @@ do { \ #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); \ @@ -453,9 +593,9 @@ do { \ SILC_PUT32_LSB(cfb[3], iv + 12); \ pad = 0; \ } \ - iv[pad] = *src ^ iv[pad]; \ - *dst = iv[pad]; \ - iv[pad++] = *src; \ + temp = *src; \ + *dst = temp ^ iv[pad]; \ + iv[pad++] = temp; \ dst++; \ src++; \ } \ @@ -491,6 +631,7 @@ do { \ #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); \ @@ -506,9 +647,9 @@ do { \ SILC_PUT32_MSB(cfb[3], iv + 12); \ pad = 0; \ } \ - iv[pad] = *src ^ iv[pad]; \ - *dst = iv[pad]; \ - iv[pad++] = *src; \ + temp = *src; \ + *dst = temp ^ iv[pad]; \ + iv[pad++] = temp; \ dst++; \ src++; \ } \ @@ -540,6 +681,7 @@ do { \ #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); \ @@ -551,9 +693,9 @@ do { \ SILC_PUT32_MSB(cfb[1], iv + 4); \ pad = 0; \ } \ - iv[pad] = *src ^ iv[pad]; \ - *dst = iv[pad]; \ - iv[pad++] = *src; \ + temp = *src; \ + *dst = temp ^ iv[pad]; \ + iv[pad++] = temp; \ dst++; \ src++; \ } \ @@ -578,15 +720,16 @@ do { \ /* 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 { \ +do { \ + unsigned char temp; \ while (len-- > 0) { \ if (pad == 16) { \ dec; \ pad = 0; \ } \ - iv[pad] = *src ^ iv[pad]; \ - *dst = iv[pad]; \ - iv[pad++] = *src; \ + temp = *src; \ + *dst = temp ^ iv[pad]; \ + iv[pad++] = temp; \ dst++; \ src++; \ } \