GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/crypt/chacha_private.h Lines: 92 96 95.8 %
Date: 2017-11-13 Branches: 9 18 50.0 %

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