Correctly handle epoch wrapping in dtls1_get_bitmap().
authorjsing <jsing@openbsd.org>
Sat, 19 Jun 2021 17:21:39 +0000 (17:21 +0000)
committerjsing <jsing@openbsd.org>
Sat, 19 Jun 2021 17:21:39 +0000 (17:21 +0000)
commitbdaf1583af1de60bbad2f5dfc8aa17126cb23563
tree36c94b9af6e9ac98ea86afdf1528861167e4a8ab
parent39e756f120e22175137065480d7840f0cd1ca2eb
Correctly handle epoch wrapping in dtls1_get_bitmap().

Due to a type bug that has been present in DTLS since the code was first
committed in 2005, dtls1_get_bitmap() fails to handle next epoch correctly
when the epoch is currently 0xffff (and wraps to zero).

For various reasons unknown, the epoch field in the SSL3_RECORD_INTERNAL
(formerly SSL3_RECORD) was added as unsigned long (even though the value
is an unsigned 16 bit value on the wire, hence cannot exceed 0xffff),
however was added to other code as unsigned short.

Due to integer promotion, the r_epoch value is incremented by one to
become 0x10000, before being cast to an unsigned long and compared to
the value pulled from the DTLS record header (which is zero). Strangely
0x10000 != 0, meaning that we drop the DTLS record, instead of queueing
it for the next epoch.

Fix this issue by using more appropriate types and pulling up the
calculation of the next epoch value for improved readability.

ok inoguchi@ tb@
lib/libssl/d1_pkt.c
lib/libssl/ssl_locl.h