Data has been likened to commodities such as oil or gold. In this connected world, more and more quality data is going to empower the smart decision-making process of machines deployed in a factory or various gadgets deployed in our houses. But there is a big challenge ahead — how can quality and trusted data be securely delivered in a scalable and automated way? Industry leaders for low-end embedded devices are working hard to bring the best hardware and software security practices widely available on high-end devices down to these microcontroller devices. Limited resources in microcontrollers, and with so many operating systems and solution stacks, leads to a complex and challenging landscape for embedded security.

We can categorize the data protection scenarios as follows;

  • Data at rest
  • Data in transit
  • Data in use

At Weeve, we are developing solutions tailored for data security for microcontroller-based IoT devices.

  • We protect data at rest by using a trusted storage solution. This data contains cryptographic assets such as keys or some digital assets such as virtual coins etc.
  • With data in transit, we have developed Weeve MQTTS, a lightweight and secure publish-subscribe protocol built on the basis of MQTT and tailored for low-end devices. This is an alternative to MQTT over TLS, which consumes more power resources at the edge.
  • For data in use, we address the integrity of the process running on an IoT device. This process might be collecting useful data using sensors or executing a data processing step or even executing business logic in the case of an actuator device. Detecting and preventing the software vulnerabilities of the process is the key here. We are developing Weeve Testimony, a real-time control attestation application, which is the topic of this blog series.

Before we introduce Weeve Testimony, here is a little bit of the technical background of problems we are solving and technologies used in our solution.

C-program vulnerability Issues

Almost all low level embedded software and firmware is developed in the C programming language. C’s lack of proper boundary checks for intended allocated memory is a source of big security threats. In addition to a buffer overflow, C-program suffers from integer-overflow, string-format vulnerability, return address overwrites, etc. There is also a new class of security threats to a C-program such as return-to-libc, and more general return-oriented programming (ROP) which are very effective against common mitigation techniques such as Data Execution Prevention and code signing. Proper code review with static and dynamic application security tools may reduce the severity of such vulnerabilities. Other techniques in the toolchain such as stack-smashing-protection, in the hardware itself like NX-bit, set for data segments, during runtime like address space layout randomization (ASLR) exist. But the program is still far from a fair vulnerability free guarantee. In the context of microcontroller-based low-end devices, the most effective mitigation technique of ASLR is not implemented because of practicality to avoid having a run-time loader.

Our Approach to Mitigate C-program Vulnerabilities

To address C-program vulnerability issues, we assume that there will always be security flaws in the program, and therefore we venture to detect them at run time. We envision the existence of a more privileged isolated guard process that inspects and testifies the behaviour of a running C-program (the MCU firmware). The guard process needs to be isolated and more privileged than the normal firmware because if it’s part of the same process or similar privilege level as normal firmware, the hacker will be able to hack the guard process as well exploiting the same vulnerability in normal firmware. A remote server for attestation is required to make the overall system more resilient to attacks, rather than relying on an isolated guard process. For example, if a program flow manipulation was detected, the trusted firmware can send an alert to the remote server, which in turn will notify the device fleet manager and take appropriate action.

Arm TrustZone and Why We Use It?

Thanks to Arm TrustZone, we can devise such a system. TrustZone is a hardware-assisted security technology that helps in the compartmentalization of the whole system in two parts. The less privileged component, known as the “Normal World”, is where general purpose application firmware and business logic runs. The privileged “Secure World” has a minimal computing base (so that it should have fewer bugs) and cannot be accessed directly from the general-purpose “Normal World”, except for a selection of allowed service calls that can be made.


Introducing Weeve Testimony Client

Our whole process security mechanism, in a nutshell, is that the full control flow execution path information of a program is extracted, and then this information is validated during the run time with a highly secure isolated guard process running in the Trusted Execution Environment (Arm TrustZone). This trusted application also acts as a remote attestation client and sends the currently executed control flow graph to a remote attestation server on demand. Weeve Testimony protects the application firmware running on the normal world. For the protection of the guard process, which is a Testimony Trusted Application, we rely on the security guarantee provided by Arm TrustZone technology.

This white paper describes the Weeve Testimony Remote Attestation and the Client-side components in particular. 

Technical Deep Dive

Here, we will dive into some technical details! A familiarity of the C-code build process and Arm Assembly instruction set is beneficial to fully grasp the subsequent material.

Preparing the Testimony Aware Firmware

Step 1. The Weeve instrumentor tool, Testimony Patcher, analyses a normal world firmware binary image. The tool replaces all control flow ARM assembly instructions with a BL instruction (BL corresponds to a function call in ARM assembly). The target address of this BL instruction is a routine written in ARM assembly. All assembly routines are dependent on the type of control flow instruction it is replacing, in other words, every ARM assembly control flow instruction type has a routine. These routines are called trampolines. The tool also generates a table with records as a tuple {sourceAddress, originalDestinationAddress}. Since we modified all the control flow destinations in the original firmware, this table contains a very crucial piece of information on original control flow destination addresses. This table will be used by the trampolines. This control flow branch table is generated in the form of a C-source file and placed in the secure world.

Every time the original firmware would perform a branch and link (BL) instruction, a special trampoline (prologue) also secures the LR (return address) on the shadow stack in the secure world. This way when the firmware would perform a return, another trampoline routine (epilogue) pops the previously secured return address from the shadow stack and compares it to the LR in the non-secure world. If they match, the program is running correctly, if they don’t - a program flow manipulation is detected and an alert is sent to the gateway. The gateway then has the power to decide what should happen next. For example, the manipulated LR value can be replaced with the correct return address from the shadow stack and the execution can continue while the device fleet manager can decide whether to send the maintenance team to check on / replace the device.


Step 2. We need to rebuild the firmware so that the control-flow branch table generated in Step 1 could be linked to the trampoline routine and available at run time. Now, this firmware is Weeve Testimony protected and ready to be downloaded on the device.

Step 3. The Weeve Testimony Trusted application needs to be also flashed to the device. 


Conclusion

We hope you enjoyed a high-level discussion of security vulnerabilities in the data supply chain and IoT, and our proposed solution: Weeve Testimony. Testimony is a guard process that guarantees the execution of MCU firmware, testifying that your device is not tampered with and reliable and notifying you when the contrary is the case. This first-mile trusted solution is critical in enabling the Machine and Data Economy.