Protected Update
โมดูล 4 · Secure boot และ Protected Update · ภาพรวมโมดูล · หน้าหลักสูตร
ใบรับรองของอุปกรณ์ต้องเปลี่ยนได้ตลอดอายุการใช้งาน แต่ถ้าใครก็เขียนช่องใบรับรองได้ ผู้โจมตีก็เขียนได้เหมือนกัน Protected Update ของ OPTIGA™ Trust M แก้ปัญหานี้ด้วยการให้ ชิปเป็นคนตรวจลายเซ็น ก่อนยอมเขียน host ที่ถูกเจาะจึงปลอมการอัปเดตไม่ได้
ต้องแยกให้ชัดตั้งแต่ต้น Protected Update ในบทนี้คือการอัปเดต object ในชิป (ใบรับรอง กุญแจ ข้อมูล metadata) ไม่ใช่การอัปเดตเฟิร์มแวร์ของ MCU เรื่องเฟิร์มแวร์เราจะเทียบกันตอนท้ายบทด้วยตัวอย่าง OTA บน Developer Hub
เป้าหมาย
หัวข้อที่มีชื่อว่า “เป้าหมาย”เมื่อจบบทเรียนนี้ คุณจะ:
- อธิบายขั้นตอนของ Protected Update ตั้งแต่คำขอจนถึงการตรวจ manifest
- อธิบายหน้าที่ของตัวนับกันย้อนรุ่น และผลของ manifest lock
- ระบุการเปลี่ยนแปลงบนชิปที่รีแฟลชแล้วก็กู้คืนไม่ได้ ตามที่ตัวอย่างของ SDK เตือนไว้
ก่อนเริ่ม
หัวข้อที่มีชื่อว่า “ก่อนเริ่ม”- เรียนมาก่อน: บทเรียน 4.1: Secure boot และ chain of trust และตาราง metadata ใน บทเรียน 2.1 (tag
C0C1D0) - บอร์ด: แม่แบบของ SDK ที่ build ได้ แล็บหลักไม่ส่งคำขอจริง ส่วนแล็บเสริมที่ส่งคำขอจริงต้องมีอุปกรณ์ที่ลงทะเบียนและเชื่อมต่อแพลตฟอร์มได้แล้ว และต้องได้รับอนุญาตจากผู้สอน
ดูของจริงก่อน
หัวข้อที่มีชื่อว่า “ดูของจริงก่อน”บท D2 ของเอกสาร SDK ให้ลำดับบรรทัดบน UART เมื่อกด Protected Update บนจอแล้วสำเร็จ
[Subscriber] Protected Update bundle (%d bytes)[PU-Ingest] Fragment count: %u[PU-Ingest] OPTIGA acquired: OK[PU-Ingest] STEP 3: Processing fragments...[PU-Ingest] STEP 4: Executing OPTIGA Trust M Protected Update[PU-Ingest] [4.1] Manifest verification OK (Trust Anchor signature valid)[PU-Ingest] PROTECTED UPDATE COMPLETED SUCCESSFULLY![PU-Ingest] [ACK] Certificate ACK published successfullyทายก่อน: ถ้า host ถูกเจาะ ผู้โจมตีพิมพ์บรรทัดไหนในนี้ปลอมได้บ้าง และอะไรคือหลักฐานที่เขา ปลอมไม่ได้
1. จากคำขอถึงการตรวจ manifest ในชิป
หัวข้อที่มีชื่อว่า “1. จากคำขอถึงการตรวจ manifest ในชิป”PROTECTED_UPDATE_CONTRACT.md ของ SDK อธิบายว่า
OPTIGA™ Trust M ไม่รับใบรับรองที่เขียนเป็นไบต์ธรรมดาลงช่องที่ถูกป้องกัน ต้องมี manifest ที่ลงนามด้วยกุญแจที่ชิปเชื่ออยู่แล้ว (trust anchor)
กับ fragment หนึ่งชิ้นขึ้นไปที่บรรจุข้อมูลจริง ชิปตรวจ manifest กับ trust anchor ก่อนเขียนอะไรทั้งสิ้น
manifest เป็น COSE_Sign1 ที่ระบุ OID ของ anchor ไว้ใน header kid (สัญญา CSR ข้อ 4.5)
เครื่องมือสร้างชุดข้อมูลของ Infineon (protected_update_data_set, MIT)
บอกว่าใน manifest มีอะไร payload_version, trust_anchor_oid, target_oid, อัลกอริทึมลายเซ็น (ค่าเริ่มต้น ES_256), ชนิดของ payload (data, key หรือ metadata)
และถ้าต้องการความลับ ก็เข้ารหัส fragment ด้วยกุญแจร่วมที่เก็บในชิปได้
ทั้งเส้นทางบนบอร์ดของเรา สรุปจากบท D2 และสัญญาของ SDK
อุปกรณ์ แพลตฟอร์ม 1. อ่าน metadata ของ 0xE0E1 เก็บไว้ (C0, D0) 2. SUBSCRIBE device/<id>/commands/# ── ก่อนขอเสมอ 3. tesaiot_publish_protected_update("E0E1","E0E8",ver,with_csr) ตรวจในเครื่องก่อน: ถ้าช่องถูกล็อกกับ anchor อื่นอยู่ ปฏิเสธเอง PUBLISH device/<id>/commands/request ─────────▶ สร้าง manifest + fragment version = max(ของเรา, ที่เคยใช้) + 1 ลงนามด้วยกุญแจของแพลตฟอร์ม ◀───── commands/protected_update (manifest, fragment_0..n, ใบของผู้ลงนาม) 4. ตรวจ correlation id: ไม่มีคำขอค้าง = ทิ้ง (กันการเล่นซ้ำ) 5. เขียนใบของผู้ลงนามลง 0xE0E8 ตั้งชนิดเป็น trust anchor 6. optiga_util_protected_update_start(manifest) ▶ ชิปตรวจลายเซ็นของ manifest กับ 0xE0E8 ◀ จุดที่ host ปลอมไม่ได้ 7. ส่ง fragment ด้วย _continue / _final ชิปเขียนช่องเป้าหมาย 8. ส่ง ACK แล้ว trustm_reset_state() ล้าง correlation id 9. อ่าน metadata อีกครั้ง: D0 เปลี่ยนเป็น 21 E0 E8, C0 ยังเป็น 01คำตอบของคำทาย ทุกบรรทัดใน log เป็นแค่ printf host ที่ถูกเจาะพิมพ์อะไรก็ได้ บท D2 ชี้ว่าเหตุการณ์ที่ปลอมไม่ได้คือ ชิปตรวจลายเซ็นของแพลตฟอร์มกับ trust anchor ของตัวเองสำเร็จ
ซึ่งเฟิร์มแวร์รายงานต่อทันทีหลังบรรทัด [4.1] แต่ถ้าจะให้เป็นหลักฐานจริง ให้ถามชิปเองด้วยการอ่าน metadata กลับมา (ขั้น 9) ไม่ใช่เชื่อ log
สิ่งที่ tesaiot_publish_protected_update() คืน 0 แปลว่า ขอแล้ว ไม่ใช่ เสร็จแล้ว ตามคอมเมนต์ของตัวอย่าง 06 ชิปยังไม่เปลี่ยนจนกว่า manifest จะมาถึงและถูก apply
OID เป็น สตริงฐานสิบหก "E0E1" ไม่ใช่ตัวเลข 0xE0E1
2. ตัวนับกันย้อนรุ่น และ manifest lock
หัวข้อที่มีชื่อว่า “2. ตัวนับกันย้อนรุ่น และ manifest lock”ตัวนับ version (tag C1) ชิปจำ version ของแต่ละ object และปฏิเสธ manifest ที่ version ไม่มากกว่าเดิม ตัวนับขึ้นได้อย่างเดียว
หน้าที่ของมันคือกันการเอา manifest เก่าที่ลงนามถูกต้องมาเล่นซ้ำ เพื่อคืนใบรับรองรุ่นเก่า
สัญญาของ SDK บอกว่าแพลตฟอร์มคำนวณ version ให้เป็น max(ของเรา, ที่เคยใช้) + 1 อุปกรณ์จึงส่ง 1 ทุกครั้งได้
แต่ตัวอย่าง 06 เตือนว่าถ้า version ที่ใช้จริง ต่ำกว่า ตัวนับในชิป ชิปจะปฏิเสธในแบบที่ดูเหมือนลายเซ็นผิด
manifest lock (tag D0) การ apply สำเร็จตั้งเงื่อนไข Change ของช่องเป้าหมายเป็น Int(anchor) หรือ 21 E0 E8
จากนั้นช่องนั้นรับเฉพาะการเขียนที่มากับ manifest ที่ลงนามโดย anchor นั้น การเขียนธรรมดาถูกปฏิเสธ นี่คือจุดประสงค์ของฟีเจอร์
ผลที่เห็นบนบอร์ดคือ ถ้ากดลงทะเบียน (Enrol) ใส่ช่องที่ถูกล็อก หน้าจอจะขึ้นว่า “This slot takes signed manifests only. Use Protect, or clear the requirement first. Nothing was changed.” ก่อนสร้างกุญแจใด ๆ
ล็อกนี้ กลับทางได้ ตราบที่ LcsO ยังต่ำกว่า op บท D2 วัดบนบอร์ดจริงว่า D0 ของ 0xE0E1 อ่านได้ 21 e0 e8 ก่อน และ e1 fc 07 หลังการเขียนกลับ
บนบอร์ดที่อยู่ในสถานะ creation เมนู HSM Security → Unlock ทำขั้นนี้ แต่ตัวอย่าง 06 บอกว่าฟังก์ชันเคลียร์ล็อกไม่ได้อยู่ใน 18 ฟังก์ชันที่ libbento_hsm.a export
คำแนะนำของ SDK จึงเป็น “วางแผนว่าจะไม่ต้องใช้มัน” และเลือกช่องเป้าหมายอย่างตั้งใจ รัน Protected Update ใส่ช่องใบรับรองที่ใช้งานจริง ก็คือล็อกใบรับรองที่ใช้งานจริง
รหัสผิดพลาดตัวเดียวแปลได้หลายอย่าง ตัวอย่าง 06 ระบุว่าชิปตอบ 0x800F ทั้งกรณีช่องถูกล็อกกับ anchor อื่น และกรณี version เก่า
สัญญา PU ของ SDK เพิ่มอีกกรณีที่เจอบ่อยที่สุด คือช่อง trust anchor ว่าง (ใบของผู้ลงนามไม่ได้ถูกเขียนลง 0xE0E8) ก็ได้ 0x800F เช่นกัน
ดังนั้นเมื่อเห็นรหัสนี้ ให้อ่าน metadata ของช่องเป้าหมายและอ่านข้อมูลของ 0xE0E8 กลับมาก่อน อย่าเพิ่งสรุปว่าลายเซ็นผิด
กันการเล่นซ้ำด้วย correlation id ทุกคำขอมี correlation id ถ้า bundle มาถึงตอนที่ไม่มีคำขอค้างอยู่ (trustm_current_correlation_id() เป็น NULL) เฟิร์มแวร์ต้องทิ้ง
บท D2 บันทึกเหตุการณ์ที่ bundle เก่าถูก apply ซ้ำโดยไม่มีใครขอ ผลคือช่องถูกล็อกซ้ำ และตัวนับถูกใช้ไปหนึ่งขั้น
เอกสารของ SDK สองฉบับอธิบายพฤติกรรมของ broker ต่างกัน (D2 บอกว่ามีการส่ง bundle ล่าสุดซ้ำทุกครั้งที่เชื่อมต่อ สัญญา PU บอกว่าแพลตฟอร์มล้าง retained message ทุกครั้งที่เชื่อมต่อ)
บทเรียนจากความขัดแย้งนี้คือ เฟิร์มแวร์ต้องไม่พึ่งพฤติกรรมของ broker แบบใดแบบหนึ่ง การตรวจ correlation id คือสิ่งที่ป้องกันได้เสมอ
3. สิ่งที่รีแฟลชแล้วกู้คืนไม่ได้
หัวข้อที่มีชื่อว่า “3. สิ่งที่รีแฟลชแล้วกู้คืนไม่ได้”ตัวอย่าง 06_protected_update.c เปิดไฟล์ด้วยหัวข้อ “READ THIS BEFORE YOU SET EITHER SWITCH” และแยกสิ่งที่เปลี่ยนไว้สามระดับ
| สิ่งที่เปลี่ยน | ย้อนได้ไหม | ใครทำให้เปลี่ยน |
|---|---|---|
LcsO (tag C0) 01 → 03 → 07 → 0F |
ไม่ได้เลย ไม่มี reflash การลบ หรือการตัดไฟใดพากลับ เมื่อถึง op การเขียน metadata หยุดถาวร |
การเขียน metadata ที่มี tag C0 ไม่มีตัวอย่างใดใน SDK ทำ และ Protected Update ในบทนี้ไม่แตะ |
ตัวนับ version (tag C1) ของช่องเป้าหมาย |
ไม่ได้ ขึ้นอย่างเดียว | ทุก Protected Update ที่ apply สำเร็จ |
manifest lock (tag D0) ของช่องเป้าหมาย |
ได้ เฉพาะเมื่อ LcsO ต่ำกว่า op บนอุปกรณ์ที่ส่งมอบแล้วถือว่าถาวร | ทุก Protected Update ที่ apply สำเร็จ |
ข้อที่รีแฟลชกู้ไม่ได้ในความหมายตรงตัวคือ LcsO ตัวอย่าง 06 บอกว่าการเลื่อนวงจรชีวิตควรอยู่ในเครื่องมือแยกที่ตั้งชื่อชัด รันโดยคนที่ตัดสินใจแล้วว่าจะส่งมอบบอร์ดนั้น ไม่ใช่ในตัวอย่างที่ใครก็กดรันเพื่อ “ดูว่าเกิดอะไรขึ้น”
อีกฟังก์ชันหนึ่งที่ต้องระวังคือ tesaiot_run_protected_update_isolated_test() ตัวอย่าง 06 ระบุว่ามันเป็น เมนูแบบโต้ตอบ ที่รอ scanf() จาก console และไม่คืนค่าจนกว่าผู้ใช้จะเลือกออก
ห้ามเรียกจาก task ที่ไม่มีคนเฝ้า จากทางบูต หรือจากที่ที่มี watchdog มันเขียน metadata ของ OID สำหรับทดสอบ และอ่าน LcsO มาแสดงแต่ไม่เขียน
เทียบกับการอัปเดตเฟิร์มแวร์ ETSI EN 303 645 ข้อ 5.3-10 (M) ให้ตรวจความแท้และความถูกต้องของอัปเดตทุกครั้งที่มาทางเครือข่าย ตัวอย่าง c_ota_client
อ่าน job document ที่มีฟิลด์ file_hash และ signature แต่ฟังก์ชันตรวจยังไม่ได้ทำงานจริง (ดูตัวอย่างสมบูรณ์) และถ้าไม่ได้ตั้งไฟล์ CA มันปิดการตรวจใบของเซิร์ฟเวอร์ด้วย
ตัวอย่างนี้เป็นจุดเริ่มที่ดีสำหรับโครงของ OTA แต่ ห้ามนำไปใช้กับอุปกรณ์จริงโดยไม่เติมการตรวจ
อีกเส้นทางใน SDK คือการอัปเดตผ่าน BLE ตามหน้า Firmware update (BLE NUS)
ทุกการ flash ที่สั่งจากเดสก์ท็อปต้องผ่านหน้าจอยืนยัน Y/N บนบอร์ดที่แสดง 8 ตัวแรกของ SHA-256 ของเป้าหมาย ไม่มีทางข้าม และหมดเวลาแล้วไม่ถือว่าตอบ Y
ข้อ 5.3-10 ของ ETSI นับการยืนยันโดยผู้ใช้เป็นความสัมพันธ์เชื่อใจแบบหนึ่ง แต่ต้องรู้ว่าเส้นทางนี้คอมไพล์เฉพาะเมื่อ ENABLE_PAGE_BENTO_BUDDY=1
และ README ของตัวอย่างฝั่ง CM33 บอกว่าในแม่แบบที่ส่งมอบ ไลบรารีนี้ยังไม่ได้ถูก link เข้าภาพเฟิร์มแวร์
ตัวอย่างสมบูรณ์
หัวข้อที่มีชื่อว่า “ตัวอย่างสมบูรณ์”คำขอ Protected Update ตัดจาก 06_protected_update.c บรรทัด 110–122 และ 167–173 (TESAIoT PSE84 Dev Kit SDK, © Thai Embedded Systems Association, Apache-2.0)
/* Hex strings, as the API takes them. "E0E1" is the TESAIoT device certificate * slot and "E0E8" the trust anchor this project pairs with it. Change the * target to the isolated test slot if you are only rehearsing. */#define EXAMPLE_PU_TARGET "E0E1"#define EXAMPLE_PU_ANCHOR "E0E8"
/* The platform takes max(chip counter, its own record, this) + 1, so a value * that is merely plausible is fine; a value LOWER than the chip's counter is * not, and the chip's refusal will look like a signature failure. */#define EXAMPLE_PU_VERSION (1U)
/* false: update the object, do not enrol a new key at the same time. */#define EXAMPLE_PU_WITH_CSR false /* The request. Returns 0 when it was published, -1 when it was not — and * -1 also covers the local refusals it makes on your behalf, such as a * target already locked to a different anchor. Its own printf says which. */ int rc = tesaiot_publish_protected_update(EXAMPLE_PU_TARGET, EXAMPLE_PU_ANCHOR, (uint32_t)EXAMPLE_PU_VERSION, EXAMPLE_PU_WITH_CSR);ตัวอย่างนี้ ปิดไว้เป็นค่าเริ่มต้น ต้อง build ด้วย DEFINES+=EXAMPLE_HSM_REQUEST_PU=1 จึงจะส่งคำขอจริง ถ้าไม่เปิด มันพิมพ์แผนของคำขอ (ช่องไหน anchor ไหน version เท่าไร) แล้วบอกว่าข้ามไป
การพิมพ์แผนก่อนทำเป็นความตั้งใจของผู้เขียน เพราะนี่คือคำสั่งเดียวใน SDK ที่ OID เป้าหมายควรถูกอ่านสองรอบก่อนกด
ฟังก์ชันตรวจเฟิร์มแวร์ใน OTA client ตัดจาก ota_client.c บรรทัด 375–386 (© 2026 TESAIoT Platform (TESA), Apache-2.0)
ota_error_t ota_verify_firmware(ota_client_t *ctx){ if (!ctx) return OTA_ERR_PARSE;
ctx->state = OTA_STATE_VERIFYING; OTA_LOG("Verifying firmware integrity...");
/* TODO: Calculate SHA256 hash and compare with ctx->job.file_hash */
ctx->state = OTA_STATE_IDLE; return OTA_OK;}ota_run_update_cycle() ในไฟล์เดียวกันเรียก ดาวน์โหลด → ota_verify_firmware() → apply_firmware ตามลำดับ ฟังก์ชันตรวจที่คืน OTA_OK เสมอ ทำให้ทุกไฟล์ที่ดาวน์โหลดมาถูก apply
เทียบกับบทเรียน 1.2 นี่คือกรณีเดียวกับ hook ตรวจโมเดล AI ฟังก์ชันที่ชื่อว่า “verify” ต้องไม่คืนผ่านถ้ายังไม่ได้ตรวจจริง
ฝึกเติม
หัวข้อที่มีชื่อว่า “ฝึกเติม”ทำนายผลของแต่ละสถานการณ์ เลือกจาก (ก) ขอสำเร็จและชิป apply (ข) ถูกปฏิเสธในเครื่องก่อนส่งคำขอ (ค) ชิปปฏิเสธตอนตรวจ manifest (ง) เฟิร์มแวร์ทิ้ง bundle เพราะไม่มีคำขอค้าง
- ช่อง
0xE0E1ถูกล็อกกับ0xE0E9อยู่แล้ว แต่คำขอระบุ anchor"E0E8"____ - bundle ที่ถูกต้องมาถึงหลังรีบูต ตอนที่
trustm_current_correlation_id()เป็นNULL____ - ใบของผู้ลงนามไม่ได้ถูกเขียนลง
0xE0E8แต่ขั้นอื่นทำครบ ____ - อุปกรณ์ subscribe
commands/#แล้วขอ ใบของผู้ลงนามถูกเขียนลง0xE0E8และ version ที่แพลตฟอร์มใช้มากกว่าตัวนับในชิป ____ - มีคนเอา manifest รุ่นก่อนหน้าที่เคย apply สำเร็จแล้ว มาส่งพร้อม correlation id ที่ตรงกับคำขอที่ค้างอยู่ ____
เฉลย
- (ข)
tesaiot_publish_protected_update()อ่านชิปก่อนและปฏิเสธเองเมื่อช่องถูกผูกกับ anchor อื่น คืน-1ตัวอย่าง 06 ชี้ว่านี่มีประโยชน์เพราะถ้าปล่อยไปถึงชิป รหัส0x800Fจะแยกไม่ออกจาก version เก่า - (ง) นี่คือการกันการเล่นซ้ำ bundle ที่ไม่มีใครขอต้องไม่ถูก apply
- (ค) ชิปไม่มีอะไรไว้ตรวจลายเซ็น ได้
0x800Fทั้งที่ลายเซ็นถูก สัญญา PU เรียกกรณีนี้ว่าสาเหตุที่พบบ่อยที่สุด - (ก)
- (ค) version ของ manifest เก่าไม่มากกว่าตัวนับในชิป ตัวนับกันย้อนรุ่นทำงาน แม้ลายเซ็นจะถูกต้องก็ตาม
เช็กความเข้าใจ
หัวข้อที่มีชื่อว่า “เช็กความเข้าใจ”คำถามข้างล่างเป็นส่วนหนึ่งของชุดเต็มใน quiz.yaml ซึ่งระบบตรวจอัตโนมัติใช้
-
ในเส้นทาง Protected Update ขั้นไหนที่ host ที่ถูกเจาะปลอมไม่ได้ (เป้าหมายข้อ 1)
- ก) การพิมพ์บรรทัด
PROTECTED UPDATE COMPLETED SUCCESSFULLY! - ข) การที่ชิปตรวจลายเซ็นของ manifest กับ trust anchor ของตัวเองสำเร็จ แล้วเขียนช่องเป้าหมาย
- ค) การส่ง ACK ขึ้นแพลตฟอร์ม
- ง) การ subscribe
commands/#
เฉลย
ข ทุกอย่างที่ host ทำหรือพิมพ์ ผู้ที่คุม host ปลอมได้ แต่ชิปไม่ยอมเขียนถ้าลายเซ็นไม่ผ่าน หลักฐานจึงอยู่ที่การอ่านสถานะจากชิปเอง
- ก) การพิมพ์บรรทัด
-
ตัวนับ version (tag
C1) ป้องกันอะไร (เป้าหมายข้อ 2)- ก) ป้องกันไม่ให้ manifest ที่ลงนามถูกต้องแต่เป็นรุ่นเก่า ถูกนำมาใช้ซ้ำ
- ข) ป้องกันการอ่านใบรับรอง
- ค) ป้องกันการเชื่อมต่อ WiFi ซ้ำ
- ง) ป้องกันการเขียน tag
C0
เฉลย
ก ลายเซ็นบอกว่าใครออก manifest แต่ไม่บอกว่ามันใหม่หรือเก่า ตัวนับทำหน้าที่ส่วนนั้น
-
บอร์ดพัฒนาที่
C0ของ0xE0E1เป็น01เพิ่งผ่าน Protected Update ข้อใดถูก (เป้าหมายข้อ 2)- ก) ช่องนี้ถูกล็อกถาวร
- ข) ช่องนี้รับเฉพาะ manifest ที่ลงนามโดย anchor แต่ล็อกยังเคลียร์ได้เพราะ LcsO ยังต่ำกว่า op ส่วนตัวนับ version ย้อนไม่ได้
- ค) ทั้งล็อกและตัวนับย้อนได้ด้วยการ reflash
- ง) LcsO เปลี่ยนเป็น op แล้ว
เฉลย
ข ต้องแยกสองอย่างนี้ให้ออก ล็อกเป็นเงื่อนไขใน metadata ส่วนตัวนับขึ้นอย่างเดียว
-
ตามตัวอย่าง 06 การเปลี่ยนแปลงใดบนชิปที่ไม่มี reflash การลบ หรือการตัดไฟใดพากลับได้ (เป้าหมายข้อ 3)
- ก) การเขียนใบรับรองลง
0xE0E1 - ข) การเลื่อน LcsO (metadata tag
C0) - ค) การเชื่อมต่อ MQTT
- ง) การอ่าน metadata
เฉลย
ข และเมื่อถึง
opการเขียน metadata หยุดถาวร ล็อกของ Protected Update จึงกลายเป็นถาวรไปด้วย - ก) การเขียนใบรับรองลง
แล็บหลัก: อ่านแผนของคำขอโดยไม่ส่งจริง
- build ตัวอย่าง 06 โดย ไม่ เปิดสวิตช์ใด
จดบรรทัด
Terminal window make build ENABLE_PAGE_EXAMPLES=1 SDK_EXAMPLE_CM33=cm33/security/06_protected_updatemake program BENTO_WORKSPACE="$(cd .. && pwd)"target OID,anchor OID,version,with_csr,life cycleและข้อความSKIPPED both pathsแล้วอธิบายเป็นภาษาของคุณว่าแต่ละบรรทัดบอกอะไร - วาดแผนภาพลำดับของ Protected Update จากคำขอถึงการอ่าน metadata กลับ ทำเครื่องหมายสามจุด จุดที่ host ปลอมได้ จุดที่ชิปตรวจลายเซ็น และจุดที่ตัวนับเปลี่ยน
- เขียนรายการตรวจสามข้อที่คุณจะทำก่อนตีความรหัส
0x800Fว่า “ลายเซ็นผิด” - OTA อ่าน ota_client.c แล้วเขียนแผนเติม
ota_verify_firmware()เป็นขั้น (เทียบ SHA-256 กับfile_hashแล้วตรวจsignatureด้วยกุญแจสาธารณะที่อุปกรณ์เชื่อ) ระบุว่ากุญแจสาธารณะนั้นควรมาจากไหน และทำไมfile_hashอย่างเดียวไม่พอ (บทเรียน 1.2)
แล็บเสริม: Protected Update จริง ทำเมื่อผู้สอนอนุญาตเท่านั้น
สิ่งที่จะเปลี่ยนถาวรบนชิปของคุณ คือตัวนับ version ของช่อง 0xE0E1 ขึ้นหนึ่งขั้น สิ่งที่จะเปลี่ยนแต่กลับได้บนบอร์ดสถานะ creation คือล็อกของช่องนั้น
ปุ่ม Protected Update บนจอเรียก tesaiot_publish_protected_update() ด้วย with_csr = true ตามบท D2 จึงสร้างคู่กุญแจใหม่ในชิปด้วย LcsO จะไม่ถูกแตะ
- อุปกรณ์ต้องเชื่อมต่อแพลตฟอร์มได้ (บทเรียน 3.2) บน variant mtb-mpy อ่าน
optiga.read_metadata(0xE0E1)จดค่า tagC0และD0ถ้าC0ไม่ใช่01หยุดและแจ้งผู้สอน - HSM Security → Protected Update บนจอ จดข้อความบนจอและบรรทัด
[PU-Ingest]บน UART เทียบกับ “ดูของจริงก่อน” - อ่าน metadata อีกครั้ง
D0ต้องเปลี่ยนเป็นค่าที่ระบุ anchor และC0ต้องเท่าเดิม ถ้าC0เปลี่ยน หยุดและรายงานทันที - ปิดเปิดบอร์ดแล้วเชื่อมต่อใหม่ ดูว่ามีบรรทัด
Ignoring a Protected Update bundle nobody asked forหรือไม่ ถ้าเห็น STEP 3 และ STEP 4 ทั้งที่ไม่ได้กดอะไร แปลว่าการกันเล่นซ้ำผิดปกติ ให้รายงาน - ลองกด Enrol ใส่ช่องที่ถูกล็อก จดข้อความบนจอ แล้วให้ผู้สอนตัดสินใจว่าจะใช้เมนู Unlock คืนสภาพหรือไม่
Protected Update ต้องมีใบรับรองของอุปกรณ์อยู่ก่อน หรือส่ง CSR ไปพร้อมคำขอ โมดูลสุดท้ายจะดูการลงทะเบียนด้วย CSR ตั้งแต่สร้างกุญแจในชิปจนได้ใบรับรองกลับมา แล้วรวมทุกอย่างเป็นอุปกรณ์ที่ปลอดภัยหนึ่งชิ้น
บทเรียนถัดไป: บทเรียน 5.1: ลงทะเบียนด้วย CSR
สะท้อนคิด
หัวข้อที่มีชื่อว่า “สะท้อนคิด”- ในระบบของคุณ log บรรทัดไหนที่ทีมเชื่อว่าเป็นหลักฐาน ทั้งที่มันเป็นแค่ข้อความที่โปรแกรมพิมพ์
- ถ้าต้องส่งมอบอุปกรณ์ที่เลื่อน LcsO แล้ว คุณจะออกแบบขั้นตอนอนุมัติอย่างไรให้ไม่มีใครทำโดยบังเอิญ
- ฟังก์ชันที่ชื่อว่า verify ในโค้ดของคุณ ตรวจอะไรจริง ๆ บ้าง
แหล่งอ้างอิง
หัวข้อที่มีชื่อว่า “แหล่งอ้างอิง”- SDK: cm33/security/06_protected_update.c
- SDK: PROTECTED_UPDATE_CONTRACT.md
- D2 — Enrolment and Protected Update end to end (เอกสาร SDK สร้างจาก commit ef72c1b)
- SDK: cm33/security/02_model_signature_hook.c
- Firmware update (BLE NUS) (เอกสาร SDK สร้างจาก commit ef72c1b)
- Infineon: protected_update_data_set tool README @ release-v5.3.0 (MIT)
- ETSI EN 303 645 V3.1.3 (2024-09) ข้อ 5.3
- ตัวอย่างบน Developer Hub: TESAIoT OTA HTTPS Client (C Version) (Apache-2.0) · PSoC Edge E84 + OPTIGA Trust M: TESAIoT MQTT Client (Cypress EULA ลิงก์เท่านั้น)
คำถามทบทวน
ลองตอบเองก่อน แล้วค่อยเปิดดูเฉลย
-
ในเส้นทาง Protected Update ขั้นไหนที่ host ที่ถูกเจาะปลอมไม่ได้ (เป้าหมายข้อ 1)
- การพิมพ์บรรทัด PROTECTED UPDATE COMPLETED SUCCESSFULLY!
- การที่ชิปตรวจลายเซ็นของ manifest กับ trust anchor ของตัวเองสำเร็จ แล้วเขียนช่องเป้าหมาย
- การส่ง ACK ขึ้นแพลตฟอร์ม
- การ subscribe commands/#
ดูเฉลย
คำตอบ: B. การที่ชิปตรวจลายเซ็นของ manifest กับ trust anchor ของตัวเองสำเร็จ แล้วเขียนช่องเป้าหมาย
ทุกอย่างที่ host ทำหรือพิมพ์ ผู้ที่คุม host ปลอมได้ แต่ชิปไม่ยอมเขียนถ้าลายเซ็นไม่ผ่าน หลักฐานจึงอยู่ที่การอ่านสถานะจากชิปเอง
-
tesaiot_publish_protected_update() คืนค่า 0 หมายความว่าอะไร (เป้าหมายข้อ 1)
- ชิปเขียนใบรับรองใหม่เสร็จแล้ว
- คำขอถูก publish แล้ว ชิปยังไม่เปลี่ยนจนกว่า manifest จะมาถึงและถูก apply
- LcsO เปลี่ยนแล้ว
- แพลตฟอร์มปฏิเสธคำขอ
ดูเฉลย
คำตอบ: B. คำขอถูก publish แล้ว ชิปยังไม่เปลี่ยนจนกว่า manifest จะมาถึงและถูก apply
คอมเมนต์ของตัวอย่าง 06 บอกว่า 0 แปลว่าขอแล้ว ไม่ใช่เสร็จแล้ว ต้องติดตามด้วย correlation id จนคำตอบมาถึง
-
ตัวนับ version (metadata tag C1) ป้องกันอะไร (เป้าหมายข้อ 2)
- ป้องกันไม่ให้ manifest ที่ลงนามถูกต้องแต่เป็นรุ่นเก่า ถูกนำมาใช้ซ้ำ
- ป้องกันการอ่านใบรับรอง
- ป้องกันการเชื่อมต่อ WiFi ซ้ำ
- ป้องกันการเขียน tag C0
ดูเฉลย
คำตอบ: A. ป้องกันไม่ให้ manifest ที่ลงนามถูกต้องแต่เป็นรุ่นเก่า ถูกนำมาใช้ซ้ำ
ลายเซ็นบอกว่าใครออก manifest แต่ไม่บอกว่ามันใหม่หรือเก่า ตัวนับที่ขึ้นอย่างเดียวทำหน้าที่ส่วนนั้น
-
บอร์ดพัฒนาที่ C0 ของ 0xE0E1 เป็น 01 เพิ่งผ่าน Protected Update ข้อใดถูก (เป้าหมายข้อ 2)
- ช่องนี้ถูกล็อกถาวร
- ช่องนี้รับเฉพาะ manifest ที่ลงนามโดย anchor แต่ล็อกยังเคลียร์ได้เพราะ LcsO ยังต่ำกว่า op ส่วนตัวนับ version ย้อนไม่ได้
- ทั้งล็อกและตัวนับย้อนได้ด้วยการ reflash
- LcsO เปลี่ยนเป็น op แล้ว
ดูเฉลย
คำตอบ: B. ช่องนี้รับเฉพาะ manifest ที่ลงนามโดย anchor แต่ล็อกยังเคลียร์ได้เพราะ LcsO ยังต่ำกว่า op ส่วนตัวนับ version ย้อนไม่ได้
ล็อกเป็นเงื่อนไข Change ใน metadata ที่เขียนกลับได้ตราบที่ LcsO ต่ำกว่า op ส่วนตัวนับขึ้นอย่างเดียว
-
ตามตัวอย่าง 06 การเปลี่ยนแปลงใดบนชิปที่ไม่มี reflash การลบ หรือการตัดไฟใดพากลับได้ (เป้าหมายข้อ 3)
- การเขียนใบรับรองลง 0xE0E1
- การเลื่อน LcsO (metadata tag C0)
- การเชื่อมต่อ MQTT
- การอ่าน metadata
ดูเฉลย
คำตอบ: B. การเลื่อน LcsO (metadata tag C0)
LcsO เดินทางเดียว cr ไป in ไป op ไป te และเมื่อถึง op การเขียน metadata หยุดถาวร ไม่มีตัวอย่างใดใน SDK เขียน tag นี้
อ้างอิงบทเรียนนี้
ถ้านำบทเรียนนี้ไปสอน ทำสไลด์ หรือทำเอกสารต่อ ให้อ้างอิงด้วยข้อความนี้ ถ้าดัดแปลงเนื้อหา ให้เติม (ดัดแปลง)ต่อท้ายชื่อบทเรียน
"Protected Update" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0
ข้อความอ้างอิงภาษาอังกฤษ: "Protected Update" from TESA Open Knowledge by the Thai Embedded Systems Association (TESA), https://github.com/tesaiot/tesa-qualification-program, licensed under CC BY-NC 4.0
บทเรียนนี้ดัดแปลงจากต้นฉบับด้านล่าง เมื่ออ้างอิงให้คงเครดิตต้นฉบับไว้ด้วย
https://github.com/tesaiot/tesaiot-pse84-devkit-sdk/tree/ef72c1b658178eee8c38b1e47d28b006f80a59b5 · SDK security examples and docs are linked at this commit; lesson pages quote short excerpts with attribution and copy no files.
TESA Open Knowledge · © 2026 สมาคมสมองกลฝังตัวไทย (TESA) · CC BY-NC 4.0
เนื้อหาเผยแพร่ภายใต้ CC BY-NC 4.0 นำไปใช้ต่อในงานที่ไม่ใช่เพื่อการค้าได้ โปรดอ้างอิงสมาคมสมองกลฝังตัวไทย (TESA) ทุกครั้ง · วิธีอ้างอิง TESA