Security model¶
What the SE050 and this driver protect, what they do not, how to provision keys, and how the common device security flows map onto the driver's calls.
This page is engineering guidance, not a certification argument. For a product, read NXP's use and security guidelines AN12514 and your configuration's entry in AN12436 alongside it.
What the SE050 gives you¶
- Keys that do not leave the chip.
GenerateEcKeyPair()creates the private key inside the SE050. The host can read the public key and ask for signatures; it cannot read the private key. - Signing and verification on chip.
EcdsaSign()andEcdsaVerify()take a digest you computed; the signature is ASN.1 DER. - Secure storage. Binary objects and AES keys in up to 50 kB of user flash, addressed by a 4-byte object identifier.
- A true random number generator.
GetRandom(); NIST SP800-90B TRNG and SP800-90A DRBG. - A certified environment. Common Criteria EAL 6+ for hardware and OS (datasheet); FIPS 140-2 level 3 only on specific product types.
- Bus protection. GlobalPlatform SCP03 between host and chip, which this driver implements.
What this driver does, and does not¶
The driver does:
- Transport: T=1 over I2C with CRC. APDUs are plaintext by default.
- Platform SCP03:
INITIALIZE UPDATEandEXTERNAL AUTHENTICATEat security level0x33(C-MAC, C-ENC, R-MAC, R-ENC), wrap and unwrap of short and extended APDUs, andBuildPutKey()to replace the key set. Every response inside the channel must carry a valid R-MAC; session keys are wiped onClose(), on any failure and when the object is destroyed. - Keys: EC key generation on NIST curves, AES key write, ECDSA sign and verify, AES-ECB, and RFC 3394 unwrap through the chip.
- No key material in the code:
OpenSecureChannel()returnsError::NotSupportedwhen you pass no keys.
It does not do (today):
- Making SCP03 mandatory on the chip (
SetPlatformSCPRequest). - Applet sessions authenticated by UserID, AESKey or ECKey, or object policies.
- RSA, ECDH, attested reads, certificate handling.
The commands go to the applet in plaintext unless you open an SCP03 channel. On a board where nobody can reach the I2C lines that may be acceptable; on most products it is not.
Threats and what stops them¶
- Read the MCU's firmware. No SE050 private key is in it. Any SCP03 host keys stored on the MCU are exposed: protect them with flash encryption.
- Listen on I2C. Without SCP03 the attacker sees every APDU and response: public keys, signatures, the data you write or read, AES keys you write. With SCP03 open, only encrypted, MACed APDUs.
- Inject or change I2C traffic. Without SCP03 the attacker can forge any response, including "signature
valid" from
EcdsaVerify()and the data ofReadObject(). With SCP03 open, a response that is tampered with, replayed from an earlier command, or sent without its R-MAC (a bare90 00) returnsError::Authenticationand closes the channel. - Move the SE050 to another board. Without SCP03 its keys work there: they are not bound to your MCU. With SCP03 made mandatory on the chip (by a provisioning tool; the driver cannot set it), the attacker needs your host keys too.
- Attack the SE050 itself to extract keys. Out of the driver's scope: that is what the chip's certification covers.
Status words without an R-MAC end the channel
Inside the channel the driver accepts no response without a verified R-MAC, including the status-only answers
of WriteBinary(), DeleteSecureObject(), GenerateEcKeyPair() and WriteAesKey(). An error status the
SE050 sends without a MAC (for example 69 82 after it rejected a C-MAC) therefore also returns
Error::Authentication: the SE050 has dropped the session too, so open a new one.
Verify firmware-update signatures on the MCU, with a public key in its protected storage, rather than trusting
EcdsaVerify() over a plaintext bus.
Provision keys¶
Platform SCP03 keys¶
Each SE050 configuration leaves the factory with a platform SCP03 key set (ENC, MAC, DEK) that is the same for every part of that configuration, and NXP documents it in AN12436. Treat those keys as public. In provisioning:
- Open an SCP03 channel with the configuration's factory keys, read from your provisioning tool, never from the firmware source.
SelectCardManager(), then sendscp03::BuildPutKey()with new keys for key version0x0B: unique per device, or at least per batch, generated by your provisioning station.- Check the response against the key check values
BuildPutKey()returns. - Store the new ENC and MAC keys on the MCU in protected storage (on ESP32: flash encryption and encrypted NVS, or keys derived from an eFuse-protected secret). Store the DEK only where you will rotate keys again.
- Record the device and key version in your backend; destroy the station's copy when policy allows.
At run time the firmware loads the keys, opens the channel and wipes its copies; the API guide has the code. The driver never contains key bytes, and its tests use only published test vectors (RFC 3394). Do not paste real keys into issues, logs or examples.
Device identity¶
- Choose an object identifier for the identity key. The applet reserves some identifiers for its own authentication objects (AN12413, section 3.2.5) and trust-provisioned configurations add their own objects: check your configuration before you pick one.
CheckObjectExists(); if it does not exist,GenerateEcKeyPair(id, EcCurve::NistP256).ReadPublicEcKey()and send the public key to your backend, with a signature over a backend challenge so the backend knows the key is live (EcdsaSign()).- The backend binds the public key to the device's serial number, or issues a certificate for it; write the
certificate back with
WriteBinary()if the device must present it.
Some SE050 configurations carry NXP trust-provisioned attestation keys and certificates (AN12436). The driver has no attested-read command; use backend registration as above, or add the command from AN12413.
Reserved objects¶
The applet's reserved authentication objects (transport lock, factory reset, platform SCP requirement and others) are described in AN12413, section 3.2.5. The driver does not use them. Leave them alone unless your provisioning procedure needs them.
Protect the bus with SCP03¶
sequenceDiagram
participant H as Host (driver)
participant S as SE050
H->>S: INITIALIZE UPDATE (key version 0B, host challenge)
S-->>H: card challenge, card cryptogram
Note over H: derive session keys, check card cryptogram
H->>S: EXTERNAL AUTHENTICATE (level 33, C-MAC)
S-->>H: 90 00
H->>S: wrapped APDU: C-ENC data, C-MAC
S-->>H: R-ENC data, R-MAC, SW
- The host challenge must be fresh random bytes for every channel; take them from the MCU's TRNG (or from the
SE050's
GetRandom()before the channel opens, accepting that those bytes crossed the bus in plaintext). - Bind the wrap buffer once with
BindScp03WrapScratch(): at leastscp03::kWrapScratchBytes(320 bytes) for short commands,scp03::kWrapScratchBytesExtendedfor commands with more than 255 bytes of data, which go out in extended form. A command's Le is kept (as00, the protected answer being longer than the plain one). - Erratum JOS.2: the SE050 does not advance its encryption counter for a command without command data. The driver
applies NXP's workaround (errata sheet 3.13.3): every command carries encrypted data, a command without data
one encrypted padding block, so
GetVersion()works inside the channel. - A response without a valid R-MAC (missing, short, tampered or replayed), or a T=1 failure inside the channel,
closes the channel and wipes its keys. The failing call returns
Error::Authentication(or the T=1 error), and so does every later command, without touching the bus, until you callScp03().Close()(back to plaintext) or open a new channel: the driver never falls back to plaintext on its own.Scp03().Failed()tells you this happened. Treat it as an attack or a wiring fault, not as a retry case. - MACs and cryptograms are compared in constant time.
Close()and the destructor wipe the session keys, MAC chaining value and counter withscp03::crypto::SecureZero(), which the compiler cannot optimise away. Wipe your copies of the static keys afterOpenSecureChannel()returns.
Deployment flows¶
TLS with an SE050-held identity¶
For Ethernet or Wi-Fi, use TLS (TCP) or DTLS (UDP) with the device key in the SE050 as the client identity, and
verify the server: reject invalid or expired certificates, pin the service identity, never disable verification
in development builds. The private-key operation of the handshake goes to EcdsaSign(); the
se050_aws_iot_lifecycle example plugs it into mbedTLS.
sequenceDiagram
participant D as Device
participant B as Server
D->>B: ClientHello
B-->>D: certificate, CertificateRequest
D->>D: verify server certificate
D->>D: EcdsaSign(handshake hash) in SE050
D->>B: certificate, CertificateVerify
B-->>D: Finished
Firmware updates¶
- Sign the image or its manifest offline, with a key that never touches the device.
- The device downloads over TLS, verifies the signature before installing and refuses a lower version (anti-rollback), then boots only a verified image.
- Keep the vendor public key where an attacker cannot replace it. Written once into the SE050 at provisioning, it is protected against replacement; verify on the MCU when the bus is plaintext, or on the SE050 only inside an SCP03 channel.
Messages without TLS¶
When a link cannot carry TLS (CAN, UART, raw radio), sign or encrypt each message yourself:
| Need | Do |
|---|---|
| Authenticity and integrity | Sign counter ‖ nonce ‖ payload with the SE050 key (EcdsaSign()), or use AES-GCM with a shared key |
| Confidentiality | AES-GCM or ChaCha20-Poly1305, with routing data and the counter as additional data |
| Freshness | A counter per sender, and a replay window at the receiver |
| Never | Reuse a nonce with the same key; accept a message whose tag or signature fails; use ECB or unauthenticated CBC |
The se050_secure_board_comms_example example shows the signed variant between two boards.
Production checklist¶
- Factory SCP03 keys replaced; host keys in protected storage; SCP03 open before any sensitive command.
- Identity key generated on chip, public key registered; no private key ever exported.
- Every message and update bound to freshness (counter, nonce or version).
- Key rotation and revocation handled by the backend.
- Security events logged: failed signature, R-MAC failure, rollback attempt, stale counter.
- Debug builds cannot skip certificate or signature checks.
- One owner task per SE050 (erratum I2C.1); ENA wired so the host can power-cycle the chip after its own reset.