[U-Boot] Sharing code between U-Boot and its secure monitor

Stephen Warren swarren at wwwdotorg.org
Fri Jun 22 19:24:09 UTC 2018


I am writing more secure monitor (PSCI) support for Jetson TK1. In 
particular, this code will support resume from the LP0 system suspend 
state, which entails signing a block of code for the boot ROM to 
validate during resume. The signing code uses lib/aes.c. This code is 
linked into U-Boot in the "main" part of U-Boot, rather than into the 
secure section that contains the monitor code. The monitor should only 
call code within the monitor section, not within the main part of U-Boot 
(in general, the monitor continues to run after U-Boot has been replaced 
in RAM, so cannot call code in U-Boot since it may no longer exist, and 
even if it does, that code is not in the secure DRAM carve-out, and 
hence it's not secure to call it). So, I need to duplicate the lib/aes.c 
object code into the monitor. The question is: what's the best way to do 
that.

So far, here's what I implemented:

a) Edit lib/aes.c to mark each function with an optional attribute which 
will force the object code into the secure section when compiled for the 
monitor:

-static const u8 sbox[256] = {
+static const u8 mon_rodata sbox[256] = {

-void aes_cbc_decrypt_blocks(...
+void mon_text aes_cbc_decrypt_blocks(...

... where mon_text evaluates to:

+#define mon_rodata
+#define mon_text

or:

+#define mon_data	__attribute__((section("._secure.data")))
+#define mon_rodata	__attribute__((section("._secure.rodata")))
+#define mon_text	__attribute__((section("._secure.text")))

b) Since the main U-Boot and the monitor code are part of the same ELF 
file, the same symbol name cannot exist in both. So, we must play 
similar games in order to rename the symbols:

-void aes_cbc_decrypt_blocks(...
+void mon_text MON_SYM(aes_cbc_decrypt_blocks)(...

(all call sites have to be updated similarly)

... where MON_SYM(x) is either:

+#define MON_SYM(x) x

or:

+#define MON_SYM(x) mon_##x

c) In the monitor, create a file mon_aes.c that sets up all the macros 
mentioned above, then #includes the main lib/aes.c. Add this file to a 
Makefile.

+#include "mon_section.h"
+#include "../../../../../lib/aes.c"

This is all rather nasty and invasive, especially when you consider more 
widely used utility functions such as malloc(), printf(), udelay(), 
etc.. Instead, I wonder if we can:

a) Link the monitor to an ELF file and extract a binary. We won't need 
any special section or symbol name logic here, since we can assume that 
all of .text/.data are part of the monitor. Simple and non-invasive!

b) Link the LP0 resume code to an ELF file and extract a binary. (It's 
nice to separate this block of code since it runs on a different CPU to 
the main U-Boot or monitor, and hence gets compiled with different 
compiler flags).

c) Include the binaries from (a) and (b) above in the main U-Boot ELF 
file or binary somehow; perhaps use binman to allow the main U-Boot to 
know where those merged binaries end up in memory.

In a slightly different context, I've talked to Simon in the past about 
building many separate binaries from U-Boot's source and chaining 
between them and merging them together and he objected to that approach. 
However, I wonder if this new requirement changes anything?

Thanks for any thoughts.


More information about the U-Boot mailing list