[BACK]Return to chacha.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/chacha.c, Revision 1.1

1.1     ! djm         1: /*
        !             2: chacha-merged.c version 20080118
        !             3: D. J. Bernstein
        !             4: Public domain.
        !             5: */
        !             6:
        !             7: #include "chacha.h"
        !             8:
        !             9: /* $OpenBSD$ */
        !            10:
        !            11: typedef unsigned char u8;
        !            12: typedef unsigned int u32;
        !            13:
        !            14: typedef struct chacha_ctx chacha_ctx;
        !            15:
        !            16: #define U8C(v) (v##U)
        !            17: #define U32C(v) (v##U)
        !            18:
        !            19: #define U8V(v) ((u8)(v) & U8C(0xFF))
        !            20: #define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
        !            21:
        !            22: #define ROTL32(v, n) \
        !            23:   (U32V((v) << (n)) | ((v) >> (32 - (n))))
        !            24:
        !            25: #define U8TO32_LITTLE(p) \
        !            26:   (((u32)((p)[0])      ) | \
        !            27:    ((u32)((p)[1]) <<  8) | \
        !            28:    ((u32)((p)[2]) << 16) | \
        !            29:    ((u32)((p)[3]) << 24))
        !            30:
        !            31: #define U32TO8_LITTLE(p, v) \
        !            32:   do { \
        !            33:     (p)[0] = U8V((v)      ); \
        !            34:     (p)[1] = U8V((v) >>  8); \
        !            35:     (p)[2] = U8V((v) >> 16); \
        !            36:     (p)[3] = U8V((v) >> 24); \
        !            37:   } while (0)
        !            38:
        !            39: #define ROTATE(v,c) (ROTL32(v,c))
        !            40: #define XOR(v,w) ((v) ^ (w))
        !            41: #define PLUS(v,w) (U32V((v) + (w)))
        !            42: #define PLUSONE(v) (PLUS((v),1))
        !            43:
        !            44: #define QUARTERROUND(a,b,c,d) \
        !            45:   a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
        !            46:   c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
        !            47:   a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
        !            48:   c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
        !            49:
        !            50: static const char sigma[16] = "expand 32-byte k";
        !            51: static const char tau[16] = "expand 16-byte k";
        !            52:
        !            53: void
        !            54: chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
        !            55: {
        !            56:   const char *constants;
        !            57:
        !            58:   x->input[4] = U8TO32_LITTLE(k + 0);
        !            59:   x->input[5] = U8TO32_LITTLE(k + 4);
        !            60:   x->input[6] = U8TO32_LITTLE(k + 8);
        !            61:   x->input[7] = U8TO32_LITTLE(k + 12);
        !            62:   if (kbits == 256) { /* recommended */
        !            63:     k += 16;
        !            64:     constants = sigma;
        !            65:   } else { /* kbits == 128 */
        !            66:     constants = tau;
        !            67:   }
        !            68:   x->input[8] = U8TO32_LITTLE(k + 0);
        !            69:   x->input[9] = U8TO32_LITTLE(k + 4);
        !            70:   x->input[10] = U8TO32_LITTLE(k + 8);
        !            71:   x->input[11] = U8TO32_LITTLE(k + 12);
        !            72:   x->input[0] = U8TO32_LITTLE(constants + 0);
        !            73:   x->input[1] = U8TO32_LITTLE(constants + 4);
        !            74:   x->input[2] = U8TO32_LITTLE(constants + 8);
        !            75:   x->input[3] = U8TO32_LITTLE(constants + 12);
        !            76: }
        !            77:
        !            78: void
        !            79: chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
        !            80: {
        !            81:   x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
        !            82:   x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
        !            83:   x->input[14] = U8TO32_LITTLE(iv + 0);
        !            84:   x->input[15] = U8TO32_LITTLE(iv + 4);
        !            85: }
        !            86:
        !            87: void
        !            88: chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
        !            89: {
        !            90:   u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
        !            91:   u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
        !            92:   u8 *ctarget = NULL;
        !            93:   u8 tmp[64];
        !            94:   u_int i;
        !            95:
        !            96:   if (!bytes) return;
        !            97:
        !            98:   j0 = x->input[0];
        !            99:   j1 = x->input[1];
        !           100:   j2 = x->input[2];
        !           101:   j3 = x->input[3];
        !           102:   j4 = x->input[4];
        !           103:   j5 = x->input[5];
        !           104:   j6 = x->input[6];
        !           105:   j7 = x->input[7];
        !           106:   j8 = x->input[8];
        !           107:   j9 = x->input[9];
        !           108:   j10 = x->input[10];
        !           109:   j11 = x->input[11];
        !           110:   j12 = x->input[12];
        !           111:   j13 = x->input[13];
        !           112:   j14 = x->input[14];
        !           113:   j15 = x->input[15];
        !           114:
        !           115:   for (;;) {
        !           116:     if (bytes < 64) {
        !           117:       for (i = 0;i < bytes;++i) tmp[i] = m[i];
        !           118:       m = tmp;
        !           119:       ctarget = c;
        !           120:       c = tmp;
        !           121:     }
        !           122:     x0 = j0;
        !           123:     x1 = j1;
        !           124:     x2 = j2;
        !           125:     x3 = j3;
        !           126:     x4 = j4;
        !           127:     x5 = j5;
        !           128:     x6 = j6;
        !           129:     x7 = j7;
        !           130:     x8 = j8;
        !           131:     x9 = j9;
        !           132:     x10 = j10;
        !           133:     x11 = j11;
        !           134:     x12 = j12;
        !           135:     x13 = j13;
        !           136:     x14 = j14;
        !           137:     x15 = j15;
        !           138:     for (i = 20;i > 0;i -= 2) {
        !           139:       QUARTERROUND( x0, x4, x8,x12)
        !           140:       QUARTERROUND( x1, x5, x9,x13)
        !           141:       QUARTERROUND( x2, x6,x10,x14)
        !           142:       QUARTERROUND( x3, x7,x11,x15)
        !           143:       QUARTERROUND( x0, x5,x10,x15)
        !           144:       QUARTERROUND( x1, x6,x11,x12)
        !           145:       QUARTERROUND( x2, x7, x8,x13)
        !           146:       QUARTERROUND( x3, x4, x9,x14)
        !           147:     }
        !           148:     x0 = PLUS(x0,j0);
        !           149:     x1 = PLUS(x1,j1);
        !           150:     x2 = PLUS(x2,j2);
        !           151:     x3 = PLUS(x3,j3);
        !           152:     x4 = PLUS(x4,j4);
        !           153:     x5 = PLUS(x5,j5);
        !           154:     x6 = PLUS(x6,j6);
        !           155:     x7 = PLUS(x7,j7);
        !           156:     x8 = PLUS(x8,j8);
        !           157:     x9 = PLUS(x9,j9);
        !           158:     x10 = PLUS(x10,j10);
        !           159:     x11 = PLUS(x11,j11);
        !           160:     x12 = PLUS(x12,j12);
        !           161:     x13 = PLUS(x13,j13);
        !           162:     x14 = PLUS(x14,j14);
        !           163:     x15 = PLUS(x15,j15);
        !           164:
        !           165:     x0 = XOR(x0,U8TO32_LITTLE(m + 0));
        !           166:     x1 = XOR(x1,U8TO32_LITTLE(m + 4));
        !           167:     x2 = XOR(x2,U8TO32_LITTLE(m + 8));
        !           168:     x3 = XOR(x3,U8TO32_LITTLE(m + 12));
        !           169:     x4 = XOR(x4,U8TO32_LITTLE(m + 16));
        !           170:     x5 = XOR(x5,U8TO32_LITTLE(m + 20));
        !           171:     x6 = XOR(x6,U8TO32_LITTLE(m + 24));
        !           172:     x7 = XOR(x7,U8TO32_LITTLE(m + 28));
        !           173:     x8 = XOR(x8,U8TO32_LITTLE(m + 32));
        !           174:     x9 = XOR(x9,U8TO32_LITTLE(m + 36));
        !           175:     x10 = XOR(x10,U8TO32_LITTLE(m + 40));
        !           176:     x11 = XOR(x11,U8TO32_LITTLE(m + 44));
        !           177:     x12 = XOR(x12,U8TO32_LITTLE(m + 48));
        !           178:     x13 = XOR(x13,U8TO32_LITTLE(m + 52));
        !           179:     x14 = XOR(x14,U8TO32_LITTLE(m + 56));
        !           180:     x15 = XOR(x15,U8TO32_LITTLE(m + 60));
        !           181:
        !           182:     j12 = PLUSONE(j12);
        !           183:     if (!j12) {
        !           184:       j13 = PLUSONE(j13);
        !           185:       /* stopping at 2^70 bytes per nonce is user's responsibility */
        !           186:     }
        !           187:
        !           188:     U32TO8_LITTLE(c + 0,x0);
        !           189:     U32TO8_LITTLE(c + 4,x1);
        !           190:     U32TO8_LITTLE(c + 8,x2);
        !           191:     U32TO8_LITTLE(c + 12,x3);
        !           192:     U32TO8_LITTLE(c + 16,x4);
        !           193:     U32TO8_LITTLE(c + 20,x5);
        !           194:     U32TO8_LITTLE(c + 24,x6);
        !           195:     U32TO8_LITTLE(c + 28,x7);
        !           196:     U32TO8_LITTLE(c + 32,x8);
        !           197:     U32TO8_LITTLE(c + 36,x9);
        !           198:     U32TO8_LITTLE(c + 40,x10);
        !           199:     U32TO8_LITTLE(c + 44,x11);
        !           200:     U32TO8_LITTLE(c + 48,x12);
        !           201:     U32TO8_LITTLE(c + 52,x13);
        !           202:     U32TO8_LITTLE(c + 56,x14);
        !           203:     U32TO8_LITTLE(c + 60,x15);
        !           204:
        !           205:     if (bytes <= 64) {
        !           206:       if (bytes < 64) {
        !           207:         for (i = 0;i < bytes;++i) ctarget[i] = c[i];
        !           208:       }
        !           209:       x->input[12] = j12;
        !           210:       x->input[13] = j13;
        !           211:       return;
        !           212:     }
        !           213:     bytes -= 64;
        !           214:     c += 64;
        !           215:     m += 64;
        !           216:   }
        !           217: }