Browse Source

fix: mac calculation fails when subsequent packet is shorter

Before AEAD encryption data are stored in a buffer. Last possition
of this buffer store data type. When subsequent TLS record is shorter
than previous, the buffer is shrinked. This causes to remove data
type, which results in wrong MAC calculation. Only in case of TLS 1.3.
v1.2.3
Kris Kwiatkowski 6 years ago
committed by Kris Kwiatkowski
parent
commit
58c559ba00
1 changed files with 11 additions and 7 deletions
  1. +11
    -7
      conn.go

+ 11
- 7
conn.go View File

@@ -472,23 +472,30 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
case aead: case aead:
// explicitIVLen is always 0 for TLS1.3 // explicitIVLen is always 0 for TLS1.3
payloadLen := len(b.data) - recordHeaderLen - explicitIVLen payloadLen := len(b.data) - recordHeaderLen - explicitIVLen
payloadOffset := recordHeaderLen + explicitIVLen
nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen] nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
if len(nonce) == 0 { if len(nonce) == 0 {
nonce = hc.seq[:] nonce = hc.seq[:]
} }
payload = b.data[recordHeaderLen+explicitIVLen:]
payload = payload[:payloadLen]


var additionalData []byte var additionalData []byte
if hc.version < VersionTLS13 { if hc.version < VersionTLS13 {
// make room in a buffer for payload + MAC
b.resize(len(b.data) + c.Overhead())

payload = b.data[payloadOffset : payloadOffset+payloadLen]
copy(hc.additionalData[:], hc.seq[:]) copy(hc.additionalData[:], hc.seq[:])
copy(hc.additionalData[8:], b.data[:3]) copy(hc.additionalData[8:], b.data[:3])
binary.BigEndian.PutUint16(hc.additionalData[11:], uint16(payloadLen)) binary.BigEndian.PutUint16(hc.additionalData[11:], uint16(payloadLen))
additionalData = hc.additionalData[:] additionalData = hc.additionalData[:]
b.resize(len(b.data) + c.Overhead())
} else { } else {
// make room in a buffer for TLSCiphertext.encrypted_record:
// payload + MAC + extra data if needed
b.resize(len(b.data) + c.Overhead() + 1)

payload = b.data[payloadOffset : payloadOffset+payloadLen+1]
// 1 byte of content type is appended to payload and encrypted // 1 byte of content type is appended to payload and encrypted
payload = append(payload, b.data[0])
payload[len(payload)-1] = b.data[0]


// opaque_type // opaque_type
b.data[0] = byte(recordTypeApplicationData) b.data[0] = byte(recordTypeApplicationData)
@@ -498,9 +505,6 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
additionalData[0] = b.data[0] additionalData[0] = b.data[0]
binary.BigEndian.PutUint16(additionalData[1:], VersionTLS12) binary.BigEndian.PutUint16(additionalData[1:], VersionTLS12)
binary.BigEndian.PutUint16(additionalData[3:], uint16(len(payload)+c.Overhead())) binary.BigEndian.PutUint16(additionalData[3:], uint16(len(payload)+c.Overhead()))

// make room for TLSCiphertext.encrypted_record
b.resize(len(payload) + recordHeaderLen + c.Overhead())
} }
c.Seal(payload[:0], nonce, payload, additionalData) c.Seal(payload[:0], nonce, payload, additionalData)
case cbcMode: case cbcMode:


Loading…
Cancel
Save