mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 04:37:36 +03:00
fix timing side channel when reading headers with invalid reserved bits
This commit is contained in:
parent
4fe0f6752c
commit
7b9b711a77
4 changed files with 105 additions and 26 deletions
|
@ -91,28 +91,40 @@ func (u *packetUnpacker) Unpack(hdr *wire.Header, data []byte) (*unpackedPacket,
|
|||
}
|
||||
|
||||
func (u *packetUnpacker) unpackLongHeaderPacket(opener handshake.LongHeaderOpener, hdr *wire.Header, data []byte) (*wire.ExtendedHeader, []byte, error) {
|
||||
extHdr, err := u.unpack(opener, hdr, data)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
extHdr, parseErr := u.unpack(opener, hdr, data)
|
||||
// If the reserved bits are set incorrectly, we still need to continue unpacking.
|
||||
// This avoids a timing side-channel, which otherwise might allow an attacker
|
||||
// to gain information about the header encryption.
|
||||
if parseErr != nil && parseErr != wire.ErrInvalidReservedBits {
|
||||
return nil, nil, fmt.Errorf("error parsing extended header: %s", parseErr)
|
||||
}
|
||||
extHdrLen := extHdr.GetLength(u.version)
|
||||
decrypted, err := opener.Open(data[extHdrLen:extHdrLen], data[extHdrLen:], extHdr.PacketNumber, data[:extHdrLen])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if parseErr != nil {
|
||||
return nil, nil, parseErr
|
||||
}
|
||||
return extHdr, decrypted, nil
|
||||
}
|
||||
|
||||
func (u *packetUnpacker) unpackShortHeaderPacket(opener handshake.ShortHeaderOpener, hdr *wire.Header, data []byte) (*wire.ExtendedHeader, []byte, error) {
|
||||
extHdr, err := u.unpack(opener, hdr, data)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
extHdr, parseErr := u.unpack(opener, hdr, data)
|
||||
// If the reserved bits are set incorrectly, we still need to continue unpacking.
|
||||
// This avoids a timing side-channel, which otherwise might allow an attacker
|
||||
// to gain information about the header encryption.
|
||||
if parseErr != nil && parseErr != wire.ErrInvalidReservedBits {
|
||||
return nil, nil, parseErr
|
||||
}
|
||||
extHdrLen := extHdr.GetLength(u.version)
|
||||
decrypted, err := opener.Open(data[extHdrLen:extHdrLen], data[extHdrLen:], extHdr.PacketNumber, extHdr.KeyPhase, data[:extHdrLen])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if parseErr != nil {
|
||||
return nil, nil, parseErr
|
||||
}
|
||||
return extHdr, decrypted, nil
|
||||
}
|
||||
|
||||
|
@ -134,9 +146,9 @@ func (u *packetUnpacker) unpack(hd headerDecryptor, hdr *wire.Header, data []byt
|
|||
data[hdrLen:hdrLen+4],
|
||||
)
|
||||
// 3. parse the header (and learn the actual length of the packet number)
|
||||
extHdr, err := hdr.ParseExtended(r, u.version)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing extended header: %s", err)
|
||||
extHdr, parseErr := hdr.ParseExtended(r, u.version)
|
||||
if parseErr != nil && parseErr != wire.ErrInvalidReservedBits {
|
||||
return nil, parseErr
|
||||
}
|
||||
// 4. if the packet number is shorter than 4 bytes, replace the remaining bytes with the copy we saved earlier
|
||||
if extHdr.PacketNumberLen != protocol.PacketNumberLen4 {
|
||||
|
@ -148,5 +160,5 @@ func (u *packetUnpacker) unpack(hd headerDecryptor, hdr *wire.Header, data []byt
|
|||
u.largestRcvdPacketNumber,
|
||||
extHdr.PacketNumber,
|
||||
)
|
||||
return extHdr, nil
|
||||
return extHdr, parseErr
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue