File Coverage

src/chacha/chacha.c
Criterion Covered Total %
statement 129 134 96.2
branch 16 22 72.7
condition n/a
subroutine n/a
pod n/a
total 145 156 92.9


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