Crypt-Bear
view release on metacpan or search on metacpan
src/ssl/ssl_rec_cbc.c view on Meta::CPAN
}
/*
* Recompute the HMAC value. The input is the concatenation of
* the sequence number (8 bytes), the record header (5 bytes),
* and the payload.
*
* At that point, min_len is the minimum plaintext length, but
* max_len still includes the MAC length.
*/
br_enc64be(tmp2, cc->seq ++);
tmp2[8] = (unsigned char)record_type;
br_enc16be(tmp2 + 9, version);
br_enc16be(tmp2 + 11, len_nomac);
br_hmac_init(&hc, &cc->mac, cc->mac_len);
br_hmac_update(&hc, tmp2, 13);
br_hmac_outCT(&hc, buf, len_nomac, min_len, max_len, tmp2);
/*
* Compare the extracted and recomputed MAC values.
*/
for (u = 0; u < cc->mac_len; u ++) {
good &= EQ0(tmp1[u] ^ tmp2[u]);
}
/*
* Check that the plaintext length is valid. The previous
* check was on the encrypted length, but the padding may have
* turned shorter than expected.
*
* Once this final test is done, the critical "constant-time"
* section ends and we can make conditional jumps again.
*/
good &= LE(len_nomac, 16384);
if (!good) {
return 0;
}
*data_len = len_nomac;
return buf;
}
/* see bearssl_ssl.h */
const br_sslrec_in_cbc_class br_sslrec_in_cbc_vtable = {
{
sizeof(br_sslrec_in_cbc_context),
(int (*)(const br_sslrec_in_class *const *, size_t))
&cbc_check_length,
(unsigned char *(*)(const br_sslrec_in_class **,
int, unsigned, void *, size_t *))
&cbc_decrypt
},
(void (*)(const br_sslrec_in_cbc_class **,
const br_block_cbcdec_class *, const void *, size_t,
const br_hash_class *, const void *, size_t, size_t,
const void *))
&in_cbc_init
};
/*
* For CBC output:
*
* -- With TLS 1.1+, there is an explicit IV. Generation method uses
* HMAC, computed over the current sequence number, and the current MAC
* key. The resulting value is truncated to the size of a block, and
* added at the head of the plaintext; it will get encrypted along with
* the data. This custom generation mechanism is "safe" under the
* assumption that HMAC behaves like a random oracle; since the MAC for
* a record is computed over the concatenation of the sequence number,
* the record header and the plaintext, the HMAC-for-IV will not collide
* with the normal HMAC.
*
* -- With TLS 1.0, for application data, we want to enforce a 1/n-1
* split, as a countermeasure against chosen-plaintext attacks. We thus
* need to leave some room in the buffer for that extra record.
*/
static void
out_cbc_init(br_sslrec_out_cbc_context *cc,
const br_block_cbcenc_class *bc_impl,
const void *bc_key, size_t bc_key_len,
const br_hash_class *dig_impl,
const void *mac_key, size_t mac_key_len, size_t mac_out_len,
const void *iv)
{
cc->vtable = &br_sslrec_out_cbc_vtable;
cc->seq = 0;
bc_impl->init(&cc->bc.vtable, bc_key, bc_key_len);
br_hmac_key_init(&cc->mac, dig_impl, mac_key, mac_key_len);
cc->mac_len = mac_out_len;
if (iv == NULL) {
memset(cc->iv, 0, sizeof cc->iv);
cc->explicit_IV = 1;
} else {
memcpy(cc->iv, iv, bc_impl->block_size);
cc->explicit_IV = 0;
}
}
static void
cbc_max_plaintext(const br_sslrec_out_cbc_context *cc,
size_t *start, size_t *end)
{
size_t blen, len;
blen = cc->bc.vtable->block_size;
if (cc->explicit_IV) {
*start += blen;
} else {
*start += 4 + ((cc->mac_len + blen + 1) & ~(blen - 1));
}
len = (*end - *start) & ~(blen - 1);
len -= 1 + cc->mac_len;
if (len > 16384) {
len = 16384;
}
*end = *start + len;
}
static unsigned char *
cbc_encrypt(br_sslrec_out_cbc_context *cc,
( run in 0.516 second using v1.01-cache-2.11-cpan-e1769b4cff6 )