GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/chacha/chacha-merged.c Lines: 153 155 98.7 %
Date: 2016-12-06 Branches: 20 24 83.3 %

Line Branch Exec Source
1
/* $OpenBSD: chacha-merged.c,v 1.7 2014/07/11 08:47:47 bcook Exp $ */
2
/*
3
chacha-merged.c version 20080118
4
D. J. Bernstein
5
Public domain.
6
*/
7
8
#include <sys/types.h>
9
10
#include <stdint.h>
11
12
#define CHACHA_MINKEYLEN 	16
13
#define CHACHA_NONCELEN		8
14
#define CHACHA_CTRLEN		8
15
#define CHACHA_STATELEN		(CHACHA_NONCELEN+CHACHA_CTRLEN)
16
#define CHACHA_BLOCKLEN		64
17
18
struct chacha_ctx {
19
	u_int input[16];
20
	uint8_t ks[CHACHA_BLOCKLEN];
21
	uint8_t unused;
22
};
23
24
static inline void chacha_keysetup(struct chacha_ctx *x, const u_char *k,
25
    u_int kbits)
26
    __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN)));
27
static inline void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv,
28
    const u_char *ctr)
29
    __attribute__((__bounded__(__minbytes__, 2, CHACHA_NONCELEN)))
30
    __attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN)));
31
static inline void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m,
32
    u_char *c, u_int bytes)
33
    __attribute__((__bounded__(__buffer__, 2, 4)))
34
    __attribute__((__bounded__(__buffer__, 3, 4)));
35
36
typedef unsigned char u8;
37
typedef unsigned int u32;
38
39
typedef struct chacha_ctx chacha_ctx;
40
41
#define U8C(v) (v##U)
42
#define U32C(v) (v##U)
43
44
#define U8V(v) ((u8)(v) & U8C(0xFF))
45
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
46
47
#define ROTL32(v, n) \
48
  (U32V((v) << (n)) | ((v) >> (32 - (n))))
49
50
#define U8TO32_LITTLE(p) \
51
  (((u32)((p)[0])) | \
52
   ((u32)((p)[1]) <<  8) | \
53
   ((u32)((p)[2]) << 16) | \
54
   ((u32)((p)[3]) << 24))
55
56
#define U32TO8_LITTLE(p, v) \
57
  do { \
58
    (p)[0] = U8V((v)); \
59
    (p)[1] = U8V((v) >>  8); \
60
    (p)[2] = U8V((v) >> 16); \
61
    (p)[3] = U8V((v) >> 24); \
62
  } while (0)
63
64
#define ROTATE(v,c) (ROTL32(v,c))
65
#define XOR(v,w) ((v) ^ (w))
66
#define PLUS(v,w) (U32V((v) + (w)))
67
#define PLUSONE(v) (PLUS((v),1))
68
69
#define QUARTERROUND(a,b,c,d) \
70
  a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
71
  c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
72
  a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
73
  c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
