SDK สำหรับ TESAIoT Dev Kit
คู่มืออ้างอิง API และ Tutorial (ModusToolbox)
Loading...
Searching...
No Matches
D3 — Weak symbol, ENABLE_OPTIGA_CLM และข้อผูกพันของผู้ใช้ไลบรารี

เป้าหมายของหัวข้อนี้

หกใน 18 ฟังก์ชันของ tesaiot_hsm ถูกประกาศเป็น weak โดยผู้เรียกทุกรายที่มีอยู่จริงในของที่ส่งมอบ และ ต้องตรวจ NULL ก่อนเรียกเสมอ บทนี้อธิบายว่าเหตุใดจึงเป็นเช่นนั้น ENABLE_OPTIGA_CLM ควบคุมอะไร archive เรียกร้องอะไร จาก ผู้ใช้ไลบรารี (consumer_must_provide.txt) และจะเห็นข้อผูกพันนี้บังคับใช้ตัวเองได้อย่างไรด้วยการ build โดยปิด CLM

ลำดับการทำงานจริงของเฟิร์มแวร์

แฟล็กนี้ทำอะไร

proj_cm33_ns/Makefile:143-161:

ENABLE_OPTIGA_CLM ?= 1
ifeq ($(ENABLE_OPTIGA_CLM),1)
SOURCES+=$(BENTO_LIBS_DIR)/kit-pse84-ai/modules/tesaiot/tesaiot_pu_ingest.c
DEFINES+=ENABLE_OPTIGA_CLM=1
endif

และที่ :464-475: libbento_hsm.a อยู่บน LDLIBS โดยไม่มีเงื่อนไข — "an archive member is pulled only when something already references it, so with `ENABLE_OPTIGA_CLM` off nothing is extracted." เมื่อปิดแฟล็กนี้ ตัว ingest จะไม่ถูกคอมไพล์ ไม่มีอะไรอ้างถึงสมาชิกฝั่ง MQTT ของ archive และ symbol ทั้ง 6 ตัวด้านล่างจึงไม่มีอยู่ในการลิงก์เลย ผู้เรียกที่มีอยู่จริงในของที่ส่งมอบยังคอมไพล์ผ่านเพราะประกาศ symbol เหล่านั้นเป็น weak

symbol 6 ตัวที่ถูกใช้แบบ weak

dist/tesaiot_hsm/overridable.txt ว่างเปล่า ไม่มีอะไรใน archive ที่เป็น weak ความเป็น weak อยู่ที่ ฝั่งผู้ใช้ไลบรารี: ผู้เรียกที่มีอยู่จริงในของที่ส่งมอบประกาศทั้ง 6 ตัวนี้เป็น __attribute__((weak)) เพื่อให้ build ที่ไม่มีเส้นทางการลงทะเบียนผ่าน MQTT ยังลิงก์ผ่าน:

Symbol ประกาศ weak ที่ จุดเรียกที่มีตัวกัน
publish_csr ipc_hsm_handler.c:1691-1693 ipc_hsm_handler.c if (publish_csr == NULL)
tesaiot_publish_protected_update ipc_hsm_handler.c:1687-1689; modtesaiot.c มีตัวกันทั้งสองที่
trustm_reset_state ipc_hsm_handler.c:1715 if (trustm_reset_state != NULL)
trustm_current_correlation_id ipc_hsm_handler.c:1721 ตรวจ NULL 2 ชั้น — พอยน์เตอร์ก่อน แล้วจึงค่าที่คืนกลับมา
trustm_requested_target_oid tesaiot_pu_ingest.c ห่อไว้ใน pu_target_oid() โดยมีค่าปริยาย 0xE0E1
trustm_requested_anchor_oid tesaiot_pu_ingest.c ห่อไว้ใน pu_anchor_oid() โดยมีค่าปริยาย 0xE0E8

การประกาศ:

extern int publish_csr(uint8_t *csr, size_t csr_length, uint16_t target_oid,
uint16_t trust_anchor_oid, uint32_t payload_version)
__attribute__((weak));

รูปแบบตรวจ NULL สองชั้นสำหรับฟังก์ชันที่คืนค่าเป็นพอยน์เตอร์:

/* ...context: inside the provisioning status reply builder ... */
const char *c = trustm_current_correlation_id();
if (c) strncpy((char *)&resp->data[HSM_PROV_CORR_OFF], c, HSM_PROV_CORR_MAX - 1U);
}

