Hi, On 25 June 2018 at 14:44, Stephen Warren <swar...@wwwdotorg.org> wrote: > On 06/24/2018 12:17 AM, Alexander Graf wrote: >> >> >> >>> Am 22.06.2018 um 21:24 schrieb Stephen Warren <swar...@wwwdotorg.org>: >>> >>> 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"))) >> >> >> Please check my recent fix to rename the efi sections. Gcc may under some >> conditions generate implicit symbols, such as rodata constants. You can only >> catch them if your text section for the function starts with .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. >> >> >> This looks quite similar to efi runtime services requirements to me. Maybe >> we can share code. >> >> The way those work is that we mark all functions and data required in >> special sections too. We also include all relocations inside a special >> section as well though. >> >> If you follow the same scheme, you could simply clone parts of U-Boot at >> runtime with different relocations to either main U-Boot or mon. During that >> relocation you could also find out if there is any relication that is >> unreachable from mon code. That could trigger a warning that CI should be >> able to quickly find. > > > So we'd have the following chunks of code (lets say sections): > > 1) U-Boot only > 2) Monitor (or UEFI) only > 3) Shared code between 1 and 2. > > ... then memcpy (3) to two places, one for (1) and one for (2)? > > On the surface that seems plausible, but what happens if we have the > following main chunks of code: > > 1) U-Boot > 2) Monitor > 3) UEFI > 4) Something else. > > Now we either have a relatively large and bloated dumping ground for all > common code: > > 5) Common code, which gets copied 4 other places, and contains many > functions some of the copy targets don't need. > > ... or many combinations: > > 5) Code shared between 1, 2, 3, 4 > 6) Code shared between 1, 2, 3 > 7) Code shared between 1, 2, 4 > 8) Code shared between 1, 3, 4 > ... > > Or a per-function section and the relocator iterates over each per-function > section separately, and works out which of 1..4 it gets copied into. > > None of those options seem very tractable once you get more than a couple of > potential copy destinations. > > Building each binary separately means the linker works out which functions > to add to each binary at compile time, so saves complexity or manual > management of function sections, and saves runtime work.
I think building a completely separate image is the most robust way, but it would be nice if Alex's approach would work. I suspect it would build faster too. Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot