What a secure element does for us
Module 2 · The OPTIGA™ Trust M secure element · Module overview · Course home
The TESAIoT Dev Kit board has one OPTIGA™ Trust M chip, on the same I2C bus as the touch controller, commanded from the CM33_NS core. This lesson opens it up: what is inside, what it can do, which reads are “free,” and which commands, once run, can never be undone.
Objectives
Section titled “Objectives”By the end of this lesson you will:
- Name at least three secure-element functions, such as key storage, signing and random numbers
- Read HSM state with calls that need no chip transaction, following the SDK’s reference example
- Explain which chip operations are irreversible, and why the lessons will not touch them
Before you start
Section titled “Before you start”- Already covered: Lesson 1.2: Crypto basics for embedded systems
- Board: a TESAIoT Dev Kit with a USB cable plugged into the KitProg port, and a serial terminal program to read CM33_NS’s console
- Software: the TESAIoT PSE84 Dev Kit SDK at commit
ef72c1b, and ModusToolbox 3.6 (the SDK’s README says this exact version is required)
git clone https://github.com/tesaiot/tesaiot-pse84-devkit-sdk.gitcd tesaiot-pse84-devkit-sdkgit checkout ef72c1b658178eee8c38b1e47d28b006f80a59b5cd bento-firmware-template-mtb-only./setup.sh --buildsetup.sh prints every command it runs before running it. The first build takes about ten minutes.
After every flash, unplug the USB cable all the way, count to ten, then plug it back in. The SDK’s README explains that the display needs a cold power edge; resetting through the debugger alone leaves the screen black.
See it work first
Section titled “See it work first”Here is the header of the ref_hsm.c example we will run today. The SDK’s author opens the file with the sentence “THIS IS A REFERENCE LIST, NOT A JOB,” followed by:
It enrols nothing, publishes nothing, and writes nothing — to the chip or anywhere else.
There is also a SAFETY paragraph stating that this file neither reads nor writes metadata tag C0, the chip’s lifecycle state, which “moves one way only and which no reflash undoes.”
Guess first: why is the very first example the SDK has us run against the secure element one that deliberately does nothing to the chip at all? Write down a one-sentence answer, and come back to compare it at the end of Concepts section 3.
Concepts
Section titled “Concepts”1. What this chip can do
Section titled “1. What this chip can do”Infineon describes the OPTIGA™ Trust M as a security controller on hardware certified to Common Criteria EAL6+ (high)
(optiga-trust-m-overview). We use six groups of functions on this board, each with real functions in Infineon’s host library (optiga_crypt.h and optiga_util.h).
| Function | Host library call | What the board’s SDK uses it for |
|---|---|---|
| Generate and store a private key | optiga_crypt_ecc_generate_keypair |
Creates a new key pair during CSR enrolment (lesson 5.1) |
| Sign and verify a signature | optiga_crypt_ecdsa_sign, optiga_crypt_ecdsa_verify |
Signs CertificateVerify in mTLS (lesson 3.1), and checks that a certificate matches a key |
| Generate random numbers with the TRNG | optiga_crypt_random |
A helper in tesaiot_crypto.c calls it with OPTIGA_RNG_TYPE_TRNG (chapter D1 notes this file is shipped as a reference but not compiled into the template) |
| Key agreement and key derivation | optiga_crypt_ecdh, optiga_crypt_hkdf, optiga_crypt_hmac |
Available, but not yet on the template’s main path |
| Read/write data and metadata | optiga_util_read_data, optiga_util_read_metadata, optiga_util_write_metadata |
Reads a certificate out for use in TLS |
| Protected update | optiga_util_protected_update_start / _continue / _final |
Accepts a new certificate signed by the platform (lesson 4.2) |
The SDK does not have us call all of these functions directly. The parts dealing with owning the chip, enrolment and Protected Update are wrapped inside libbento_hsm.a,
which, per the tesaiot_hsm docs, exports 18 functions.
2. Objects, metadata and the lifecycle state
Section titled “2. Objects, metadata and the lifecycle state”The inside of the chip is divided into slots (objects), each with a two-byte address called an OID. This table combines Infineon’s example dump
(trust_m3_json.txt, MIT)
with the usage the SDK records in tesaiot_config.h and in chapter C4.
| OID | Factory value (Infineon’s example dump) | What TESAIoT uses it for |
|---|---|---|
0xE0C2 |
The chip’s 27-byte UID, always readable, cannot be changed | The source of the factory_uid value used as the MQTT client id in mTLS mode |
0xE0E0 |
Certificate from Infineon, Change = never | The factory identity |
0xE0F0 |
An ECC P-256 key, paired with 0xE0E0, Change = never, Execute = always |
Signs TLS before enrolment |
0xE0E1 |
A certificate slot, Change = LcsO < op | TESAIoT’s device certificate |
0xE0F1 |
A key slot, Change = LcsO < op | The key paired with 0xE0E1, created during enrolment |
0xE0E8 |
A trust-anchor slot, Change = LcsO < op | The anchor used to verify a Protected Update manifest |
Each slot’s metadata is a TLV starting with tag 20. There are only a handful of tags you need to be able to read in this course (see the dump, and Infineon’s example_optiga_util_protected_update.c).
| Tag | Meaning | Common values |
|---|---|---|
C0 |
LcsO, the object’s lifecycle state | 01 creation, 03 initialization, 07 operational, 0F termination |
C1 |
The object’s version, used to prevent rollback in Protected Update | Only ever goes up |
D0 |
Change access condition — who can write | FF never, E1 FC 07 = LcsO < op, 21 E0 E8 = requires a manifest verified with 0xE0E8 |
D1 / D3 |
Read / Execute access condition | 00 always |
E8 |
The object’s type | 11 trust anchor, 12 device certificate |
Look closely at E1 FC 07: it means “writable as long as LcsO is still below operational.” Most of the slots we use are writable precisely because the chip is still at creation (01).
Chapter D2 of the SDK docs says every board on the lab bench should read C0 as 01.
3. What cannot be undone, and free state reads
Section titled “3. What cannot be undone, and free state reads”The irreversible operations, as 06_protected_update.c states plainly, are:
- LcsO (tag
C0) travels one way only:cr (0x01) -> in (0x03) -> op (0x07) -> te (0x0F). No reflash, no erase, no power cut brings it back. What moves it is writing metadata that contains tagC0. Once it reachesop, writing metadata can stop being possible forever, and any slot whose Change condition isLcsO < opcan no longer be written normally either. - The version counter (tag
C1) of an object that has been through a Protected Update only ever goes up; the next manifest must carry a larger number than the last. - Change = never on
0xE0E0and0xE0F0: the factory identity can never be changed at all. This is not something we do, but you must know there is no way around it.
The Protected Update lock (tag D0 = 21 E0 E8), on the other hand, can be reversed as long as LcsO is still below op. Example 06 stresses that you must always say which kind of board you mean:
“permanent lock” is true for a device that has shipped, and not true for a development board.
No example in the SDK writes tag C0, and example 06 states that none of the 18 functions in libbento_hsm.a writes it either.
This course never has you write C0 or advance LcsO, under any circumstance, because the result is a board that can no longer be used for learning, with no way to recover it.
Example 06 sets the principle that advancing the lifecycle should live in a separate, clearly named tool, run only by someone who has already decided to ship that board.
Free state reads: ref_hsm.c splits the questions into two kinds.
- Three functions read a plain variable, touching the chip not at all — call them from any task, as often as you like, even while enrolment is in flight:
trustm_requested_target_oid(),trustm_requested_anchor_oid()andtrustm_current_correlation_id(). optiga_manager_lock()is not free. It acquires the chip’s access gate. If it returnstrue, you must return it withoptiga_manager_unlock()every time, and if it returnsfalse, that may just mean you have waited out the full ten-second timeout — so never call it from a UI tick.
Worked example
Section titled “Worked example”Taken from ref_hsm.c, lines 65–89 (TESAIoT PSE84 Dev Kit SDK, © Thai Embedded Systems Association, Apache-2.0)
/* NULL when nothing is in flight; otherwise the id the platform's reply is * matched against. This is the "is an enrolment outstanding?" test, and it * is the value trustm_reset_state() destroys — so check it before you * reset anything. Print it guarded: %s given NULL faults on this * platform's newlib. */ const char *cid = trustm_current_correlation_id(); printf(" trustm_current_correlation_id()= %s\r\n", (cid != NULL) ? cid : "(none — nothing in flight)");
/* ── Chip readiness — a balanced probe, not a free read ──────────────── */
if (optiga_manager_lock()) { /* True means both "the manager is up" and "the gate is now ours". The * unlock is not optional and there is no path out of here without it. */ printf(" optiga_manager_lock() = true (manager up, chip free)\r\n"); optiga_manager_unlock(); printf(" optiga_manager_unlock() — gate returned\r\n"); } else { /* Either optiga_manager_init() has never run, or another task has held * the chip for the full 10-second timeout. Those are different problems * and the return value does not separate them; if you need to know, * track whether your own code has called init(). */ printf(" optiga_manager_lock() = false (manager not " "initialised, or another task holds the chip)\r\n"); }Three things worth noticing in this code:
- Printing NULL needs a guard.
printf("%s", NULL)faults newlib on this platform, per the comment, so the example substitutes a message. - Acquire it, and you must return it. In the
truebranch, there is no path out of the function that skipsoptiga_manager_unlock(). - A
falsevalue does not say why. It can mean either “no one has initialised the manager yet” or “another task has held the chip for the full ten seconds.” If you need to tell these two cases apart, your own code has to remember whether it has already calledoptiga_manager_init().
Practice
Section titled “Practice”Sort each action into free (does not touch the chip), holds the gate (must be returned), a chip transaction (the chip does real work), or irreversible.
trustm_requested_anchor_oid()____optiga_manager_lock()____optiga_crypt_ecdsa_sign(me, digest, 32, OPTIGA_KEY_ID_E0F0, sig, &len)____- Writing metadata containing tag
C0with value07to a slot ____ - A Protected Update that applies successfully — the part that is that slot’s version counter ____
trustm_current_correlation_id()____
Solution
- Free. Reads a variable; the default value after reset is
0xE0E8. - Holds the gate. Getting
truemeans you must calloptiga_manager_unlock(). - A chip transaction, and it must happen while you hold the gate (lesson 2.2).
- Irreversible. That slot’s LcsO advances to operational; never do this in this course.
- Irreversible. The counter only goes up; the slot’s lock, however, can still be reversed if LcsO is below
op. - Free. NULL means no request is outstanding.
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.
-
Which of these is not a function the OPTIGA™ Trust M provides to the board’s SDK? (objective 1)
- a) Generating random numbers with the TRNG
- b) Making an ECDSA signature with a key inside the chip
- c) Encrypting the image on the LCD screen
- d) Storing a private key generated inside the chip
Solution
c. Drawing to the screen is CM55’s job; the secure element has nothing to do with it.
-
Which function does
ref_hsm.csay is not a free read? (objective 2)- a)
trustm_requested_target_oid() - b)
trustm_current_correlation_id() - c)
optiga_manager_lock() - d)
trustm_requested_anchor_oid()
Solution
c. It holds the chip’s access gate —
truemust be returned, and afalseresult may just mean you have already waited ten seconds. - a)
-
A development board has tag
C0of slot0xE0E1reading01, andD0reading21 E0 E8. Which statement is correct? (objective 3)- a) This slot is permanently locked; there is no way to write it normally ever again
- b) This slot accepts only a manifest verified with
0xE0E8, but the lock can still be cleared because LcsO is still below op - c) The chip is broken
- d) This slot can be written normally, as usual
Solution
b. The Protected Update lock is a condition in metadata, not a fuse. As long as LcsO is still at creation, writing metadata is still possible.
-
Why does this course never have you write tag
C0? (objective 3)- a) Because the chip does not support it
- b) Because LcsO travels one way only, no reflash can bring it back, and once it reaches op, writing metadata can stop permanently
- c) Because it requires a password from Infineon
- d) Because it would break WiFi
Solution
b. The result is a board that can no longer be used for learning, with no way to recover it. The SDK’s example 06 sets the principle that this job should live in a separate, clearly named tool.
Read HSM state without starting anything at all. Write down every line you get in your learning log.
- Build the template with the examples enabled, and select
ref_hsmto run on CM33_NS (the example’s id is in thesdk_examples_cm33_table.ctable).Then unplug the USB cable, count to ten, plug it back in, and open a serial terminal on the KitProg port.Terminal window make build ENABLE_PAGE_EXAMPLES=1 SDK_EXAMPLE_CM33=cm33/security/ref_hsmmake program BENTO_WORKSPACE="$(cd .. && pwd)" - Guess before you look at the result: what values will
trustm_requested_target_oid()andtrustm_requested_anchor_oid()return (read the comments in the file), and willoptiga_manager_lock()returntrueorfalse? - The example runner waits three seconds after boot, prints the full list of examples, then runs the one you selected. The source says the output looks like this:
Compare it against your guess. If--- tesaiot_hsm/ref_tesaiot_hsm (reference list) ---trustm_requested_target_oid() = 0x....trustm_requested_anchor_oid() = 0x....trustm_current_correlation_id()= ...optiga_manager_lock() = ...
optiga_manager_lock()returnsfalse, explain which of the two cases it is, and how you know. - Rebuild with
SDK_EXAMPLE_CM33=cm33/security/03_chip_ownership. This example callsoptiga_manager_init()first, then holds the gate. See how theoptiga_manager_lock()line changes, and explain it using reason 3 from the worked example. - Write a two-column table, “what this example can tell us” and “what it cannot tell us,” with at least two items on each side.
Forbidden in this lab: do not enable EXAMPLE_HSM_REQUEST_PU and EXAMPLE_HSM_ISOLATED_TEST in example 06, and do not write any metadata at all.
If you want to see a different reference project, look at PSoC Edge E84 + OPTIGA Trust M: TESAIoT MQTT Client on the Developer Hub.
It is menu-driven firmware with a menu to read the UID and the factory certificate, and a menu to read metadata. This project ships with the PSOC™ Edge E84 Evaluation Kit’s BSP (APP_KIT_PSE84_EVAL_EPC2)
and is under the Cypress (Infineon) EULA, so this course references it by link only and does not copy its code.
Going further
Section titled “Going further”We have already seen that just asking “is the chip free?” means acquiring the gate and returning it. The next lesson goes deeper on that gate: why it has three names, why touch must be kept off the bus, and what kind of work must never happen inside the task that draws the screen.
Next lesson: Lesson 2.2: Rules for accessing the chip
Reflect
Section titled “Reflect”- In your own project, which commands are irreversible once run, and are any of them hidden inside an example that anyone could just click to run?
- If you had to write an HSM status screen, which values from this example would you use, and which calls would you avoid making from the screen-draw loop?
- Has a
falsevalue with two possible meanings ever led you to fix the wrong thing in another piece of work?
References
Section titled “References”- Infineon optiga-trust-m (host library, MIT) @ release-v5.8.3, and the version the SDK uses @ release-v5.3.0
- Infineon optiga-trust-m-overview (MIT)
- SDK: tesaiot_hsm docs
- SDK: cm33/security/ref_hsm.c (reading state without starting a transaction)
- SDK: cm33/security/06_protected_update.c (what cannot be undone)
- SDK: CM33-side examples (what you need to know about LcsO state)
- SDK: tesaiot_config.h (TESAIoT’s OID map)
- D2 — Enrolment and Protected Update end to end (SDK docs built from commit ef72c1b)
- Example on the Developer Hub: PSoC Edge E84 + OPTIGA Trust M: TESAIoT MQTT Client (Cypress EULA, link only)
Review questions
Answer on your own first, then open the answer.
-
Which of these is not a job OPTIGA™ Trust M does for the board's SDK? (Objective 1)
- สร้างเลขสุ่มด้วย TRNG
- ลงลายเซ็น ECDSA ด้วยกุญแจที่อยู่ในชิป
- เข้ารหัสภาพบนจอ LCD
- เก็บกุญแจลับที่สร้างขึ้นในชิป
Show answer
Answer: C. เข้ารหัสภาพบนจอ LCD
การวาดจอเป็นงานของ CM55 ชิปความปลอดภัยไม่เกี่ยว
-
Select every Infineon host-library function that performs a cryptographic operation inside the chip. (Objective 1)
- optiga_crypt_ecdsa_sign
- optiga_crypt_random
- optiga_crypt_ecc_generate_keypair
- printf
Show answer
Answer: A. optiga_crypt_ecdsa_sign · B. optiga_crypt_random · C. optiga_crypt_ecc_generate_keypair
สามตัวแรกอยู่ใน optiga_crypt.h ลงนาม สุ่มเลข และสร้างคู่กุญแจในชิป printf เป็นฟังก์ชันของ C library
-
According to ref_hsm.c, which call is not a free read? (Objective 2)
- trustm_requested_target_oid()
- trustm_current_correlation_id()
- optiga_manager_lock()
- trustm_requested_anchor_oid()
Show answer
Answer: C. optiga_manager_lock()
optiga_manager_lock() ถือประตูเข้าชิป ได้ true ต้องคืนด้วย optiga_manager_unlock() และได้ false อาจแปลว่าเพิ่งรอครบสิบวินาที
-
What does a false return from optiga_manager_lock() in ref_hsm.c mean? (Objective 2)
- ชิปเสีย
- ยังไม่มีใครเรียก optiga_manager_init() หรือมี task อื่นถือชิปอยู่ครบสิบวินาที และค่าที่คืนแยกสองกรณีนี้ไม่ได้
- LcsO เดินไป operational แล้ว
- ไม่มีใบรับรองในช่อง 0xE0E1
Show answer
Answer: B. ยังไม่มีใครเรียก optiga_manager_init() หรือมี task อื่นถือชิปอยู่ครบสิบวินาที และค่าที่คืนแยกสองกรณีนี้ไม่ได้
คอมเมนต์ในตัวอย่างบอกว่าสองกรณีนี้เป็นปัญหาต่างกัน ถ้าต้องแยก โค้ดของคุณต้องจำเองว่าเรียก init แล้วหรือยัง
-
Why does this course never ask you to write metadata tag C0? (Objective 3)
- เพราะชิปไม่รองรับ
- เพราะ LcsO เดินทางเดียว ไม่มี reflash ใดพากลับได้ และเมื่อถึง op การเขียน metadata จะหยุดถาวร
- เพราะต้องใช้รหัสผ่านจาก Infineon
- เพราะจะทำให้ WiFi ใช้ไม่ได้
Show answer
Answer: B. เพราะ LcsO เดินทางเดียว ไม่มี reflash ใดพากลับได้ และเมื่อถึง op การเขียน metadata จะหยุดถาวร
ผลคือบอร์ดที่ใช้เรียนต่อไม่ได้และไม่มีทางกู้ ตัวอย่าง 06 ของ SDK ให้หลักว่างานนี้ควรอยู่ในเครื่องมือแยกที่ตั้งชื่อชัด
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.
"What a secure element does for us" 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: "ชิปความปลอดภัยทำอะไรให้เรา" จาก 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