|
SDK สำหรับ TESAIoT Dev Kit
คู่มืออ้างอิง API และ Tutorial (MTB & µPython)
|
กุญแจส่วนตัวอยู่ที่ใด (อยู่ภายใน Trust M ใน slot ที่มันไม่เคยออกมา) การจับมือ (handshake) ของ TLS บน CM33_NS ไปถึงกุญแจนั้นได้อย่างไร (opaque key ของ PSA → ไดรเวอร์ของ secure element (ชิปนิรภัยแยกส่วน) → trustm_ecdsa_sign) และมีอะไรบ้างที่ถูก patch ในทรีของ ModusToolbox เพื่อให้สิ่งนี้เป็นไปได้ — รวมถึงวิธีนำ patch ทั้ง 11 รายการที่ส่งมากับแพ็กเกจนี้ไปใช้ และวิธียืนยันว่าลงถูกต้อง
มีสองคู่ และหนึ่ง CA:
| OID | เนื้อหา | ใครใช้ |
|---|---|---|
| 0xE0E0 / 0xE0F0 | ใบรับรอง (certificate) / กุญแจจากโรงงานของ Infineon | บทนี้ — ตัวตนของ TLS |
| 0xE0E1 / 0xE0F1 | ใบรับรอง / กุญแจของอุปกรณ์ฝั่ง TESAIoT | การลงทะเบียน (enrolment) และ Protected Update — บท D2 |
| 0xE0E9 | TESA CA (trust anchor ของคู่กุญแจฝั่งอุปกรณ์) | D2 |
mqtt_mtls_setup_optiga() เลือก cert_oid = 0xE0E0 และ key_oid = 0xE0F0 หากลงทะเบียนคู่ของ TESAIoT (D2) แล้วต้องการให้ TLS ใช้คู่นั้น นี่คือบรรทัดที่ต้องแก้ ไม่มีอย่างอื่นที่เลือกตัวตนนี้
ใบรับรองจากโรงงานพิสูจน์อะไร และไม่พิสูจน์อะไร ใบรับรองใน 0xE0E0 มี subject เป็น CN=InfineonIoTNode เท่ากันทุกชิ้นบนชิป OPTIGA Trust M ทุกตัว (ถอดรหัสจริงจาก board-factory-cert-cd16334d.pem ด้วย openssl x509 เมื่อ 2026-08-29 ได้ issuer Infineon OPTIGA(TM) Trust M CA 300 อายุ 2025-10-21 ถึง 2045-10-21 ไม่มี SAN และไม่มีฟิลด์ระบุอุปกรณ์) ฟิลด์ที่ต่างกันไปในแต่ละชิปมีเพียง serial number และกุญแจสาธารณะ
สิ่งที่ handshake นี้พิสูจน์จึงคือ อุปกรณ์ปลายทางถือ Trust M ของแท้จาก Infineon เท่านั้น ไม่ได้พิสูจน์ว่าอุปกรณ์นั้นคือเครื่องใด ในขณะเดียวกัน MQTT client id ในโหมด mTLS มาจาก cfg.factory_uid และหัวข้อคำสั่งที่สมัครรับมาจาก cfg.device_id (mqtt_client_config.c:143-144, subscriber_task.c:92-93) ซึ่งทั้งสองค่าเป็นสตริงที่ตั้งได้จาก MicroPython ด้วย tesaiot.config_set(...) และถูกบันทึกลงไฟล์ตั้งค่า (tesaiot_config_store.c:174-176)
ผลที่ตามมาต้องระบุให้ตรง: ในระดับเฟิร์มแวร์ไม่มีสิ่งใดผูกตัวตนที่อุปกรณ์ประกาศเข้ากับใบรับรองที่อุปกรณ์นั้นแสดง การป้องกันที่ชี้ขาดอยู่ที่ฝั่ง broker — ต้องมี ACL ที่อนุญาตหัวข้อ device/{id}/# เฉพาะกับ client ที่ใบรับรองของมันถูกผูกไว้กับ id นั้น (ผูกด้วย fingerprint ของกุญแจสาธารณะหรือ serial number ของใบรับรอง ไม่ใช่ด้วย subject ซึ่งเหมือนกันหมด) ให้ตรวจสอบ ACL นั้นก่อนนำขั้นตอนการลงทะเบียนในบท D2 ไปใช้จริง
mqtt_client_config_init() (บท C3) เรียก mqtt_mtls_setup_optiga() เมื่อ tls_mode == TESAIOT_MODE_MTLS ฟังก์ชันนั้น (mqtt_mtls_setup.c:61-310) ทำดังนี้:
ระหว่างการจับมือของ TLS ตัว cy_tls.c ที่ผ่านการ patch จะสร้าง mbedtls_pk แบบ opaque จาก key id แล้วติดตั้งด้วย mbedtls_ssl_conf_own_cert() (cy_tls.c:1755-1809 ใน secure-sockets ที่ผ่านการ patch — ดูข้อควรระวังด้านล่าง) เมื่อฝั่งเซิร์ฟเวอร์ขอ CertificateVerify mbedTLS จะเรียก PSA, PSA ส่งต่อไปยังไดรเวอร์ของ secure element ที่ลงทะเบียนไว้ และ optiga_psa_sign() ของไดรเวอร์ (optiga_psa_se.c:315 ลงทะเบียนที่ :151 และ :235-236) เรียก trustm_ecdsa_sign(map->oid, hash, …) ฟังก์ชันนั้นจับ optiga_manager_lock() แล้วจับ optiga_manager_touch_hold() ตลอดทั้ง transaction (optiga_trust_helpers.c:1665, :1673) — วินัยของบท D1 ที่ถูกใช้จริงทุกครั้งที่เชื่อมต่อ
ชุดรหัสแบบ SHA-384: ไดรเวอร์ตัด hash ให้เหลือ 256 บิตซ้ายสุด (optiga_psa_se.c:332-343) นั่นคือสิ่งที่ทำให้ PSA_ALG_ANY_HASH ใช้งานได้
การผูก cy_tls เข้ากับ OPTIGA ไม่ได้อยู่ในเทมเพลต แต่อยู่ใน mtb_shared/ ซึ่งเป็นทรีของบุคคลที่สาม แพ็กเกจนี้จึงส่ง third_party_patches/ มาให้ครบ ประกอบด้วย diff จำนวน 11 รายการใน asset 5 ตัว, แฟ้ม series ที่กำหนดลำดับการลง และ PATCHED.sha256 ซึ่งระบุพาธไฟล์ 11 รายการใต้ mtb_shared/ พร้อมค่า SHA-256 ที่แต่ละไฟล์ต้องมี รวมถึง secure-sockets/…/cy_tls.c, cy_tls_optiga_key.c และ cy_tls_optiga_key.h
การส่ง diff มาด้วยเป็นข้อยุติที่ตัดสินเมื่อ 28 สิงหาคม 2569 บนหลักปฏิบัติเดียวกับที่ Buildroot ใช้กับแพ็กเกจที่ห้ามแจกจ่ายซ้ำ และที่ Infineon เองใช้ในเลเยอร์ meta-freescale กล่าวคือ ตัว patch ถือลิขสิทธิ์ตามงานที่ถูกแก้ไข และหากขาด patch ลูกค้าจะ build ไม่ได้เลย
patch เหล่านั้นถูกนำไปใช้แล้วในขั้นตอน patch ของบท A1/A2 และตรวจสอบด้วย shasum -a 256 -c PATCHED.sha256 หากการตรวจนั้นไม่ผ่าน mTLS จะทำงานไม่ได้: cy_tls_set_optiga_key_id() จะไม่มีอยู่และ build จะล้มเหลวตอนลิงก์ — หรือในกรณีที่ cy_tls.c ที่ยังไม่ได้ patch บังเอิญลิงก์ผ่าน การจับมือจะไม่ใช้ใบรับรองฝั่งไคลเอนต์เลย และ broker จะปฏิเสธ
สิ่งที่ควรสังเกต ทุกบรรทัดต้องขึ้น OK หากพบ FAILED แม้บรรทัดเดียว แสดงว่าทรีนี้ไม่ใช่ทรีที่เฟิร์มแวร์ชุดนี้ถูกสร้างขึ้นมาสำหรับมัน ให้หยุดที่ตรงนี้
ตั้ง tls_mode=0 ใน /.tesaiot_config (บท C3) ปล่อย port= ไว้ตามเดิม เพราะไม่ถูกใช้ โหมดเป็นตัวเลือกพอร์ต 8883 เอง
สิ่งที่ควรสังเกต ยังไม่มีอะไร
เรียก tesaiot.connect() หรือกดปุ่ม Connect บนหน้าจอ
สิ่งที่ควรสังเกต บน UART พิมพ์จริง ตามลำดับ:
ค่า Client= ในบรรทัด [MQTT-Config] ตอนนี้คือ factory UID ไม่ใช่ device_id
บรรทัด [PSA-Sign] (optiga_psa_se.c:364-365) ต้องอ่านอย่างแม่นยำ บรรทัดนี้พิมพ์ ก่อนที่จะพยายามลงลายเซ็น จึงหมายถึง "พยายามลงลายเซ็นด้วย OID ที่คลี่ออกมาได้" ไม่ใช่ "ลงลายเซ็นสำเร็จ" ความสำเร็จยังต้องอาศัยการไม่ปรากฏของบรรทัด ERROR ที่ตามมาในฟังก์ชันเดียวกันด้วย:
(optiga_psa_se.c:372) สัญญาณของความสำเร็จคือคู่ต่อไปนี้ — มีบรรทัด Using Key OID ไม่มีบรรทัด ERROR: trustm_ecdsa_sign แล้วตามด้วย [MQTT] Connected to broker บรรทัด ERROR ของ [PSA-Sign] ในอีกสี่รูปแบบ (:328, :346, :352, :359) แปลว่าไดรเวอร์ไปไม่ถึงชิปเลย
บนหน้าจอ: หน้า TESAIoT แสดงว่าเชื่อมต่อแล้ว และในโหมดนี้ยังแสดง optiga_state = PROVISIONED กับ cert_state = LOADED ด้วย (tesaiot_mqtt.c:60-64)
หาก secure-sockets ที่ผ่านการ patch ถูก build โดยนิยาม TLS_DIAG ไว้ (cy_tls.c:168) จะมีอีก 2 บรรทัดปรากฏระหว่างการตั้งค่ากับการลงลายเซ็น: [TLS-DIAG] optiga_key=lu cert_ready=d และ [TLS-DIAG] mbedtls_pk_setup_opaque = d (-0x%04X) ทั้งสองอยู่ในโค้ดที่ผ่านการ patch และปิดไว้เป็นค่าปริยาย มีไว้ก็มีประโยชน์ แต่ไม่จำเป็นต่อการตรวจสอบข้างต้น
ถอด I2C ของ Trust M ออก (หรือบนบอร์ดที่มี debug header ให้กดชิปค้างไว้ในสถานะรีเซ็ต) แล้วต่อกลับ
สิ่งที่ควรสังเกต [mTLS] Certificate read จะไม่ปรากฏเลย แต่จะได้อย่างใดอย่างหนึ่งใน 3 บรรทัดนี้แทน: [mTLS] OPTIGA application would not open — aborting mTLS setup, [mTLS] optiga_manager_init failed — signing would be impossible หรือ [mTLS] No usable certificate in OID 0x%04X (got u bytes) (:182, :208, :223) ตามด้วย [MQTT-Config] mTLS OPTIGA setup failed และ [MQTT] Configuration failed — not attempting to connect ไม่มีกุญแจส่วนตัวอยู่ที่ใดในหน่วยความจำแฟลชให้ถอยไปใช้แทน นั่นคือประเด็นทั้งหมด
ตัดการเชื่อมต่อจาก broker แล้วเชื่อมต่อใหม่โดยไม่รีบูต
สิ่งที่ควรสังเกต [mTLS] Re-binding existing OPTIGA key (key_id=lu, cert=u bytes) (:107) — หรือหากการรื้อระบบล้างกุญแจของ PSA ไปแล้ว จะได้ [mTLS] PSA key lu no longer exists — the TLS teardown wiped … (:95) ตามด้วยการตั้งค่าใหม่ทั้งชุด ทั้ง 2 แบบเป็นเรื่องปกติ และแบบที่สองคือเหตุผลที่ขั้นที่ 5 ของการตั้งค่าต้องลงทะเบียนไดรเวอร์ใหม่ทุกครั้ง
libbento_hsm.a ไม่ต้องใช้ symbol ของ MicroPython เลย (variants/mtb-only.mk:14) และ mqtt_mtls_setup.c, optiga_psa_se.c กับ optiga_trust_helpers.c คอมไพล์ได้ทั้งสอง variant สิ่งเดียวในบทนี้ที่เป็นของ mtb-mpy โดยเฉพาะคือจุดเริ่ม tesaiot.connect() ส่วนลำดับการลงทะเบียนไดรเวอร์ PSA ตอนบูต — optiga_psa_register() แล้วจึง psa_crypto_init() — อยู่ที่ proj_cm33_ns/main.c:228-235 เหมือนกันทั้งสอง variant บรรทัดแจ้งความล้มเหลว [BOOT] optiga_psa_register failed: d และ [BOOT] psa_crypto_init failed: d พิมพ์จริง ส่วนความสำเร็จนั้นเงียบ