1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:57:35 +00:00

LibTLS: Simplify record padding logic and ASSERT more assumptions

This commit is contained in:
AnotherTest 2020-06-04 16:52:56 +04:30 committed by Andreas Kling
parent 63cc2f58ea
commit b67acf9c88

View file

@ -68,24 +68,21 @@ void TLSv12::update_packet(ByteBuffer& packet)
if (m_context.cipher_spec_set && m_context.crypto.created) {
size_t length = packet.size() - header_size + mac_length();
auto block_size = m_aes_local->cipher().block_size();
// if length is a multiple of block size, pad it up again
// since it seems no one handles aligned unpadded blocks
size_t padding = 0;
if (length % block_size == 0) {
padding = block_size;
length += padding;
}
// If the length is already a multiple a block_size,
// an entire block of padding is added.
// In short, we _never_ have no padding.
size_t padding = block_size - length % block_size;
length += padding;
size_t mac_size = mac_length();
if (m_context.crypto.created == 1) {
// `buffer' will continue to be encrypted
auto buffer = ByteBuffer::create_zeroed(length);
size_t buffer_position = 0;
u16 aligned_length = length + block_size - length % block_size;
auto iv_size = iv_length();
// we need enough space for a header, iv_length bytes of IV and whatever the packet contains
auto ct = ByteBuffer::create_zeroed(aligned_length + header_size + iv_size);
// We need enough space for a header, iv_length bytes of IV and whatever the packet contains
auto ct = ByteBuffer::create_zeroed(length + header_size + iv_size);
// copy the header over
ct.overwrite(0, packet.data(), header_size - 2);
@ -101,32 +98,30 @@ void TLSv12::update_packet(ByteBuffer& packet)
buffer.overwrite(buffer_position, mac.data(), mac.size());
buffer_position += mac.size();
// if there's some padding to be done (since a packet MUST always be padded)
// apply it manually
if (padding) {
memset(buffer.offset_pointer(buffer_position), padding - 1, padding);
buffer_position += padding;
}
// Apply the padding (a packet MUST always be padded)
memset(buffer.offset_pointer(buffer_position), padding - 1, padding);
buffer_position += padding;
// should be the same value, but the manual padding
// throws a wrench into our plans
buffer.trim(buffer_position);
ASSERT(buffer_position == buffer.size());
// FIXME: REALLY Should be filled with random bytes
auto iv = ByteBuffer::create_zeroed(iv_size);
auto iv = ByteBuffer::create_uninitialized(iv_size);
AK::fill_with_random(iv.data(), iv.size());
// write it into the ciphertext portion of the message
ct.overwrite(header_size, iv.data(), iv.size());
ct.trim(length + block_size - length % block_size + header_size + block_size - padding);
ASSERT(header_size + iv_size + length == ct.size());
ASSERT(length % block_size == 0);
// get a block to encrypt into
auto view = ct.slice_view(header_size + iv_size, length + block_size - length % block_size + block_size - padding - iv_size);
auto view = ct.slice_view(header_size + iv_size, length);
// encrypt the message
m_aes_local->encrypt(buffer, view, iv);
// store the correct ciphertext length into the packet
u16 ct_length = (u16)ct.size() - header_size;
*(u16*)ct.offset_pointer(header_size - 2) = convert_between_host_and_network(ct_length);
// replace the packet with the ciphertext