This repository contains a proof-of-concept Trusted Application for authentication using a Physical Unclonable Function (PUF) combined with zero-knowledge proofs.
The application's trust model is backed by the CROSSCON Hypervisor, which provides isolation and integrity. A subset of the GlobalPlatform Core and Client APIs has been implemented to enable structured communication and improve portability.
Note: This app uses Zephyr RTOS and not a full-featured TEE like OP-TEE/MTower. At the time of starting this project no TEE was available for the platform.
For more theoretical background and a basis for this work take a look at
L. Petzi, A. Dmitrienko, and I. Visconti, "PUF-Based Authentication in IoT Against Strong Physical Adversary Using Zero-Knowledge Proofs," 2024 IEEE Security and Privacy Workshops (SPW), San Francisco, CA, USA, 2024, pp. 312–319. doi: 10.1109/SPW63631.2024.10918871
The application can be used as a standalone demo via the
lpcxpresso55s69/lpc55s69/cpu0 target when building with
west.
However, it is primarily intended to be run as part of
crosscon/UC1.1-Manifest.
Has to be called before other functions. Initializes PUF hardware and neccessary
ECC variables as well as returns
Internally produces responses
Additional hashing with TA UUID serves as a PoC of identity scoping that could happen in a true multi-tenant TEE. This mitigates the risk of some TA compromising platform via misuse or exfiltration of the physically unique secret.
Multiple
It's crucial that
Once the device is enrolled, it can use this function to authenticate itself to other
devices. The process is initiated by the verifier, which sends
challenges
Two random values
This is used to create a hash
Two zero-knowledge proofs are calculated, denoted as
These along with saved PUF_TA_verify_ZK_proofs or the
example scripts from scripts/proofs.
For more info on how to proof/authenticate take a look at scripts/proofs/README.md
This function is provided as a PoC of device-to-device authentication. It allows for two devices running the TA to authenticate each other as the second factor.
To verify device the following equation must hold true
The function takes values generated by prover and returns TEE_SUCCESS if the equation holds.
For the security model this function doesn't have to run in the secure world but is provided for clarity.
The struct with all necessary values needs to be provided in a specific order as a memory reference due to nature of TEE communication.
typedef struct {
uint8_t g_x[32];
uint8_t g_y[32];
uint8_t h_x[32];
uint8_t h_y[32];
uint8_t COM_x[32];
uint8_t COM_y[32];
uint8_t P_x[32];
uint8_t P_y[32];
uint8_t v[64];
uint8_t w[64];
uint8_t n[64];
} zk_proofs_mem_struct;The app uses a subset of Global Platform Client API for communication.
An example of client-side communication can be seen at GUEST_VM0 branch.
TA UUID - 0x00112233445566778899AABBCCDDEEFF
| Handler | Function ID | Parameter 1 (atrr/b) |
Parameter 2 (atrr/b) |
Parameter 3 (atrr/b) |
Parameter 4 (atrr/b) |
|---|---|---|---|---|---|
PUF_TA_init |
0x00112233 |
TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT / 32 bytes) |
TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT / 32 bytes) |
TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT / 32 bytes) |
TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT / 32 bytes) |
PUF_TA_get_commitment |
0x11223344 |
TEE_PARAM_ATTR_TYPE_MEMREF_INPUT / 32 bytes) |
TEE_PARAM_ATTR_TYPE_MEMREF_INPUT / 32 bytes) |
TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT / 32 bytes) |
TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT / 32 bytes) |
PUF_TA_get_ZK_proofs |
0x22334455 |
TEE_PARAM_ATTR_TYPE_MEMREF_INOUT / 32 bytes) |
TEE_PARAM_ATTR_TYPE_MEMREF_INOUT / 32 bytes) |
TEE_PARAM_ATTR_TYPE_MEMREF_INOUT / 64 bytes) |
TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT / 64 bytes) |
PUF_TA_verify_ZK_proofs |
0x33445566 |
zk_proofs_mem_struct (TEE_PARAM_ATTR_TYPE_MEMREF_INPUT / 448 bytes) |
- (TEE_PARAM_ATTR_TYPE_NONE / 0 bytes) |
- (TEE_PARAM_ATTR_TYPE_NONE / 0 bytes) |
- (TEE_PARAM_ATTR_TYPE_NONE / 0 bytes) |
This app implements a subset of Global Platform Core API for potential modularity portability of the authentication scheme. This is aligned with the TRL 3/4 research nature of the project and is not intended as full GP compliance.
| Category | GP Feature/API | Status |
|---|---|---|
| BigInt Arithmetic | TEE_BigInt* ops (Alloc, Add, Mul, Mod, Convert) |
Implemented |
TEE_BigIntSub, ExpMod, etc. |
Not Implemented | |
| Digest / Hashing | TEE_Digest* (SHA-256) |
Implemented |
| Other hash functions (SHA-1, MD5, SM3) | Not Implemented | |
| Symmetric Crypto | AES, 3DES, SM4, Cipher API | Not Implemented |
| MAC / HMAC | HMAC, CMAC APIs | Not Implemented |
| Asymmetric Crypto | RSA, DSA, DH | Not Implemented |
EC arithmetic (TEE_ECPoint, TEE_ECCurve) |
Custom Helper Types Only | |
| Key Management | TEE_AllocateTransientObject, TEE_SetOperationKey |
Not Implemented |
| Randomness | TEE_GenerateRandom |
Implemented |
| Time Functions | TEE_GetSystemTime, TEE_Wait |
Not Implemented |
| Session Management | TA_OpenSessionEntryPoint, etc. |
Partial |
| Error Codes | TEE_Result, TEE_ORIGIN_*, TEE_ERROR_* |
Implemented |
| Object APIs | Persistent objects, secure storage | Not Implemented |
mbectls_ecp_point.
To reconstruct the MbedTLS compatible byte sequence a byte with value 0x04
needs to be prepended. The final structure thus should look like 0x04||X||Y.
See LICENSE file.
The work presented in this repository is part of the CROSSCON project that received funding from the European Union’s Horizon Europe research and innovation programme under grant agreement No 101070537.



