Skip to content

Commit 9b456fa

Browse files
committed
Add script to find key in dump
1 parent 162f528 commit 9b456fa

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

check_key_with_route.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env python3
2+
import struct
3+
import argparse
4+
5+
from Crypto.Hash import CMAC
6+
from Crypto.Cipher import AES
7+
8+
from openpilot.tools.lib.route import Route
9+
from openpilot.tools.lib.logreader import LogReader
10+
11+
KEY_LEN = 16
12+
13+
def build_sync_mac(key, trip_cnt, reset_cnt, id_=0xf):
14+
id_ = struct.pack('>H', id_) # 16
15+
trip_cnt = struct.pack('>H', trip_cnt) # 16
16+
reset_cnt = struct.pack('>I', reset_cnt << 12)[:-1] # 20 + 4 padding
17+
18+
to_auth = id_ + trip_cnt + reset_cnt # SecOC 11.4.1.1 page 138
19+
20+
cmac = CMAC.new(key, ciphermod=AES)
21+
cmac.update(to_auth)
22+
23+
msg = "0" + cmac.digest().hex()[:7]
24+
msg = bytes.fromhex(msg)
25+
return struct.unpack('>I', msg)[0]
26+
27+
28+
def find_key(data, sync_msg):
29+
trip_cnt = struct.unpack('>H', sync_msg[:2])[0]
30+
reset_cnt = struct.unpack('>I', b'\x00' + sync_msg[2:5])[0] >> 4
31+
good_mac = struct.unpack('>I', sync_msg[4:])[0] & 0xfffffff
32+
33+
for offset in range(len(data) - KEY_LEN + 1):
34+
key = data[offset:offset + KEY_LEN]
35+
mac = build_sync_mac(key, trip_cnt, reset_cnt)
36+
37+
if mac == good_mac:
38+
print(f"Found key {key.hex()}, offset 0x{offset:x}")
39+
40+
if __name__ == "__main__":
41+
parser = argparse.ArgumentParser()
42+
parser.add_argument("route", help="Route to check")
43+
parser.add_argument("dataflash", help="Filename to dataflash dump")
44+
args = parser.parse_args()
45+
46+
route = Route(args.route)
47+
logs = [s for s in route.log_paths() + route.qlog_paths() if s is not None]
48+
49+
with open(args.dataflash, 'rb') as f:
50+
data = f.read()
51+
52+
sync_msg_seen = False
53+
for path in logs:
54+
log = LogReader(path)
55+
56+
for msg in log:
57+
if msg.which == 'can':
58+
for c in msg.can:
59+
if c.src == 0 and c.address == 0xf:
60+
print("Sync Msg", c.dat.hex())
61+
find_key(data, c.dat)
62+
sync_msg_seen = True
63+
64+
if not sync_msg_seen:
65+
print("Warning: No SecOC Synchronization message in route")

0 commit comments

Comments
 (0)