boot1-compatible GELI and GPT code?

Eric McCorkle eric at metricspace.net
Sun Mar 20 19:10:58 UTC 2016


In EFI, you don't have the bootinfo struct, you just have command-line style args going from boot to loader.  Right now, the efi loader doesn't even look at the args.

Some thoughts:
* The ideal solution (if you trust HSMs and have one at all) would be to load the keys into an HSM in boot, and rely on it from there.  That's a lot of hardware support in boot, though.
* There is some incentive to avoid args/env variables. There's a very real risk of your keys getting leaked by debugging/logging messages.  Also, at least in the efi boot to loader transition, I wouldn't put it past the likes of Lenovo to record all ExecImage activity, which would slurp the keys if that method was used. Also, it'd be big change to the efi loader to add args (and a potential vuln to parse them)
* With the variable injection method I proposed as well as with a method of synthesizing a loadable module in memory, an attacker capable of getting the keys would have to be able to access kernel memory.

The only safe option to me seems to be either injecting the keys straight into the executable, or else synthesizing modules containing them and loading them.  Now, you'll need to also do this for loader, which is a COFF binary.  Both approaches have their merits, though I think I slightly prefer the injection method.

> On Mar 20, 2016, at 14:45, Allan Jude <allanjude at freebsd.org> wrote:
> 
>> On 2016-03-20 14:05, Ian Lepore wrote:
>>> On Sun, 2016-03-20 at 13:13 -0400, Eric McCorkle wrote:
>>> Hello everyone,
>>> 
>>> I'm working (among other things) on expanding the capabilities of the
>>> EFI boot block to be able to load GELI-encrypted partitions, which
>>> may contain a GPT partition table, in order to support full-disk
>>> encryption.
>>> 
>>> I'm wondering, is there any code for reading either of these formats
>>> that could be used in boot1 hiding out anywhere?  It'd be best to
>>> avoid rewriting this stuff if possible.
>>> 
>>> Also, I haven't investigated the capabilities of loader with regard
>>> to GELI yet beyond cursory inspection.  Most importantly, I need to
>>> know if loader can handle GPTs and other partition formats inside a
>>> GELI, or just single filesystems.
>>> 
>>> As an additional note, it'd be best if there was a method for having
>>> boot1 pass the key(s) along to loader and ultimately the kernel, so
>>> the users don't have to input their keys 3 times.  I'm open to
>>> suggestions as to how to do this.  My initial thought is to create
>>> some kind of variable in both loader and kernel, then use the elf
>>> data to locate it and directly inject the data prior to booting.  The
>>> rationale is to avoid mechanisms like arguments that could
>>> potentially reveal the keys.
>> 
>> GELI keys are currently passed from loader(8) to the kernel as
>> environment variables.  I was semi-horrified when I stumbled across
>> that -- not the knee-jerk-reaction you'd expect from a security
>> -obsessed person (because I'm soooo not one of those), but rather
>> because it means that the memory passed from loader to the kernel
>> containing the initial env vars must be writable, so that the geli key
>> stuff can be zeroed after it's acccessed.  That prevents making the
>> pointer to that memory const everywhere, as it should be.
>> 
>> It seems to me that a more correct way to pass the information may be
>> as an opaque data blob, roughly the same way kernel modules and other
>> loaded data gets passed from loader to the kernel.  That might
>> facilitate obscuring the info in some way as well.
>> 
>> That doesn't really answer your question of how to pass it from boot1
>> to loader(8), though.  There really isn't a lot of leeway there, you
>> pretty much have to put it in memory somewhere (likely into an arch
>> -specific bootinfo struct), and pass a pointer to it in a register when
>> jumping to the loader(8) entry point.  (Remember that all of this stuff
>> applies to multiple platforms, not just x86, so it can't just be
>> dropped into some well-known location in memory or anything like that.)
> 
> This is how I did it in my recent work. Added an additional field to the
> 'extended boot info' struct, to pass the data from boot2 to the loader.
> My work only targeted i386/amd64.
> 
>> -- Ian
>> 
>> _______________________________________________
>> freebsd-hackers at freebsd.org mailing list
>> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe at freebsd.org"
> 
> 
> -- 
> Allan Jude
> 


More information about the freebsd-hackers mailing list