Skip to main content
On an edge device, we still face an issue when the model is loaded: the plaintext weights live in process memory and can be dumped by anything with sufficient privilege (/proc/pid/mem, ptrace, /dev/mem). Linux memory protection closes that gap by keeping decryption inside ARM TrustZone and gating access to the decrypted buffer on a per-binary signature check.

How it works

Three components cooperate on the device: To leverage this, we use an ARM TrustZone OP-TEE application that will be used to decrypt the binary file that will be useful to the main application (typically an AI model). Once decrypted, payload will be written in a memory slot that will be safeguarded by a kernel module. This module will verify that the application (typically an inference software) will be approved to access this memory space.

Data flow

model.enc  ─►  loader  ─►  TA (secure world, AES-256-CTR)
                             v
                             v
                   /dev/secure-mem  ◄── mmap(PROT_READ, signed app only)
                   (kernel buffer)          v
                                            v
                                      inference engine

Hypothetical usage

From the inference application’s perspective, the secure buffer looks like an ordinary file:
let file = fs::File::open("/dev/secure-mem")?;
let mmap = unsafe { Mmap::map(&file)? };
let model = load_model(&mmap[..])?;
The hardening only holds if the surrounding platform is locked down: kernel_lockdown=confidentiality, yama.ptrace_scope=3, forced module signing, secure boot, and dm-verity. Without these, a privileged attacker can bypass the signature gate entirely.

Security properties

  • Model ciphertext at rest
  • Decryption key in OP-TEE secure storage
  • Plaintext never materializes in the loader process
  • Read access to plaintext limited to binaries carrying a valid signature