1230587Sken/*
2230587Sken * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
3181643Skmacy *
4181643Skmacy * Permission is hereby granted, free of charge, to any person obtaining
5230587Sken * a copy of this software and associated documentation files (the
6230587Sken * "Software"), to deal in the Software without restriction, including
7181643Skmacy * without limitation the rights to use, copy, modify, merge, publish,
8230587Sken * distribute, sublicense, and/or sell copies of the Software, and to
9230587Sken * permit persons to whom the Software is furnished to do so, subject to
10230587Sken * the following conditions:
11230587Sken *
12230587Sken * The above copyright notice and this permission notice shall be
13230587Sken * included in all copies or substantial portions of the Software.
14230587Sken *
15230587Sken * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16181643Skmacy * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17230587Sken * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18230587Sken * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19230587Sken * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20230587Sken * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21230587Sken * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22230587Sken * SOFTWARE.
23230587Sken */
24230587Sken
25230587Sken#include "inner.h"
26230587Sken
27230587Skenstatic void
28230587Skenin_cbc_init(br_sslrec_in_cbc_context *cc,
29181643Skmacy	const br_block_cbcdec_class *bc_impl,
30230587Sken	const void *bc_key, size_t bc_key_len,
31230587Sken	const br_hash_class *dig_impl,
32230587Sken	const void *mac_key, size_t mac_key_len, size_t mac_out_len,
33181643Skmacy	const void *iv)
34181643Skmacy{
35181643Skmacy	cc->vtable = &br_sslrec_in_cbc_vtable;
36181643Skmacy	cc->seq = 0;
37230587Sken	bc_impl->init(&cc->bc.vtable, bc_key, bc_key_len);
38230587Sken	br_hmac_key_init(&cc->mac, dig_impl, mac_key, mac_key_len);
39230587Sken	cc->mac_len = mac_out_len;
40230587Sken	if (iv == NULL) {
41230587Sken		memset(cc->iv, 0, sizeof cc->iv);
42230587Sken		cc->explicit_IV = 1;
43230587Sken	} else {
44230587Sken		memcpy(cc->iv, iv, bc_impl->block_size);
45259541Sglebius		cc->explicit_IV = 0;
46230587Sken	}
47230587Sken}
48188066Srrs
49181643Skmacystatic int
50181643Skmacycbc_check_length(const br_sslrec_in_cbc_context *cc, size_t rlen)
51181643Skmacy{
52181643Skmacy	/*
53230587Sken	 * Plaintext size: at most 16384 bytes
54181643Skmacy	 * Padding: at most 256 bytes
55230587Sken	 * MAC: mac_len extra bytes
56230587Sken	 * TLS 1.1+: each record has an explicit IV
57230587Sken	 *
58181643Skmacy	 * Minimum length includes at least one byte of padding, and the
59181643Skmacy	 * MAC.
60181643Skmacy	 *
61181643Skmacy	 * Total length must be a multiple of the block size.
62230587Sken	 */
63230587Sken	size_t blen;
64230587Sken	size_t min_len, max_len;
65181643Skmacy
66181643Skmacy	blen = cc->bc.vtable->block_size;
67181643Skmacy	min_len = (blen + cc->mac_len) & ~(blen - 1);
68181643Skmacy	max_len = (16384 + 256 + cc->mac_len) & ~(blen - 1);
69230587Sken	if (cc->explicit_IV) {
70230587Sken		min_len += blen;
71181643Skmacy		max_len += blen;
72230587Sken	}
73230587Sken	return min_len <= rlen && rlen <= max_len;
74181643Skmacy}
75230587Sken
76181643Skmacy/*
77230587Sken * Rotate array buf[] of length 'len' to the left (towards low indices)
78230587Sken * by 'num' bytes if ctl is 1; otherwise, leave it unchanged. This is
79230916Sken * constant-time. 'num' MUST be lower than 'len'. 'len' MUST be lower
80230916Sken * than or equal to 64.
81181643Skmacy */
82230587Skenstatic void
83181643Skmacycond_rotate(uint32_t ctl, unsigned char *buf, size_t len, size_t num)
84255040Sgibbs{
85255040Sgibbs	unsigned char tmp[64];
86230587Sken	size_t u, v;
87230587Sken
88230587Sken	for (u = 0, v = num; u < len; u ++) {
89181643Skmacy		tmp[u] = MUX(ctl, buf[v], buf[u]);
90255040Sgibbs		if (++ v == len) {
91255040Sgibbs			v = 0;
92230587Sken		}
93181643Skmacy	}
94230587Sken	memcpy(buf, tmp, len);
95230587Sken}
96230587Sken
97230587Skenstatic unsigned char *
98230587Skencbc_decrypt(br_sslrec_in_cbc_context *cc,
99230587Sken	int record_type, unsigned version, void *data, size_t *data_len)
100230587Sken{
101230587Sken	/*
102230587Sken	 * We represent all lengths on 32-bit integers, because:
103230587Sken	 * -- SSL record lengths always fit in 32 bits;
104230587Sken	 * -- our constant-time primitives operate on 32-bit integers.
105230587Sken	 */
106230587Sken	unsigned char *buf;
107230587Sken	uint32_t u, v, len, blen, min_len, max_len;
108230587Sken	uint32_t good, pad_len, rot_count, len_withmac, len_nomac;
109230587Sken	unsigned char tmp1[64], tmp2[64];
110230587Sken	int i;
111181643Skmacy	br_hmac_context hc;
112230587Sken
113181643Skmacy	buf = data;
114181643Skmacy	len = *data_len;
115230587Sken	blen = cc->bc.vtable->block_size;
116230587Sken
117181643Skmacy	/*
118230587Sken	 * Decrypt data, and skip the explicit IV (if applicable). Note
119230587Sken	 * that the total length is supposed to have been verified by
120181643Skmacy	 * the caller. If there is an explicit IV, then we actually
121230587Sken	 * "decrypt" it using the implicit IV (from previous record),
122230587Sken	 * which is useless but harmless.
123181643Skmacy	 */
124230587Sken	cc->bc.vtable->run(&cc->bc.vtable, cc->iv, data, len);
125230587Sken	if (cc->explicit_IV) {
126230587Sken		buf += blen;
127230587Sken		len -= blen;
128230587Sken	}
129230587Sken
130230587Sken	/*
131230587Sken	 * Compute minimum and maximum length of plaintext + MAC. These
132230587Sken	 * lengths can be inferred from the outside: they are not secret.
133230587Sken	 */
134181643Skmacy	min_len = (cc->mac_len + 256 < len) ? len - 256 : cc->mac_len;
135230587Sken	max_len = len - 1;
136230587Sken
137181643Skmacy	/*
138230587Sken	 * Use the last decrypted byte to compute the actual payload
139230587Sken	 * length. Take care not to overflow (we use unsigned types).
140230587Sken	 */
141230587Sken	pad_len = buf[max_len];
142230587Sken	good = LE(pad_len, (uint32_t)(max_len - min_len));
143181643Skmacy	len = MUX(good, (uint32_t)(max_len - pad_len), min_len);
144230587Sken
145230587Sken	/*
146230587Sken	 * Check padding contents: all padding bytes must be equal to
147181643Skmacy	 * the value of pad_len.
148230587Sken	 */
149230587Sken	for (u = min_len; u < max_len; u ++) {
150230587Sken		good &= LT(u, len) | EQ(buf[u], pad_len);
151230587Sken	}
152230587Sken
153230587Sken	/*
154230587Sken	 * Extract the MAC value. This is done in one pass, but results
155230587Sken	 * in a "rotated" MAC value depending on where it actually
156230587Sken	 * occurs. The 'rot_count' value is set to the offset of the
157230587Sken	 * first MAC byte within tmp1[].
158230587Sken	 *
159230587Sken	 * min_len and max_len are also adjusted to the minimum and
160230587Sken	 * maximum lengths of the plaintext alone (without the MAC).
161230587Sken	 */
162230587Sken	len_withmac = (uint32_t)len;
163230587Sken	len_nomac = len_withmac - cc->mac_len;
164230587Sken	min_len -= cc->mac_len;
165230587Sken	rot_count = 0;
166230587Sken	memset(tmp1, 0, cc->mac_len);
167230587Sken	v = 0;
168230587Sken	for (u = min_len; u < max_len; u ++) {
169230587Sken		tmp1[v] |= MUX(GE(u, len_nomac) & LT(u, len_withmac),
170230587Sken			buf[u], 0x00);
171230587Sken		rot_count = MUX(EQ(u, len_nomac), v, rot_count);
172230587Sken		if (++ v == cc->mac_len) {
173230587Sken			v = 0;
174230587Sken		}
175230587Sken	}
176230587Sken	max_len -= cc->mac_len;
177230587Sken
178230587Sken	/*
179230587Sken	 * Rotate back the MAC value. The loop below does the constant-time
180230587Sken	 * rotation in time n*log n for a MAC output of length n. We assume
181230587Sken	 * that the MAC output length is no more than 64 bytes, so the
182230587Sken	 * rotation count fits on 6 bits.
183230587Sken	 */
184230587Sken	for (i = 5; i >= 0; i --) {
185230587Sken		uint32_t rc;
186230587Sken
187230587Sken		rc = (uint32_t)1 << i;
188230587Sken		cond_rotate(rot_count >> i, tmp1, cc->mac_len, rc);
189230587Sken		rot_count &= ~rc;
190230587Sken	}
191230587Sken
192230587Sken	/*
193230587Sken	 * Recompute the HMAC value. The input is the concatenation of
194230587Sken	 * the sequence number (8 bytes), the record header (5 bytes),
195230587Sken	 * and the payload.
196230587Sken	 *
197259541Sglebius	 * At that point, min_len is the minimum plaintext length, but
198259541Sglebius	 * max_len still includes the MAC length.
199259541Sglebius	 */
200230587Sken	br_enc64be(tmp2, cc->seq ++);
201181643Skmacy	tmp2[8] = (unsigned char)record_type;
202181643Skmacy	br_enc16be(tmp2 + 9, version);
203230587Sken	br_enc16be(tmp2 + 11, len_nomac);
204230587Sken	br_hmac_init(&hc, &cc->mac, cc->mac_len);
205230587Sken	br_hmac_update(&hc, tmp2, 13);
206230587Sken	br_hmac_outCT(&hc, buf, len_nomac, min_len, max_len, tmp2);
207230587Sken
208230587Sken	/*
209230587Sken	 * Compare the extracted and recomputed MAC values.
210230587Sken	 */
211230587Sken	for (u = 0; u < cc->mac_len; u ++) {
212230587Sken		good &= EQ0(tmp1[u] ^ tmp2[u]);
213181643Skmacy	}
214230587Sken
215230587Sken	/*
216230587Sken	 * Check that the plaintext length is valid. The previous
217230587Sken	 * check was on the encrypted length, but the padding may have
218230587Sken	 * turned shorter than expected.
219230587Sken	 *
220230587Sken	 * Once this final test is done, the critical "constant-time"
221181643Skmacy	 * section ends and we can make conditional jumps again.
222230587Sken	 */
223230587Sken	good &= LE(len_nomac, 16384);
224230587Sken
225230587Sken	if (!good) {
226230587Sken		return 0;
227230587Sken	}
228230587Sken	*data_len = len_nomac;
229181643Skmacy	return buf;
230230587Sken}
231230587Sken
232181643Skmacy/* see bearssl_ssl.h */
233230587Skenconst br_sslrec_in_cbc_class br_sslrec_in_cbc_vtable = {
234230587Sken	{
235181643Skmacy		sizeof(br_sslrec_in_cbc_context),
236230587Sken		(int (*)(const br_sslrec_in_class *const *, size_t))
237230587Sken			&cbc_check_length,
238230587Sken		(unsigned char *(*)(const br_sslrec_in_class **,
239230587Sken			int, unsigned, void *, size_t *))
240230587Sken			&cbc_decrypt
241181643Skmacy	},
242230587Sken	(void (*)(const br_sslrec_in_cbc_class **,
243230587Sken		const br_block_cbcdec_class *, const void *, size_t,
244230587Sken		const br_hash_class *, const void *, size_t, size_t,
245230587Sken		const void *))
246230587Sken		&in_cbc_init
247230587Sken};
248181643Skmacy
249230587Sken/*
250230587Sken * For CBC output:
251230587Sken *
252181643Skmacy * -- With TLS 1.1+, there is an explicit IV. Generation method uses
253230587Sken * HMAC, computed over the current sequence number, and the current MAC
254230587Sken * key. The resulting value is truncated to the size of a block, and
255230587Sken * added at the head of the plaintext; it will get encrypted along with
256230587Sken * the data. This custom generation mechanism is "safe" under the
257230587Sken * assumption that HMAC behaves like a random oracle; since the MAC for
258230587Sken * a record is computed over the concatenation of the sequence number,
259181643Skmacy * the record header and the plaintext, the HMAC-for-IV will not collide
260230587Sken * with the normal HMAC.
261230587Sken *
262230587Sken * -- With TLS 1.0, for application data, we want to enforce a 1/n-1
263230587Sken * split, as a countermeasure against chosen-plaintext attacks. We thus
264230587Sken * need to leave some room in the buffer for that extra record.
265230587Sken */
266181643Skmacy
267230587Skenstatic void
268230587Skenout_cbc_init(br_sslrec_out_cbc_context *cc,
269230587Sken	const br_block_cbcenc_class *bc_impl,
270230587Sken	const void *bc_key, size_t bc_key_len,
271230587Sken	const br_hash_class *dig_impl,
272230587Sken	const void *mac_key, size_t mac_key_len, size_t mac_out_len,
273181643Skmacy	const void *iv)
274230587Sken{
275230587Sken	cc->vtable = &br_sslrec_out_cbc_vtable;
276230587Sken	cc->seq = 0;
277230587Sken	bc_impl->init(&cc->bc.vtable, bc_key, bc_key_len);
278230587Sken	br_hmac_key_init(&cc->mac, dig_impl, mac_key, mac_key_len);
279230587Sken	cc->mac_len = mac_out_len;
280181643Skmacy	if (iv == NULL) {
281230587Sken		memset(cc->iv, 0, sizeof cc->iv);
282230587Sken		cc->explicit_IV = 1;
283230587Sken	} else {
284230587Sken		memcpy(cc->iv, iv, bc_impl->block_size);
285230587Sken		cc->explicit_IV = 0;
286230587Sken	}
287230587Sken}
288230587Sken
289230587Skenstatic void
290230587Skencbc_max_plaintext(const br_sslrec_out_cbc_context *cc,
291230587Sken	size_t *start, size_t *end)
292230587Sken{
293230587Sken	size_t blen, len;
294230587Sken
295230587Sken	blen = cc->bc.vtable->block_size;
296230587Sken	if (cc->explicit_IV) {
297230587Sken		*start += blen;
298230587Sken	} else {
299230587Sken		*start += 4 + ((cc->mac_len + blen + 1) & ~(blen - 1));
300181643Skmacy	}
301181643Skmacy	len = (*end - *start) & ~(blen - 1);
302230587Sken	len -= 1 + cc->mac_len;
303181643Skmacy	if (len > 16384) {
304230587Sken		len = 16384;
305230587Sken	}
306230587Sken	*end = *start + len;
307230587Sken}
308230587Sken
309230587Skenstatic unsigned char *
310230587Skencbc_encrypt(br_sslrec_out_cbc_context *cc,
311181643Skmacy	int record_type, unsigned version, void *data, size_t *data_len)
312181643Skmacy{
313181643Skmacy	unsigned char *buf, *rbuf;
314181643Skmacy	size_t len, blen, plen;
315230587Sken	unsigned char tmp[13];
316230587Sken	br_hmac_context hc;
317230587Sken
318230587Sken	buf = data;
319230587Sken	len = *data_len;
320230587Sken	blen = cc->bc.vtable->block_size;
321230587Sken
322230587Sken	/*
323230587Sken	 * If using TLS 1.0, with more than one byte of plaintext, and
324230587Sken	 * the record is application data, then we need to compute
325230587Sken	 * a "split". We do not perform the split on other record types
326230587Sken	 * because it turned out that some existing, deployed
327230587Sken	 * implementations of SSL/TLS do not tolerate the splitting of
328230587Sken	 * some message types (in particular the Finished message).
329230587Sken	 *
330181643Skmacy	 * If using TLS 1.1+, then there is an explicit IV. We produce
331230587Sken	 * that IV by adding an extra initial plaintext block, whose
332230587Sken	 * value is computed with HMAC over the record sequence number.
333230587Sken	 */
334230587Sken	if (cc->explicit_IV) {
335230587Sken		/*
336230587Sken		 * We use here the fact that all the HMAC variants we
337181643Skmacy		 * support can produce at least 16 bytes, while all the
338230587Sken		 * block ciphers we support have blocks of no more than
339230587Sken		 * 16 bytes. Thus, we can always truncate the HMAC output
340230587Sken		 * down to the block size.
341230587Sken		 */
342230587Sken		br_enc64be(tmp, cc->seq);
343230587Sken		br_hmac_init(&hc, &cc->mac, blen);
344230587Sken		br_hmac_update(&hc, tmp, 8);
345230587Sken		br_hmac_out(&hc, buf - blen);
346230587Sken		rbuf = buf - blen - 5;
347230587Sken	} else {
348230587Sken		if (len > 1 && record_type == BR_SSL_APPLICATION_DATA) {
349230587Sken			/*
350230587Sken			 * To do the split, we use a recursive invocation;
351230587Sken			 * since we only give one byte to the inner call,
352230587Sken			 * the recursion stops there.
353230587Sken			 *
354230587Sken			 * We need to compute the exact size of the extra
355230587Sken			 * record, so that the two resulting records end up
356230587Sken			 * being sequential in RAM.
357230587Sken			 *
358230587Sken			 * We use here the fact that cbc_max_plaintext()
359230587Sken			 * adjusted the start offset to leave room for the
360230587Sken			 * initial fragment.
361230587Sken			 */
362230587Sken			size_t xlen;
363230587Sken
364230587Sken			rbuf = buf - 4
365230587Sken				- ((cc->mac_len + blen + 1) & ~(blen - 1));
366181643Skmacy			rbuf[0] = buf[0];
367230587Sken			xlen = 1;
368230587Sken			rbuf = cbc_encrypt(cc, record_type,
369181643Skmacy				version, rbuf, &xlen);
370230587Sken			buf ++;
371230587Sken			len --;
372230587Sken		} else {
373230587Sken			rbuf = buf - 5;
374230587Sken		}
375181643Skmacy	}
376230587Sken
377230587Sken	/*
378181643Skmacy	 * Compute MAC.
379230587Sken	 */
380230587Sken	br_enc64be(tmp, cc->seq ++);
381230587Sken	tmp[8] = record_type;
382181643Skmacy	br_enc16be(tmp + 9, version);
383230587Sken	br_enc16be(tmp + 11, len);
384230587Sken	br_hmac_init(&hc, &cc->mac, cc->mac_len);
385230587Sken	br_hmac_update(&hc, tmp, 13);
386230587Sken	br_hmac_update(&hc, buf, len);
387230587Sken	br_hmac_out(&hc, buf + len);
388230587Sken	len += cc->mac_len;
389230587Sken
390230587Sken	/*
391230587Sken	 * Add padding.
392181643Skmacy	 */
393230587Sken	plen = blen - (len & (blen - 1));
394230587Sken	memset(buf + len, (unsigned)plen - 1, plen);
395230587Sken	len += plen;
396230587Sken
397230587Sken	/*
398230587Sken	 * If an explicit IV is used, the corresponding extra block was
399181643Skmacy	 * already put in place earlier; we just have to account for it
400230587Sken	 * here.
401181643Skmacy	 */
402230587Sken	if (cc->explicit_IV) {
403230587Sken		buf -= blen;
404181643Skmacy		len += blen;
405230587Sken	}
406230587Sken
407181643Skmacy	/*
408230587Sken	 * Encrypt the whole thing. If there is an explicit IV, we also
409230587Sken	 * encrypt it, which is fine (encryption of a uniformly random
410181643Skmacy	 * block is still a uniformly random block).
411230587Sken	 */
412230587Sken	cc->bc.vtable->run(&cc->bc.vtable, cc->iv, buf, len);
413181643Skmacy
414230587Sken	/*
415181643Skmacy	 * Add the header and return.
416230587Sken	 */
417230587Sken	buf[-5] = record_type;
418230587Sken	br_enc16be(buf - 4, version);
419230587Sken	br_enc16be(buf - 2, len);
420230587Sken	*data_len = (size_t)((buf + len) - rbuf);
421230587Sken	return rbuf;
422230587Sken}
423230587Sken
424230587Sken/* see bearssl_ssl.h */
425230587Skenconst br_sslrec_out_cbc_class br_sslrec_out_cbc_vtable = {
426181643Skmacy	{
427230587Sken		sizeof(br_sslrec_out_cbc_context),
428230587Sken		(void (*)(const br_sslrec_out_class *const *,
429230587Sken			size_t *, size_t *))
430230587Sken			&cbc_max_plaintext,
431230587Sken		(unsigned char *(*)(const br_sslrec_out_class **,
432230587Sken			int, unsigned, void *, size_t *))
433181643Skmacy			&cbc_encrypt
434230587Sken	},
435230587Sken	(void (*)(const br_sslrec_out_cbc_class **,
436181643Skmacy		const br_block_cbcenc_class *, const void *, size_t,
437230587Sken		const br_hash_class *, const void *, size_t, size_t,
438230587Sken		const void *))
439181643Skmacy		&out_cbc_init
440255040Sgibbs};
441255040Sgibbs