|
| 1 | +# DICE Attestation |
| 2 | + |
| 3 | +This document describes the DICE-based PSA attestation service in wolfBoot, |
| 4 | +including the token format, keying options, and how to access the service from |
| 5 | +non-secure code. |
| 6 | + |
| 7 | +## Protocol overview |
| 8 | + |
| 9 | +wolfBoot implements the PSA Certified Attestation API and emits a |
| 10 | +COSE_Sign1-wrapped EAT token following the PSA Attestation Token profile. |
| 11 | +The minimum claim set includes: |
| 12 | + |
| 13 | +- Nonce binding (challenge). |
| 14 | +- Device identity (UEID). |
| 15 | +- Implementation ID and lifecycle when available. |
| 16 | +- Measured boot components for wolfBoot and the boot image. |
| 17 | + |
| 18 | +The attestation token is produced by the secure world service and signed with |
| 19 | +an attestation key derived by DICE or supplied as a provisioned IAK. |
| 20 | + |
| 21 | +## Implementation summary |
| 22 | + |
| 23 | +The implementation lives under `src/dice/` and is shared across targets. The |
| 24 | +service is invoked through the PSA Initial Attestation API and builds the |
| 25 | +COSE_Sign1 token using a minimal CBOR encoder. |
| 26 | + |
| 27 | +- Claim construction and COSE_Sign1 encoding: `src/dice/dice.c`. |
| 28 | +- PSA Initial Attestation service dispatch: `src/arm_tee_psa_ipc.c`. |
| 29 | +- NSC wrappers for the PSA Initial Attestation API: `zephyr/src/arm_tee_attest_api.c`. |
| 30 | + |
| 31 | +Measured boot claims reuse the image hashing pipeline already used by |
| 32 | +wolfBoot to validate images. Component claims include a measurement type, |
| 33 | +measurement value, and a description string. |
| 34 | + |
| 35 | +## Keying model |
| 36 | + |
| 37 | +wolfBoot supports two keying modes selected at build time. |
| 38 | + |
| 39 | +### DICE derived key (default for no provisioning) |
| 40 | + |
| 41 | +- UDS/HUK-derived secret is fetched via `hal_uds_derive_key()`. |
| 42 | +- CDI and signing key material are derived deterministically using HKDF. |
| 43 | +- The attestation keypair is derived deterministically and used to sign the |
| 44 | + COSE_Sign1 payload. |
| 45 | + |
| 46 | +This path requires no external provisioning and binds the attestation key to |
| 47 | +UDS plus measured boot material. |
| 48 | + |
| 49 | +### Provisioned IAK |
| 50 | + |
| 51 | +If a platform already provisions an Initial Attestation Key (IAK), wolfBoot |
| 52 | +can use it directly to sign the token. |
| 53 | + |
| 54 | +The attestation service calls `hal_attestation_get_iak_private_key()` to |
| 55 | +retrieve the private key material from secure storage (or a manufacturer |
| 56 | +injection flow). The IAK is used instead of the DICE derived key. |
| 57 | + |
| 58 | +## HAL integration (per-target) |
| 59 | + |
| 60 | +These HAL hooks are optional and have weak stubs for non-TZ boards. Target |
| 61 | +families must implement the appropriate subset based on hardware support. |
| 62 | + |
| 63 | +- `hal_uds_derive_key(uint8_t *out, size_t out_len)` |
| 64 | + - Returns a device-unique secret (UDS/HUK-derived) for DICE key derivation. |
| 65 | +- `hal_attestation_get_ueid(uint8_t *buf, size_t *len)` |
| 66 | + - Returns a stable UEID. If unavailable, the UEID is derived from UDS. |
| 67 | +- `hal_attestation_get_implementation_id(uint8_t *buf, size_t *len)` |
| 68 | + - Optional implementation ID for the token. |
| 69 | +- `hal_attestation_get_lifecycle(uint32_t *lifecycle)` |
| 70 | + - Optional lifecycle state for the token. |
| 71 | +- `hal_attestation_get_iak_private_key(uint8_t *buf, size_t *len)` |
| 72 | + - Optional provisioned IAK private key (used in IAK mode only). |
| 73 | + |
| 74 | +## NSC access (non-secure API) |
| 75 | + |
| 76 | +The non-secure application calls the PSA Initial Attestation API wrappers: |
| 77 | + |
| 78 | +- `psa_initial_attest_get_token_size()` |
| 79 | +- `psa_initial_attest_get_token()` |
| 80 | + |
| 81 | +These are provided in `zephyr/include/psa/initial_attestation.h` and are |
| 82 | +implemented as NSC calls in `zephyr/src/arm_tee_attest_api.c`. |
| 83 | + |
| 84 | +When `WOLFBOOT_TZ_PSA=1`, the NS application can also use PSA Crypto through |
| 85 | +`zephyr/include/psa/crypto.h` via the NSC dispatch path |
| 86 | +(`zephyr/src/arm_tee_crypto_api.c`). PSA Protected Storage uses |
| 87 | +`zephyr/include/psa/protected_storage.h` in the same fashion. |
| 88 | + |
| 89 | +## Test application |
| 90 | + |
| 91 | +The STM32H5 TrustZone test application in `test-app/` exercises PSA crypto, |
| 92 | +attestation, and store access. It requests a token at boot and can perform |
| 93 | +PSA crypto operations from the non-secure side. |
| 94 | + |
| 95 | +See `docs/Targets.md` for the STM32H5 TrustZone scenarios and how to enable |
| 96 | +PSA mode. |
0 commit comments