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