summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto
diff options
context:
space:
mode:
authorjsing <>2014-05-01 13:15:22 +0000
committerjsing <>2014-05-01 13:15:22 +0000
commit01bc5de569d5ec2e77fcaec43eae5ce76f9c3800 (patch)
tree84ee4c644a7257b0b1e244eb263e26464f79887b /src/lib/libcrypto
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@
Diffstat (limited to 'src/lib/libcrypto')
-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
4 files changed, 320 insertions, 1 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 \