Real Time Decryption of TLS 1.3 packets Asked today Modified today
I am attempting to perform real time decryption of TLS 1.3 packets (TLS_AES_256_GCM_SHA384
). I have retrieved the mastersecrets for the specific flow by using uprobes on OpenSSL, and matched the mastersecrets to the flow using ClientRandom. So I have client_application_traffic_secret
and server_application_traffic_secret
. In order to obtain the client_write_key
/server_write_key
, I am using the following function which is written as specified in RFC 8446,
func ExpandLabel(secret []byte, label string, context []byte, length int) []byte {
var hkdfLabel cryptobyte.Builder
hkdfLabel.AddUint16(uint16(length))
hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes([]byte("tls13 "))
b.AddBytes([]byte(label))
})
hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(context)
})
out := make([]byte, length)
n, err := hkdf.Expand(crypto.SHA384.New, secret, hkdfLabel.BytesOrPanic()).Read(out)
if err != nil || n != length {
panic("tls: HKDF-Expand-Label invocation failed unexpectedly")
}
return out
}
I am calling this function in this way - ExpandLabel(ClientAppTrafficSecret, "key", nil, 32)
for client_write_key
and ExpandLabel(ClientAppTrafficSecret, "iv", nil, 32)
for client_write_iv
.
And to generate the per record nonce as specified in RFC 8466,
func GeneratePerRecordNonce(sequenceNumber uint64, WriteIV []byte) ([]byte, error) {
ivLength := len(WriteIV)
nonce := make([]byte, ivLength)
// Encode the sequence number in big-endian format
seqNumBytes := make([]byte, 8) // 8 bytes for uint64
binary.BigEndian.PutUint64(seqNumBytes, sequenceNumber)
// Pad sequence number to the left with zeros to match IV length
copy(nonce[ivLength-8:], seqNumBytes)
// XOR with WriteIV
for i := range WriteIV {
nonce[i] ^= WriteIV[i]
}
return nonce, nil
}
I am calling this function this way - GeneratePerRecordNonce(clientRecordSeqNo, client_write_iv)
. I am maintaining a sequence number starting from 0 for ClientHello
for the client side and a sequence number starting from 0 for ServerHello
for server side, and incrementing client sequence number each time a packet is sent from the client and incrementing server sequence number each time a packet is sent from the server. For decryption,
client_write_key := ExpandLabel(ClientAppTrafficSecret, "key", nil, 32)
client_write_iv := ExpandLabel(ClientAppTrafficSecret, "iv", nil, 12)
aes, err := aes.NewCipher(client_write_key)
if err != nil {
logger.Error("failed to obtain cipher using key", zap.Error(err))
}
aead, err := cipher.NewGCM(aes)
if err != nil {
logger.Error("failed to obtain aead from cipher", zap.Error(err))
}
nonce, err := GeneratePerRecordNonce(clientRecordSeqNo, client_write_iv)
if err != nil {
logger.Error("failed to generate per record nonce", zap.Error(err))
}
additionalData := buffer[:5]
recordLength := binary.BigEndian.Uint16(additionalData[3:5])
record := buffer[5 : 5+recordLength]
plaintext, err := aead.Open(nil, nonce, record, additionalData)
if err != nil {
logger.Error("failed to decrypt", zap.Error(err))
}
Here the buffer is the packet data in application layer. I am getting message authentication failed
for this. What am I doing wrong?