|
6 | 6 | # Summary |
7 | 7 | [summary]: #summary |
8 | 8 |
|
9 | | -Support the `cmse-nonsecure-entry` and `cmse-nonsecure-call` calling conventions on `thumbv8` targets. |
| 9 | +Support for the `cmse-nonsecure-entry` and `cmse-nonsecure-call` calling conventions on `thumbv8` targets, and a lint preventing (partially) uninitialized values from crossing the security boundary. |
10 | 10 |
|
11 | 11 | # Motivation |
12 | 12 | [motivation]: #motivation |
13 | 13 |
|
14 | 14 | Rust and Trustzone form an excellent pairing for developing embedded projects that are secure and robust. |
15 | 15 |
|
| 16 | +Trustzone creates a security boundary between a secure and non-secure application. The secure application can work with secure information (e.g. encryption keys). By limiting the interactions between the secure and non-secure applications, large classes of security bugs are statically prevented. |
| 17 | + |
| 18 | +In embedded systems it is common to have an extra physical chip, a secure enclave, to handle secure information. With Trustzone, this additional chip is not needed: a secure enclave is created on the main chip instead. |
| 19 | + |
| 20 | +The cmse calling conventions define the interactions between secure and non-secure code. By automatically checking the constraints placed on secure and non-secure functions, it becomes ergonomic to write secure code. In the absence of compiler support for these calling conventions, global assembly is needed for all calls across the security boundary, which is obviously inconvenient and error-prone. |
| 21 | + |
| 22 | +A specific use case is encapsulating C APIs. Providing a C interface is still the standard way for a hardware vendor to provide access to system components. Libraries for networking (LTE, Bluetooth) are notorious for their bugs. Running such code in non-secure mode significantly reduces the risk of bugs leaking secure information. |
| 23 | + |
| 24 | +Trustzone is growing in availability and use. More and more of the new medium and large ARM microcontrollers have support. Large industry players have requested Rust support for Trustzone. |
16 | 25 | # Guide-level explanation |
17 | 26 | [guide-level-explanation]: #guide-level-explanation |
18 | 27 |
|
@@ -256,4 +265,26 @@ The [`cortex_m`](https://docs.rs/cortex-m/latest/cortex_m/cmse/index.html) crate |
256 | 265 | # Future possibilities |
257 | 266 | [future-possibilities]: #future-possibilities |
258 | 267 |
|
259 | | -Some ideas of future lints were discussed. For instance, an entry function that accepts a reference may set users up for failure. The secure application (which defines the entry function) must consider the non-secure application to be hostile. Because the non-secure application can configure signal handlers that mutate arbitrary memory, there is a risk of time-of-check-time-of-use attacks. Assuming the strong guarantees of a reference might give a false sense of security. |
| 268 | +## Lint on references crossing the secure boundary |
| 269 | + |
| 270 | +The secure application should never accept a reference because there is no guarantee that a hostile non-secure application does not provide an invalid value (`NULL`, not properly aligned, etc.). There are other types with layout assumptions (e.g. `NonZeroU64` and friends) that are almost certainly invalid for a secure application to accept. |
| 271 | + |
| 272 | +We'd like to wait with adding further lints until we see more usage of Trustzone, so that we can design a lint that covers all practical cases of too-strong assumptions. |
| 273 | +## An "initialize padding" attribute |
| 274 | + |
| 275 | +The current lint for partially uninitialized values crossing the security boundary does not have a proper workaround: the advice is to just not send such values over the secure boundary, and essentially treat the warning as an error. |
| 276 | + |
| 277 | +A suggestion that was floated is to provide some mechanism to ensure that a value is fully initialized, e.g. by zeroing any potentially uninitialized parts. |
| 278 | + |
| 279 | +One potential method is to extend the`repr` attribute with an option that adds fields where padding is needed internally. These user-hidden padding fields would be zeroed upon creation. |
| 280 | +```rust |
| 281 | +#[repr(C, align(8), initialized)] |
| 282 | +struct Foo { |
| 283 | + a: u8, |
| 284 | + _padding0: [u8; 1], |
| 285 | + b: u16, |
| 286 | + _padding1: [u8; 4], |
| 287 | +} |
| 288 | +``` |
| 289 | + |
| 290 | +This feature still has many open design questions. We don't think such an attribute is required for practical Trustzone development, so we defer it for now. |
0 commit comments