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