ชั้นแรกคือพอยน์เตอร์ของฟังก์ชัน (ลิงก์เข้ามาหรือไม่) ชั้นที่สองคือสตริงที่คืนกลับมา (มีคำขอค้างอยู่หรือไม่) การข้ามชั้นแรกทำให้เกิดการอ้างถึงที่อยู่ศูนย์บน build ที่ปิด CLM ส่วนการข้ามชั้นที่สองเปลี่ยน "ไม่มีคำขอค้างอยู่" ให้กลายเป็น replay (บท D2)

รูปแบบตัวเข้าถึงที่ห่อไว้พร้อมค่าปริยาย:

/* Which object this bundle is for — see the note on the definition. Weak so a
* build without the MQTT request path still links. */
extern uint16_t trustm_requested_target_oid(void) __attribute__((weak));
extern uint16_t trustm_requested_anchor_oid(void) __attribute__((weak));
/* The anchor the last request named. Everything below used to bake 0xE0E8 in,
* including the target's Change access condition — so asking for a different
* anchor was accepted, stored, and then quietly ignored, and the chip would
* verify the manifest against an object the platform had not signed for. That
* is 0x800F with no diagnostic, the same failure the target OID caused before
* it was made to follow the request. */
static uint16_t pu_anchor_oid(void)
{
: 0xE0E8U;
}
static uint16_t pu_target_oid(void)
{
return (trustm_requested_target_oid != NULL)
: 0xE0E1U; /* certificate slot — the platform's default target */
}

ให้ห่อตัวเข้าถึงชนิด weak ทุกตัวไว้ในฟังก์ชันภายในที่จัดหาค่าปริยายให้ ห้ามโปรย != NULL ? f() : default ไว้ตามจุดเรียกต่าง ๆ

binding ฝั่ง MicroPython ทำแบบเดียวกัน เพียงแต่ยกข้อผิดพลาดขึ้นแทนการคืนค่า — tesaiot_protected_update_py() ที่ modtesaiot.c:730-768 marker [hsm_publish_pu_mpy_binding] (มีเฉพาะใน zip ของ mtb-mpy — ไฟล์นี้ไม่อยู่ในแพ็กเกจ mtb-only):

mp_raise_msg(&mp_type_OSError,
MP_ERROR_TEXT("Protected Update not built in "
"(needs ENABLE_OPTIGA_CLM=1)"));
}
int tesaiot_publish_protected_update(const char *target_oid, const char *trust_anchor_oid, uint32_t payload_version, bool with_csr)
ขอ Protected Update จากแพลตฟอร์ม (OID เป็น hex string); เป็น weak — ให้ตรวจ NULL ก่อน

archive เรียกร้องอะไรจากผู้ใช้ไลบรารี

template/lib/tesaiot_hsm/consumer_must_provide.txt คือรายการที่เครื่องสร้างขึ้นของ symbol ที่ archive อ้างถึงแต่ไม่ได้นิยามเอง แบ่งเป็นกลุ่มได้ดังนี้:

  • อ็อบเจ็กต์ของ MQTT clientcy_mqtt_publish, mqtt_connection, mqtt_device_id, publisher_task_q, tesaiot_mqtt_client_id, tesaiot_mqtt_username archive เป็นเจ้าของกรอบครอบ (envelope) ของคำขอ ส่วนผู้ใช้ไลบรารีเป็นเจ้าของการเชื่อมต่อที่มัน publish ออกไป
  • ฟังก์ชันพื้นฐานของ OPTIGAoptiga_util_create/destroy, optiga_util_open_application/close_application, optiga_util_read_data/read_metadata, optiga_util_protected_update_start/final, optiga_crypt_*, optiga_generate_device_keypair, optiga_generate_csr_pem, optiga_read_factory_uid, optiga_slot_info, optiga_check_certificate_validity ตัวที่จัดหาให้คือ optiga_trust_helpers.c ของเทมเพลต
  • IPC ฝั่ง touchipc_hsm_touch_pause, ipc_hsm_touch_pause_reason, ipc_hsm_touch_resume วินัยของบท D1 ขึ้นอยู่กับการที่ 3 ตัวนี้เป็น implementation ที่นับจำนวน จาก ipc_hsm_handler.c
  • การประสานงานกับ ingestg_protected_update_just_completed, certificate_sync_success, sync_certificate_response_*, upload_certificate_response_*, check_certificate_response_*, platform_has_certificate, tesaiot_is_licensed, tesaiot_read_lcso, tesaiot_read_data, tesaiot_read_metadata
  • libc / FreeRTOSmbedtls_base64_encode/decode, malloc, free, pvPortMalloc, printf, scanf, snprintf, strcpy, memcpy, …

