Skip to content

Commit

Permalink
fix: export TLSv1.3 key log file
Browse files Browse the repository at this point in the history
  • Loading branch information
blaisewang committed Sep 15, 2022
1 parent b57ba45 commit d037a2a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 89 deletions.
5 changes: 0 additions & 5 deletions kern/masterkey_kern.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,6 @@ int probe_ssl_master_key(struct pt_regs *ctx) {
mastersecret->version = version; // int version;
#endif
debug_bpf_printk("TLS version :%d\n", mastersecret->version);
if (mastersecret->version == TLS1_3_VERSION) {
// for debug TODO
// TLS 1.3 return 0
return 0;
}

// Get ssl3_state_st pointer
ret = bpf_probe_read_user(&address, sizeof(address), ssl_s3_st_ptr);
Expand Down
29 changes: 6 additions & 23 deletions pkg/util/hkdf/hkdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ package hkdf

import (
"crypto"
"fmt"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/crypto/hkdf"
"hash"
)

const (
Expand All @@ -41,45 +39,30 @@ const (
KeyLogLabelExporterSecret = "EXPORTER_SECRET"
)

// crypto/tls/cipher_suites.go line 678
// TLS 1.3 cipher suites.
const (
// crypto/tls/cipher_suites.go line 678
// TLS 1.3 cipher suites.
TLS_AES_128_GCM_SHA256 uint16 = 0x1301
TLS_AES_256_GCM_SHA384 uint16 = 0x1302
TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303
)

// expandLabel implements HKDF-Expand-Label from RFC 8446, Section 7.1.
func expandLabel(secret []byte, label string, context []byte, length int, cipherId uint32) []byte {
// ExpandLabel implements HKDF-Expand-Label from RFC 8446, Section 7.1.
func ExpandLabel(secret []byte, label string, context []byte, length int, transcript crypto.Hash) []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)
b.AddBytes(context[:length])
})
out := make([]byte, length)

var transcript crypto.Hash
switch uint16(cipherId & 0x0000FFFF) {
case TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256:
transcript = crypto.SHA256
case TLS_AES_256_GCM_SHA384:
transcript = crypto.SHA384
default:
panic(fmt.Sprintf("Unknown cipher: %d", cipherId))
}
n, err := hkdf.Expand(transcript.New, secret, hkdfLabel.BytesOrPanic()).Read(out)
n, err := hkdf.Expand(transcript.New, secret[:length], hkdfLabel.BytesOrPanic()).Read(out)
if err != nil || n != length {
panic("tls: HKDF-Expand-Label invocation failed unexpectedly")
}
return out
}

// from crypto/tls/key_schedule.go line 35
// DeriveSecret implements Derive-Secret from RFC 8446, Section 7.1.
func DeriveSecret(secret []byte, label string, transcript hash.Hash, cipherId uint32) []byte {
return expandLabel(secret, label, transcript.Sum(nil), transcript.Size(), cipherId)
}
51 changes: 21 additions & 30 deletions pkg/util/hkdf/hkdf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,63 +3,54 @@ package hkdf
import (
"crypto"
_ "crypto/sha256"
"hash"
_ "crypto/sha512"
"testing"
)

