You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
+
The implementation is tracked in:
12
+
13
+
-https://github.com/rust-lang/rust/issues/75835
14
+
-https://github.com/rust-lang/rust/issues/81391
15
+
-https://github.com/rust-lang/rust/pull/147697
16
+
11
17
# Motivation
12
18
[motivation]: #motivation
13
19
@@ -17,9 +23,9 @@ Trustzone creates a security boundary between a secure and non-secure applicatio
17
23
18
24
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 simulated on the main chip instead.
19
25
20
-
The secure and non-secure applications communicate over an FFI boundary: the two applications run on the same chip and use the same address space, but are not linked together. The cmse calling conventions are used to cross this FFI boundary, and apply restrictions on how it can be crossed.
26
+
The secure and non-secure applications communicate over an FFI boundary: the two applications run on the same chip and use the same address space, but are not linked together. The cmse calling conventions are used to cross this FFI boundary, and apply restrictions on how it can be crossed.
21
27
22
-
Much like how `unsafe` in rust limits where the programmer must be careful not to introduce UB, these special calling conventions clearly mark where secure data might be leaked. They also handle the clearing of registers before the secure boundary is crossed, so that a malicious non-secure application cannot read lingering secure data.
28
+
Functions that use these ABIs must be reviewed carefully because they mark where secure data might be leaked. This is analogous to `unsafe` limiting where UB might be introduced in a program. The calling conventions automatically handle the clearing of registers before the secure boundary is crossed, so that a malicious non-secure application cannot read lingering secure data.
23
29
24
30
Without compiler support it is much harder to know where to focus review effort, and every call that crosses the secure boundary requires inline assembly, which is inconvenient and error-prone.
25
31
@@ -29,7 +35,7 @@ Trustzone is growing in availability and use. More and more of the new medium an
The cmse calling conventions are part of the *Cortex-M Security Extension* that are available on thumbv8 systems. They are used together with Trustzone (hardware isolation) to create more secure embedded applications.
38
+
The cmse calling conventions are part of the *Cortex-M Security Extension* that are available on thumbv8 systems. They are used together with Trustzone (hardware isolation) to create more secure embedded applications.
33
39
34
40
The main idea of Trustzone is to split an embedded application into two executables. The secure executable has access to secrets (e.g. encryption keys), and must be careful not to leak those secrets. The non-secure executable cannot access these secrets or any memory that is marked as secure: the system will raise a SecureFault when a program dereferences a pointer to memory that it does not have access to. In this way a whole class of security issues is prevented in the non-secure app.
35
41
@@ -39,7 +45,7 @@ The `cmse-nonsecure-entry` calling convention is used in the secure executable t
39
45
40
46
The `cmse-nonsecure-call` calling convention is used in the other direction, when the secure executable wants to call into the non-secure executable. This calling convention can only occur on function pointers, not on definitions or extern blocks. The secure executable can acquire a non-secure function pointer via shared memory, or a non-secure callback can be passed to an entry function.
41
47
42
-
Both calling conventions are based on the platform's C calling convention, but will not use the stack to pass arguments or the return value. In practice that means that the arguments must fit in the 4 available argument registers, and the return value must fit in a single 32-bit register, or be abi-compatible with a 64-bit integer or float. The compiler checks that the signature is valid, and reports an error if not.
48
+
Both calling conventions are based on the platform's C calling convention, but will not use the stack to pass arguments or the return value. In practice that means that the arguments must fit in the 4 available argument registers, and the return value must fit in a single 32-bit register, or be abi-compatible with a 64-bit integer or float. The compiler checks that the signature is valid.
@@ -50,9 +56,9 @@ The `cmse-nonsecure-call` and `cmse-nonsecure-entry` ABIs are only accepted on `
50
56
51
57
The foundation of the cmse ABIs is the platform's standard AAPCS calling convention. On `thumbv8m` targets `extern "aapcs"` is the default C ABI and equivalent to `extern "C"`.
52
58
53
-
The `cmse-nonsecure-call` ABI can only be used on function pointers. Using it in for a function definition or extern block emits an error. It is invalid to cast to or from `extern "aapcs"`.
59
+
The `cmse-nonsecure-call` ABI can only be used on function pointers. Using it in for a function definition or extern block emits an error. It is invalid to cast to or from `extern "aapcs"`.
54
60
55
-
The `cmse-nonsecure-entry` ABI is allowed on function definitions, extern blocks and function pointers. It is sound and valid (in some cases even encouraged) to cast such a function to `extern "aapcs"`. Calling the function is valid and will behave as expected in both the secure and non-secure applications. Casting from `extern "aapcs"` to `extern "C"` is invalid.
61
+
The `cmse-nonsecure-entry` ABI is allowed on function definitions, extern blocks and function pointers. It is sound and valid (in some cases even encouraged) to cast such a function to `extern "aapcs"`. Calling the function is valid and will behave as expected in both the secure and non-secure applications. Casting from `extern "aapcs"` to `extern "C"` is invalid.
The `cmse-nonsecure-call` calling convention can only be used on function pointers, which already disallows generics. For `cmse-nonsecure-entry`, it is standard to add a `#[no_mangle]` or similar attribute, which also disallows generics. Explicitly disallowing generics enables the pre-monomorphization layout calculation that is required for good error messages for signatures that use too many registers.
109
115
### No C-variadics (currently)
110
116
111
-
Currently both ABIs disallow the use of c-variadics. For `cmse-nonsecure-entry`, the toolchain actually does not support c-variadic signatures (likely because of how they interact with shim that switches to secure mode), though the specification does not say that explicitly).
117
+
Currently both ABIs disallow the use of c-variadics. For `cmse-nonsecure-entry`, the toolchain actually does not support c-variadic signatures (likely because of how they interact with shim that switches to secure mode, though the specification does not say that explicitly).
- but accepts c-variadic nonsecure calls: https://godbolt.org/z/5rdK58ar4
@@ -274,7 +280,7 @@ For a true ergonomic experience more work is needed, but we believe this can all
274
280
275
281
Clang and GCC support CMSE using the `__attribute__((cmse_nonsecure_entry))` and `__attribute__((cmse_nonsecure_call))` attributes. As mentioned the ABI restrictions are checked, but only late in the compilation process.
276
282
277
-
The [`cortex_m`](https://docs.rs/cortex-m/latest/cortex_m/cmse/index.html) crate already provides some primitives for building cmse applications.
283
+
The [`cortex_m`](https://docs.rs/cortex-m/latest/cortex_m/cmse/index.html) crate already provides some primitives for building cmse applications, e.g. to query whether a pointer points to secure or non-secure memory.
0 commit comments