summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2014-05-01 13:15:22 +0000
committerjsing <>2014-05-01 13:15:22 +0000
commit01bc5de569d5ec2e77fcaec43eae5ce76f9c3800 (patch)
tree84ee4c644a7257b0b1e244eb263e26464f79887b
parenta4b876b424f6cd1cc57b8a19f1d0a213cf99013c (diff)
downloadopenbsd-01bc5de569d5ec2e77fcaec43eae5ce76f9c3800.tar.gz
openbsd-01bc5de569d5ec2e77fcaec43eae5ce76f9c3800.tar.bz2
openbsd-01bc5de569d5ec2e77fcaec43eae5ce76f9c3800.zip
Add ChaCha to libcrypto, based on djb's public domain implementation.
ok deraadt@
-rw-r--r--src/lib/libcrypto/chacha/chacha-merged.c237
-rw-r--r--src/lib/libcrypto/chacha/chacha.c38
-rw-r--r--src/lib/libcrypto/chacha/chacha.h39
-rw-r--r--src/lib/libcrypto/crypto/Makefile7
-rw-r--r--src/lib/libssl/src/crypto/chacha/chacha-merged.c237
-rw-r--r--src/lib/libssl/src/crypto/chacha/chacha.c38
-rw-r--r--src/lib/libssl/src/crypto/chacha/chacha.h39
-rw-r--r--src/regress/lib/libcrypto/Makefile3
-rw-r--r--src/regress/lib/libcrypto/chacha/Makefile7
-rw-r--r--src/regress/lib/libcrypto/chacha/chachatest.c261
10 files changed, 904 insertions, 2 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}
diff --git a/src/lib/libcrypto/chacha/chacha.c b/src/lib/libcrypto/chacha/chacha.c
new file mode 100644
index 0000000000..d76d64de4a
--- /dev/null
+++ b/src/lib/libcrypto/chacha/chacha.c
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "chacha-merged.c"
18
19void
20CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len,
21 const unsigned char key[32], const unsigned char iv[8], size_t counter)
22{
23 struct chacha_ctx ctx;
24
25 /*
26 * chacha_ivsetup expects the counter to be in u8. Rather than
27 * converting size_t to u8 and then back again, pass a counter of
28 * NULL and manually assign it afterwards.
29 */
30 chacha_keysetup(&ctx, key, 256);
31 chacha_ivsetup(&ctx, iv, NULL);
32 if (counter != 0) {
33 ctx.input[12] = (uint32_t)counter;
34 ctx.input[13] = (uint32_t)(((uint64_t)counter) >> 32);
35 }
36
37 chacha_encrypt_bytes(&ctx, in, out, (uint32_t)len);
38}
diff --git a/src/lib/libcrypto/chacha/chacha.h b/src/lib/libcrypto/chacha/chacha.h
new file mode 100644
index 0000000000..d66a719ae4
--- /dev/null
+++ b/src/lib/libcrypto/chacha/chacha.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright (c) Joel Sing <jsing@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HEADER_CHACHA_H
18#define HEADER_CHACHA_H
19
20#include <openssl/opensslconf.h>
21
22#if defined(OPENSSL_NO_CHACHA)
23#error ChaCha is disabled.
24#endif
25
26#include <stddef.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32void CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len,
33 const unsigned char key[32], const unsigned char iv[8], size_t counter);
34
35#ifdef __cplusplus
36}
37#endif
38
39#endif /* HEADER_CHACHA_H */
diff --git a/src/lib/libcrypto/crypto/Makefile b/src/lib/libcrypto/crypto/Makefile
index fbd26e20da..20ac4e6a37 100644
--- a/src/lib/libcrypto/crypto/Makefile
+++ b/src/lib/libcrypto/crypto/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.28 2014/04/27 16:19:04 jsing Exp $ 1# $OpenBSD: Makefile,v 1.29 2014/05/01 13:15:22 jsing Exp $
2 2
3LIB= crypto 3LIB= crypto
4 4
@@ -76,6 +76,9 @@ SRCS+= buffer.c buf_err.c buf_str.c
76# cast/ 76# cast/
77SRCS+= c_skey.c c_ecb.c c_enc.c c_cfb64.c c_ofb64.c 77SRCS+= c_skey.c c_ecb.c c_enc.c c_cfb64.c c_ofb64.c
78 78
79# chacha/
80SRCS+= chacha.c
81
79# cmac/ 82# cmac/
80SRCS+= cmac.c cm_ameth.c cm_pmeth.c 83SRCS+= cmac.c cm_ameth.c cm_pmeth.c
81 84
@@ -271,6 +274,7 @@ SRCS+= v3_asid.c v3_addr.c
271 ${LCRYPTO_SRC}/buffer \ 274 ${LCRYPTO_SRC}/buffer \
272 ${LCRYPTO_SRC}/camellia \ 275 ${LCRYPTO_SRC}/camellia \
273 ${LCRYPTO_SRC}/cast \ 276 ${LCRYPTO_SRC}/cast \
277 ${LCRYPTO_SRC}/chacha \
274 ${LCRYPTO_SRC}/cmac \ 278 ${LCRYPTO_SRC}/cmac \
275 ${LCRYPTO_SRC}/cms \ 279 ${LCRYPTO_SRC}/cms \
276 ${LCRYPTO_SRC}/comp \ 280 ${LCRYPTO_SRC}/comp \
@@ -329,6 +333,7 @@ HDRS=\
329 crypto/buffer/buffer.h \ 333 crypto/buffer/buffer.h \
330 crypto/camellia/camellia.h \ 334 crypto/camellia/camellia.h \
331 crypto/cast/cast.h \ 335 crypto/cast/cast.h \
336 crypto/chacha/chacha.h \
332 crypto/cmac/cmac.h \ 337 crypto/cmac/cmac.h \
333 crypto/cms/cms.h \ 338 crypto/cms/cms.h \
334 crypto/comp/comp.h \ 339 crypto/comp/comp.h \
diff --git a/src/lib/libssl/src/crypto/chacha/chacha-merged.c b/src/lib/libssl/src/crypto/chacha/chacha-merged.c
new file mode 100644
index 0000000000..a31d8a8301
--- /dev/null
+++ b/src/lib/libssl/src/crypto/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}
diff --git a/src/lib/libssl/src/crypto/chacha/chacha.c b/src/lib/libssl/src/crypto/chacha/chacha.c
new file mode 100644
index 0000000000..d76d64de4a
--- /dev/null
+++ b/src/lib/libssl/src/crypto/chacha/chacha.c
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "chacha-merged.c"
18
19void
20CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len,
21 const unsigned char key[32], const unsigned char iv[8], size_t counter)
22{
23 struct chacha_ctx ctx;
24
25 /*
26 * chacha_ivsetup expects the counter to be in u8. Rather than
27 * converting size_t to u8 and then back again, pass a counter of
28 * NULL and manually assign it afterwards.
29 */
30 chacha_keysetup(&ctx, key, 256);
31 chacha_ivsetup(&ctx, iv, NULL);
32 if (counter != 0) {
33 ctx.input[12] = (uint32_t)counter;
34 ctx.input[13] = (uint32_t)(((uint64_t)counter) >> 32);
35 }
36
37 chacha_encrypt_bytes(&ctx, in, out, (uint32_t)len);
38}
diff --git a/src/lib/libssl/src/crypto/chacha/chacha.h b/src/lib/libssl/src/crypto/chacha/chacha.h
new file mode 100644
index 0000000000..d66a719ae4
--- /dev/null
+++ b/src/lib/libssl/src/crypto/chacha/chacha.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright (c) Joel Sing <jsing@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HEADER_CHACHA_H
18#define HEADER_CHACHA_H
19
20#include <openssl/opensslconf.h>
21
22#if defined(OPENSSL_NO_CHACHA)
23#error ChaCha is disabled.
24#endif
25
26#include <stddef.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32void CRYPTO_chacha_20(unsigned char *out, const unsigned char *in, size_t len,
33 const unsigned char key[32], const unsigned char iv[8], size_t counter);
34
35#ifdef __cplusplus
36}
37#endif
38
39#endif /* HEADER_CHACHA_H */
diff --git a/src/regress/lib/libcrypto/Makefile b/src/regress/lib/libcrypto/Makefile
index df9e45f96a..436fb12598 100644
--- a/src/regress/lib/libcrypto/Makefile
+++ b/src/regress/lib/libcrypto/Makefile
@@ -1,10 +1,11 @@
1# $OpenBSD: Makefile,v 1.4 2014/04/22 21:27:13 miod Exp $ 1# $OpenBSD: Makefile,v 1.5 2014/05/01 13:15:22 jsing Exp $
2 2
3SUBDIR= \ 3SUBDIR= \
4 aeswrap \ 4 aeswrap \
5 bf \ 5 bf \
6 bn \ 6 bn \
7 cast \ 7 cast \
8 chacha \
8 des \ 9 des \
9 dh \ 10 dh \
10 dsa \ 11 dsa \
diff --git a/src/regress/lib/libcrypto/chacha/Makefile b/src/regress/lib/libcrypto/chacha/Makefile
new file mode 100644
index 0000000000..b09dda17a1
--- /dev/null
+++ b/src/regress/lib/libcrypto/chacha/Makefile
@@ -0,0 +1,7 @@
1# $OpenBSD: Makefile,v 1.1 2014/05/01 13:15:22 jsing Exp $
2
3PROG= chachatest
4LDADD= -lcrypto
5DPADD= ${LIBCRYPTO}
6
7.include <bsd.regress.mk>
diff --git a/src/regress/lib/libcrypto/chacha/chachatest.c b/src/regress/lib/libcrypto/chacha/chachatest.c
new file mode 100644
index 0000000000..ff67fbf59a
--- /dev/null
+++ b/src/regress/lib/libcrypto/chacha/chachatest.c
@@ -0,0 +1,261 @@
1/*
2 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <err.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22#include <openssl/chacha.h>
23
24struct chacha_tv {
25 const char *desc;
26 const unsigned char key[32];
27 const unsigned char iv[8];
28 const size_t len;
29 const unsigned char out[512];
30};
31
32/*
33 * Test vectors from:
34 * http://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-01
35 */
36struct chacha_tv chacha_test_vectors[] = {
37 {
38 "TC1: All zero key and IV",
39 {
40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 },
45 {
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 },
48 64,
49 {
50 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90,
51 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28,
52 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a,
53 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7,
54 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d,
55 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37,
56 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c,
57 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86,
58 },
59 },
60 {
61 "TC2: Single bit in key set, all zero IV",
62 {
63 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 },
68 {
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 },
71 64,
72 {
73 0xc5, 0xd3, 0x0a, 0x7c, 0xe1, 0xec, 0x11, 0x93,
74 0x78, 0xc8, 0x4f, 0x48, 0x7d, 0x77, 0x5a, 0x85,
75 0x42, 0xf1, 0x3e, 0xce, 0x23, 0x8a, 0x94, 0x55,
76 0xe8, 0x22, 0x9e, 0x88, 0x8d, 0xe8, 0x5b, 0xbd,
77 0x29, 0xeb, 0x63, 0xd0, 0xa1, 0x7a, 0x5b, 0x99,
78 0x9b, 0x52, 0xda, 0x22, 0xbe, 0x40, 0x23, 0xeb,
79 0x07, 0x62, 0x0a, 0x54, 0xf6, 0xfa, 0x6a, 0xd8,
80 0x73, 0x7b, 0x71, 0xeb, 0x04, 0x64, 0xda, 0xc0,
81 },
82 },
83 {
84 "TC3: Single bit in IV set, all zero key",
85 {
86 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
87 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
88 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
89 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
90 },
91 {
92 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
93 },
94 64,
95 {
96 0xd9, 0xbf, 0x3f, 0x6b, 0xce, 0x6e, 0xd0, 0xb5,
97 0x42, 0x54, 0x55, 0x77, 0x67, 0xfb, 0x57, 0x44,
98 0x3d, 0xd4, 0x77, 0x89, 0x11, 0xb6, 0x06, 0x05,
99 0x5c, 0x39, 0xcc, 0x25, 0xe6, 0x74, 0xb8, 0x36,
100 0x3f, 0xea, 0xbc, 0x57, 0xfd, 0xe5, 0x4f, 0x79,
101 0x0c, 0x52, 0xc8, 0xae, 0x43, 0x24, 0x0b, 0x79,
102 0xd4, 0x90, 0x42, 0xb7, 0x77, 0xbf, 0xd6, 0xcb,
103 0x80, 0xe9, 0x31, 0x27, 0x0b, 0x7f, 0x50, 0xeb,
104 },
105 },
106 {
107 "TC4: All bits in key and IV are set",
108 {
109 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
110 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
111 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
112 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
113 },
114 {
115 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
116 },
117 64,
118 {
119 0xaf, 0xf7, 0x41, 0x82, 0x93, 0xf3, 0xa5, 0x53,
120 0x89, 0x4b, 0x1e, 0x74, 0x84, 0xbd, 0x1e, 0x8e,
121 0xde, 0x19, 0x6e, 0xce, 0xd5, 0xa1, 0xd6, 0x81,
122 0x4d, 0xe3, 0x70, 0x91, 0xe0, 0x7e, 0x07, 0x6e,
123 0x34, 0xbb, 0xba, 0x81, 0x07, 0xa6, 0x86, 0xc9,
124 0x82, 0x85, 0x0f, 0x0a, 0x73, 0x53, 0x94, 0x0d,
125 0x40, 0xdb, 0x1a, 0xb0, 0xb5, 0x76, 0x5b, 0x78,
126 0xb4, 0xcf, 0x47, 0x3d, 0x94, 0x85, 0xa3, 0xdd,
127 },
128 },
129 {
130 "TC5: Every even bit set in key and IV",
131 {
132 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
133 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
134 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
135 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
136 },
137 {
138 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
139 },
140 64,
141 {
142 0xbe, 0xa9, 0x41, 0x1a, 0xa4, 0x53, 0xc5, 0x43,
143 0x4a, 0x5a, 0xe8, 0xc9, 0x28, 0x62, 0xf5, 0x64,
144 0x39, 0x68, 0x55, 0xa9, 0xea, 0x6e, 0x22, 0xd6,
145 0xd3, 0xb5, 0x0a, 0xe1, 0xb3, 0x66, 0x33, 0x11,
146 0xa4, 0xa3, 0x60, 0x6c, 0x67, 0x1d, 0x60, 0x5c,
147 0xe1, 0x6c, 0x3a, 0xec, 0xe8, 0xe6, 0x1e, 0xa1,
148 0x45, 0xc5, 0x97, 0x75, 0x01, 0x7b, 0xee, 0x2f,
149 0xa6, 0xf8, 0x8a, 0xfc, 0x75, 0x80, 0x69, 0xf7,
150 },
151 },
152 {
153 "TC6: Every odd bit set in key and IV",
154 {
155 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
156 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
157 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
158 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
159 },
160 {
161 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
162 },
163 64,
164 {
165 0x9a, 0xa2, 0xa9, 0xf6, 0x56, 0xef, 0xde, 0x5a,
166 0xa7, 0x59, 0x1c, 0x5f, 0xed, 0x4b, 0x35, 0xae,
167 0xa2, 0x89, 0x5d, 0xec, 0x7c, 0xb4, 0x54, 0x3b,
168 0x9e, 0x9f, 0x21, 0xf5, 0xe7, 0xbc, 0xbc, 0xf3,
169 0xc4, 0x3c, 0x74, 0x8a, 0x97, 0x08, 0x88, 0xf8,
170 0x24, 0x83, 0x93, 0xa0, 0x9d, 0x43, 0xe0, 0xb7,
171 0xe1, 0x64, 0xbc, 0x4d, 0x0b, 0x0f, 0xb2, 0x40,
172 0xa2, 0xd7, 0x21, 0x15, 0xc4, 0x80, 0x89, 0x06,
173 },
174 },
175 {
176 "TC7: Sequence patterns in key and IV",
177 {
178 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
179 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
180 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88,
181 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00,
182 },
183 {
184 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78,
185 },
186 64,
187 {
188 0x9f, 0xad, 0xf4, 0x09, 0xc0, 0x08, 0x11, 0xd0,
189 0x04, 0x31, 0xd6, 0x7e, 0xfb, 0xd8, 0x8f, 0xba,
190 0x59, 0x21, 0x8d, 0x5d, 0x67, 0x08, 0xb1, 0xd6,
191 0x85, 0x86, 0x3f, 0xab, 0xbb, 0x0e, 0x96, 0x1e,
192 0xea, 0x48, 0x0f, 0xd6, 0xfb, 0x53, 0x2b, 0xfd,
193 0x49, 0x4b, 0x21, 0x51, 0x01, 0x50, 0x57, 0x42,
194 0x3a, 0xb6, 0x0a, 0x63, 0xfe, 0x4f, 0x55, 0xf7,
195 0xa2, 0x12, 0xe2, 0x16, 0x7c, 0xca, 0xb9, 0x31,
196 },
197 },
198 {
199 "TC8: key: 'All your base are belong to us!, IV: 'IETF2013'",
200 {
201 0xc4, 0x6e, 0xc1, 0xb1, 0x8c, 0xe8, 0xa8, 0x78,
202 0x72, 0x5a, 0x37, 0xe7, 0x80, 0xdf, 0xb7, 0x35,
203 0x1f, 0x68, 0xed, 0x2e, 0x19, 0x4c, 0x79, 0xfb,
204 0xc6, 0xae, 0xbe, 0xe1, 0xa6, 0x67, 0x97, 0x5d,
205 },
206 {
207 0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21,
208 },
209 64,
210 {
211 0xf6, 0x3a, 0x89, 0xb7, 0x5c, 0x22, 0x71, 0xf9,
212 0x36, 0x88, 0x16, 0x54, 0x2b, 0xa5, 0x2f, 0x06,
213 0xed, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2b, 0x00,
214 0xb5, 0xe8, 0xf8, 0x0a, 0xe9, 0xa4, 0x73, 0xaf,
215 0xc2, 0x5b, 0x21, 0x8f, 0x51, 0x9a, 0xf0, 0xfd,
216 0xd4, 0x06, 0x36, 0x2e, 0x8d, 0x69, 0xde, 0x7f,
217 0x54, 0xc6, 0x04, 0xa6, 0xe0, 0x0f, 0x35, 0x3f,
218 0x11, 0x0f, 0x77, 0x1b, 0xdc, 0xa8, 0xab, 0x92,
219 },
220 },
221};
222
223#define N_VECTORS (sizeof(chacha_test_vectors) / sizeof(*chacha_test_vectors))
224
225int
226main(int argc, char **argv)
227{
228 struct chacha_tv *tv;
229 unsigned char *in, *out;
230 int i, j;
231
232 for (i = 0; i < N_VECTORS; i++) {
233 tv = &chacha_test_vectors[i];
234
235 in = malloc(tv->len);
236 if (in == NULL)
237 errx(1, "malloc in");
238 out = malloc(tv->len);
239 if (out == NULL)
240 errx(1, "malloc out");
241 memset(in, 0, tv->len);
242
243 CRYPTO_chacha_20(out, in, tv->len, tv->key, tv->iv, 0);
244
245 if (memcmp(out, tv->out, tv->len) != 0) {
246 printf("ChaCha %s failed!\n", tv->desc);
247 for (j = 0; j < tv->len; j++)
248 printf("%2.2x", out[j]);
249 printf("\n");
250 for (j = 0; j < tv->len; j++)
251 printf("%2.2x", tv->out[j]);
252 printf("\n");
253 return 1;
254 }
255
256 free(in);
257 free(out);
258 }
259
260 return 0;
261}