func TestHkdf(t *testing.T) {
t.Log("TestHkdf")
//TODO
var length int
var transcript crypto.Hash
var cipherId uint32 = 50336513
var transcript hash.Hash
// test with different cipherID
switch uint16(cipherId & 0x0000FFFF) {
case TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256:
transcript = crypto.SHA256.New()
length = 32
transcript = crypto.SHA256
case TLS_AES_256_GCM_SHA384:
transcript = crypto.SHA384.New()
length = 48
transcript = crypto.SHA384
default:
t.Log("Unknown cipher")
}

// HandshakeSecret
handshakeSecret := []byte{0x33, 0xad, 0x0a, 0x1c, 0x60, 0x7e, 0xc0, 0x3b, 0x09, 0xe6, 0xcd, 0x98, 0x93, 0x68, 0x0c, 0xe2, 0x10, 0xad, 0xf3, 0x00, 0xaa, 0x1f, 0x26, 0x60, 0xe1, 0xb2, 0x2e, 0x10, 0xf1, 0x70, 0xf9, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

// masterSecret
// MasterSecret
masterSecret := []byte{0x95, 0x8a, 0x8a, 0xfc, 0xa1, 0x12, 0x34, 0xac, 0x64, 0xf5, 0x9b, 0x09, 0xb3, 0xd2, 0xaf, 0xbb, 0xd3, 0xe8, 0x46, 0x4d, 0xce, 0xa5, 0x27, 0x6d, 0x30, 0xd4, 0x26, 0x85, 0x5a, 0x7a, 0xde, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

// HandshakeTrafficHash
handshakeTrafficHash := []byte{0x89, 0xf6, 0x4d, 0x87, 0xef, 0xf1, 0x30, 0x91, 0xfb, 0xa9, 0x9f, 0x20, 0x20, 0xb5, 0x16, 0xf9, 0x3a, 0x4a, 0xc4, 0x51, 0x6a, 0xd2, 0x6a, 0x94, 0x62, 0x04, 0x27, 0xe4, 0xe9, 0xa1, 0xd5, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
// ServerFinishedHash
serverFinishedHash := []byte{0x75, 0x28, 0xcb, 0x64, 0x54, 0xfb, 0x4c, 0xab, 0xbc, 0x00, 0x6a, 0x64, 0x01, 0xaa, 0xc6, 0xf3, 0x7f, 0x7d, 0xa0, 0x82, 0x72, 0x66, 0xc0, 0x6c, 0x5b, 0xbd, 0x96, 0x91, 0x02, 0xac, 0xf6, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

// ExporterMasterSecret
exporterMasterSecret := []byte{0x7d, 0x43, 0x64, 0x4b, 0xfa, 0x10, 0x38, 0x66, 0x18, 0x54, 0xac, 0x12, 0xff, 0x72, 0x6c, 0xcf, 0x26, 0xbe, 0x8d, 0x80, 0x8c, 0xf2, 0x0b, 0x16, 0x05, 0x71, 0xb1, 0xd4, 0xd4, 0xab, 0x5e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

transcript.Write(handshakeTrafficHash)
clientSecret := DeriveSecret(handshakeSecret,
ClientHandshakeTrafficLabel, transcript, cipherId)
t.Logf("%s: %x", KeyLogLabelClientHandshake, clientSecret)
clientHandshakeSecret := ExpandLabel(handshakeSecret[:length],
ClientHandshakeTrafficLabel, handshakeTrafficHash[:length], length, transcript)
t.Logf("%s: %x", KeyLogLabelClientHandshake, clientHandshakeSecret)

serverHandshakeSecret := DeriveSecret(handshakeSecret,
ServerHandshakeTrafficLabel, transcript, cipherId)
serverHandshakeSecret := ExpandLabel(handshakeSecret[:length],
ServerHandshakeTrafficLabel, handshakeTrafficHash[:length], length, transcript)
t.Logf("%s: %x", KeyLogLabelServerHandshake, serverHandshakeSecret)

transcript = crypto.SHA256.New()
transcript.Write(serverFinishedHash)
trafficSecret := DeriveSecret(masterSecret,
ClientApplicationTrafficLabel, transcript, cipherId)
t.Logf("%s: %x", KeyLogLabelClientTraffic, trafficSecret)
clientTrafficSecret := ExpandLabel(masterSecret[:length],
ClientApplicationTrafficLabel, serverFinishedHash[:length], length, transcript)
t.Logf("%s: %x", KeyLogLabelClientTraffic, clientTrafficSecret)

transcript = crypto.SHA256.New()
//finished := &finishedMsg{
// verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
//}
//
//hs.transcript.Write(finished.marshal())
transcript.Write(serverFinishedHash)
serverSecret := DeriveSecret(masterSecret,
ServerApplicationTrafficLabel, transcript, cipherId)
t.Logf("%s: %x", KeyLogLabelServerTraffic, serverSecret)
serverTrafficSecret := ExpandLabel(masterSecret[:length],
ServerApplicationTrafficLabel, serverFinishedHash[:length], length, transcript)
t.Logf("%s: %x", KeyLogLabelServerTraffic, serverTrafficSecret)

t.Logf("%s: %x", KeyLogLabelServerTraffic, exporterMasterSecret[:transcript.Size()])
t.Logf("%s: %x", KeyLogLabelExporterSecret, exporterMasterSecret[:length])
}
60 changes: 29 additions & 31 deletions user/module/probe_openssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
manager "github.com/ehids/ebpfmanager"
"github.com/google/gopacket/pcapgo"
"golang.org/x/sys/unix"
"hash"
"log"
"math"
"os"
Expand All @@ -25,16 +24,6 @@ import (

const (
CONN_NOT_FOUND = "[ADDR_NOT_FOUND]"

// tls 1.2
CLIENT_RANDOM = "CLIENT_RANDOM"

// tls 1.3
SERVER_HANDSHAKE_TRAFFIC_SECRET = "SERVER_HANDSHAKE_TRAFFIC_SECRET"
EXPORTER_SECRET = "EXPORTER_SECRET"
SERVER_TRAFFIC_SECRET_0 = "SERVER_TRAFFIC_SECRET_0"
CLIENT_HANDSHAKE_TRAFFIC_SECRET = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"
CLIENT_TRAFFIC_SECRET_0 = "CLIENT_TRAFFIC_SECRET_0"
)

type Tls13MasterSecret struct {
Expand Down Expand Up @@ -484,39 +473,48 @@ func (this *MOpenSSLProbe) saveMasterSecret(secretEvent *event.MasterSecretEvent
var b *bytes.Buffer
switch secretEvent.Version {
case event.TLS1_2_VERSION:
b = bytes.NewBufferString(fmt.Sprintf("%s %02x %02x\n", CLIENT_RANDOM, secretEvent.ClientRandom, secretEvent.MasterKey))
b = bytes.NewBufferString(fmt.Sprintf("%s %02x %02x\n", hkdf.KeyLogLabelTLS12, secretEvent.ClientRandom, secretEvent.MasterKey))
case event.TLS1_3_VERSION:
// secretEvent.CipherId = 0x1301 // 50336513

var transcript hash.Hash
// check crypto type
var length int
var transcript crypto.Hash
switch uint16(secretEvent.CipherId & 0x0000FFFF) {
case hkdf.TLS_AES_128_GCM_SHA256, hkdf.TLS_CHACHA20_POLY1305_SHA256:
transcript = crypto.SHA256.New()
length = 32
transcript = crypto.SHA256
case hkdf.TLS_AES_256_GCM_SHA384:
transcript = crypto.SHA384.New()
length = 48
transcript = crypto.SHA384
default:
this.logger.Printf("non-tls 1.3 ciphersuite in tls13_hkdf_expand, CipherId: %d", secretEvent.CipherId)
this.logger.Printf("non-TLSv1.3 cipher suite in tls13_hkdf_expand, CipherId: %d", secretEvent.CipherId)
return
}
transcript.Write(secretEvent.HandshakeTrafficHash[:])
clientSecret := hkdf.DeriveSecret(secretEvent.HandshakeSecret[:], hkdf.ClientHandshakeTrafficLabel, transcript, secretEvent.CipherId)
b = bytes.NewBufferString(fmt.Sprintf("%s %02x %02x\n", hkdf.KeyLogLabelClientHandshake, secretEvent.ClientRandom, clientSecret))

serverHandshakeSecret := hkdf.DeriveSecret(secretEvent.HandshakeSecret[:], hkdf.ServerHandshakeTrafficLabel, transcript, secretEvent.CipherId)
b.WriteString(fmt.Sprintf("%s %02x %02x\n", hkdf.KeyLogLabelServerHandshake, secretEvent.ClientRandom, serverHandshakeSecret))
clientHandshakeSecret := hkdf.ExpandLabel(secretEvent.HandshakeSecret[:length],
hkdf.ClientHandshakeTrafficLabel, secretEvent.HandshakeTrafficHash[:length], length, transcript)
b = bytes.NewBufferString(fmt.Sprintf("%s %02x %02x\n",
hkdf.KeyLogLabelClientHandshake, secretEvent.ClientRandom, clientHandshakeSecret))

serverHandshakeSecret := hkdf.ExpandLabel(secretEvent.HandshakeSecret[:length],
hkdf.ServerHandshakeTrafficLabel, secretEvent.HandshakeTrafficHash[:length], length, transcript)
b.WriteString(fmt.Sprintf("%s %02x %02x\n",
hkdf.KeyLogLabelServerHandshake, secretEvent.ClientRandom, serverHandshakeSecret))

clientTrafficSecret := hkdf.ExpandLabel(secretEvent.MasterSecret[:length],
hkdf.ClientApplicationTrafficLabel, secretEvent.ServerFinishedHash[:length], length, transcript)
b.WriteString(fmt.Sprintf("%s %02x %02x\n",
hkdf.KeyLogLabelClientTraffic, secretEvent.ClientRandom, clientTrafficSecret))

transcript.Reset()
transcript.Write(secretEvent.ServerFinishedHash[:])
serverTrafficSecret := hkdf.ExpandLabel(secretEvent.MasterSecret[:length],
hkdf.ServerApplicationTrafficLabel, secretEvent.ServerFinishedHash[:length], length, transcript)
b.WriteString(fmt.Sprintf("%s %02x %02x\n",
hkdf.KeyLogLabelServerTraffic, secretEvent.ClientRandom, serverTrafficSecret))

trafficSecret := hkdf.DeriveSecret(secretEvent.MasterSecret[:], hkdf.ClientApplicationTrafficLabel, transcript, secretEvent.CipherId)
b.WriteString(fmt.Sprintf("%s %02x %02x\n", hkdf.KeyLogLabelClientTraffic, secretEvent.ClientRandom, trafficSecret))
serverSecret := hkdf.DeriveSecret(secretEvent.MasterSecret[:], hkdf.ServerApplicationTrafficLabel, transcript, secretEvent.CipherId)
b.WriteString(fmt.Sprintf("%s %02x %02x\n", hkdf.KeyLogLabelServerTraffic, secretEvent.ClientRandom, serverSecret))
b.WriteString(fmt.Sprintf("%s %02x %02x\n",
hkdf.KeyLogLabelExporterSecret, secretEvent.ClientRandom, secretEvent.ExporterMasterSecret[:length]))

// TODO MasterSecret sum
default:
b = bytes.NewBufferString(fmt.Sprintf("%s %02x %02x\n", CLIENT_RANDOM, secretEvent.ClientRandom, secretEvent.MasterKey))
b = bytes.NewBufferString(fmt.Sprintf("%s %02x %02x\n", hkdf.KeyLogLabelTLS12, secretEvent.ClientRandom, secretEvent.MasterKey))
}
v := event.TlsVersion{Version: secretEvent.Version}
l, e := this.keylogger.WriteString(b.String())
Expand Down

0 comments on commit d037a2a

Please sign in to comment.