Source-linked AI summary
C-FLAT: Control-FLow ATtestation for Embedded Systems Software
Tigist Abera, N. Asokan, Lucas Davi, Jan-Erik Ekberg, Thomas Nyman, Andrew Paverd, Ahmad-Reza Sadeghi, Gene Tsudik
TL;DR
Precise verification of embedded applications’ control flow remains unavailable despite memory-corruption risks; C-FLAT attests execution paths at binary level, complementing static attestation. Its Raspberry Pi prototype detects runtime exploitation that manipulates liquid dispensed by a syringe pump.
Problem
No mechanism yet allows precise verification of embedded applications’ control flow to detect memory-corruption attacks.
Source: §10 · p. 11Method
C-FLAT measures an embedded application’s execution path at the binary level, capturing runtime behavior alongside static attestation.
Source: §1 · p. 2Results
On an ARM-based Raspberry Pi, C-FLAT detected runtime exploitation against syringe-pump software, including attacker manipulation of the amount of liquid dispensed.
Source: §10 · pp. 11–12Takeaways & Limitations
The work advances runtime attestation for embedded software by providing precise execution-path verification alongside static attestation.
Source: §1 · p. 2C-FLAT does not cover pure data-oriented attacks that alter memory loads or stores without inducing unintended control flows.
Source: §2 · p. 3
Abstract
from arXiv · showhide
Remote attestation is a crucial security service particularly relevant to increasingly popular IoT (and other embedded) devices. It allows a trusted party (verifier) to learn the state of a remote, and potentially malware-infected, device (prover). Most existing approaches are static in nature and only check whether benign software is initially loaded on the prover. However, they are vulnerable to run-time attacks that hijack the application's control or data flow, e.g., via return-oriented programming or data-oriented exploits. As a concrete step towards more comprehensive run-time remote attestation, we present the design and implementation of Control- FLow ATtestation (C-FLAT) that enables remote attestation of an application's control-flow path, without requiring the source code. We describe a full prototype implementation of C-FLAT on Raspberry Pi using its ARM TrustZone hardware security extensions. We evaluate C-FLAT's performance using a real-world embedded (cyber-physical) application, and demonstrate its efficacy against control-flow hijacking attacks.
1. INTRODUCTION
C-FLAT complements static attestation by reporting an embedded application’s exact binary-level control-flow path, addressing runtime attacks that binary measurements can miss.
Goals and Contributions
- Static attestation measures binaries rather than execution, so control-flow hijacks can leave hashes unchanged; reporting only whether an attack occurred also misses unauthorized paths enabled by data-oriented exploits.Such exploits can corrupt variables, such as authentication state, to reach a valid but unauthorized privileged path.Source: §1 · pp. 1–2
- C-FLAT aggregates an authenticator over the exact executed instruction sequence, including branches and returns, so a verifier can trace the path and detect compromised execution.Combined with static attestation, it enables precise attestation of embedded software execution.Source: §1 · p. 2
- The proof of concept targets single-threaded programs on small IoT microcontrollers and is not intended for arbitrary complex applications.The implementation uses ARM TrustZone-A, while the authors point to TrustZone-M as a route to commercial microcontroller deployments.Source: §1 · p. 2
- The prototype combines static analysis of valid control flows, ARM binary instrumentation, and a TrustZone trusted service that monitors runtime control flow and generates attestation responses.The design addresses path-attestation challenges including loops and matching calls with returns.Source: §1 · p. 2
- The paper systematically evaluates C-FLAT on the Open Syringe Pump embedded control application and demonstrates resilience against runtime attacks.The syringe pump represents a widely used class of cyber-physical systems.Source: §1 · p. 2
2. PROBLEM SETTING
Runtime attacks exploit vulnerabilities to cause unauthorized actions, often by manipulating control-flow information or data that determines execution. C-FLAT focuses on control-flow-related attacks and excludes pure data-oriented attacks that leave control flow unchanged.
- Runtime attacks commonly exploit buffer overflows to corrupt adjacent memory and manipulate control-flow information stored on the program’s stack or heap.Source: §2 · p. 2
- Overwritten code pointers can redirect execution to injected code or existing code, including code-reuse sequences that enable malicious actions and undermine DEP.Source: §2 · p. 2, Figure 1 · p. 2
- CFI and CPI do not prevent non-control-data attacks, which can change auth and route execution into a privileged path without authentication.Source: §2 · pp. 2–3, Figure 1 · p. 2
- C-FLAT covers attacks that manipulate control-flow information or non-control data, but excludes pure DOP attacks that alter memory operations without changing program flow.Source: §2 · p. 3
3. SYSTEM MODEL
C-FLAT lets a verifier attest an embedded application's runtime control flow using application binaries and a trusted measurement engine. The model relies on verifier-side preprocessing and a prover with an isolated trust anchor, under a threat model that excludes physical attacks.
3. SYSTEM MODEL
- The verifier attests a program or function on a remote embedded prover, and both parties are assumed to have the application's binaries.The verifier's goal is to attest the module's runtime control flows.Source: §3 · p. 3
3.1 Overview
- The verifier builds the module's control-flow graph, measures each possible path with H, and stores the results in a database, a one-time task the resource-limited prover cannot perform.The verifier is assumed to have no such resource limitations.Source: §3.1 · p. 3
- The verifier challenges the prover with a module name and nonce; a trusted Measurement Engine accumulates a path authenticator, and the prover returns a signed report over the challenge and authenticator.The report is signed using a key known only to the Measurement Engine.Source: §3.1 · p. 3
- Any deviation from legitimate control flow yields an unrecognized measurement, while non-control-data attacks can yield unexpected but valid measurements; static attestation confirms the intended application is running.Together, these checks let the verifier detect runtime attacks, including attacks within the application's valid control-flow graph.Source: §3.1 · p. 3
3.2 Requirements and Adversarial Model
- The adversary may introduce arbitrary malware and exploit public interfaces to hijack execution, but physical attacks are excluded.The focus is on attacks that hijack the execution path of the code being attested.Source: §3.2 · p. 3
- The prover is assumed to enforce DEP and provide an isolated measurement engine and fresh authenticated reports; reports must resist replay and masquerading.The measurement engine cannot be disabled or modified by non-physical means.Source: §3.2 · p. 3
4. C-FLAT DESIGN
C-FLAT attests runtime control-flow paths by cumulatively hashing executed transitions, enabling a verifier to check the path without recording every instruction or branch. Its design handles loops, loop exits, recursion, and call-return matching so that path measurements remain distinguishable and verifiable.
4.1 C-FLAT: High-Level Description
- C-FLAT builds a cumulative hash chain of executed control-flow transitions; an unexpected measurement signals an illegal path and can reveal whether a privileged path ran.The verifier checks application paths at branch-level granularity, including direct and indirect branches, calls, and returns.Source: §4 · pp. 3–4, §4.1 · p. 4
- C-FLAT uses BLAKE-24 for cumulative hashing and signs the verifier’s challenge and the resulting Auth measurement with a key protected by the trust anchor.A MAC is also possible; the paper uses signatures without loss of generality.Source: §4.1 · p. 4
4.2 Challenges
- Loops are measured as separate sub-programs, with their path measurements and iteration counts reported in Auth and counters separated by the pre-loop measurement.The loop’s prior cumulative value is retained for computation at exit; tracking counts per distinct path ensures each iteration is attested, though Auth grows with the number of loop paths.Source: §4.2 · pp. 4–5
- Separate measurement chains support nested loops and recursion, while call-return matching distinguishes loop instances and handles calls within loop bodies.Matching identifies when execution leaves a loop’s routine context, avoiding treating a subroutine located after the loop in memory as its exit.Source: §4.2 · p. 5
- Break and loop-terminating goto statements are treated as special exits, recording the pre-loop hash and the node that terminated the loop.Source: §4.2 · p. 5
- Indexing corresponding call and return edges lets the verifier reject mismatched returns that could otherwise permit an unintended control-flow path.For the example with two calls to one subroutine, the indices restrict legal Auth values to the measurements corresponding to matched call-return pairs.Source: §4.2 · p. 5
5. IMPLEMENTATION
C-FLAT’s prototype combines binary analysis and rewriting with a trusted runtime measurement engine to attest program control flow on Raspberry Pi 2. Its implementation relies on ARM-specific trampolines to intercept branches and forward their measurements securely.
5.1 Architecture of Proof-of-Concept
- The prototype runs on Raspberry Pi 2 using ARM TrustZone-A, with a bare-metal, single-purpose program in the Normal World.The authors chose this platform because lightweight trust anchors for small embedded devices were not commercially available; they note the approach can also apply when applications run over an embedded OS.Source: §5.1 · p. 6
- C-FLAT combines a program analyzer, Runtime Tracer, and isolated Measurement Engine; the prototype uses dynamic analysis and rewrites ARM binaries to intercept branches.The analyzer computes legal program measurements, while the tracer and engine trace and measure the runtime control-flow path.Source: §5.1 · p. 6, Figure 8 · p. 6
- Instrumentation records direct-branch and loop information in read-only tables, while cfa_init starts a trace and cfa_quote finalizes it into an attestation response.Trampolines report branch sources and destinations to the Measurement Engine, which incrementally computes cumulative Auth with BLAKE2; attestation can target a selected program operation.Source: §5.1 · p. 6
- The Measurement Engine runs as a trusted kernel in TrustZone’s Secure World, isolated from the target program and Runtime Tracer, while static attestation covers Normal World software.The engine can validate that a recorded branch destination matches the algorithm input before returning control to the trampoline, helping detect tracer tampering.Source: §5.1 · p. 6
- C-FLAT uses basic-block entry and exit addresses as node IDs, which avoids extra instrumentation but requires alternatives or reporting the base address when ASLR changes them.The authors selected this approach because many embedded systems lack an MMU and do not support ASLR.Source: §5.1 · pp. 6–7
5.2 ARM Instrumentation
- ARM rewriting redirects control-flow instructions through bl dispatches to type-specific trampolines, which recover destinations and invoke the Measurement Engine with branch addresses.Direct targets come from a read-only branch table, indirect targets from their destination registers, and returns from the saved link register or stack; non-taken conditional branches are inferred using branch information and the prior basic block. The target must not use lr as a general-purpose register, enforceable at compile time.Source: §5.2 · p. 7
6. EVALUATION
C-FLAT was evaluated on two embedded cyber-physical controllers by attesting their security-critical control flows. The evaluation reports path-identifying attestation results and measures the runtime overhead and its practical impact.
6.1 Case Study of a Cyber-Physical System
- The syringe-pump study ported Open Syringe Pump to a bare-metal Raspberry Pi implementation with less than 25% source-code changes and no change to functionality or its control-flow graph.The compiled application had 13,000 instructions and 332 static CFG edges, including 20 loops.Source: §6.1 · p. 8
6.2 Attestation Results
- Repeated executions of the same control-flow path produced the same final hash, while loop information captured quantity-dependent iterations and simplified attestation output.The syringe-pump set-quantity path had a maximum Auth length of 1527 bytes, with 16 loop invocations and 18 unique loop paths; move-syringe had 1179 bytes, 12 invocations, and 14 paths.Source: §6.2 · p. 8
6.3 Performance Impact
- Attestation overhead grew linearly with control-flow events; trampolines, context switches, and the Secure World algorithm contributed most of the measured overhead.For set-quantity, the shares were 8.3%, 11.9%, and 79.8%; for move-syringe, they were 10.2%, 17.5%, and 72.3%, respectively.Source: §6.3 · p. 8
- Attestation overhead was 1.2 s, 2.4 s, and 4.8 s for dispensing 0.5 ml, 1.0 ml, and 2.0 ml, respectively, or 0.03%–0.13% of real-world operation.The overhead percentages remained roughly constant across the syringe pump’s state-variable values.Source: §6.3 · p. 8
- Running attestation only occasionally can reduce syringe-pump overhead by 72% to 80%; time-calibrated delay loops may require recalibration, avoidable by using system timers.When source code is available, minor application changes such as shortening delay loops can also compensate for overhead.Source: §6.3 · p. 9
6.4 Second Case Study
- The second case study used a 70,000-instruction soldering-iron temperature controller with 1,020 static control-flow edges, including 40 loops.Its attested security-critical section was the PID controller, which reads current temperature, compares it with the desired temperature, and calculates output to adjust temperature.Source: §6.4 · p. 9
- 237 µs of C-FLAT overhead was added per PID-controller iteration; attesting once per second resulted in 0.03% overhead, with a maximum Auth length of 490 bytes.The overhead was averaged over 100 runs, with a standard deviation of 1 µs; the correct hash values were verified.Source: §6.4 · p. 9
7. SECURITY CONSIDERATIONS
C-FLAT uses attestation measurements to detect three practical syringe-program exploits and several runtime control-flow attacks. Its detection has limits when corrupted data enables code injection without unexpected control flow.
Security assumptions
- The security analysis assumes runtime attacks; tracer integrity relies on static attestation, measurement-engine integrity on a trust anchor, and attestation freshness on challenge-response.The trust anchor may be the TrustZone Secure World.Source: §7 · p. 9
Exploiting the syringe program
- C-FLAT detects all three syringe exploits: gadget-chain execution via hash mismatch, altered dispensing amount via loop counts, and forged keypad input via key-processing iterations.Detecting the keypad attack assumes the verifier knows the physical key was not pressed.Source: §7 · p. 9
Code Injection
- Injected nodes and reported memory-permission calls expose conventional code injection, but corrupted arguments to benign permission-changing calls evade direct control-flow detection unless injected code makes unexpected calls.Platforms enforce data execution prevention, preventing code pages from being writable and executable simultaneously; C-FLAT reports the relevant memory-modification system calls.Source: §7 · pp. 9–10
Return-oriented programming
- C-FLAT detects ROP, including JIT-ROP, through unknown control-flow edges; mid-node entry and invalid CFG edges produce mismatching or unknown hashes.For returns to valid CFG nodes that mismatch the caller context, indexed call-return edges help detect the attack; unresolved indirect calls require dynamic analysis or over-approximation.Source: §7 · p. 10
Jump-oriented programming
- C-FLAT detects jump-oriented programming when static or dynamic analysis identifies the target addresses of indirect jumps and calls.This enables valid measurements for those transfers and reveals malicious control-flow deviations.Source: §7 · p. 10
Function-reuse attacks and non-control-data attacks
- C-FLAT detects function-reuse attacks, including COOP, and non-control-data path manipulation through measurements of function order, loop iterations, and path-specific execution.Loop counts also let the verifier detect a data modification that changes the amount dispensed by the syringe pump.Source: §7 · p. 10
8. DISCUSSION
The discussion considers how C-FLAT could extend to microcontrollers and operating-system-based devices, and outlines optimizations and future work for broader instruction-set, data-flow, and program-path coverage.
Towards control-flow attestation of MCUs
- TrustZone-M and TrustLite offer hardware foundations for bringing C-FLAT to 32-bit IoT microcontrollers, where trusted-application switching can take only a few cycles.TrustZone-M uses processor-enforced protection regions and marked call gates, without a dedicated Secure Monitor context.Source: §8 · pp. 10–11
Reducing context switch overhead
- On TrustZone-A, secure-world transitions cost approximately 3700 cycles or 5µs at 800MHz; caching control-flow information before bulk transfer can improve overall performance.The Secure Monitor mediates transitions, which can be triggered only from Non-Secure privileged mode.Source: §8 · pp. 10–11
Embedded operating systems
- For devices with embedded operating systems, C-FLAT should treat the OS and application as one isolation domain and instrument them as a single bare-metal program.The prototype currently runs bare-metal; controllers often lack the contexts or memory protection needed to isolate tasks or the OS from applications.Source: §8 · p. 11
Thumb-2 instrumentation
- Ongoing work is extending C-FLAT instrumentation to support variable-length Thumb-2 instructions used by modern ARM-M microcontrollers.Thumb-2 improves code density to maximize use of on-chip Flash memory.Source: §8 · p. 11
Data-flow attestation
- Future work will explore data-flow attestation to track data pointers and validate function arguments and return values against pure data-oriented attacks.Such attacks can, for example, alter a pointer used in a network operation to reference sensitive information.Source: §8 · p. 11
Probe-based runtime attestation
- For programs with complex control-flow graphs, probe-based attestation could report cumulative hashes for segments and let verifiers check execution evolution at arbitrary intervals.Segment authenticators, such as one per subroutine, aim to avoid cumbersome validation when many paths create a combinatorial explosion of valid hash values.Source: §8 · p. 11
9. RELATED WORK
Prior work addresses static attestation, exploit mitigation, and narrower forms of runtime attestation; C-FLAT complements static attestation by attesting runtime behavior and control flow.
9. RELATED WORK
- TPM-based methods are costly for low-end embedded devices, software-based methods rely on strict assumptions, and hybrid schemes use minimal hardware trust anchors; C-FLAT complements them with runtime attestation.Hybrid schemes include SMART, TrustLite, and TyTAN; TPM-based techniques include, while software-based examples include SWATT, Pioneer, and VIPER.Source: §9 · p. 11
- CFI restricts execution to valid CFG paths but misses non-control-data attacks along valid paths; code randomization and CPI also do not reveal the control-flow path taken.Code randomization can still be bypassed through branch instructions, while CPI protects code pointers but does not cover non-control-data attacks.Source: §9 · p. 11
- Property-based, semantic, and software-based attestation do not cover control-flow attacks at the binary level, and property-based schemes typically require a trusted third party.Software-based attestation hashes application code memory and depends on timing and hash-function assumptions; semantic attestation enforces local policies at the Java bytecode layer.Source: §9 · p. 11
- Existing dynamic attestation approaches capture narrower behavior: ReDAS checks selected properties, trusted virtual containers attest module launch order, and DynIMA validates return-instruction invariants.ReDAS checks properties such as a function’s base-pointer integrity; trusted virtual containers do not attest internal control flows, and DynIMA checks instruction counts between consecutive returns.Source: §9 · p. 11
10. CONCLUSION
C-FLAT provides control-flow attestation to detect runtime control-flow deviations on embedded systems. Its ARM-based Raspberry Pi prototype detected attacks that manipulated the amount of liquid dispensed by a syringe pump.
10. CONCLUSION
- C-FLAT enables a verifier to detect control-flow deviations caused by code injection, code-reuse, or non-control-data attacks.The paper identifies the lack of a mechanism for precise application control-flow verification as the problem it addresses.Source: §10 · p. 11
- The paper frames precise verification of application control flow as an unmet need for detecting memory-corruption attacks on embedded systems used in safety-critical infrastructure.It notes that memory-corruption attacks occur across diverse computing platforms and can cause significant damage on embedded systems.Source: §10 · p. 11
- On an ARM-based Raspberry Pi, C-FLAT detected runtime exploitation techniques against embedded software, including manipulation of the amount of liquid dispensed by a syringe pump.The C-FLAT source code is available at https://goo.gl/pTiVdU.Source: §10 · pp. 11–12