File: | crypto/chacha_private.h |
Warning: | line 121, column 16 Array access (via field 'input') results in a null pointer dereference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: chachapoly.c,v 1.6 2020/07/22 13:54:30 tobhe Exp $ */ | |||
2 | /* | |||
3 | * Copyright (c) 2015 Mike Belopuhov | |||
4 | * | |||
5 | * Permission to use, copy, modify, and distribute this software for any | |||
6 | * purpose with or without fee is hereby granted, provided that the above | |||
7 | * copyright notice and this permission notice appear in all copies. | |||
8 | * | |||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
16 | */ | |||
17 | ||||
18 | #include <sys/param.h> | |||
19 | #include <sys/systm.h> | |||
20 | #include <lib/libkern/libkern.h> | |||
21 | ||||
22 | #include <crypto/chacha_private.h> | |||
23 | #include <crypto/poly1305.h> | |||
24 | #include <crypto/chachapoly.h> | |||
25 | ||||
26 | int | |||
27 | chacha20_setkey(void *sched, u_int8_t *key, int len) | |||
28 | { | |||
29 | struct chacha20_ctx *ctx = (struct chacha20_ctx *)sched; | |||
30 | ||||
31 | if (len != CHACHA20_KEYSIZE32 + CHACHA20_SALT4) | |||
32 | return (-1); | |||
33 | ||||
34 | /* initial counter is 1 */ | |||
35 | ctx->nonce[0] = 1; | |||
36 | memcpy(ctx->nonce + CHACHA20_CTR, key + CHACHA20_KEYSIZE,__builtin_memcpy((ctx->nonce + 4), (key + 32), (4)) | |||
37 | CHACHA20_SALT)__builtin_memcpy((ctx->nonce + 4), (key + 32), (4)); | |||
38 | chacha_keysetup((chacha_ctx *)&ctx->block, key, CHACHA20_KEYSIZE32 * 8); | |||
39 | return (0); | |||
40 | } | |||
41 | ||||
42 | void | |||
43 | chacha20_reinit(caddr_t key, u_int8_t *iv) | |||
44 | { | |||
45 | struct chacha20_ctx *ctx = (struct chacha20_ctx *)key; | |||
46 | ||||
47 | chacha_ivsetup((chacha_ctx *)ctx->block, iv, ctx->nonce); | |||
| ||||
48 | } | |||
49 | ||||
50 | void | |||
51 | chacha20_crypt(caddr_t key, u_int8_t *data) | |||
52 | { | |||
53 | struct chacha20_ctx *ctx = (struct chacha20_ctx *)key; | |||
54 | ||||
55 | chacha_encrypt_bytes((chacha_ctx *)ctx->block, data, data, | |||
56 | CHACHA20_BLOCK_LEN64); | |||
57 | } | |||
58 | ||||
59 | void | |||
60 | Chacha20_Poly1305_Init(void *xctx) | |||
61 | { | |||
62 | CHACHA20_POLY1305_CTX *ctx = xctx; | |||
63 | ||||
64 | memset(ctx, 0, sizeof(*ctx))__builtin_memset((ctx), (0), (sizeof(*ctx))); | |||
65 | } | |||
66 | ||||
67 | void | |||
68 | Chacha20_Poly1305_Setkey(void *xctx, const uint8_t *key, uint16_t klen) | |||
69 | { | |||
70 | CHACHA20_POLY1305_CTX *ctx = xctx; | |||
71 | ||||
72 | /* salt is provided with the key material */ | |||
73 | memcpy(ctx->nonce + CHACHA20_CTR, key + CHACHA20_KEYSIZE,__builtin_memcpy((ctx->nonce + 4), (key + 32), (4)) | |||
74 | CHACHA20_SALT)__builtin_memcpy((ctx->nonce + 4), (key + 32), (4)); | |||
75 | chacha_keysetup((chacha_ctx *)&ctx->chacha, key, CHACHA20_KEYSIZE32 * 8); | |||
76 | } | |||
77 | ||||
78 | void | |||
79 | Chacha20_Poly1305_Reinit(void *xctx, const uint8_t *iv, uint16_t ivlen) | |||
80 | { | |||
81 | CHACHA20_POLY1305_CTX *ctx = xctx; | |||
82 | ||||
83 | /* initial counter is 0 */ | |||
84 | chacha_ivsetup((chacha_ctx *)&ctx->chacha, iv, ctx->nonce); | |||
85 | chacha_encrypt_bytes((chacha_ctx *)&ctx->chacha, ctx->key, ctx->key, | |||
86 | POLY1305_KEYLEN32); | |||
87 | poly1305_init((poly1305_state *)&ctx->poly, ctx->key); | |||
88 | } | |||
89 | ||||
90 | int | |||
91 | Chacha20_Poly1305_Update(void *xctx, const uint8_t *data, uint16_t len) | |||
92 | { | |||
93 | static const char zeroes[POLY1305_BLOCK_LEN16]; | |||
94 | CHACHA20_POLY1305_CTX *ctx = xctx; | |||
95 | size_t rem; | |||
96 | ||||
97 | poly1305_update((poly1305_state *)&ctx->poly, data, len); | |||
98 | ||||
99 | /* number of bytes in the last 16 byte block */ | |||
100 | rem = (len + POLY1305_BLOCK_LEN16) & (POLY1305_BLOCK_LEN16 - 1); | |||
101 | if (rem > 0) | |||
102 | poly1305_update((poly1305_state *)&ctx->poly, zeroes, | |||
103 | POLY1305_BLOCK_LEN16 - rem); | |||
104 | return (0); | |||
105 | } | |||
106 | ||||
107 | void | |||
108 | Chacha20_Poly1305_Final(uint8_t tag[POLY1305_TAGLEN16], void *xctx) | |||
109 | { | |||
110 | CHACHA20_POLY1305_CTX *ctx = xctx; | |||
111 | ||||
112 | poly1305_finish((poly1305_state *)&ctx->poly, tag); | |||
113 | explicit_bzero(ctx, sizeof(*ctx)); | |||
114 | } | |||
115 | ||||
116 | static const uint8_t pad0[16] = { 0 }; | |||
117 | ||||
118 | void | |||
119 | chacha20poly1305_encrypt( | |||
120 | uint8_t *dst, | |||
121 | const uint8_t *src, | |||
122 | const size_t src_len, | |||
123 | const uint8_t *ad, | |||
124 | const size_t ad_len, | |||
125 | const uint64_t nonce, | |||
126 | const uint8_t key[CHACHA20POLY1305_KEY_SIZE32] | |||
127 | ) { | |||
128 | poly1305_state poly1305_ctx; | |||
129 | chacha_ctx chacha_ctx; | |||
130 | union { | |||
131 | uint8_t b0[CHACHA20POLY1305_KEY_SIZE32]; | |||
132 | uint64_t lens[2]; | |||
133 | } b = { { 0 } }; | |||
134 | uint64_t le_nonce = htole64(nonce)((__uint64_t)(nonce)); | |||
135 | ||||
136 | chacha_keysetup(&chacha_ctx, key, CHACHA20POLY1305_KEY_SIZE32 * 8); | |||
137 | chacha_ivsetup(&chacha_ctx, (uint8_t *) &le_nonce, NULL((void *)0)); | |||
138 | chacha_encrypt_bytes(&chacha_ctx, b.b0, b.b0, sizeof(b.b0)); | |||
139 | poly1305_init(&poly1305_ctx, b.b0); | |||
140 | ||||
141 | poly1305_update(&poly1305_ctx, ad, ad_len); | |||
142 | poly1305_update(&poly1305_ctx, pad0, (0x10 - ad_len) & 0xf); | |||
143 | ||||
144 | chacha_encrypt_bytes(&chacha_ctx, (uint8_t *) src, dst, src_len); | |||
145 | ||||
146 | poly1305_update(&poly1305_ctx, dst, src_len); | |||
147 | poly1305_update(&poly1305_ctx, pad0, (0x10 - src_len) & 0xf); | |||
148 | ||||
149 | b.lens[0] = htole64(ad_len)((__uint64_t)(ad_len)); | |||
150 | b.lens[1] = htole64(src_len)((__uint64_t)(src_len)); | |||
151 | poly1305_update(&poly1305_ctx, (uint8_t *)b.lens, sizeof(b.lens)); | |||
152 | ||||
153 | poly1305_finish(&poly1305_ctx, dst + src_len); | |||
154 | ||||
155 | explicit_bzero(&chacha_ctx, sizeof(chacha_ctx)); | |||
156 | explicit_bzero(&b, sizeof(b)); | |||
157 | } | |||
158 | ||||
159 | int | |||
160 | chacha20poly1305_decrypt( | |||
161 | uint8_t *dst, | |||
162 | const uint8_t *src, | |||
163 | const size_t src_len, | |||
164 | const uint8_t *ad, | |||
165 | const size_t ad_len, | |||
166 | const uint64_t nonce, | |||
167 | const uint8_t key[CHACHA20POLY1305_KEY_SIZE32] | |||
168 | ) { | |||
169 | poly1305_state poly1305_ctx; | |||
170 | chacha_ctx chacha_ctx; | |||
171 | int ret; | |||
172 | size_t dst_len; | |||
173 | union { | |||
174 | uint8_t b0[CHACHA20POLY1305_KEY_SIZE32]; | |||
175 | uint8_t mac[CHACHA20POLY1305_AUTHTAG_SIZE16]; | |||
176 | uint64_t lens[2]; | |||
177 | } b = { { 0 } }; | |||
178 | uint64_t le_nonce = htole64(nonce)((__uint64_t)(nonce)); | |||
179 | ||||
180 | if (src_len < CHACHA20POLY1305_AUTHTAG_SIZE16) | |||
181 | return 0; | |||
182 | ||||
183 | chacha_keysetup(&chacha_ctx, key, CHACHA20POLY1305_KEY_SIZE32 * 8); | |||
184 | chacha_ivsetup(&chacha_ctx, (uint8_t *) &le_nonce, NULL((void *)0)); | |||
185 | chacha_encrypt_bytes(&chacha_ctx, b.b0, b.b0, sizeof(b.b0)); | |||
186 | poly1305_init(&poly1305_ctx, b.b0); | |||
187 | ||||
188 | poly1305_update(&poly1305_ctx, ad, ad_len); | |||
189 | poly1305_update(&poly1305_ctx, pad0, (0x10 - ad_len) & 0xf); | |||
190 | ||||
191 | dst_len = src_len - CHACHA20POLY1305_AUTHTAG_SIZE16; | |||
192 | poly1305_update(&poly1305_ctx, src, dst_len); | |||
193 | poly1305_update(&poly1305_ctx, pad0, (0x10 - dst_len) & 0xf); | |||
194 | ||||
195 | b.lens[0] = htole64(ad_len)((__uint64_t)(ad_len)); | |||
196 | b.lens[1] = htole64(dst_len)((__uint64_t)(dst_len)); | |||
197 | poly1305_update(&poly1305_ctx, (uint8_t *)b.lens, sizeof(b.lens)); | |||
198 | ||||
199 | poly1305_finish(&poly1305_ctx, b.mac); | |||
200 | ||||
201 | ret = timingsafe_bcmp(b.mac, src + dst_len, CHACHA20POLY1305_AUTHTAG_SIZE16); | |||
202 | if (!ret) | |||
203 | chacha_encrypt_bytes(&chacha_ctx, (uint8_t *) src, dst, dst_len); | |||
204 | ||||
205 | explicit_bzero(&chacha_ctx, sizeof(chacha_ctx)); | |||
206 | explicit_bzero(&b, sizeof(b)); | |||
207 | ||||
208 | return !ret; | |||
209 | } | |||
210 | ||||
211 | void | |||
212 | xchacha20poly1305_encrypt( | |||
213 | uint8_t *dst, | |||
214 | const uint8_t *src, | |||
215 | const size_t src_len, | |||
216 | const uint8_t *ad, | |||
217 | const size_t ad_len, | |||
218 | const uint8_t nonce[XCHACHA20POLY1305_NONCE_SIZE24], | |||
219 | const uint8_t key[CHACHA20POLY1305_KEY_SIZE32] | |||
220 | ) { | |||
221 | int i; | |||
222 | uint32_t derived_key[CHACHA20POLY1305_KEY_SIZE32 / sizeof(uint32_t)]; | |||
223 | uint64_t h_nonce; | |||
224 | ||||
225 | memcpy(&h_nonce, nonce + 16, sizeof(h_nonce))__builtin_memcpy((&h_nonce), (nonce + 16), (sizeof(h_nonce ))); | |||
226 | h_nonce = le64toh(h_nonce)((__uint64_t)(h_nonce)); | |||
227 | hchacha20(derived_key, nonce, key); | |||
228 | ||||
229 | for(i = 0; i < (sizeof(derived_key)/sizeof(derived_key[0])); i++) | |||
230 | (derived_key[i]) = htole32((derived_key[i]))((__uint32_t)((derived_key[i]))); | |||
231 | ||||
232 | chacha20poly1305_encrypt(dst, src, src_len, ad, ad_len, | |||
233 | h_nonce, (uint8_t *)derived_key); | |||
234 | explicit_bzero(derived_key, CHACHA20POLY1305_KEY_SIZE32); | |||
235 | } | |||
236 | ||||
237 | int | |||
238 | xchacha20poly1305_decrypt( | |||
239 | uint8_t *dst, | |||
240 | const uint8_t *src, | |||
241 | const size_t src_len, | |||
242 | const uint8_t *ad, | |||
243 | const size_t ad_len, | |||
244 | const uint8_t nonce[XCHACHA20POLY1305_NONCE_SIZE24], | |||
245 | const uint8_t key[CHACHA20POLY1305_KEY_SIZE32] | |||
246 | ) { | |||
247 | int ret, i; | |||
248 | uint32_t derived_key[CHACHA20POLY1305_KEY_SIZE32 / sizeof(uint32_t)]; | |||
249 | uint64_t h_nonce; | |||
250 | ||||
251 | memcpy(&h_nonce, nonce + 16, sizeof(h_nonce))__builtin_memcpy((&h_nonce), (nonce + 16), (sizeof(h_nonce ))); | |||
252 | h_nonce = le64toh(h_nonce)((__uint64_t)(h_nonce)); | |||
253 | hchacha20(derived_key, nonce, key); | |||
254 | for(i = 0; i < (sizeof(derived_key)/sizeof(derived_key[0])); i++) | |||
255 | (derived_key[i]) = htole32((derived_key[i]))((__uint32_t)((derived_key[i]))); | |||
256 | ||||
257 | ret = chacha20poly1305_decrypt(dst, src, src_len, ad, ad_len, | |||
258 | h_nonce, (uint8_t *)derived_key); | |||
259 | explicit_bzero(derived_key, CHACHA20POLY1305_KEY_SIZE32); | |||
260 | ||||
261 | return ret; | |||
262 | } |
1 | /* $OpenBSD: chacha_private.h,v 1.4 2020/07/22 13:54:30 tobhe Exp $ */ | |||
2 | /* | |||
3 | chacha-merged.c version 20080118 | |||
4 | D. J. Bernstein | |||
5 | Public domain. | |||
6 | */ | |||
7 | ||||
8 | #include <sys/systm.h> | |||
9 | ||||
10 | typedef unsigned char u8; | |||
11 | typedef unsigned int u32; | |||
12 | ||||
13 | typedef struct | |||
14 | { | |||
15 | u32 input[16]; /* could be compressed */ | |||
16 | } chacha_ctx; | |||
17 | ||||
18 | #define U8C(v)(vU) (v##U) | |||
19 | #define U32C(v)(vU) (v##U) | |||
20 | ||||
21 | #define U8V(v)((u8)(v) & (0xFFU)) ((u8)(v) & U8C(0xFF)(0xFFU)) | |||
22 | #define U32V(v)((u32)(v) & (0xFFFFFFFFU)) ((u32)(v) & U32C(0xFFFFFFFF)(0xFFFFFFFFU)) | |||
23 | ||||
24 | #define ROTL32(v, n)(((u32)((v) << (n)) & (0xFFFFFFFFU)) | ((v) >> (32 - (n)))) \ | |||
25 | (U32V((v) << (n))((u32)((v) << (n)) & (0xFFFFFFFFU)) | ((v) >> (32 - (n)))) | |||
26 | ||||
27 | #define U8TO32_LITTLE(p)(((u32)((p)[0]) ) | ((u32)((p)[1]) << 8) | ((u32)((p)[2 ]) << 16) | ((u32)((p)[3]) << 24)) \ | |||
28 | (((u32)((p)[0]) ) | \ | |||
29 | ((u32)((p)[1]) << 8) | \ | |||
30 | ((u32)((p)[2]) << 16) | \ | |||
31 | ((u32)((p)[3]) << 24)) | |||
32 | ||||
33 | #define U32TO8_LITTLE(p, v)do { (p)[0] = ((u8)((v)) & (0xFFU)); (p)[1] = ((u8)((v) >> 8) & (0xFFU)); (p)[2] = ((u8)((v) >> 16) & (0xFFU )); (p)[3] = ((u8)((v) >> 24) & (0xFFU)); } while ( 0) \ | |||
34 | do { \ | |||
35 | (p)[0] = U8V((v) )((u8)((v)) & (0xFFU)); \ | |||
36 | (p)[1] = U8V((v) >> 8)((u8)((v) >> 8) & (0xFFU)); \ | |||
37 | (p)[2] = U8V((v) >> 16)((u8)((v) >> 16) & (0xFFU)); \ | |||
38 | (p)[3] = U8V((v) >> 24)((u8)((v) >> 24) & (0xFFU)); \ | |||
39 | } while (0) | |||
40 | ||||
41 | #define ROTATE(v,c)((((u32)((v) << (c)) & (0xFFFFFFFFU)) | ((v) >> (32 - (c))))) (ROTL32(v,c)(((u32)((v) << (c)) & (0xFFFFFFFFU)) | ((v) >> (32 - (c))))) | |||
42 | #define XOR(v,w)((v) ^ (w)) ((v) ^ (w)) | |||
43 | #define PLUS(v,w)(((u32)((v) + (w)) & (0xFFFFFFFFU))) (U32V((v) + (w))((u32)((v) + (w)) & (0xFFFFFFFFU))) | |||
44 | #define PLUSONE(v)((((u32)(((v)) + (1)) & (0xFFFFFFFFU)))) (PLUS((v),1)(((u32)(((v)) + (1)) & (0xFFFFFFFFU)))) | |||
45 | ||||
46 | #define QUARTERROUND(a,b,c,d)a = (((u32)((a) + (b)) & (0xFFFFFFFFU))); d = ((((u32)((( (d) ^ (a))) << (16)) & (0xFFFFFFFFU)) | ((((d) ^ (a ))) >> (32 - (16))))); c = (((u32)((c) + (d)) & (0xFFFFFFFFU ))); b = ((((u32)((((b) ^ (c))) << (12)) & (0xFFFFFFFFU )) | ((((b) ^ (c))) >> (32 - (12))))); a = (((u32)((a) + (b)) & (0xFFFFFFFFU))); d = ((((u32)((((d) ^ (a))) << (8)) & (0xFFFFFFFFU)) | ((((d) ^ (a))) >> (32 - (8 ))))); c = (((u32)((c) + (d)) & (0xFFFFFFFFU))); b = (((( u32)((((b) ^ (c))) << (7)) & (0xFFFFFFFFU)) | ((((b ) ^ (c))) >> (32 - (7))))); \ | |||
47 | a = PLUS(a,b)(((u32)((a) + (b)) & (0xFFFFFFFFU))); d = ROTATE(XOR(d,a),16)((((u32)((((d) ^ (a))) << (16)) & (0xFFFFFFFFU)) | ( (((d) ^ (a))) >> (32 - (16))))); \ | |||
48 | c = PLUS(c,d)(((u32)((c) + (d)) & (0xFFFFFFFFU))); b = ROTATE(XOR(b,c),12)((((u32)((((b) ^ (c))) << (12)) & (0xFFFFFFFFU)) | ( (((b) ^ (c))) >> (32 - (12))))); \ | |||
49 | a = PLUS(a,b)(((u32)((a) + (b)) & (0xFFFFFFFFU))); d = ROTATE(XOR(d,a), 8)((((u32)((((d) ^ (a))) << (8)) & (0xFFFFFFFFU)) | ( (((d) ^ (a))) >> (32 - (8))))); \ | |||
50 | c = PLUS(c,d)(((u32)((c) + (d)) & (0xFFFFFFFFU))); b = ROTATE(XOR(b,c), 7)((((u32)((((b) ^ (c))) << (7)) & (0xFFFFFFFFU)) | ( (((b) ^ (c))) >> (32 - (7))))); | |||
51 | ||||
52 | static const char sigma[16] = "expand 32-byte k"; | |||
53 | static const char tau[16] = "expand 16-byte k"; | |||
54 | ||||
55 | static inline void | |||
56 | hchacha20(u32 derived_key[8], const u8 nonce[16], const u8 key[32]) | |||
57 | { | |||
58 | int i; | |||
59 | uint32_t x[] = { | |||
60 | U8TO32_LITTLE(sigma + 0)(((u32)((sigma + 0)[0]) ) | ((u32)((sigma + 0)[1]) << 8 ) | ((u32)((sigma + 0)[2]) << 16) | ((u32)((sigma + 0)[ 3]) << 24)), | |||
61 | U8TO32_LITTLE(sigma + 4)(((u32)((sigma + 4)[0]) ) | ((u32)((sigma + 4)[1]) << 8 ) | ((u32)((sigma + 4)[2]) << 16) | ((u32)((sigma + 4)[ 3]) << 24)), | |||
62 | U8TO32_LITTLE(sigma + 8)(((u32)((sigma + 8)[0]) ) | ((u32)((sigma + 8)[1]) << 8 ) | ((u32)((sigma + 8)[2]) << 16) | ((u32)((sigma + 8)[ 3]) << 24)), | |||
63 | U8TO32_LITTLE(sigma + 12)(((u32)((sigma + 12)[0]) ) | ((u32)((sigma + 12)[1]) << 8) | ((u32)((sigma + 12)[2]) << 16) | ((u32)((sigma + 12 )[3]) << 24)), | |||
64 | U8TO32_LITTLE(key + 0)(((u32)((key + 0)[0]) ) | ((u32)((key + 0)[1]) << 8) | ( (u32)((key + 0)[2]) << 16) | ((u32)((key + 0)[3]) << 24)), | |||
65 | U8TO32_LITTLE(key + 4)(((u32)((key + 4)[0]) ) | ((u32)((key + 4)[1]) << 8) | ( (u32)((key + 4)[2]) << 16) | ((u32)((key + 4)[3]) << 24)), | |||
66 | U8TO32_LITTLE(key + 8)(((u32)((key + 8)[0]) ) | ((u32)((key + 8)[1]) << 8) | ( (u32)((key + 8)[2]) << 16) | ((u32)((key + 8)[3]) << 24)), | |||
67 | U8TO32_LITTLE(key + 12)(((u32)((key + 12)[0]) ) | ((u32)((key + 12)[1]) << 8) | ((u32)((key + 12)[2]) << 16) | ((u32)((key + 12)[3]) << 24)), | |||
68 | U8TO32_LITTLE(key + 16)(((u32)((key + 16)[0]) ) | ((u32)((key + 16)[1]) << 8) | ((u32)((key + 16)[2]) << 16) | ((u32)((key + 16)[3]) << 24)), | |||
69 | U8TO32_LITTLE(key + 20)(((u32)((key + 20)[0]) ) | ((u32)((key + 20)[1]) << 8) | ((u32)((key + 20)[2]) << 16) | ((u32)((key + 20)[3]) << 24)), | |||
70 | U8TO32_LITTLE(key + 24)(((u32)((key + 24)[0]) ) | ((u32)((key + 24)[1]) << 8) | ((u32)((key + 24)[2]) << 16) | ((u32)((key + 24)[3]) << 24)), | |||
71 | U8TO32_LITTLE(key + 28)(((u32)((key + 28)[0]) ) | ((u32)((key + 28)[1]) << 8) | ((u32)((key + 28)[2]) << 16) | ((u32)((key + 28)[3]) << 24)), | |||
72 | U8TO32_LITTLE(nonce + 0)(((u32)((nonce + 0)[0]) ) | ((u32)((nonce + 0)[1]) << 8 ) | ((u32)((nonce + 0)[2]) << 16) | ((u32)((nonce + 0)[ 3]) << 24)), | |||
73 | U8TO32_LITTLE(nonce + 4)(((u32)((nonce + 4)[0]) ) | ((u32)((nonce + 4)[1]) << 8 ) | ((u32)((nonce + 4)[2]) << 16) | ((u32)((nonce + 4)[ 3]) << 24)), | |||
74 | U8TO32_LITTLE(nonce + 8)(((u32)((nonce + 8)[0]) ) | ((u32)((nonce + 8)[1]) << 8 ) | ((u32)((nonce + 8)[2]) << 16) | ((u32)((nonce + 8)[ 3]) << 24)), | |||
75 | U8TO32_LITTLE(nonce + 12)(((u32)((nonce + 12)[0]) ) | ((u32)((nonce + 12)[1]) << 8) | ((u32)((nonce + 12)[2]) << 16) | ((u32)((nonce + 12 )[3]) << 24)) | |||
76 | }; | |||
77 | ||||
78 | for (i = 20;i > 0;i -= 2) { | |||
79 | QUARTERROUND( x[0], x[4], x[8],x[12])x[0] = (((u32)((x[0]) + (x[4])) & (0xFFFFFFFFU))); x[12] = ((((u32)((((x[12]) ^ (x[0]))) << (16)) & (0xFFFFFFFFU )) | ((((x[12]) ^ (x[0]))) >> (32 - (16))))); x[8] = (( (u32)((x[8]) + (x[12])) & (0xFFFFFFFFU))); x[4] = ((((u32 )((((x[4]) ^ (x[8]))) << (12)) & (0xFFFFFFFFU)) | ( (((x[4]) ^ (x[8]))) >> (32 - (12))))); x[0] = (((u32)(( x[0]) + (x[4])) & (0xFFFFFFFFU))); x[12] = ((((u32)((((x[ 12]) ^ (x[0]))) << (8)) & (0xFFFFFFFFU)) | ((((x[12 ]) ^ (x[0]))) >> (32 - (8))))); x[8] = (((u32)((x[8]) + (x[12])) & (0xFFFFFFFFU))); x[4] = ((((u32)((((x[4]) ^ ( x[8]))) << (7)) & (0xFFFFFFFFU)) | ((((x[4]) ^ (x[8 ]))) >> (32 - (7))))); | |||
80 | QUARTERROUND( x[1], x[5], x[9],x[13])x[1] = (((u32)((x[1]) + (x[5])) & (0xFFFFFFFFU))); x[13] = ((((u32)((((x[13]) ^ (x[1]))) << (16)) & (0xFFFFFFFFU )) | ((((x[13]) ^ (x[1]))) >> (32 - (16))))); x[9] = (( (u32)((x[9]) + (x[13])) & (0xFFFFFFFFU))); x[5] = ((((u32 )((((x[5]) ^ (x[9]))) << (12)) & (0xFFFFFFFFU)) | ( (((x[5]) ^ (x[9]))) >> (32 - (12))))); x[1] = (((u32)(( x[1]) + (x[5])) & (0xFFFFFFFFU))); x[13] = ((((u32)((((x[ 13]) ^ (x[1]))) << (8)) & (0xFFFFFFFFU)) | ((((x[13 ]) ^ (x[1]))) >> (32 - (8))))); x[9] = (((u32)((x[9]) + (x[13])) & (0xFFFFFFFFU))); x[5] = ((((u32)((((x[5]) ^ ( x[9]))) << (7)) & (0xFFFFFFFFU)) | ((((x[5]) ^ (x[9 ]))) >> (32 - (7))))); | |||
81 | QUARTERROUND( x[2], x[6],x[10],x[14])x[2] = (((u32)((x[2]) + (x[6])) & (0xFFFFFFFFU))); x[14] = ((((u32)((((x[14]) ^ (x[2]))) << (16)) & (0xFFFFFFFFU )) | ((((x[14]) ^ (x[2]))) >> (32 - (16))))); x[10] = ( ((u32)((x[10]) + (x[14])) & (0xFFFFFFFFU))); x[6] = ((((u32 )((((x[6]) ^ (x[10]))) << (12)) & (0xFFFFFFFFU)) | ( (((x[6]) ^ (x[10]))) >> (32 - (12))))); x[2] = (((u32)( (x[2]) + (x[6])) & (0xFFFFFFFFU))); x[14] = ((((u32)((((x [14]) ^ (x[2]))) << (8)) & (0xFFFFFFFFU)) | ((((x[14 ]) ^ (x[2]))) >> (32 - (8))))); x[10] = (((u32)((x[10]) + (x[14])) & (0xFFFFFFFFU))); x[6] = ((((u32)((((x[6]) ^ (x[10]))) << (7)) & (0xFFFFFFFFU)) | ((((x[6]) ^ ( x[10]))) >> (32 - (7))))); | |||
82 | QUARTERROUND( x[3], x[7],x[11],x[15])x[3] = (((u32)((x[3]) + (x[7])) & (0xFFFFFFFFU))); x[15] = ((((u32)((((x[15]) ^ (x[3]))) << (16)) & (0xFFFFFFFFU )) | ((((x[15]) ^ (x[3]))) >> (32 - (16))))); x[11] = ( ((u32)((x[11]) + (x[15])) & (0xFFFFFFFFU))); x[7] = ((((u32 )((((x[7]) ^ (x[11]))) << (12)) & (0xFFFFFFFFU)) | ( (((x[7]) ^ (x[11]))) >> (32 - (12))))); x[3] = (((u32)( (x[3]) + (x[7])) & (0xFFFFFFFFU))); x[15] = ((((u32)((((x [15]) ^ (x[3]))) << (8)) & (0xFFFFFFFFU)) | ((((x[15 ]) ^ (x[3]))) >> (32 - (8))))); x[11] = (((u32)((x[11]) + (x[15])) & (0xFFFFFFFFU))); x[7] = ((((u32)((((x[7]) ^ (x[11]))) << (7)) & (0xFFFFFFFFU)) | ((((x[7]) ^ ( x[11]))) >> (32 - (7))))); | |||
83 | QUARTERROUND( x[0], x[5],x[10],x[15])x[0] = (((u32)((x[0]) + (x[5])) & (0xFFFFFFFFU))); x[15] = ((((u32)((((x[15]) ^ (x[0]))) << (16)) & (0xFFFFFFFFU )) | ((((x[15]) ^ (x[0]))) >> (32 - (16))))); x[10] = ( ((u32)((x[10]) + (x[15])) & (0xFFFFFFFFU))); x[5] = ((((u32 )((((x[5]) ^ (x[10]))) << (12)) & (0xFFFFFFFFU)) | ( (((x[5]) ^ (x[10]))) >> (32 - (12))))); x[0] = (((u32)( (x[0]) + (x[5])) & (0xFFFFFFFFU))); x[15] = ((((u32)((((x [15]) ^ (x[0]))) << (8)) & (0xFFFFFFFFU)) | ((((x[15 ]) ^ (x[0]))) >> (32 - (8))))); x[10] = (((u32)((x[10]) + (x[15])) & (0xFFFFFFFFU))); x[5] = ((((u32)((((x[5]) ^ (x[10]))) << (7)) & (0xFFFFFFFFU)) | ((((x[5]) ^ ( x[10]))) >> (32 - (7))))); | |||
84 | QUARTERROUND( x[1], x[6],x[11],x[12])x[1] = (((u32)((x[1]) + (x[6])) & (0xFFFFFFFFU))); x[12] = ((((u32)((((x[12]) ^ (x[1]))) << (16)) & (0xFFFFFFFFU )) | ((((x[12]) ^ (x[1]))) >> (32 - (16))))); x[11] = ( ((u32)((x[11]) + (x[12])) & (0xFFFFFFFFU))); x[6] = ((((u32 )((((x[6]) ^ (x[11]))) << (12)) & (0xFFFFFFFFU)) | ( (((x[6]) ^ (x[11]))) >> (32 - (12))))); x[1] = (((u32)( (x[1]) + (x[6])) & (0xFFFFFFFFU))); x[12] = ((((u32)((((x [12]) ^ (x[1]))) << (8)) & (0xFFFFFFFFU)) | ((((x[12 ]) ^ (x[1]))) >> (32 - (8))))); x[11] = (((u32)((x[11]) + (x[12])) & (0xFFFFFFFFU))); x[6] = ((((u32)((((x[6]) ^ (x[11]))) << (7)) & (0xFFFFFFFFU)) | ((((x[6]) ^ ( x[11]))) >> (32 - (7))))); | |||
85 | QUARTERROUND( x[2], x[7], x[8],x[13])x[2] = (((u32)((x[2]) + (x[7])) & (0xFFFFFFFFU))); x[13] = ((((u32)((((x[13]) ^ (x[2]))) << (16)) & (0xFFFFFFFFU )) | ((((x[13]) ^ (x[2]))) >> (32 - (16))))); x[8] = (( (u32)((x[8]) + (x[13])) & (0xFFFFFFFFU))); x[7] = ((((u32 )((((x[7]) ^ (x[8]))) << (12)) & (0xFFFFFFFFU)) | ( (((x[7]) ^ (x[8]))) >> (32 - (12))))); x[2] = (((u32)(( x[2]) + (x[7])) & (0xFFFFFFFFU))); x[13] = ((((u32)((((x[ 13]) ^ (x[2]))) << (8)) & (0xFFFFFFFFU)) | ((((x[13 ]) ^ (x[2]))) >> (32 - (8))))); x[8] = (((u32)((x[8]) + (x[13])) & (0xFFFFFFFFU))); x[7] = ((((u32)((((x[7]) ^ ( x[8]))) << (7)) & (0xFFFFFFFFU)) | ((((x[7]) ^ (x[8 ]))) >> (32 - (7))))); | |||
86 | QUARTERROUND( x[3], x[4], x[9],x[14])x[3] = (((u32)((x[3]) + (x[4])) & (0xFFFFFFFFU))); x[14] = ((((u32)((((x[14]) ^ (x[3]))) << (16)) & (0xFFFFFFFFU )) | ((((x[14]) ^ (x[3]))) >> (32 - (16))))); x[9] = (( (u32)((x[9]) + (x[14])) & (0xFFFFFFFFU))); x[4] = ((((u32 )((((x[4]) ^ (x[9]))) << (12)) & (0xFFFFFFFFU)) | ( (((x[4]) ^ (x[9]))) >> (32 - (12))))); x[3] = (((u32)(( x[3]) + (x[4])) & (0xFFFFFFFFU))); x[14] = ((((u32)((((x[ 14]) ^ (x[3]))) << (8)) & (0xFFFFFFFFU)) | ((((x[14 ]) ^ (x[3]))) >> (32 - (8))))); x[9] = (((u32)((x[9]) + (x[14])) & (0xFFFFFFFFU))); x[4] = ((((u32)((((x[4]) ^ ( x[9]))) << (7)) & (0xFFFFFFFFU)) | ((((x[4]) ^ (x[9 ]))) >> (32 - (7))))); | |||
87 | } | |||
88 | ||||
89 | memcpy(derived_key + 0, x + 0, sizeof(u32) * 4)__builtin_memcpy((derived_key + 0), (x + 0), (sizeof(u32) * 4 )); | |||
90 | memcpy(derived_key + 4, x + 12, sizeof(u32) * 4)__builtin_memcpy((derived_key + 4), (x + 12), (sizeof(u32) * 4 )); | |||
91 | } | |||
92 | ||||
93 | static void | |||
94 | chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits) | |||
95 | { | |||
96 | const char *constants; | |||
97 | ||||
98 | x->input[4] = U8TO32_LITTLE(k + 0)(((u32)((k + 0)[0]) ) | ((u32)((k + 0)[1]) << 8) | ((u32 )((k + 0)[2]) << 16) | ((u32)((k + 0)[3]) << 24)); | |||
99 | x->input[5] = U8TO32_LITTLE(k + 4)(((u32)((k + 4)[0]) ) | ((u32)((k + 4)[1]) << 8) | ((u32 )((k + 4)[2]) << 16) | ((u32)((k + 4)[3]) << 24)); | |||
100 | x->input[6] = U8TO32_LITTLE(k + 8)(((u32)((k + 8)[0]) ) | ((u32)((k + 8)[1]) << 8) | ((u32 )((k + 8)[2]) << 16) | ((u32)((k + 8)[3]) << 24)); | |||
101 | x->input[7] = U8TO32_LITTLE(k + 12)(((u32)((k + 12)[0]) ) | ((u32)((k + 12)[1]) << 8) | (( u32)((k + 12)[2]) << 16) | ((u32)((k + 12)[3]) << 24)); | |||
102 | if (kbits == 256) { /* recommended */ | |||
103 | k += 16; | |||
104 | constants = sigma; | |||
105 | } else { /* kbits == 128 */ | |||
106 | constants = tau; | |||
107 | } | |||
108 | x->input[8] = U8TO32_LITTLE(k + 0)(((u32)((k + 0)[0]) ) | ((u32)((k + 0)[1]) << 8) | ((u32 )((k + 0)[2]) << 16) | ((u32)((k + 0)[3]) << 24)); | |||
109 | x->input[9] = U8TO32_LITTLE(k + 4)(((u32)((k + 4)[0]) ) | ((u32)((k + 4)[1]) << 8) | ((u32 )((k + 4)[2]) << 16) | ((u32)((k + 4)[3]) << 24)); | |||
110 | x->input[10] = U8TO32_LITTLE(k + 8)(((u32)((k + 8)[0]) ) | ((u32)((k + 8)[1]) << 8) | ((u32 )((k + 8)[2]) << 16) | ((u32)((k + 8)[3]) << 24)); | |||
111 | x->input[11] = U8TO32_LITTLE(k + 12)(((u32)((k + 12)[0]) ) | ((u32)((k + 12)[1]) << 8) | (( u32)((k + 12)[2]) << 16) | ((u32)((k + 12)[3]) << 24)); | |||
112 | x->input[0] = U8TO32_LITTLE(constants + 0)(((u32)((constants + 0)[0]) ) | ((u32)((constants + 0)[1]) << 8) | ((u32)((constants + 0)[2]) << 16) | ((u32)((constants + 0)[3]) << 24)); | |||
113 | x->input[1] = U8TO32_LITTLE(constants + 4)(((u32)((constants + 4)[0]) ) | ((u32)((constants + 4)[1]) << 8) | ((u32)((constants + 4)[2]) << 16) | ((u32)((constants + 4)[3]) << 24)); | |||
114 | x->input[2] = U8TO32_LITTLE(constants + 8)(((u32)((constants + 8)[0]) ) | ((u32)((constants + 8)[1]) << 8) | ((u32)((constants + 8)[2]) << 16) | ((u32)((constants + 8)[3]) << 24)); | |||
115 | x->input[3] = U8TO32_LITTLE(constants + 12)(((u32)((constants + 12)[0]) ) | ((u32)((constants + 12)[1]) << 8) | ((u32)((constants + 12)[2]) << 16) | ((u32)((constants + 12)[3]) << 24)); | |||
116 | } | |||
117 | ||||
118 | static void | |||
119 | chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter) | |||
120 | { | |||
121 | x->input[12] = counter == NULL((void *)0) ? 0 : U8TO32_LITTLE(counter + 0)(((u32)((counter + 0)[0]) ) | ((u32)((counter + 0)[1]) << 8) | ((u32)((counter + 0)[2]) << 16) | ((u32)((counter + 0)[3]) << 24)); | |||
| ||||
122 | x->input[13] = counter == NULL((void *)0) ? 0 : U8TO32_LITTLE(counter + 4)(((u32)((counter + 4)[0]) ) | ((u32)((counter + 4)[1]) << 8) | ((u32)((counter + 4)[2]) << 16) | ((u32)((counter + 4)[3]) << 24)); | |||
123 | x->input[14] = U8TO32_LITTLE(iv + 0)(((u32)((iv + 0)[0]) ) | ((u32)((iv + 0)[1]) << 8) | (( u32)((iv + 0)[2]) << 16) | ((u32)((iv + 0)[3]) << 24)); | |||
124 | x->input[15] = U8TO32_LITTLE(iv + 4)(((u32)((iv + 4)[0]) ) | ((u32)((iv + 4)[1]) << 8) | (( u32)((iv + 4)[2]) << 16) | ((u32)((iv + 4)[3]) << 24)); | |||
125 | } | |||
126 | ||||
127 | static void | |||
128 | chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) | |||
129 | { | |||
130 | u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; | |||
131 | u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; | |||
132 | u8 *ctarget = NULL((void *)0); | |||
133 | u8 tmp[64]; | |||
134 | u_int i; | |||
135 | ||||
136 | if (!bytes) return; | |||
137 | ||||
138 | j0 = x->input[0]; | |||
139 | j1 = x->input[1]; | |||
140 | j2 = x->input[2]; | |||
141 | j3 = x->input[3]; | |||
142 | j4 = x->input[4]; | |||
143 | j5 = x->input[5]; | |||
144 | j6 = x->input[6]; | |||
145 | j7 = x->input[7]; | |||
146 | j8 = x->input[8]; | |||
147 | j9 = x->input[9]; | |||
148 | j10 = x->input[10]; | |||
149 | j11 = x->input[11]; | |||
150 | j12 = x->input[12]; | |||
151 | j13 = x->input[13]; | |||
152 | j14 = x->input[14]; | |||
153 | j15 = x->input[15]; | |||
154 | ||||
155 | for (;;) { | |||
156 | if (bytes < 64) { | |||
157 | for (i = 0;i < bytes;++i) tmp[i] = m[i]; | |||
158 | m = tmp; | |||
159 | ctarget = c; | |||
160 | c = tmp; | |||
161 | } | |||
162 | x0 = j0; | |||
163 | x1 = j1; | |||
164 | x2 = j2; | |||
165 | x3 = j3; | |||
166 | x4 = j4; | |||
167 | x5 = j5; | |||
168 | x6 = j6; | |||
169 | x7 = j7; | |||
170 | x8 = j8; | |||
171 | x9 = j9; | |||
172 | x10 = j10; | |||
173 | x11 = j11; | |||
174 | x12 = j12; | |||
175 | x13 = j13; | |||
176 | x14 = j14; | |||
177 | x15 = j15; | |||
178 | for (i = 20;i > 0;i -= 2) { | |||
179 | QUARTERROUND( x0, x4, x8,x12)x0 = (((u32)((x0) + (x4)) & (0xFFFFFFFFU))); x12 = ((((u32 )((((x12) ^ (x0))) << (16)) & (0xFFFFFFFFU)) | (((( x12) ^ (x0))) >> (32 - (16))))); x8 = (((u32)((x8) + (x12 )) & (0xFFFFFFFFU))); x4 = ((((u32)((((x4) ^ (x8))) << (12)) & (0xFFFFFFFFU)) | ((((x4) ^ (x8))) >> (32 - (12))))); x0 = (((u32)((x0) + (x4)) & (0xFFFFFFFFU))); x12 = ((((u32)((((x12) ^ (x0))) << (8)) & (0xFFFFFFFFU )) | ((((x12) ^ (x0))) >> (32 - (8))))); x8 = (((u32)(( x8) + (x12)) & (0xFFFFFFFFU))); x4 = ((((u32)((((x4) ^ (x8 ))) << (7)) & (0xFFFFFFFFU)) | ((((x4) ^ (x8))) >> (32 - (7))))); | |||
180 | QUARTERROUND( x1, x5, x9,x13)x1 = (((u32)((x1) + (x5)) & (0xFFFFFFFFU))); x13 = ((((u32 )((((x13) ^ (x1))) << (16)) & (0xFFFFFFFFU)) | (((( x13) ^ (x1))) >> (32 - (16))))); x9 = (((u32)((x9) + (x13 )) & (0xFFFFFFFFU))); x5 = ((((u32)((((x5) ^ (x9))) << (12)) & (0xFFFFFFFFU)) | ((((x5) ^ (x9))) >> (32 - (12))))); x1 = (((u32)((x1) + (x5)) & (0xFFFFFFFFU))); x13 = ((((u32)((((x13) ^ (x1))) << (8)) & (0xFFFFFFFFU )) | ((((x13) ^ (x1))) >> (32 - (8))))); x9 = (((u32)(( x9) + (x13)) & (0xFFFFFFFFU))); x5 = ((((u32)((((x5) ^ (x9 ))) << (7)) & (0xFFFFFFFFU)) | ((((x5) ^ (x9))) >> (32 - (7))))); | |||
181 | QUARTERROUND( x2, x6,x10,x14)x2 = (((u32)((x2) + (x6)) & (0xFFFFFFFFU))); x14 = ((((u32 )((((x14) ^ (x2))) << (16)) & (0xFFFFFFFFU)) | (((( x14) ^ (x2))) >> (32 - (16))))); x10 = (((u32)((x10) + ( x14)) & (0xFFFFFFFFU))); x6 = ((((u32)((((x6) ^ (x10))) << (12)) & (0xFFFFFFFFU)) | ((((x6) ^ (x10))) >> (32 - (12))))); x2 = (((u32)((x2) + (x6)) & (0xFFFFFFFFU))); x14 = ((((u32)((((x14) ^ (x2))) << (8)) & (0xFFFFFFFFU )) | ((((x14) ^ (x2))) >> (32 - (8))))); x10 = (((u32)( (x10) + (x14)) & (0xFFFFFFFFU))); x6 = ((((u32)((((x6) ^ ( x10))) << (7)) & (0xFFFFFFFFU)) | ((((x6) ^ (x10))) >> (32 - (7))))); | |||
182 | QUARTERROUND( x3, x7,x11,x15)x3 = (((u32)((x3) + (x7)) & (0xFFFFFFFFU))); x15 = ((((u32 )((((x15) ^ (x3))) << (16)) & (0xFFFFFFFFU)) | (((( x15) ^ (x3))) >> (32 - (16))))); x11 = (((u32)((x11) + ( x15)) & (0xFFFFFFFFU))); x7 = ((((u32)((((x7) ^ (x11))) << (12)) & (0xFFFFFFFFU)) | ((((x7) ^ (x11))) >> (32 - (12))))); x3 = (((u32)((x3) + (x7)) & (0xFFFFFFFFU))); x15 = ((((u32)((((x15) ^ (x3))) << (8)) & (0xFFFFFFFFU )) | ((((x15) ^ (x3))) >> (32 - (8))))); x11 = (((u32)( (x11) + (x15)) & (0xFFFFFFFFU))); x7 = ((((u32)((((x7) ^ ( x11))) << (7)) & (0xFFFFFFFFU)) | ((((x7) ^ (x11))) >> (32 - (7))))); | |||
183 | QUARTERROUND( x0, x5,x10,x15)x0 = (((u32)((x0) + (x5)) & (0xFFFFFFFFU))); x15 = ((((u32 )((((x15) ^ (x0))) << (16)) & (0xFFFFFFFFU)) | (((( x15) ^ (x0))) >> (32 - (16))))); x10 = (((u32)((x10) + ( x15)) & (0xFFFFFFFFU))); x5 = ((((u32)((((x5) ^ (x10))) << (12)) & (0xFFFFFFFFU)) | ((((x5) ^ (x10))) >> (32 - (12))))); x0 = (((u32)((x0) + (x5)) & (0xFFFFFFFFU))); x15 = ((((u32)((((x15) ^ (x0))) << (8)) & (0xFFFFFFFFU )) | ((((x15) ^ (x0))) >> (32 - (8))))); x10 = (((u32)( (x10) + (x15)) & (0xFFFFFFFFU))); x5 = ((((u32)((((x5) ^ ( x10))) << (7)) & (0xFFFFFFFFU)) | ((((x5) ^ (x10))) >> (32 - (7))))); | |||
184 | QUARTERROUND( x1, x6,x11,x12)x1 = (((u32)((x1) + (x6)) & (0xFFFFFFFFU))); x12 = ((((u32 )((((x12) ^ (x1))) << (16)) & (0xFFFFFFFFU)) | (((( x12) ^ (x1))) >> (32 - (16))))); x11 = (((u32)((x11) + ( x12)) & (0xFFFFFFFFU))); x6 = ((((u32)((((x6) ^ (x11))) << (12)) & (0xFFFFFFFFU)) | ((((x6) ^ (x11))) >> (32 - (12))))); x1 = (((u32)((x1) + (x6)) & (0xFFFFFFFFU))); x12 = ((((u32)((((x12) ^ (x1))) << (8)) & (0xFFFFFFFFU )) | ((((x12) ^ (x1))) >> (32 - (8))))); x11 = (((u32)( (x11) + (x12)) & (0xFFFFFFFFU))); x6 = ((((u32)((((x6) ^ ( x11))) << (7)) & (0xFFFFFFFFU)) | ((((x6) ^ (x11))) >> (32 - (7))))); | |||
185 | QUARTERROUND( x2, x7, x8,x13)x2 = (((u32)((x2) + (x7)) & (0xFFFFFFFFU))); x13 = ((((u32 )((((x13) ^ (x2))) << (16)) & (0xFFFFFFFFU)) | (((( x13) ^ (x2))) >> (32 - (16))))); x8 = (((u32)((x8) + (x13 )) & (0xFFFFFFFFU))); x7 = ((((u32)((((x7) ^ (x8))) << (12)) & (0xFFFFFFFFU)) | ((((x7) ^ (x8))) >> (32 - (12))))); x2 = (((u32)((x2) + (x7)) & (0xFFFFFFFFU))); x13 = ((((u32)((((x13) ^ (x2))) << (8)) & (0xFFFFFFFFU )) | ((((x13) ^ (x2))) >> (32 - (8))))); x8 = (((u32)(( x8) + (x13)) & (0xFFFFFFFFU))); x7 = ((((u32)((((x7) ^ (x8 ))) << (7)) & (0xFFFFFFFFU)) | ((((x7) ^ (x8))) >> (32 - (7))))); | |||
186 | QUARTERROUND( x3, x4, x9,x14)x3 = (((u32)((x3) + (x4)) & (0xFFFFFFFFU))); x14 = ((((u32 )((((x14) ^ (x3))) << (16)) & (0xFFFFFFFFU)) | (((( x14) ^ (x3))) >> (32 - (16))))); x9 = (((u32)((x9) + (x14 )) & (0xFFFFFFFFU))); x4 = ((((u32)((((x4) ^ (x9))) << (12)) & (0xFFFFFFFFU)) | ((((x4) ^ (x9))) >> (32 - (12))))); x3 = (((u32)((x3) + (x4)) & (0xFFFFFFFFU))); x14 = ((((u32)((((x14) ^ (x3))) << (8)) & (0xFFFFFFFFU )) | ((((x14) ^ (x3))) >> (32 - (8))))); x9 = (((u32)(( x9) + (x14)) & (0xFFFFFFFFU))); x4 = ((((u32)((((x4) ^ (x9 ))) << (7)) & (0xFFFFFFFFU)) | ((((x4) ^ (x9))) >> (32 - (7))))); | |||
187 | } | |||
188 | x0 = PLUS(x0,j0)(((u32)((x0) + (j0)) & (0xFFFFFFFFU))); | |||
189 | x1 = PLUS(x1,j1)(((u32)((x1) + (j1)) & (0xFFFFFFFFU))); | |||
190 | x2 = PLUS(x2,j2)(((u32)((x2) + (j2)) & (0xFFFFFFFFU))); | |||
191 | x3 = PLUS(x3,j3)(((u32)((x3) + (j3)) & (0xFFFFFFFFU))); | |||
192 | x4 = PLUS(x4,j4)(((u32)((x4) + (j4)) & (0xFFFFFFFFU))); | |||
193 | x5 = PLUS(x5,j5)(((u32)((x5) + (j5)) & (0xFFFFFFFFU))); | |||
194 | x6 = PLUS(x6,j6)(((u32)((x6) + (j6)) & (0xFFFFFFFFU))); | |||
195 | x7 = PLUS(x7,j7)(((u32)((x7) + (j7)) & (0xFFFFFFFFU))); | |||
196 | x8 = PLUS(x8,j8)(((u32)((x8) + (j8)) & (0xFFFFFFFFU))); | |||
197 | x9 = PLUS(x9,j9)(((u32)((x9) + (j9)) & (0xFFFFFFFFU))); | |||
198 | x10 = PLUS(x10,j10)(((u32)((x10) + (j10)) & (0xFFFFFFFFU))); | |||
199 | x11 = PLUS(x11,j11)(((u32)((x11) + (j11)) & (0xFFFFFFFFU))); | |||
200 | x12 = PLUS(x12,j12)(((u32)((x12) + (j12)) & (0xFFFFFFFFU))); | |||
201 | x13 = PLUS(x13,j13)(((u32)((x13) + (j13)) & (0xFFFFFFFFU))); | |||
202 | x14 = PLUS(x14,j14)(((u32)((x14) + (j14)) & (0xFFFFFFFFU))); | |||
203 | x15 = PLUS(x15,j15)(((u32)((x15) + (j15)) & (0xFFFFFFFFU))); | |||
204 | ||||
205 | #ifndef KEYSTREAM_ONLY | |||
206 | x0 = XOR(x0,U8TO32_LITTLE(m + 0))((x0) ^ ((((u32)((m + 0)[0]) ) | ((u32)((m + 0)[1]) << 8 ) | ((u32)((m + 0)[2]) << 16) | ((u32)((m + 0)[3]) << 24)))); | |||
207 | x1 = XOR(x1,U8TO32_LITTLE(m + 4))((x1) ^ ((((u32)((m + 4)[0]) ) | ((u32)((m + 4)[1]) << 8 ) | ((u32)((m + 4)[2]) << 16) | ((u32)((m + 4)[3]) << 24)))); | |||
208 | x2 = XOR(x2,U8TO32_LITTLE(m + 8))((x2) ^ ((((u32)((m + 8)[0]) ) | ((u32)((m + 8)[1]) << 8 ) | ((u32)((m + 8)[2]) << 16) | ((u32)((m + 8)[3]) << 24)))); | |||
209 | x3 = XOR(x3,U8TO32_LITTLE(m + 12))((x3) ^ ((((u32)((m + 12)[0]) ) | ((u32)((m + 12)[1]) << 8) | ((u32)((m + 12)[2]) << 16) | ((u32)((m + 12)[3]) << 24)))); | |||
210 | x4 = XOR(x4,U8TO32_LITTLE(m + 16))((x4) ^ ((((u32)((m + 16)[0]) ) | ((u32)((m + 16)[1]) << 8) | ((u32)((m + 16)[2]) << 16) | ((u32)((m + 16)[3]) << 24)))); | |||
211 | x5 = XOR(x5,U8TO32_LITTLE(m + 20))((x5) ^ ((((u32)((m + 20)[0]) ) | ((u32)((m + 20)[1]) << 8) | ((u32)((m + 20)[2]) << 16) | ((u32)((m + 20)[3]) << 24)))); | |||
212 | x6 = XOR(x6,U8TO32_LITTLE(m + 24))((x6) ^ ((((u32)((m + 24)[0]) ) | ((u32)((m + 24)[1]) << 8) | ((u32)((m + 24)[2]) << 16) | ((u32)((m + 24)[3]) << 24)))); | |||
213 | x7 = XOR(x7,U8TO32_LITTLE(m + 28))((x7) ^ ((((u32)((m + 28)[0]) ) | ((u32)((m + 28)[1]) << 8) | ((u32)((m + 28)[2]) << 16) | ((u32)((m + 28)[3]) << 24)))); | |||
214 | x8 = XOR(x8,U8TO32_LITTLE(m + 32))((x8) ^ ((((u32)((m + 32)[0]) ) | ((u32)((m + 32)[1]) << 8) | ((u32)((m + 32)[2]) << 16) | ((u32)((m + 32)[3]) << 24)))); | |||
215 | x9 = XOR(x9,U8TO32_LITTLE(m + 36))((x9) ^ ((((u32)((m + 36)[0]) ) | ((u32)((m + 36)[1]) << 8) | ((u32)((m + 36)[2]) << 16) | ((u32)((m + 36)[3]) << 24)))); | |||
216 | x10 = XOR(x10,U8TO32_LITTLE(m + 40))((x10) ^ ((((u32)((m + 40)[0]) ) | ((u32)((m + 40)[1]) << 8) | ((u32)((m + 40)[2]) << 16) | ((u32)((m + 40)[3]) << 24)))); | |||
217 | x11 = XOR(x11,U8TO32_LITTLE(m + 44))((x11) ^ ((((u32)((m + 44)[0]) ) | ((u32)((m + 44)[1]) << 8) | ((u32)((m + 44)[2]) << 16) | ((u32)((m + 44)[3]) << 24)))); | |||
218 | x12 = XOR(x12,U8TO32_LITTLE(m + 48))((x12) ^ ((((u32)((m + 48)[0]) ) | ((u32)((m + 48)[1]) << 8) | ((u32)((m + 48)[2]) << 16) | ((u32)((m + 48)[3]) << 24)))); | |||
219 | x13 = XOR(x13,U8TO32_LITTLE(m + 52))((x13) ^ ((((u32)((m + 52)[0]) ) | ((u32)((m + 52)[1]) << 8) | ((u32)((m + 52)[2]) << 16) | ((u32)((m + 52)[3]) << 24)))); | |||
220 | x14 = XOR(x14,U8TO32_LITTLE(m + 56))((x14) ^ ((((u32)((m + 56)[0]) ) | ((u32)((m + 56)[1]) << 8) | ((u32)((m + 56)[2]) << 16) | ((u32)((m + 56)[3]) << 24)))); | |||
221 | x15 = XOR(x15,U8TO32_LITTLE(m + 60))((x15) ^ ((((u32)((m + 60)[0]) ) | ((u32)((m + 60)[1]) << 8) | ((u32)((m + 60)[2]) << 16) | ((u32)((m + 60)[3]) << 24)))); | |||
222 | #endif | |||
223 | ||||
224 | j12 = PLUSONE(j12)((((u32)(((j12)) + (1)) & (0xFFFFFFFFU)))); | |||
225 | if (!j12) { | |||
226 | j13 = PLUSONE(j13)((((u32)(((j13)) + (1)) & (0xFFFFFFFFU)))); | |||
227 | /* stopping at 2^70 bytes per nonce is user's responsibility */ | |||
228 | } | |||
229 | ||||
230 | U32TO8_LITTLE(c + 0,x0)do { (c + 0)[0] = ((u8)((x0)) & (0xFFU)); (c + 0)[1] = (( u8)((x0) >> 8) & (0xFFU)); (c + 0)[2] = ((u8)((x0) >> 16) & (0xFFU)); (c + 0)[3] = ((u8)((x0) >> 24) & (0xFFU)); } while (0); | |||
231 | U32TO8_LITTLE(c + 4,x1)do { (c + 4)[0] = ((u8)((x1)) & (0xFFU)); (c + 4)[1] = (( u8)((x1) >> 8) & (0xFFU)); (c + 4)[2] = ((u8)((x1) >> 16) & (0xFFU)); (c + 4)[3] = ((u8)((x1) >> 24) & (0xFFU)); } while (0); | |||
232 | U32TO8_LITTLE(c + 8,x2)do { (c + 8)[0] = ((u8)((x2)) & (0xFFU)); (c + 8)[1] = (( u8)((x2) >> 8) & (0xFFU)); (c + 8)[2] = ((u8)((x2) >> 16) & (0xFFU)); (c + 8)[3] = ((u8)((x2) >> 24) & (0xFFU)); } while (0); | |||
233 | U32TO8_LITTLE(c + 12,x3)do { (c + 12)[0] = ((u8)((x3)) & (0xFFU)); (c + 12)[1] = ( (u8)((x3) >> 8) & (0xFFU)); (c + 12)[2] = ((u8)((x3 ) >> 16) & (0xFFU)); (c + 12)[3] = ((u8)((x3) >> 24) & (0xFFU)); } while (0); | |||
234 | U32TO8_LITTLE(c + 16,x4)do { (c + 16)[0] = ((u8)((x4)) & (0xFFU)); (c + 16)[1] = ( (u8)((x4) >> 8) & (0xFFU)); (c + 16)[2] = ((u8)((x4 ) >> 16) & (0xFFU)); (c + 16)[3] = ((u8)((x4) >> 24) & (0xFFU)); } while (0); | |||
235 | U32TO8_LITTLE(c + 20,x5)do { (c + 20)[0] = ((u8)((x5)) & (0xFFU)); (c + 20)[1] = ( (u8)((x5) >> 8) & (0xFFU)); (c + 20)[2] = ((u8)((x5 ) >> 16) & (0xFFU)); (c + 20)[3] = ((u8)((x5) >> 24) & (0xFFU)); } while (0); | |||
236 | U32TO8_LITTLE(c + 24,x6)do { (c + 24)[0] = ((u8)((x6)) & (0xFFU)); (c + 24)[1] = ( (u8)((x6) >> 8) & (0xFFU)); (c + 24)[2] = ((u8)((x6 ) >> 16) & (0xFFU)); (c + 24)[3] = ((u8)((x6) >> 24) & (0xFFU)); } while (0); | |||
237 | U32TO8_LITTLE(c + 28,x7)do { (c + 28)[0] = ((u8)((x7)) & (0xFFU)); (c + 28)[1] = ( (u8)((x7) >> 8) & (0xFFU)); (c + 28)[2] = ((u8)((x7 ) >> 16) & (0xFFU)); (c + 28)[3] = ((u8)((x7) >> 24) & (0xFFU)); } while (0); | |||
238 | U32TO8_LITTLE(c + 32,x8)do { (c + 32)[0] = ((u8)((x8)) & (0xFFU)); (c + 32)[1] = ( (u8)((x8) >> 8) & (0xFFU)); (c + 32)[2] = ((u8)((x8 ) >> 16) & (0xFFU)); (c + 32)[3] = ((u8)((x8) >> 24) & (0xFFU)); } while (0); | |||
239 | U32TO8_LITTLE(c + 36,x9)do { (c + 36)[0] = ((u8)((x9)) & (0xFFU)); (c + 36)[1] = ( (u8)((x9) >> 8) & (0xFFU)); (c + 36)[2] = ((u8)((x9 ) >> 16) & (0xFFU)); (c + 36)[3] = ((u8)((x9) >> 24) & (0xFFU)); } while (0); | |||
240 | U32TO8_LITTLE(c + 40,x10)do { (c + 40)[0] = ((u8)((x10)) & (0xFFU)); (c + 40)[1] = ((u8)((x10) >> 8) & (0xFFU)); (c + 40)[2] = ((u8)( (x10) >> 16) & (0xFFU)); (c + 40)[3] = ((u8)((x10) >> 24) & (0xFFU)); } while (0); | |||
241 | U32TO8_LITTLE(c + 44,x11)do { (c + 44)[0] = ((u8)((x11)) & (0xFFU)); (c + 44)[1] = ((u8)((x11) >> 8) & (0xFFU)); (c + 44)[2] = ((u8)( (x11) >> 16) & (0xFFU)); (c + 44)[3] = ((u8)((x11) >> 24) & (0xFFU)); } while (0); | |||
242 | U32TO8_LITTLE(c + 48,x12)do { (c + 48)[0] = ((u8)((x12)) & (0xFFU)); (c + 48)[1] = ((u8)((x12) >> 8) & (0xFFU)); (c + 48)[2] = ((u8)( (x12) >> 16) & (0xFFU)); (c + 48)[3] = ((u8)((x12) >> 24) & (0xFFU)); } while (0); | |||
243 | U32TO8_LITTLE(c + 52,x13)do { (c + 52)[0] = ((u8)((x13)) & (0xFFU)); (c + 52)[1] = ((u8)((x13) >> 8) & (0xFFU)); (c + 52)[2] = ((u8)( (x13) >> 16) & (0xFFU)); (c + 52)[3] = ((u8)((x13) >> 24) & (0xFFU)); } while (0); | |||
244 | U32TO8_LITTLE(c + 56,x14)do { (c + 56)[0] = ((u8)((x14)) & (0xFFU)); (c + 56)[1] = ((u8)((x14) >> 8) & (0xFFU)); (c + 56)[2] = ((u8)( (x14) >> 16) & (0xFFU)); (c + 56)[3] = ((u8)((x14) >> 24) & (0xFFU)); } while (0); | |||
245 | U32TO8_LITTLE(c + 60,x15)do { (c + 60)[0] = ((u8)((x15)) & (0xFFU)); (c + 60)[1] = ((u8)((x15) >> 8) & (0xFFU)); (c + 60)[2] = ((u8)( (x15) >> 16) & (0xFFU)); (c + 60)[3] = ((u8)((x15) >> 24) & (0xFFU)); } while (0); | |||
246 | ||||
247 | if (bytes <= 64) { | |||
248 | if (bytes < 64) { | |||
249 | for (i = 0;i < bytes;++i) ctarget[i] = c[i]; | |||
250 | } | |||
251 | x->input[12] = j12; | |||
252 | x->input[13] = j13; | |||
253 | return; | |||
254 | } | |||
255 | bytes -= 64; | |||
256 | c += 64; | |||
257 | #ifndef KEYSTREAM_ONLY | |||
258 | m += 64; | |||
259 | #endif | |||
260 | } | |||
261 | } |