หากเปลี่ยน HSM handler หรือโมดูล MQTT ของเทมเพลต ทุกชื่อในรายการนั้นต้องยังคลี่ออกมาได้ และต้องมีความหมายเดิม โดยเฉพาะ 3 ตัวของ IPC ฝั่ง touch: การแทนที่ด้วย resume ที่ไม่นับจำนวนจะนำลายเซ็น 0x0102 ของบท D1 กลับมาอีกครั้ง

ทีละขั้น

ขั้นที่ 1 — build โดยเปิด CLM (ค่าปริยาย) แล้วยืนยันว่า symbol มีอยู่

cd proj_cm33_ns && make build -j
arm-none-eabi-nm build/*/Release/proj_cm33_ns.elf | grep -E ' (publish_csr|tesaiot_publish_protected_update|trustm_reset_state|trustm_current_correlation_id|trustm_requested_target_oid|trustm_requested_anchor_oid)$'

สิ่งที่ควรสังเกต symbol ชนิด T 6 ตัว (ให้ใช้ glob กับพาธของ ELF เพราะชื่อไดเรกทอรีของ TARGET ต่างกันไปตามคิต)

ขั้นที่ 2 — build โดยปิด CLM

cd proj_cm33_ns && make build -j ENABLE_OPTIGA_CLM=0

สิ่งที่ควรสังเกต build สำเร็จ ซึ่งคือผลของการประกาศแบบ weak ที่ทำงานถูกต้อง เมื่อรันบรรทัด nm เดิมซ้ำ จะไม่พบชื่อทั้งหกนั้น (อย่างมากได้ U/w ไม่มี T เลย) tesaiot_pu_ingest.o ไม่อยู่ในการลิงก์ และสตริง [PU-Ingest] หายไปจาก ELF

ขั้นที่ 3 — แฟลชแล้วกดปุ่ม

ตัดไฟแล้วจ่ายไฟใหม่หลังแฟลช จากนั้น Home → HSM Security → Enrol Certificate

สิ่งที่ควรสังเกต หน้าจอแสดงข้อความต่อไปนี้โดยไม่แตะชิปเลย:

CSR enrolment is not built into this firmware

(ipc_hsm_handler.c กิ่ง publish_csr == NULL ใน prov_run_locked) จากนั้นลอง Protected Update:

Protected Update is not built into this firmware

(กิ่ง tesaiot_publish_protected_update == NULL) บน mtb-mpy การเรียก tesaiot.protected_update(...) จาก REPL จะยกข้อผิดพลาด:

OSError: Protected Update not built in (needs ENABLE_OPTIGA_CLM=1)

(modtesaiot.c:739-743) สามสตริงนั้น คือการตรวจสอบ ของบทนี้ แต่ละสตริงคือตัวกัน NULL ที่กำลังปฏิเสธ ณ ตำแหน่งที่ตารางด้านบนระบุไว้พอดี

สิ่งที่ ไม่ควร เห็น: HardFault หน้าจอดับ หรือการเชื่อมต่อ [MQTT] ใหม่ ตัวกันทำงานก่อนที่จะไปถึงแพลตฟอร์ม

ขั้นที่ 4 — ยืนยันว่าส่วนอื่นของ HSM ยังทำงานได้เมื่อปิด CLM

ลองอ่าน slot ข้อมูลรับรอง (รายการที่บันทึกไว้บนหน้า WiFi หรือ optiga.read_metadata() บน mtb-mpy)

สิ่งที่ควรสังเกต ใช้งานได้ตามปกติ optiga_manager_*, optiga_chip_* และ IPC ฝั่งข้อมูลรับรองไม่ขึ้นกับแฟล็กนี้ — ฟังก์ชัน 10 ตัวของบท D1 ถูกดึงออกมาจาก archive เพราะ ipc_hsm_handler.c อ้างถึงโดยไม่มีเงื่อนไข สิ่งที่หายไปมีเพียงเส้นทางการลงทะเบียนฝั่ง MQTT เท่านั้น

ขั้นที่ 5 — build ใหม่โดยเปิด CLM

cd proj_cm33_ns && make build -j

แฟลช ตัดไฟแล้วจ่ายไฟใหม่ จากนั้นทำขั้นที่ 2 ของบท D2 เพื่อยืนยันว่า Enrol ผ่านตัวกันไปได้แล้ว

กับดัก

กับดัก 1 — เรียก symbol ที่ถูกใช้แบบ weak โดยไม่ตรวจ NULL
บน build ที่ปิด CLM พอยน์เตอร์นั้นเป็นศูนย์ ผู้เรียกทุกรายที่มีอยู่จริงในของที่ส่งมอบตรวจ และผู้เรียกของตนก็ต้องตรวจเช่นกัน (ภาคผนวก X ข้อ 19)
กับดัก 2 — ประกาศ symbol เป็น strong ในไฟล์ของตนเอง
หาก translation unit ใดประกาศ publish_csr โดยไม่มี weak แล้ว build ที่ปิด CLM จะล้มเหลวตอนลิงก์ด้วย undefined reference ซึ่งตรงข้ามกับการปฏิเสธอย่างนุ่มนวลข้างต้น ให้คัดลอกการประกาศที่ส่งมอบมาไปใช้
กับดัก 3 — คาดหวังให้ overridable.txt มีรายชื่อเหล่านี้
ไฟล์นั้นว่างเปล่า weak ฝั่งผู้ใช้ไม่ใช่ weak ฝั่งผู้นิยาม: นิยามใน archive เป็น strong ส่วนการประกาศของผู้ใช้ไลบรารีเป็น weak ไม่มีอะไรใน libbento_hsm.a ที่เขียนทับ (override) ได้
กับดัก 4 — แทนที่ IPC ฝั่ง touch 3 ตัวด้วย resume ดิบ
consumer_must_provide.txt ระบุชื่อ ipc_hsm_touch_resume ไว้ และ archive คาดหวังความหมายแบบนับจำนวนตามที่บท D1 อธิบาย implementation ที่ "ง่ายกว่า" ซึ่งส่ง IPC_CMD_TOUCH_RESUME โดยไม่มีเงื่อนไขจะทำให้ได้ 0x0102
กับดัก 5 — tesaiot_run_protected_update_isolated_test()
ฟังก์ชันที่ถูกส่งออกตัวที่สิบแปดนี้ ไม่มี call site ที่ส่งมอบมาเลย (ผู้เรียกจริงรายเดียวอยู่ในไฟล์ที่ไม่ได้ส่งมอบ) มันเป็นการทดสอบตัวเองแบบโต้ตอบ: มันบล็อกอยู่ที่ scanf() บน stdin แบบวนถาม ต้องเรียก optiga_manager_init() และ เปิด application ไว้ก่อน และคืนค่าต่อเมื่อผู้ใช้เลือกตัวเลือกออกจากเมนูของมันเท่านั้น ห้ามเรียกจาก task ที่ระบบย่อยอื่นรออยู่ ตัวอย่างใด ๆ ของมันในเอกสารชุดนี้เป็นตัวอย่างที่เขียนขึ้นเอง ไม่ได้ตัดมาจากซอร์สจริง
กับดัก 6 — อ่าน ENABLE_OPTIGA_CLM ว่าเป็น "เปิด/ปิด OPTIGA"
แฟล็กนี้กั้นเฉพาะโพรโทคอลการลงทะเบียนผ่าน MQTT และการ ingest bundle เท่านั้น mTLS (บท C4) การเก็บข้อมูลรับรอง (C2) และวินัยการเข้าถึงชิป (D1) ไม่ได้รับผลกระทบ

Variant

variant ที่ใช้ได้
mtb-mpy และ mtb-only

แฟล็กนี้ การประกาศ weak ทั้งหก ตัวกัน และสตริงปฏิเสธบนหน้าจอ เหมือนกันทั้งสอง variant ส่วนการปฏิเสธด้วย OSError มีเฉพาะบน mtb-mpy เพราะ modtesaiot.c เป็นหนึ่งใน 10 ไฟล์ที่แพ็กเกจ mtb-only ตัดออก ไฟล์ consumer_must_provide.txt เป็นไฟล์เดียวกันในทั้งสอง zip และบน mtb-only รายการ printf/scanf คลี่ไปที่ retarget-io เหมือนกับบน mtb-mpy ทุกประการ