aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2019-07-18 10:39:22 -0400
committerJack Lloyd <[email protected]>2019-07-18 10:41:55 -0400
commitc365d3922f7963d0bbf3b7390a574415e381851c (patch)
tree8fc0315bbf236b1b77a68dced9dac3779cfa9d14 /src/lib
parentaa314cddff4d8875542de036739f9916720e5e9e (diff)
Split more carefully to exactly MTU in DTLS handshake fragmentation.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/tls/tls_handshake_io.cpp36
1 files changed, 25 insertions, 11 deletions
diff --git a/src/lib/tls/tls_handshake_io.cpp b/src/lib/tls/tls_handshake_io.cpp
index 3f3e672de..6e2bf0284 100644
--- a/src/lib/tls/tls_handshake_io.cpp
+++ b/src/lib/tls/tls_handshake_io.cpp
@@ -426,6 +426,8 @@ std::vector<uint8_t> Datagram_Handshake_IO::send_message(uint16_t msg_seq,
Handshake_Type msg_type,
const std::vector<uint8_t>& msg_bits)
{
+ const size_t DTLS_HANDSHAKE_HEADER_LEN = 12;
+
const std::vector<uint8_t> no_fragment =
format_w_seq(msg_bits, msg_type, msg_seq);
@@ -437,22 +439,34 @@ std::vector<uint8_t> Datagram_Handshake_IO::send_message(uint16_t msg_seq,
{
size_t frag_offset = 0;
- const size_t DTLS_HANDSHAKE_HEADERS = 32;
- const size_t ciphersuite_overhead = (epoch > 0) ? 32 : 0;
- const size_t max_rec_size = m_mtu - DTLS_HANDSHAKE_HEADERS - ciphersuite_overhead;
+ /**
+ * Largest possible overhead is for SHA-384 CBC ciphers, with 16 byte IV,
+ * 16+ for padding and 48 bytes for MAC. 128 is probably a strict
+ * over-estimate here. When CBC ciphers are removed this can be reduced
+ * since AEAD modes have no padding, at most 16 byte mac, and smaller
+ * per-record nonce.
+ */
+ const size_t ciphersuite_overhead = (epoch > 0) ? 128 : 0;
+ const size_t header_overhead = DTLS_HEADER_SIZE + DTLS_HANDSHAKE_HEADER_LEN;
+
+ if(m_mtu <= (header_overhead + ciphersuite_overhead))
+ throw Invalid_Argument("DTLS MTU is too small to send headers");
+
+ const size_t max_rec_size = m_mtu - (header_overhead + ciphersuite_overhead);
while(frag_offset != msg_bits.size())
{
const size_t frag_len = std::min<size_t>(msg_bits.size() - frag_offset, max_rec_size);
- m_send_hs(epoch,
- HANDSHAKE,
- format_fragment(&msg_bits[frag_offset],
- frag_len,
- static_cast<uint16_t>(frag_offset),
- static_cast<uint16_t>(msg_bits.size()),
- msg_type,
- msg_seq));
+ const std::vector<uint8_t> frag =
+ format_fragment(&msg_bits[frag_offset],
+ frag_len,
+ static_cast<uint16_t>(frag_offset),
+ static_cast<uint16_t>(msg_bits.size()),
+ msg_type,
+ msg_seq);
+
+ m_send_hs(epoch, HANDSHAKE, frag);
frag_offset += frag_len;
}