Path: blob/main/contrib/bearssl/src/ssl/ssl_rec_cbc.c
39488 views
/*1* Copyright (c) 2016 Thomas Pornin <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining4* a copy of this software and associated documentation files (the5* "Software"), to deal in the Software without restriction, including6* without limitation the rights to use, copy, modify, merge, publish,7* distribute, sublicense, and/or sell copies of the Software, and to8* permit persons to whom the Software is furnished to do so, subject to9* the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*/2324#include "inner.h"2526static void27in_cbc_init(br_sslrec_in_cbc_context *cc,28const br_block_cbcdec_class *bc_impl,29const void *bc_key, size_t bc_key_len,30const br_hash_class *dig_impl,31const void *mac_key, size_t mac_key_len, size_t mac_out_len,32const void *iv)33{34cc->vtable = &br_sslrec_in_cbc_vtable;35cc->seq = 0;36bc_impl->init(&cc->bc.vtable, bc_key, bc_key_len);37br_hmac_key_init(&cc->mac, dig_impl, mac_key, mac_key_len);38cc->mac_len = mac_out_len;39if (iv == NULL) {40memset(cc->iv, 0, sizeof cc->iv);41cc->explicit_IV = 1;42} else {43memcpy(cc->iv, iv, bc_impl->block_size);44cc->explicit_IV = 0;45}46}4748static int49cbc_check_length(const br_sslrec_in_cbc_context *cc, size_t rlen)50{51/*52* Plaintext size: at most 16384 bytes53* Padding: at most 256 bytes54* MAC: mac_len extra bytes55* TLS 1.1+: each record has an explicit IV56*57* Minimum length includes at least one byte of padding, and the58* MAC.59*60* Total length must be a multiple of the block size.61*/62size_t blen;63size_t min_len, max_len;6465blen = cc->bc.vtable->block_size;66min_len = (blen + cc->mac_len) & ~(blen - 1);67max_len = (16384 + 256 + cc->mac_len) & ~(blen - 1);68if (cc->explicit_IV) {69min_len += blen;70max_len += blen;71}72return min_len <= rlen && rlen <= max_len;73}7475/*76* Rotate array buf[] of length 'len' to the left (towards low indices)77* by 'num' bytes if ctl is 1; otherwise, leave it unchanged. This is78* constant-time. 'num' MUST be lower than 'len'. 'len' MUST be lower79* than or equal to 64.80*/81static void82cond_rotate(uint32_t ctl, unsigned char *buf, size_t len, size_t num)83{84unsigned char tmp[64];85size_t u, v;8687for (u = 0, v = num; u < len; u ++) {88tmp[u] = MUX(ctl, buf[v], buf[u]);89if (++ v == len) {90v = 0;91}92}93memcpy(buf, tmp, len);94}9596static unsigned char *97cbc_decrypt(br_sslrec_in_cbc_context *cc,98int record_type, unsigned version, void *data, size_t *data_len)99{100/*101* We represent all lengths on 32-bit integers, because:102* -- SSL record lengths always fit in 32 bits;103* -- our constant-time primitives operate on 32-bit integers.104*/105unsigned char *buf;106uint32_t u, v, len, blen, min_len, max_len;107uint32_t good, pad_len, rot_count, len_withmac, len_nomac;108unsigned char tmp1[64], tmp2[64];109int i;110br_hmac_context hc;111112buf = data;113len = *data_len;114blen = cc->bc.vtable->block_size;115116/*117* Decrypt data, and skip the explicit IV (if applicable). Note118* that the total length is supposed to have been verified by119* the caller. If there is an explicit IV, then we actually120* "decrypt" it using the implicit IV (from previous record),121* which is useless but harmless.122*/123cc->bc.vtable->run(&cc->bc.vtable, cc->iv, data, len);124if (cc->explicit_IV) {125buf += blen;126len -= blen;127}128129/*130* Compute minimum and maximum length of plaintext + MAC. These131* lengths can be inferred from the outside: they are not secret.132*/133min_len = (cc->mac_len + 256 < len) ? len - 256 : cc->mac_len;134max_len = len - 1;135136/*137* Use the last decrypted byte to compute the actual payload138* length. Take care not to overflow (we use unsigned types).139*/140pad_len = buf[max_len];141good = LE(pad_len, (uint32_t)(max_len - min_len));142len = MUX(good, (uint32_t)(max_len - pad_len), min_len);143144/*145* Check padding contents: all padding bytes must be equal to146* the value of pad_len.147*/148for (u = min_len; u < max_len; u ++) {149good &= LT(u, len) | EQ(buf[u], pad_len);150}151152/*153* Extract the MAC value. This is done in one pass, but results154* in a "rotated" MAC value depending on where it actually155* occurs. The 'rot_count' value is set to the offset of the156* first MAC byte within tmp1[].157*158* min_len and max_len are also adjusted to the minimum and159* maximum lengths of the plaintext alone (without the MAC).160*/161len_withmac = (uint32_t)len;162len_nomac = len_withmac - cc->mac_len;163min_len -= cc->mac_len;164rot_count = 0;165memset(tmp1, 0, cc->mac_len);166v = 0;167for (u = min_len; u < max_len; u ++) {168tmp1[v] |= MUX(GE(u, len_nomac) & LT(u, len_withmac),169buf[u], 0x00);170rot_count = MUX(EQ(u, len_nomac), v, rot_count);171if (++ v == cc->mac_len) {172v = 0;173}174}175max_len -= cc->mac_len;176177/*178* Rotate back the MAC value. The loop below does the constant-time179* rotation in time n*log n for a MAC output of length n. We assume180* that the MAC output length is no more than 64 bytes, so the181* rotation count fits on 6 bits.182*/183for (i = 5; i >= 0; i --) {184uint32_t rc;185186rc = (uint32_t)1 << i;187cond_rotate(rot_count >> i, tmp1, cc->mac_len, rc);188rot_count &= ~rc;189}190191/*192* Recompute the HMAC value. The input is the concatenation of193* the sequence number (8 bytes), the record header (5 bytes),194* and the payload.195*196* At that point, min_len is the minimum plaintext length, but197* max_len still includes the MAC length.198*/199br_enc64be(tmp2, cc->seq ++);200tmp2[8] = (unsigned char)record_type;201br_enc16be(tmp2 + 9, version);202br_enc16be(tmp2 + 11, len_nomac);203br_hmac_init(&hc, &cc->mac, cc->mac_len);204br_hmac_update(&hc, tmp2, 13);205br_hmac_outCT(&hc, buf, len_nomac, min_len, max_len, tmp2);206207/*208* Compare the extracted and recomputed MAC values.209*/210for (u = 0; u < cc->mac_len; u ++) {211good &= EQ0(tmp1[u] ^ tmp2[u]);212}213214/*215* Check that the plaintext length is valid. The previous216* check was on the encrypted length, but the padding may have217* turned shorter than expected.218*219* Once this final test is done, the critical "constant-time"220* section ends and we can make conditional jumps again.221*/222good &= LE(len_nomac, 16384);223224if (!good) {225return 0;226}227*data_len = len_nomac;228return buf;229}230231/* see bearssl_ssl.h */232const br_sslrec_in_cbc_class br_sslrec_in_cbc_vtable = {233{234sizeof(br_sslrec_in_cbc_context),235(int (*)(const br_sslrec_in_class *const *, size_t))236&cbc_check_length,237(unsigned char *(*)(const br_sslrec_in_class **,238int, unsigned, void *, size_t *))239&cbc_decrypt240},241(void (*)(const br_sslrec_in_cbc_class **,242const br_block_cbcdec_class *, const void *, size_t,243const br_hash_class *, const void *, size_t, size_t,244const void *))245&in_cbc_init246};247248/*249* For CBC output:250*251* -- With TLS 1.1+, there is an explicit IV. Generation method uses252* HMAC, computed over the current sequence number, and the current MAC253* key. The resulting value is truncated to the size of a block, and254* added at the head of the plaintext; it will get encrypted along with255* the data. This custom generation mechanism is "safe" under the256* assumption that HMAC behaves like a random oracle; since the MAC for257* a record is computed over the concatenation of the sequence number,258* the record header and the plaintext, the HMAC-for-IV will not collide259* with the normal HMAC.260*261* -- With TLS 1.0, for application data, we want to enforce a 1/n-1262* split, as a countermeasure against chosen-plaintext attacks. We thus263* need to leave some room in the buffer for that extra record.264*/265266static void267out_cbc_init(br_sslrec_out_cbc_context *cc,268const br_block_cbcenc_class *bc_impl,269const void *bc_key, size_t bc_key_len,270const br_hash_class *dig_impl,271const void *mac_key, size_t mac_key_len, size_t mac_out_len,272const void *iv)273{274cc->vtable = &br_sslrec_out_cbc_vtable;275cc->seq = 0;276bc_impl->init(&cc->bc.vtable, bc_key, bc_key_len);277br_hmac_key_init(&cc->mac, dig_impl, mac_key, mac_key_len);278cc->mac_len = mac_out_len;279if (iv == NULL) {280memset(cc->iv, 0, sizeof cc->iv);281cc->explicit_IV = 1;282} else {283memcpy(cc->iv, iv, bc_impl->block_size);284cc->explicit_IV = 0;285}286}287288static void289cbc_max_plaintext(const br_sslrec_out_cbc_context *cc,290size_t *start, size_t *end)291{292size_t blen, len;293294blen = cc->bc.vtable->block_size;295if (cc->explicit_IV) {296*start += blen;297} else {298*start += 4 + ((cc->mac_len + blen + 1) & ~(blen - 1));299}300len = (*end - *start) & ~(blen - 1);301len -= 1 + cc->mac_len;302if (len > 16384) {303len = 16384;304}305*end = *start + len;306}307308static unsigned char *309cbc_encrypt(br_sslrec_out_cbc_context *cc,310int record_type, unsigned version, void *data, size_t *data_len)311{312unsigned char *buf, *rbuf;313size_t len, blen, plen;314unsigned char tmp[13];315br_hmac_context hc;316317buf = data;318len = *data_len;319blen = cc->bc.vtable->block_size;320321/*322* If using TLS 1.0, with more than one byte of plaintext, and323* the record is application data, then we need to compute324* a "split". We do not perform the split on other record types325* because it turned out that some existing, deployed326* implementations of SSL/TLS do not tolerate the splitting of327* some message types (in particular the Finished message).328*329* If using TLS 1.1+, then there is an explicit IV. We produce330* that IV by adding an extra initial plaintext block, whose331* value is computed with HMAC over the record sequence number.332*/333if (cc->explicit_IV) {334/*335* We use here the fact that all the HMAC variants we336* support can produce at least 16 bytes, while all the337* block ciphers we support have blocks of no more than338* 16 bytes. Thus, we can always truncate the HMAC output339* down to the block size.340*/341br_enc64be(tmp, cc->seq);342br_hmac_init(&hc, &cc->mac, blen);343br_hmac_update(&hc, tmp, 8);344br_hmac_out(&hc, buf - blen);345rbuf = buf - blen - 5;346} else {347if (len > 1 && record_type == BR_SSL_APPLICATION_DATA) {348/*349* To do the split, we use a recursive invocation;350* since we only give one byte to the inner call,351* the recursion stops there.352*353* We need to compute the exact size of the extra354* record, so that the two resulting records end up355* being sequential in RAM.356*357* We use here the fact that cbc_max_plaintext()358* adjusted the start offset to leave room for the359* initial fragment.360*/361size_t xlen;362363rbuf = buf - 4364- ((cc->mac_len + blen + 1) & ~(blen - 1));365rbuf[0] = buf[0];366xlen = 1;367rbuf = cbc_encrypt(cc, record_type,368version, rbuf, &xlen);369buf ++;370len --;371} else {372rbuf = buf - 5;373}374}375376/*377* Compute MAC.378*/379br_enc64be(tmp, cc->seq ++);380tmp[8] = record_type;381br_enc16be(tmp + 9, version);382br_enc16be(tmp + 11, len);383br_hmac_init(&hc, &cc->mac, cc->mac_len);384br_hmac_update(&hc, tmp, 13);385br_hmac_update(&hc, buf, len);386br_hmac_out(&hc, buf + len);387len += cc->mac_len;388389/*390* Add padding.391*/392plen = blen - (len & (blen - 1));393memset(buf + len, (unsigned)plen - 1, plen);394len += plen;395396/*397* If an explicit IV is used, the corresponding extra block was398* already put in place earlier; we just have to account for it399* here.400*/401if (cc->explicit_IV) {402buf -= blen;403len += blen;404}405406/*407* Encrypt the whole thing. If there is an explicit IV, we also408* encrypt it, which is fine (encryption of a uniformly random409* block is still a uniformly random block).410*/411cc->bc.vtable->run(&cc->bc.vtable, cc->iv, buf, len);412413/*414* Add the header and return.415*/416buf[-5] = record_type;417br_enc16be(buf - 4, version);418br_enc16be(buf - 2, len);419*data_len = (size_t)((buf + len) - rbuf);420return rbuf;421}422423/* see bearssl_ssl.h */424const br_sslrec_out_cbc_class br_sslrec_out_cbc_vtable = {425{426sizeof(br_sslrec_out_cbc_context),427(void (*)(const br_sslrec_out_class *const *,428size_t *, size_t *))429&cbc_max_plaintext,430(unsigned char *(*)(const br_sslrec_out_class **,431int, unsigned, void *, size_t *))432&cbc_encrypt433},434(void (*)(const br_sslrec_out_cbc_class **,435const br_block_cbcenc_class *, const void *, size_t,436const br_hash_class *, const void *, size_t, size_t,437const void *))438&out_cbc_init439};440441442