Secure boot and the chain of trust
Module 4 · Secure boot and Protected Update · Module overview · Course home
mTLS proves the key lives inside the chip, but if the firmware that commands the chip has been swapped, an attacker can have the chip sign on our behalf anyway (lesson 1.2). So this lesson’s question is: “is the firmware running right now the firmware we meant to run?” — and on this board, who checks that, and how far does the check go?
Objectives
Section titled “Objectives”By the end of this lesson you will:
- Explain the role of the CM33_S core in the firmware template’s secure boot
- Draw the chain of trust from ROM to application, and mark where signatures are checked
- Explain the difference between secure boot and firmware encryption
Before you start
Section titled “Before you start”- Already covered: Lesson 3.2: MQTTs to the TESAIoT Platform, and review signatures from lesson 1.2
- Software: the SDK’s
bento-firmware-template-mtb-onlytemplate atef72c1b, already building - What this lesson will not have you do: provisioning a device to enable secure boot (
secure_boot=truein the OEM policy), and transferring device ownership with an OEM key. The README of Infineon’s basic secure app example says that once provisioned, Extended Boot opens the first image only if its signature verifies. This changes the device’s behaviour at the chip level, and must follow AN237849 Getting started with PSOC™ Edge security, done by someone who has already decided to do it and who can manage the OEM key.
See it work first
Section titled “See it work first”The “which core does what” table in the template’s README has this as its first row.
| Core | Runs | Typical work |
|---|---|---|
| CM33_S | secure boot | you will not touch this |
Meanwhile proj_cm33_s/main.c, the whole file, is under fifty lines.
Its header comment reads “CM33 Secure boot - TrustZone setup and jump to CM33_NS.” Inside main() there is only cybsp_init(), enabling interrupts,
reading the stack pointer and reset handler from CM33_NS’s vector table, and jumping there.
Guess first: before jumping, does CM33_S verify the signature of the CM33_NS firmware? And if not, who checks what?
Concepts
Section titled “Concepts”1. The role of CM33_S
Section titled “1. The role of CM33_S”The PSoC™ Edge E84 has three cores, and its main Cortex-M33 is split into secure and non-secure sides with TrustZone. So the template has three projects: proj_cm33_s, proj_cm33_ns, proj_cm55.
Infineon’s example README explains the order: Extended Boot opens the CM33 secure project from a fixed location in memory.
CM33 secure sets up protections, then opens the CM33 non-secure app; CM33 non-secure then starts the CM55 core.
In our template, this last step lives in init_cm55_boot(), which calls Cy_SysEnableCM55(), per chapter B1 of the SDK docs.
So CM33_S is the first user image that Extended Boot sees, and the only joint where Extended Boot can verify a signature at all.
The template’s common.mk has a SECURE_BOOT switch with two values.
SECURE_BOOT=0(the default) usesconfigs/boot_with_extended_boot.json. The CM33_S image gets only the MCUboot header and is not signed.SECURE_BOOT=1usesconfigs/secure_boot_with_extended_boot.json. The CM33_S image is signed with the OEM root-of-trust key that a device provisionedsecure_boot=truerequires. The build log prints confirmation of which key file CM33_S will be signed with.
Any value other than 0 or 1, such as true or yes, makes the build stop with an error immediately. The comment in the file explains why: a mistyped value must never turn into a silently unsigned build.
2. This board’s chain of trust, and where signatures are actually checked
Section titled “2. This board’s chain of trust, and where signatures are actually checked”The root of trust is the part we trust with no one else checking it. ETSI EN 303 645 provision 5.7-1 explains that a hardware root of trust is one way to make secure boot meaningful. On this board, that starting point is Infineon’s code inside the chip, and each stage opens the next. The question is: before opening it, is there a check?
Boot ROM (Infineon's code inside the chip) │ ▼ Extended Boot (Infineon's) │ verifies the CM33_S image's signature with the OEM key │ ✔ when the device is provisioned secure_boot=true and built with SECURE_BOOT=1 │ ✘ in the template's default state (SECURE_BOOT=0) ▼ CM33_S (proj_cm33_s) cybsp_init(), then jumps to CM33_NS's reset handler │ ✘ does not verify CM33_NS's signature (the template's main.c) ▼ CM33_NS (proj_cm33_ns) FreeRTOS, PSA + the OPTIGA driver, WiFi, MQTT, then Cy_SysEnableCM55() │ ✘ does not verify CM55's signature ▼ CM55 (proj_cm55) display, Edge AI ◦ an AI model uploaded at runtime goes through the optiga_verify_staged_model() hook (lesson 1.2)The evidence that signing covers only CM33_S is in secure_boot_with_extended_boot.json: the sign stage takes exactly one input file, proj_cm33_s.hex.
proj_cm33_ns.hex only goes through the hex-relocate stage, and proj_cm55.hex goes straight into a merge stage; all three are combined into one app_combined.hex file.
A conclusion that belongs in your threat model: even with secure boot fully enabled, this template’s chain breaks right after CM33_S. Whoever can write to the flash region of CM33_NS or CM55 can run their own code, unchecked. If your work needs a complete chain, CM33_S (or a bootloader sitting there) must verify the next image before jumping to it. Infineon has an EdgeProtect Bootloader that the example README references, but this template does not use it.
There are two other places in this course where a signature is checked, but neither is a boot stage:
- A Protected Update manifest is verified inside the chip, by the OPTIGA™ Trust M, before it writes an object (lesson 4.2)
- The hook that verifies an AI model uploaded at runtime — in the SDK, this defaults to a weak function that answers “this device cannot verify signatures” (
-10), per the02_model_signature_hook.cexample
3. Secure boot is not firmware encryption
Section titled “3. Secure boot is not firmware encryption”These two answer different questions.
| Secure boot | Firmware encryption | |
|---|---|---|
| Answers | Does this code come from the key’s owner, unaltered? | Can someone else read this code? |
| Property | Integrity and authenticity | Confidentiality |
| Tool | A digital signature, verified with a public key the device trusts | Symmetric encryption, needing a private key on the device to decrypt |
| Does not protect against | Someone reading the code in flash, a bug in already-signed code, an attack at runtime | Running different code in its place, if no signature check accompanies it |
This template has no image-encryption stage in either config file, so even with secure boot enabled, anyone who can read flash can still read the code. Secrets embedded in the image (such as a compiled-in password) get no protection from secure boot at all — this is another reason for ETSI provision 5.4-3 from lesson 3.2.
One more small thing worth noticing: the signed config sets security-counter to 1, which, in MCUboot’s format, is the number used to prevent image rollback.
The documentation this course could check does not confirm how Extended Boot enforces this number, so it does not yet count as a verified firmware anti-rollback mechanism. Lesson 4.2 looks at the anti-rollback mechanism that can actually be verified, inside the OPTIGA™ chip.
Worked example
Section titled “Worked example”The header comment of secure_boot_with_extended_boot.json, lines 1–15 (TESAIoT PSE84 Dev Kit SDK, © Thai Embedded Systems Association, Apache-2.0)
// Signed variant of boot_with_extended_boot.json — selected by SECURE_BOOT=1 in common.mk.//// Identical to boot_with_extended_boot.json except the CM33_S sign stage additionally// carries "signing-key" + "security-counter", which turn the MCUboot metadata into a real// OEM signature that Extended Boot verifies once the device is provisioned secure_boot=true.//// Geometry (header-size / fill-value / slot-size / hex-address) is intentionally IDENTICAL to// the unsigned config — it is this project's real flashmap. Do NOT replace it with the values// from mtb-example-psoc-edge-basic-secure-app (slot-size 0x80000, hardcoded 0x70100000).//// {{OEM_SIGNING_KEY}} is supplied by common.mk via:// MTB_COMBINE_SIGN_ARGS += -s OEM_SIGNING_KEY "$(SECURE_BOOT_KEY)"// Override the key with: make SECURE_BOOT=1 SECURE_BOOT_KEY=/abs/path/to/key.pem// If you invoke run-config by hand you MUST pass -s OEM_SIGNING_KEY <path>; an unset// variable is a hard error ("Unknown variable: OEM_SIGNING_KEY"), never a silent unsigned build.Reading this gives you three things:
- Only two fields differ from the unsigned version —
"signing-key"and"security-counter"in CM33_S’s sign stage. The MCUboot header is already present in both. - The signature only means something once the device has been provisioned. A board not yet provisioned
secure_boot=truedoes not check this signature at all. - The author designed it to “fail loudly.” If no key is supplied, the build must error out, not silently produce an unsigned image — the same principle as
common.mkrefusing anySECURE_BOOTvalue besides0and1.
Practice
Section titled “Practice”For each statement below, is it true of secure boot, firmware encryption, both, or neither?
- Stops a competitor who buys the board from reading flash and understanding the code ____
- Stops a provisioned board from booting an image signed with a different key ____
- Prevents a buffer overflow bug in correctly signed code ____
- Needs a private key present on the device to work ____
- Prevents CM55’s firmware from being swapped in this template, even with
SECURE_BOOT=1and provisioning done ____
Solution
- Firmware encryption
- Secure boot
- Neither — signed code can still have bugs; a signature only tells you who it came from
- Firmware encryption — needs a decryption key on the device; secure boot only needs a public key to verify with
- Neither — in this template, signing covers only the CM33_S image
Check your understanding
Section titled “Check your understanding”The questions below are part of the full set in quiz.yaml, which the automated grader uses.
-
In the template’s
proj_cm33_s/main.c, what does CM33_S do before starting CM33_NS? (objective 1)- a) Verifies CM33_NS’s signature with the OPTIGA™ Trust M
- b)
cybsp_init(), then reads the stack pointer and reset handler from CM33_NS’s vector table and jumps there - c) Decrypts the CM33_NS image
- d) Connects to WiFi
Solution
b. There is no signature check at this stage, which is why the template’s chain breaks right after CM33_S.
-
You build with
SECURE_BOOT=1and flash a board that is not yet provisionedsecure_boot=true. What happens? (objective 2)- a) The board does not boot
- b) Extended Boot has not yet been forced to check the signature, so having a signature adds no protection yet
- c) The OPTIGA chip locks
- d) LcsO changes to operational
Solution
b. The comment in the config says Extended Boot checks this signature “once the device is provisioned secure_boot=true.”
-
Which statement correctly describes the difference between secure boot and firmware encryption? (objective 3)
- a) Secure boot hides the code; encryption confirms who wrote it
- b) Secure boot confirms the code comes from the key’s owner and is unaltered; encryption stops others from reading the code
- c) They are the same thing
- d) Secure boot needs a private key on the device
Solution
b. You need both together if you want integrity and confidentiality. This template has no image-encryption stage.
Read your board’s chain from the evidence. This lesson does not provision anything, and does not flash a signed image.
- 1. Diff the two configs from the template’s folder.
Write down every line that differs. Besides comments, how many fields are left? Does it match item 1 in the worked example?
Terminal window diff configs/boot_with_extended_boot.json configs/secure_boot_with_extended_boot.json - 2. Prove the build system fails loudly. Build with an invalid value and record the error message.
Write one sentence on why this command failing is a good thing.
Terminal window make build SECURE_BOOT=yes - 3. Count what actually gets signed. Open
configs/secure_boot_with_extended_boot.json, find every"command", and write a table of which stages each core’s hex file goes through (sign, hex-relocate, merge). - 4. Draw your own chain, in two versions: the board you are holding right now, and a shipped product with secure boot fully enabled. Mark ✔ or ✘ at every joint, each with one line of evidence (file and line).
- 5. Update the threat model from lesson 1.1, in the T row about firmware and in the ETSI 5.7-1 row, to reflect what you found, including the fact that the chain breaks after CM33_S.
- 6. Read further (no need to do it) in the README of Infineon’s basic secure app example. Write down the list of steps that must happen on a device before Extended Boot starts checking signatures, and mark which step you think needs someone’s sign-off before it happens.
Going further
Section titled “Going further”Secure boot answers the question about firmware at power-on, but some data inside the chip — a device’s certificate, for instance — must be changeable over the device’s lifetime. The next lesson looks at how the OPTIGA™ Trust M accepts that change without trusting the host, and how it prevents rollback.
Next lesson: Lesson 4.2: Protected Update
Reflect
Section titled “Reflect”- In your own product, where does the chain of trust break, and who can write to the part that goes unchecked?
- If the OEM key used for signing were to leak, how would you find out, and what would you do next?
- Does your customer need the confidentiality of the code, the integrity of the code, or both?
References
Section titled “References”- SDK: the mtb-only template README (CM33_S secure boot)
- B1 — CM33_NS boot walk-through (SDK docs built from commit ef72c1b)
- SDK: common.mk (the SECURE_BOOT switch)
- SDK: configs/secure_boot_with_extended_boot.json and boot_with_extended_boot.json
- SDK: proj_cm33_s/main.c
- Infineon: PSOC™ Edge MCU basic secure application (linked, not copied)
- Infineon AN237849: Getting started with PSOC™ Edge security
- PSA Certified
- ETSI EN 303 645 V3.1.3 (2024-09), provision 5.7
Review questions
Answer on your own first, then open the answer.
-
In the template's proj_cm33_s/main.c, what does CM33_S do before starting CM33_NS? (Objective 1)
- ตรวจลายเซ็นของ CM33_NS ด้วย OPTIGA™ Trust M
- cybsp_init() แล้วอ่าน stack pointer และ reset handler จากตาราง vector ของ CM33_NS แล้วกระโดดไป
- ถอดรหัส image ของ CM33_NS
- เชื่อมต่อ WiFi
Show answer
Answer: B. cybsp_init() แล้วอ่าน stack pointer และ reset handler จากตาราง vector ของ CM33_NS แล้วกระโดดไป
ไม่มีการตรวจลายเซ็นในขั้นนี้ ห่วงโซ่ความเชื่อใจในแม่แบบจึงขาดหลัง CM33_S
-
What does the template's build do with SECURE_BOOT=true, and why? (Objective 1)
- ถือว่าเป็น 1 แล้วลงนามให้
- ถือว่าเป็น 0 แล้ว build แบบไม่ลงนาม
- หยุดด้วย error เพราะค่าที่พิมพ์ผิดต้องไม่กลายเป็น build ที่ไม่ได้ลงนามแบบเงียบ ๆ
- ข้ามขั้น sign ทั้งหมด
Show answer
Answer: C. หยุดด้วย error เพราะค่าที่พิมพ์ผิดต้องไม่กลายเป็น build ที่ไม่ได้ลงนามแบบเงียบ ๆ
common.mk ยอมรับแค่ 0 กับ 1 ค่าอื่นเป็น hard error ตามคอมเมนต์ในไฟล์
-
With SECURE_BOOT=1 on a device provisioned secure_boot=true, at which boot link is a signature checked? (Objective 2)
- Extended Boot ตรวจ image ของ CM33_S เท่านั้น
- ทุกข้อต่อจนถึง CM55
- CM33_S ตรวจ CM33_NS
- CM33_NS ตรวจ CM55
Show answer
Answer: A. Extended Boot ตรวจ image ของ CM33_S เท่านั้น
ในไฟล์ secure_boot_with_extended_boot.json ขั้น sign มีอินพุตเดียวคือ proj_cm33_s.hex ส่วน CM33_NS และ CM55 ไม่ได้ถูกลงนาม
-
You build with SECURE_BOOT=1 and flash a board not yet provisioned secure_boot=true. What happens? (Objective 2)
- บอร์ดไม่บูต
- Extended Boot ยังไม่บังคับตรวจลายเซ็น การมีลายเซ็นจึงยังไม่ได้เพิ่มการป้องกัน
- ชิป OPTIGA ถูกล็อก
- LcsO เปลี่ยนเป็น operational
Show answer
Answer: B. Extended Boot ยังไม่บังคับตรวจลายเซ็น การมีลายเซ็นจึงยังไม่ได้เพิ่มการป้องกัน
คอมเมนต์ใน config บอกว่า Extended Boot ตรวจลายเซ็นนี้เมื่ออุปกรณ์ provision secure_boot=true แล้วเท่านั้น
-
Which statement correctly contrasts secure boot and firmware encryption? (Objective 3)
- secure boot ซ่อนโค้ด การเข้ารหัสยืนยันว่าใครเขียน
- secure boot ยืนยันว่าโค้ดมาจากเจ้าของกุญแจและไม่ถูกแก้ การเข้ารหัสทำให้คนอื่นอ่านโค้ดไม่ได้
- ทั้งสองอย่างเหมือนกัน
- secure boot ต้องใช้กุญแจลับบนอุปกรณ์
Show answer
Answer: B. secure boot ยืนยันว่าโค้ดมาจากเจ้าของกุญแจและไม่ถูกแก้ การเข้ารหัสทำให้คนอื่นอ่านโค้ดไม่ได้
ต้องใช้คู่กันถ้าต้องการทั้งความถูกต้องและความลับ แม่แบบนี้ไม่มีขั้นเข้ารหัส image
Cite this lesson
If you teach from this lesson or reuse it in slides or documents, credit it with the text below. If you changed it, add (adapted) after the title.
"Secure boot and the chain of trust" 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
Thai attribution: "Secure boot และ chain of trust" จาก TESA Open Knowledge โดยสมาคมสมองกลฝังตัวไทย (Thai Embedded Systems Association: TESA) https://github.com/tesaiot/tesa-qualification-program สัญญาอนุญาต CC BY-NC 4.0
This lesson adapts the source below; keep its credit too.
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
Content is licensed CC BY-NC 4.0. Reuse it non-commercially and credit the Thai Embedded Systems Association (TESA) every time. · How to cite TESA