74
75
static const char sigma[16] = "expand 32-byte k";
76
static const char tau[16] = "expand 16-byte k";
77
78
static inline void
79
chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits)
80
445
{
81
	const char *constants;
82
83
445
	x->input[4] = U8TO32_LITTLE(k + 0);
84
445
	x->input[5] = U8TO32_LITTLE(k + 4);
85
445
	x->input[6] = U8TO32_LITTLE(k + 8);
86
445
	x->input[7] = U8TO32_LITTLE(k + 12);
87
445
	if (kbits == 256) { /* recommended */
88
445
		k += 16;
89
445
		constants = sigma;
90
	} else { /* kbits == 128 */
91
		constants = tau;
92
	}
93
445
	x->input[8] = U8TO32_LITTLE(k + 0);
94
445
	x->input[9] = U8TO32_LITTLE(k + 4);
95
445
	x->input[10] = U8TO32_LITTLE(k + 8);
96
445
	x->input[11] = U8TO32_LITTLE(k + 12);
97
445
	x->input[0] = U8TO32_LITTLE(constants + 0);
98
445
	x->input[1] = U8TO32_LITTLE(constants + 4);
99
445
	x->input[2] = U8TO32_LITTLE(constants + 8);
100
445
	x->input[3] = U8TO32_LITTLE(constants + 12);
101
445
}
102
103
static inline void
104
chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
105
445
{
106
445
	x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
107
445
	x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
108
445
	x->input[14] = U8TO32_LITTLE(iv + 0);
109
445
	x->input[15] = U8TO32_LITTLE(iv + 4);
110
445
}
111
112
static inline void
113
chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes)
114
997
{
115
	u32 x0, x1, x2, x3, x4, x5, x6, x7;
116
	u32 x8, x9, x10, x11, x12, x13, x14, x15;
117
	u32 j0, j1, j2, j3, j4, j5, j6, j7;
118
	u32 j8, j9, j10, j11, j12, j13, j14, j15;
119
997
	u8 *ctarget = NULL;
120
	u8 tmp[64];
121
	u_int i;
122
123
997
	if (!bytes)
124
554
		return;
125
126
443
	j0 = x->input[0];
127
443
	j1 = x->input[1];
128
443
	j2 = x->input[2];
129
443
	j3 = x->input[3];
130
443
	j4 = x->input[4];
131
443
	j5 = x->input[5];
132
443
	j6 = x->input[6];
133
443
	j7 = x->input[7];
134
443
	j8 = x->input[8];
135
443
	j9 = x->input[9];
136
443
	j10 = x->input[10];
137
443
	j11 = x->input[11];
138
443
	j12 = x->input[12];
139
443
	j13 = x->input[13];
140
443
	j14 = x->input[14];
141
443
	j15 = x->input[15];
142
143
	for (;;) {
144
693
		if (bytes < 64) {
145
13277
			for (i = 0; i < bytes; ++i)
146
12858
				tmp[i] = m[i];
147
419
			m = tmp;
148
419
			ctarget = c;
149
419
			c = tmp;
150
		}
151
693
		x0 = j0;
152
693
		x1 = j1;
153
693
		x2 = j2;
154
693
		x3 = j3;
155
693
		x4 = j4;
156
693
		x5 = j5;
157
693
		x6 = j6;
158
693
		x7 = j7;
159
693
		x8 = j8;
160
693
		x9 = j9;
161
693
		x10 = j10;
162
693
		x11 = j11;
163
693
		x12 = j12;
164
693
		x13 = j13;
165
693
		x14 = j14;
166
693
		x15 = j15;
167
7623
		for (i = 20; i > 0; i -= 2) {
168
6930
			QUARTERROUND(x0, x4, x8, x12)
169
6930
			QUARTERROUND(x1, x5, x9, x13)
170
6930
			QUARTERROUND(x2, x6, x10, x14)
171
6930
			QUARTERROUND(x3, x7, x11, x15)
172
6930
			QUARTERROUND(x0, x5, x10, x15)
173
6930
			QUARTERROUND(x1, x6, x11, x12)
174
6930
			QUARTERROUND(x2, x7, x8, x13)
175
6930
			QUARTERROUND(x3, x4, x9, x14)
176
		}
177
693
		x0 = PLUS(x0, j0);
178
693
		x1 = PLUS(x1, j1);
179
693
		x2 = PLUS(x2, j2);
180
693
		x3 = PLUS(x3, j3);
181
693
		x4 = PLUS(x4, j4);
182
693
		x5 = PLUS(x5, j5);
183
693
		x6 = PLUS(x6, j6);
184
693
		x7 = PLUS(x7, j7);
185
693
		x8 = PLUS(x8, j8);
186
693
		x9 = PLUS(x9, j9);
187
693
		x10 = PLUS(x10, j10);
188
693
		x11 = PLUS(x11, j11);
189
693
		x12 = PLUS(x12, j12);
190
693
		x13 = PLUS(x13, j13);
191
693
		x14 = PLUS(x14, j14);
192
693
		x15 = PLUS(x15, j15);
193
194
693
		if (bytes < 64) {
195
419
			U32TO8_LITTLE(x->ks + 0, x0);
196
419
			U32TO8_LITTLE(x->ks + 4, x1);
197
419
			U32TO8_LITTLE(x->ks + 8, x2);
198
419
			U32TO8_LITTLE(x->ks + 12, x3);
199
419
			U32TO8_LITTLE(x->ks + 16, x4);
200
419
			U32TO8_LITTLE(x->ks + 20, x5);
201
419
			U32TO8_LITTLE(x->ks + 24, x6);
202
419
			U32TO8_LITTLE(x->ks + 28, x7);
203
419
			U32TO8_LITTLE(x->ks + 32, x8);
204
419
			U32TO8_LITTLE(x->ks + 36, x9);
205
419
			U32TO8_LITTLE(x->ks + 40, x10);
206
419
			U32TO8_LITTLE(x->ks + 44, x11);
207
419
			U32TO8_LITTLE(x->ks + 48, x12);
208
419
			U32TO8_LITTLE(x->ks + 52, x13);
209
419
			U32TO8_LITTLE(x->ks + 56, x14);
210
419
			U32TO8_LITTLE(x->ks + 60, x15);
211
		}
212
213
693
		x0 = XOR(x0, U8TO32_LITTLE(m + 0));
214
693
		x1 = XOR(x1, U8TO32_LITTLE(m + 4));
215
693
		x2 = XOR(x2, U8TO32_LITTLE(m + 8));
216
693
		x3 = XOR(x3, U8TO32_LITTLE(m + 12));
217
693
		x4 = XOR(x4, U8TO32_LITTLE(m + 16));
218
693
		x5 = XOR(x5, U8TO32_LITTLE(m + 20));
219
693
		x6 = XOR(x6, U8TO32_LITTLE(m + 24));
220
693
		x7 = XOR(x7, U8TO32_LITTLE(m + 28));
221
693
		x8 = XOR(x8, U8TO32_LITTLE(m + 32));
222
693
		x9 = XOR(x9, U8TO32_LITTLE(m + 36));
223
693
		x10 = XOR(x10, U8TO32_LITTLE(m + 40));
224
693
		x11 = XOR(x11, U8TO32_LITTLE(m + 44));
225
693
		x12 = XOR(x12, U8TO32_LITTLE(m + 48));
226
693
		x13 = XOR(x13, U8TO32_LITTLE(m + 52));
227
693
		x14 = XOR(x14, U8TO32_LITTLE(m + 56));
228
693
		x15 = XOR(x15, U8TO32_LITTLE(m + 60));
229
230
693
		j12 = PLUSONE(j12);
231
693
		if (!j12) {
232
			j13 = PLUSONE(j13);
233
			/*
234
			 * Stopping at 2^70 bytes per nonce is the user's
235
			 * responsibility.
236
			 */
237
		}
238
239
693
		U32TO8_LITTLE(c + 0, x0);
240
693
		U32TO8_LITTLE(c + 4, x1);
241
693
		U32TO8_LITTLE(c + 8, x2);
242
693
		U32TO8_LITTLE(c + 12, x3);
243
693
		U32TO8_LITTLE(c + 16, x4);
244
693
		U32TO8_LITTLE(c + 20, x5);
245
693
		U32TO8_LITTLE(c + 24, x6);
246
693
		U32TO8_LITTLE(c + 28, x7);
247
693
		U32TO8_LITTLE(c + 32, x8);
248
693
		U32TO8_LITTLE(c + 36, x9);
249
693
		U32TO8_LITTLE(c + 40, x10);
250
693
		U32TO8_LITTLE(c + 44, x11);
251
693
		U32TO8_LITTLE(c + 48, x12);
252
693
		U32TO8_LITTLE(c + 52, x13);
253
693
		U32TO8_LITTLE(c + 56, x14);
254
693
		U32TO8_LITTLE(c + 60, x15);
255
256
693
		if (bytes <= 64) {
257
443
			if (bytes < 64) {
258
13277
				for (i = 0; i < bytes; ++i)
259
12858
					ctarget[i] = c[i];
260
			}
261
443
			x->input[12] = j12;
262
443
			x->input[13] = j13;
263
443
			x->unused = 64 - bytes;
264
443
			return;
265
		}
266
250
		bytes -= 64;
267
250
		c += 64;
268
250
		m += 64;
269
250
	}
270
}