add comms handler to get MCU UID (#1212)

* cleanup first

* get uid

* add to bootstub and test

* fix pedal

* match that

Co-authored-by: Comma Device <device@comma.ai>
This commit is contained in:
Adeeb Shihadeh
2023-01-15 20:13:26 -08:00
committed by GitHub
parent fa678e28fc
commit b8693da342
5 changed files with 37 additions and 1 deletions

View File

@@ -41,6 +41,13 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
resp[1] = 0xff;
}
break;
// **** 0xc3: fetch MCU UID
case 0xc3:
#ifdef UID_BASE
(void)memcpy(resp, ((uint8_t *)UID_BASE), 12);
resp_len = 12;
#endif
break;
// **** 0xd0: fetch serial number
case 0xd0:
#ifndef STM32F2

View File

@@ -147,7 +147,7 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
resp[0] = hw_type;
resp_len = 1;
break;
// **** 0xd0: fetch serial number
// **** 0xc2: CAN health stats
case 0xc2:
COMPILE_TIME_ASSERT(sizeof(can_health_t) <= USBPACKET_MAX_SIZE);
if (req->param1 < 3U) {
@@ -160,6 +160,12 @@ int comms_control_handler(ControlPacket_t *req, uint8_t *resp) {
(void)memcpy(resp, &can_health[req->param1], resp_len);
}
break;
// **** 0xc3: fetch MCU UID
case 0xc3:
(void)memcpy(resp, ((uint8_t *)UID_BASE), 12);
resp_len = 12;
break;
// **** 0xd0: fetch serial (aka the provisioned dongle ID)
case 0xd0:
// addresses are OTP
if (req->param1 == 1U) {

View File

@@ -1,3 +1,6 @@
// this is where we manage the dongle ID assigned during our
// manufacturing. aside from this, there's a UID for the MCU
#define PROVISION_CHUNK_LEN 0x20
void get_provision_chunk(uint8_t *resp) {

View File

@@ -5,6 +5,7 @@ import time
import usb1
import struct
import hashlib
import binascii
import datetime
import traceback
import warnings
@@ -588,14 +589,28 @@ class Panda:
return self.get_type() in Panda.INTERNAL_DEVICES
def get_serial(self):
"""
Returns the comma-issued dongle ID from our provisioning
"""
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xd0, 0, 0, 0x20)
hashsig, calc_hash = dat[0x1c:], hashlib.sha1(dat[0:0x1c]).digest()[0:4]
assert(hashsig == calc_hash)
return [dat[0:0x10].decode("utf8"), dat[0x10:0x10 + 10].decode("utf8")]
def get_usb_serial(self):
"""
Returns the serial number reported from the USB descriptor;
matches the MCU UID
"""
return self._serial
def get_uid(self):
"""
Returns the UID from the MCU
"""
dat = self._handle.controlRead(Panda.REQUEST_IN, 0xc3, 0, 0, 12)
return binascii.hexlify(dat).decode()
def get_secret(self):
return self._handle.controlRead(Panda.REQUEST_IN, 0xd0, 1, 0, 0x10)

View File

@@ -53,6 +53,10 @@ def test_hw_type(p):
mcu_type = p.get_mcu_type()
assert mcu_type is not None
app_uid = p.get_uid()
usb_serial = p.get_usb_serial()
assert app_uid == usb_serial
p.reset(enter_bootstub=True, reconnect=True)
p.close()
time.sleep(3)
@@ -60,6 +64,7 @@ def test_hw_type(p):
assert pp.bootstub
assert pp.get_type() == hw_type, "Bootstub and app hw type mismatch"
assert pp.get_mcu_type() == mcu_type, "Bootstub and app MCU type mismatch"
assert pp.get_uid() == app_uid
@test_all_pandas