• caglararli@hotmail.com
  • 05386281520

Real Time Decryption of TLS 1.3 packets Asked today Modified today

Çağlar Arlı      -    19 Views

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?