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