Discussion:
EFI GELI support ready for testers
(too old to reply)
Eric McCorkle
2016-05-27 23:39:57 UTC
Permalink
I am pleased to announce that my work to add support for GELI in the EFI boot loader (as well as perform more general refactoring) is now ready for testing. I am able to successfully detect multiple GELI partitions in boot1 and pass the keys into the kernel.

My work can be found here: https://github.com/emc2/freebsd/tree/geli_efi

Also of note is the efize branch, which I posted about two weeks ago. I have not yet merged this with master, but I will begin doing so on a regular schedule.

I have left the LOADER_PATH variable as "/boot/loader.tst" If you plan on testing this, I *strongly* recommend the following procedure:

* Be aware that because of the nature of this patch, A PROBLEM COULD RESULT IN YOUR FILES BEING INACCESSIBLE! Take necessary precautions to protect your data, read carefully, ask before you leap, and proceed with caution!
* Read and understand thoroughly the basics of EFI and the FreeBSD boot architecture before you do anything.
* Install an EFI shell program on your ESP.
* Install the modified boot1 to something like /efi/boot/bootx64.tst on your ESP
* Install the modified loader to /boot/loader.tst
* Try creating an auxiliary encrypted partition containing unimportant data first
* After this, try a minimal root image on the auxiliary partition.
* Only move to an encrypted root once you have tried the above steps, and BACK UP YOUR DATA FIRST.


I have personally done the following tests on this:

* Detect ZFS filesystem at boot (ZFS checksum verification gives a high level of certainty that decryption is correct)
* Load a kernel and multiple modules from a ZFS partition and boot them.
* AES CBC and XTS encryption (see notes on limited GELI feature support)
* Multiple encrypted partitions with different keys, both shared and different pass phrases.
* Ensure that keys are passed into the kernel properly.

Normally I would convert my own system and wait a week or two; however, the graphics update 4.6 testing is going on, and I want to make sure my hardware (purism laptop) is accounted for in that. Two experimental patches is just too much branch management (especially when a misstep would effectively destroy all my files!)

Due to the scope of this changeset and the material risks associated with it, I am NOT recommending that it be considered for the 11 release. It's just too close to be adding something like this.

A note on GELI feature support: the current GELI boot code does not support all features. Only AES encryption is supported, only 512 block sizes are supported, authentication is not supported, and key files are not supported. (These are limitations inherited from the GELI boot code, and my refactoring a may make them easier to address). Make sure not to use an unsupported mode!


The contents of this work break down into roughly four areas, which apply in the following order:


EFI Refactoring: see my earlier mail for full details. The abridged version is that the EFI boot1 and loader are refactored to make much greater use of the EFI API. Filesystems are now managed by attaching an EFI_SIMPLE_FILE_SYSTEM_PROTOCOL interface. The filesystem drivers in loader have been replaced with a single driver that talks through this interface. This allows loader to use any filesystem driver installed by itself, boot1 or another tool, or the native firmware. This refactoring also puts both boot1 and loader on a common code base driver-wise, eliminating the duplication that previously existed. I was unable to move the efipart and backend filesystem drivers fully into the EFI driver model, however, as the bcache code is fundamental built on the model of static detection.


Boot Crypto: this is a small refactoring that moves crypto code out of the existing geliboot code and into a common framework. This should make the business of adding new ciphers easier. A difficulty with this is resolving the need for building a 32-bit version of the library for legacy BIOS geliboot, as well as a native version for EFI. I currently resolve this by building a static library for EFI, and including the source files in the BIOS make files. If someone with a better handle on the build system could figure out how to build both a 32-bit and native version of the library, I'd be grateful.


GELI EFI driver: this is simply an EFI driver that detects GELI partitions and creates a new device handle with a EFI_BLOCK_IO_PROTOCOL interface implementing access to the partition. This driver, as well as the kernel KMS driver could be exported from the FreeBSD sources and contributed to the likes of GRUB without much trouble.


Kernel key intake framework: this adds a kernel interface (and one that will likely be imminently useful, at the very least to the BIOS GELI support), so it warrants further discussion:

* On the boot/loader side, there is a "kernel injector KMS" driver which creates a device handle that implements the EFI_KMS_PROTOCOL. The GELI driver attempts to obtain the handle supporting this interface, and uses it to report both GELI pass phrases as well as the raw keys as it discovers them. It also uses the handle to obtain previous keys and passphrases, and tries the before asking for a new passphrase.
* The kernel injector KMS uses the register client function to inform the KMS of a kernel. This is done in the same code path that adds metadata to the kernel image (the existing metadata is how the kernel gets the EFI frame buffer info, among other things)
* On the kernel side, a new kind of metadata is added for the key intake buffer. A simple interface for accessing the key intake buffer is presented in crypto/intake.h
* The GELI kernel-side code has been modified to check the intake buffer when detecting GELI partitions at boot before asking for a passphrase.
* The existing environment variable used by the BIOS GELI support has been left alone. However, it would probably be a good idea to move to the key intake buffer, as it is more featureful and marginally more secure.

A guiding principle behind this design was the desire to make it easy to add support for hardware-based key storage options. This is why I used KMS interfaces on the EFI side. I also designed it to support a wider range of keys than what GELI alone needed, intending for it to become a common interface for communicating keys from the loader to the kernel.


Let me know if there are any questions about this work. I would prefer that it undergo a period of testing before moving towards commit (which is necessary anyway in light of the upcoming release).
Konstantin Belousov
2016-05-28 08:36:57 UTC
Permalink
Post by Eric McCorkle
I am pleased to announce that my work to add support for GELI in the EFI boot loader (as well as perform more general refactoring) is now ready for testing. I am able to successfully detect multiple GELI partitions in boot1 and pass the keys into the kernel.
Can somebody explain in which way this is useful ?
Same question for the GELI code for non-EFI loader.

BIOS cannot read raw data from the encrypted partition, so you need
either old boot or the loader and some additional data on EFI boot
partition anyway.

Features adds significant amount of code, which must be maintained in
parallel with the kernel code.
Eric McCorkle
2016-05-28 13:37:29 UTC
Permalink
Full-disk encryption is a powerful security feature, and one which is available in one form or another in every major competing OS. It is a requirement for data protection in many organizations, and something that many individuals desire to help protect their data.

In EFI, there is an EFI System Partition (ESP) which is expected to be formatted with msdosfs. This contains the boot1 program. This must be unencrypted in order for EFI to be able to read it (unless you do something fancy with coreboot or whatever). That is the only thing that needs to live on the ESP, and the only thing that needs to be stored as plaintext. The rest of the system past that point can reside on encrypted partitions. Without support for GELI in the boot1/loader code, you have to keep part of the system unencrypted.

Making it so that only boot1 has to be stored as plaintext dramatically reduces the attack surface. It can also be combined with EFI secure boot to create a powerful tamper-resistance scheme, wherein a per-machine private key is stored on the encrypted disk and used to sign boot1. This prevents an attacker from modifying boot1, as they would need the signing key to do that, but they can't get it without decrypting the disk.

I'll also mention that my changes actually delete quite a bit of code and remove the boot1-specific filesystem backends, so that boot1 and loader now use the same filesystem and backend code.
Post by Konstantin Belousov
Post by Eric McCorkle
I am pleased to announce that my work to add support for GELI in the EFI boot loader (as well as perform more general refactoring) is now ready for testing. I am able to successfully detect multiple GELI partitions in boot1 and pass the keys into the kernel.
Can somebody explain in which way this is useful ?
Same question for the GELI code for non-EFI loader.
BIOS cannot read raw data from the encrypted partition, so you need
either old boot or the loader and some additional data on EFI boot
partition anyway.
Features adds significant amount of code, which must be maintained in
parallel with the kernel code.
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
Allan Jude
2016-05-28 14:27:40 UTC
Permalink
Post by Konstantin Belousov
Post by Eric McCorkle
I am pleased to announce that my work to add support for GELI in the EFI boot loader (as well as perform more general refactoring) is now ready for testing. I am able to successfully detect multiple GELI partitions in boot1 and pass the keys into the kernel.
Can somebody explain in which way this is useful ?
Same question for the GELI code for non-EFI loader.
BIOS cannot read raw data from the encrypted partition, so you need
either old boot or the loader and some additional data on EFI boot
partition anyway.
Features adds significant amount of code, which must be maintained in
parallel with the kernel code.
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
The motivation for my work (GELI in boot2 and loader for non-EFI boot)
was supporting ZFS boot environments. Previously, when you use GELI you
needed to have two ZFS pools, one for an unencrypted /boot and one for
the encrypted /

This breaks ZFS boot environments, since a snapshot of the root file
system won't include the correct kernel etc.

The final version of my geliboot took an extra effort to reuse the AES
code from sys/crypto/rijndael and sys/opencrypto and GELI directly from
sys/geom/eli to avoid maintaining a separate copy of that code in sys/boot

Hopefully the work I did to make sys/opencrypto and sys/geom/eli more
reusable outside of the kernel will make it easier for Eric to do the
same for the EFI version.

The motivation for the EFI version is the same, ZFS boot environments,
plus the obvious security advantages of having the kernel stored
encrypted rather than not.
--
Allan Jude
Eric McCorkle
2016-05-28 15:23:41 UTC
Permalink
Post by Allan Jude
The final version of my geliboot took an extra effort to reuse the AES
code from sys/crypto/rijndael and sys/opencrypto and GELI directly from
sys/geom/eli to avoid maintaining a separate copy of that code in sys/boot
Hopefully the work I did to make sys/opencrypto and sys/geom/eli more
reusable outside of the kernel will make it easier for Eric to do the
same for the EFI version.
It did indeed make things easier, though I think there is potential for work to be done on the crypto framework. It looks like the crypto framework has kind of accumulated code over time from different sources and has become somewhat disorganized. There seem to be two codebases (crypto and opencrypto), and multiple differing implementations for some ciphers. I ran into this when trying to figure out how to add Camellia support. There's a usable interface for AES CBC/XTS, but not Camellia CBC. There are also some insecure ciphers (DES, RC4, etc) in there, some more modern ciphers (like chacha20) are missing, and it's possible to implement ciphers other than AES using AESNI/AVX instructions to achieve hardware acceleration.

It also ought to be simpler to share crypto code between kernel, boot, and userland, imo. In theory, one could have a single library (with multiple compilations for different ABIs) that could be statically linked into the kernel and boot loaders, and also installed in to the base OS.

I'm not sure if there's any plans for crypto, but it might be worth a discussion.
Post by Allan Jude
The motivation for the EFI version is the same, ZFS boot environments,
plus the obvious security advantages of having the kernel stored
encrypted rather than not.
The ability to have a single ZFS filesystem is indeed a motivator for the EFI work. I forgot to mention it because my personal motivations are strongly focused on security and tamper-resistance.
Alan Somers
2016-05-28 17:24:55 UTC
Permalink
Post by Eric McCorkle
Post by Allan Jude
The final version of my geliboot took an extra effort to reuse the AES
code from sys/crypto/rijndael and sys/opencrypto and GELI directly from
sys/geom/eli to avoid maintaining a separate copy of that code in sys/boot
Hopefully the work I did to make sys/opencrypto and sys/geom/eli more
reusable outside of the kernel will make it easier for Eric to do the
same for the EFI version.
It did indeed make things easier, though I think there is potential for work to be done on the crypto framework. It looks like the crypto framework has kind of accumulated code over time from different sources and has become somewhat disorganized. There seem to be two codebases (crypto and opencrypto), and multiple differing implementations for some ciphers. I ran into this when trying to figure out how to add Camellia support. There's a usable interface for AES CBC/XTS, but not Camellia CBC. There are also some insecure ciphers (DES, RC4, etc) in there, some more modern ciphers (like chacha20) are missing, and it's possible to implement ciphers other than AES using AESNI/AVX instructions to achieve hardware acceleration.
It also ought to be simpler to share crypto code between kernel, boot, and userland, imo. In theory, one could have a single library (with multiple compilations for different ABIs) that could be statically linked into the kernel and boot loaders, and also installed in to the base OS.
I'm not sure if there's any plans for crypto, but it might be worth a discussion.
Post by Allan Jude
The motivation for the EFI version is the same, ZFS boot environments,
plus the obvious security advantages of having the kernel stored
encrypted rather than not.
The ability to have a single ZFS filesystem is indeed a motivator for the EFI work. I forgot to mention it because my personal motivations are strongly focused on security and tamper-resistance.
The problem with opencrypto is that it was written when crypto
accelerators lived on PCI cards and were treated as shared resources.
That's why userland programs wishing to use opencrypto have to send
all of their data into the kernel. It's a very inefficient way of
using CPU-resident accelerators like AESNI and Padlock. For clients
within the kernel, it's not so bad. It adds a few extra stack frames
and a lot of code but there are no additional data copies. crypto(3),
OTOH, is part of OpenSSL. AFAIK it doesn't have the data copies
problem, but it's still quite complicated. ken@ once tried to build
OpenSSL into the kernel but gave up because it has too many
dependencies.

So neither of these libraries is suitable for use in both kernel and
userland. I don't know of any that is (though I haven't looked).

-Alan
Eric McCorkle
2016-05-28 20:19:12 UTC
Permalink
I see. They're part device interface, part software crypto implementation. I guess the question is, does the software crypto *have* to live there, or could it be in a separate library?

I'm less inclined to trust OpenSSL completely these days, and it certainly is a beast to integrate into anything.

Some compelling alternatives have emerged in the wake of heartbleed. Off the cuff, I'd say NaCl is a good option: it's public domain and it's got some big names in crypto attached to it. But I don't know enough to say for sure if it could do what I proposed.
Post by Allan Jude
Post by Eric McCorkle
Post by Allan Jude
The final version of my geliboot took an extra effort to reuse the
AES
Post by Eric McCorkle
Post by Allan Jude
code from sys/crypto/rijndael and sys/opencrypto and GELI directly
from
Post by Eric McCorkle
Post by Allan Jude
sys/geom/eli to avoid maintaining a separate copy of that code in
sys/boot
Post by Eric McCorkle
Post by Allan Jude
Hopefully the work I did to make sys/opencrypto and sys/geom/eli
more
Post by Eric McCorkle
Post by Allan Jude
reusable outside of the kernel will make it easier for Eric to do
the
Post by Eric McCorkle
Post by Allan Jude
same for the EFI version.
It did indeed make things easier, though I think there is potential
for work to be done on the crypto framework. It looks like the crypto
framework has kind of accumulated code over time from different sources
and has become somewhat disorganized. There seem to be two codebases
(crypto and opencrypto), and multiple differing implementations for
some ciphers. I ran into this when trying to figure out how to add
Camellia support. There's a usable interface for AES CBC/XTS, but not
Camellia CBC. There are also some insecure ciphers (DES, RC4, etc) in
there, some more modern ciphers (like chacha20) are missing, and it's
possible to implement ciphers other than AES using AESNI/AVX
instructions to achieve hardware acceleration.
Post by Eric McCorkle
It also ought to be simpler to share crypto code between kernel,
boot, and userland, imo. In theory, one could have a single library
(with multiple compilations for different ABIs) that could be
statically linked into the kernel and boot loaders, and also installed
in to the base OS.
Post by Eric McCorkle
I'm not sure if there's any plans for crypto, but it might be worth a
discussion.
Post by Eric McCorkle
Post by Allan Jude
The motivation for the EFI version is the same, ZFS boot
environments,
Post by Eric McCorkle
Post by Allan Jude
plus the obvious security advantages of having the kernel stored
encrypted rather than not.
The ability to have a single ZFS filesystem is indeed a motivator for
the EFI work. I forgot to mention it because my personal motivations
are strongly focused on security and tamper-resistance.
The problem with opencrypto is that it was written when crypto
accelerators lived on PCI cards and were treated as shared resources.
That's why userland programs wishing to use opencrypto have to send
all of their data into the kernel. It's a very inefficient way of
using CPU-resident accelerators like AESNI and Padlock. For clients
within the kernel, it's not so bad. It adds a few extra stack frames
and a lot of code but there are no additional data copies. crypto(3),
OTOH, is part of OpenSSL. AFAIK it doesn't have the data copies
OpenSSL into the kernel but gave up because it has too many
dependencies.
So neither of these libraries is suitable for use in both kernel and
userland. I don't know of any that is (though I haven't looked).
-Alan
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
Konstantin Belousov
2016-05-28 17:26:18 UTC
Permalink
Post by Allan Jude
Post by Konstantin Belousov
Post by Eric McCorkle
I am pleased to announce that my work to add support for GELI in the EFI boot loader (as well as perform more general refactoring) is now ready for testing. I am able to successfully detect multiple GELI partitions in boot1 and pass the keys into the kernel.
Can somebody explain in which way this is useful ?
Same question for the GELI code for non-EFI loader.
BIOS cannot read raw data from the encrypted partition, so you need
either old boot or the loader and some additional data on EFI boot
partition anyway.
Features adds significant amount of code, which must be maintained in
parallel with the kernel code.
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
The motivation for my work (GELI in boot2 and loader for non-EFI boot)
was supporting ZFS boot environments. Previously, when you use GELI you
needed to have two ZFS pools, one for an unencrypted /boot and one for
the encrypted /
This breaks ZFS boot environments, since a snapshot of the root file
system won't include the correct kernel etc.
Why cannot /boot included into the boot environment ?
When I last saw Solaris, somewhere in its 10-th, any amount of
filesystems could be added to the bootenv. But whatever the definition
of bootenv is used, it exists at a level of the shell scripts and selecting
the actual partition for loader. Throw thousand lines of code into
the unstable and very hard to debug environment of loader looks somewhat
unproductive.
Post by Allan Jude
The final version of my geliboot took an extra effort to reuse the AES
code from sys/crypto/rijndael and sys/opencrypto and GELI directly from
sys/geom/eli to avoid maintaining a separate copy of that code in sys/boot
Which means that kernel code must be also runnable in the strange and
incompatible environment of the loader. I cannot see how this reduces
code maintanability even a bit. I am already rather unhappy about ZFS
kernel code being compiled as the userspace library, which hurt me
and other people more than once. Now (?) the kernel code must be also
verified for the loader.
Post by Allan Jude
Hopefully the work I did to make sys/opencrypto and sys/geom/eli more
reusable outside of the kernel will make it easier for Eric to do the
same for the EFI version.
The motivation for the EFI version is the same, ZFS boot environments,
plus the obvious security advantages of having the kernel stored
encrypted rather than not.
Obvious security advantages ? Seriously ?
What is a single 'security' advantage of hiding the kernel ?

Since you noted a 'security', I realized that your changes decrypt the
keys in the pre-kernel environment. In other words, very sensitive
material becoming accessible to strange and unknown code which is
managed by firmware. Putting aside ineradicable evil of Intel ME or its
AMD twin, and SMM handler, you are exposing keys to whatever code happen
to inhabit the preboot env, not neccessary originating from the firmware
vendor. Secure Boot would not help there, since when the measurement
indicate that untrusted component was there, it is too late. I.e.,
you making much easier for malice hacker to steal the keys.
Konstantin Belousov
2016-05-29 09:18:27 UTC
Permalink
Post by Konstantin Belousov
Post by Allan Jude
Post by Konstantin Belousov
Post by Eric McCorkle
I am pleased to announce that my work to add support for GELI in the EFI boot loader (as well as perform more general refactoring) is now ready for testing. I am able to successfully detect multiple GELI partitions in boot1 and pass the keys into the kernel.
Can somebody explain in which way this is useful ?
Same question for the GELI code for non-EFI loader.
BIOS cannot read raw data from the encrypted partition, so you need
either old boot or the loader and some additional data on EFI boot
partition anyway.
Features adds significant amount of code, which must be maintained in
parallel with the kernel code.
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
The motivation for my work (GELI in boot2 and loader for non-EFI boot)
was supporting ZFS boot environments. Previously, when you use GELI you
needed to have two ZFS pools, one for an unencrypted /boot and one for
the encrypted /
This breaks ZFS boot environments, since a snapshot of the root file
system won't include the correct kernel etc.
Why cannot /boot included into the boot environment ?
When I last saw Solaris, somewhere in its 10-th, any amount of
filesystems could be added to the bootenv. But whatever the definition
of bootenv is used, it exists at a level of the shell scripts and selecting
the actual partition for loader. Throw thousand lines of code into
the unstable and very hard to debug environment of loader looks somewhat
unproductive.
You misunderstand. Alan was talking about pure ZFS systems, where there is one big ZFS pool holding everything. You need to be able to access /boot obviously, but ZFS does not allow you to assign separate out data on to a single device. It creates a pool, which combines all devices.
To have /boot unencrypted, you have to have a separate partition for just /boot, which is undesirable.
Why it is undesirable ? You must have EFI boot partition by any means.

And why it is simultaneously desirable to add a bunch of code to loader
to hide this ?
Post by Konstantin Belousov
Post by Allan Jude
The final version of my geliboot took an extra effort to reuse the AES
code from sys/crypto/rijndael and sys/opencrypto and GELI directly from
sys/geom/eli to avoid maintaining a separate copy of that code in sys/boot
Which means that kernel code must be also runnable in the strange and
incompatible environment of the loader. I cannot see how this reduces
code maintanability even a bit. I am already rather unhappy about ZFS
kernel code being compiled as the userspace library, which hurt me
and other people more than once. Now (?) the kernel code must be also
verified for the loader.
I mean, the loader has to be able to access the filesystems, there's no way around it (barring crazy coreboot stuff).
Also, it should be possible to create a synthetic EFI test-harness that runs in *userland*. EFI is basically just a bunch of tables of function pointers, no bios interrupts or anything. As long as you implement the interfaces, any loader should also run in your synthetic environment. I had plans to look into this after this work is done.
Of course EFI is not 'just a bunch of tables'. It might look so when you
have tunnel vision and all you do is writing code making calls, but it
is definitely not when you consider it as a part of platform.

UEFI makes it absurdly easy to distribute a code that gets executed on
every boot before boot loaders. The most straighforward is to put UEFI
driver binary into the UEFI FAT and register it into some variables (too
lazy to remember details). You get this way both boot- and runtime-
injection, officially supported. This was one of the reason for secure
boot.

To avoid trivial debunks, I put a note that of course drivers are not
the only way for such code to appear on the system, without
requiring any hardware modifications. The rich programming environment,
with flat memory and full control over hardware, with easily explorable
data structures, with documented and compatible ways to get code
persistent are the characteristics of it.

It is much easier to target such preboot env then to maintain dynamic
list of the userspace escalation code.
Post by Konstantin Belousov
Post by Allan Jude
Hopefully the work I did to make sys/opencrypto and sys/geom/eli more
reusable outside of the kernel will make it easier for Eric to do the
same for the EFI version.
The motivation for the EFI version is the same, ZFS boot environments,
plus the obvious security advantages of having the kernel stored
encrypted rather than not.
Obvious security advantages ? Seriously ?
What is a single 'security' advantage of hiding the kernel ?
There are plenty.
Right up at the top, an attacker able to access /boot is free to tamper with anything, and can insert back-doors into the kernel, loader, or any module. If you assume that the attacker can't write, then they can still scan the kernel and modules for signatures for known vulnerabilities (since the kernel itself has a commit id and detailed version info, they can compare this against a CVE database). Even if they can't do that for some reason, they could still potentially exfilt a kernel address map for use in rootkit attacks against your system. Lastly, general security principles say to minimize the attack surface, which would definitely mean you should protect the core of the system.
I cannot believe that somebody considers hiding kernel binary even
remotely viable 'security' measure. But let me accompany that for a
second and see what attack surface does the attacker get from knowing
the kernel binary ?

From inspecting quirks in the syscalls it is (almost trivially) easy
to reconstruct the date of kernel sources up to probably month, without
causing much observable havoc in the system. The kern.osreldate is around
as well, not only as sysctl, but also having some impact on the runtime
behaviour of several syscalls and image activators.

Same fingerprints are available from the sizes of the objects in UMA
zones, readily available from vmstat -z. Changes in the basic kernel
structures layout are reflected in the size changes.

Facilities like procstat -kk would show code reorganization and refactoring
changes.

The list above was written after about 10 minutes spent on thinking how
to identify the system sources without having access to binaries. I
believe another 10 minutes would give even more suggestions.
Post by Konstantin Belousov
Since you noted a 'security', I realized that your changes decrypt the
keys in the pre-kernel environment. In other words, very sensitive
material becoming accessible to strange and unknown code which is
managed by firmware.
The likelihood of such an attack, while something I considered, is very low. A key should look like random binary data (much like the GUIDs prevalent in EFI code). I seriously doubt someone could write a firmware module that could dig through the memory state of an arbitrary OS's boot loader and find keys. You'd basically have to put a full online binary analysis framework in the firmware, and have it run fast enough to not be noticed. That would be some serious Turing award-worthy work kept secret from the world solely to build firmware backdoors. I don't think even Lenovo would go that far.
(I know I mentioned scanning the kernel as a threat above; that's an offline attack that can be done on a copy. Online undetectable analysis of a running program is WAY harder.)
Nobody would scan for random data looking like keys. If attacker is
interested in keys from the freebsd loader or password decrypting the
keys, the address of the memory region where the material is stored and
region' layout are immediately available for any code collocated in the
common address space.

The hooks into the interfaces and pre-recorded sequence of calls for
the initialization of loader give unique execution profile which allow
to determine the password and key storage location.

Exact attack scenario is not the point I am trying to make. Instead, I
point out that UEFI execution environment is shared one, with no walls
between software components from arbitrary sources. It is absolutely
unsuitable for exposing sensitive material. Even more laughtable to
simultaneosly hide kernel binary.

In contrast with the kernel environment, which even with ME/BMC/ACPI/UEFI
runtime components, is less penetrable by trying to own the execution
state of the machine.
Besides, if someone wants to do evil things in firmware, I think it's far more likely they'd just backdoor the network or USB controllers to let someone send an override packet and execute bundled code in kernel mode. That works every time for every OS and doesn't require surreptitiously picking apart arbitrary programs' data structures in real time.
Of course backdoring hardware is order of magnitude harder and requires
physical access to the machine. The realistic action by level of script
kiddie is getting UEFI driver installed.

To close this branch, backdored busmasters (but not ME) are
trivially mitigated by enabling IOMMU, FWIW.
For what it's worth, I have considered possible hardening measures: using alias GUIDs to disguise interfaces and adding per-build padding or XOR masks to structures with keys to throw off scanners. However, I don't think the threat is realistic enough to warrant such measures.
I do not see a way to comment about the measures, without adding
the word 'theatre'.
Post by Konstantin Belousov
Putting aside ineradicable evil of Intel ME or its
AMD twin, and SMM handler, you are exposing keys to whatever code happen
to inhabit the preboot env, not neccessary originating from the firmware
vendor. Secure Boot would not help there, since when the measurement
indicate that untrusted component was there, it is too late. I.e.,
you making much easier for malice hacker to steal the keys.
I mean, the same argument holds for the kernel, if not moreso. You have ACPI bytecode, SMM, device blobs, anything that the boot environment chose to keep around for runtime by marking that memory as "unavailable", and of course, the evil that is Intel ME. This is an unavoidable risk of having keys in main memory ever.
See above.
If you really want any kind of safety from this, you need to use a hardware crypto device that stores keys in a separate memory (which, I specifically designed things to make it easy to add support for one). Of course, you then have to trust the device...
No, what I want is avoiding bad choices which are seemingly made just
because code can be written. Code exposing sensitive material is written
for very weak and leaking environment, at least without secure boot
turned on. Arguments supporting that decision reference 'security' by
e.g. hiding kernel binary, and undesire to have /boot partition. Please
take a step outside and see bigger picture.
Eric McCorkle
2016-05-29 14:10:16 UTC
Permalink
Post by Konstantin Belousov
Post by Konstantin Belousov
Post by Allan Jude
Post by Konstantin Belousov
Post by Eric McCorkle
I am pleased to announce that my work to add support for GELI in the EFI boot loader (as well as perform more general refactoring) is now ready for testing. I am able to successfully detect multiple GELI partitions in boot1 and pass the keys into the kernel.
Can somebody explain in which way this is useful ?
Same question for the GELI code for non-EFI loader.
BIOS cannot read raw data from the encrypted partition, so you need
either old boot or the loader and some additional data on EFI boot
partition anyway.
Features adds significant amount of code, which must be maintained in
parallel with the kernel code.
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
The motivation for my work (GELI in boot2 and loader for non-EFI boot)
was supporting ZFS boot environments. Previously, when you use GELI you
needed to have two ZFS pools, one for an unencrypted /boot and one for
the encrypted /
This breaks ZFS boot environments, since a snapshot of the root file
system won't include the correct kernel etc.
Why cannot /boot included into the boot environment ?
When I last saw Solaris, somewhere in its 10-th, any amount of
filesystems could be added to the bootenv. But whatever the definition
of bootenv is used, it exists at a level of the shell scripts and selecting
the actual partition for loader. Throw thousand lines of code into
the unstable and very hard to debug environment of loader looks somewhat
unproductive.
You misunderstand. Alan was talking about pure ZFS systems, where there is one big ZFS pool holding everything. You need to be able to access /boot obviously, but ZFS does not allow you to assign separate out data on to a single device. It creates a pool, which combines all devices.
To have /boot unencrypted, you have to have a separate partition for just /boot, which is undesirable.
Why it is undesirable ? You must have EFI boot partition by any means.
And why it is simultaneously desirable to add a bunch of code to loader
to hide this ?
It's undesirable because the whole point of ZFS is to have one ZFS volume for the whole system. The ESP is a minor annoyance that's unavoidable. But having to have a UFS volume or two ZFS systems just so I can keep the kernel, loader, and all the modules unencrypted is bad.
Post by Konstantin Belousov
Post by Konstantin Belousov
Post by Allan Jude
The final version of my geliboot took an extra effort to reuse the AES
code from sys/crypto/rijndael and sys/opencrypto and GELI directly from
sys/geom/eli to avoid maintaining a separate copy of that code in sys/boot
Which means that kernel code must be also runnable in the strange and
incompatible environment of the loader. I cannot see how this reduces
code maintanability even a bit. I am already rather unhappy about ZFS
kernel code being compiled as the userspace library, which hurt me
and other people more than once. Now (?) the kernel code must be also
verified for the loader.
I mean, the loader has to be able to access the filesystems, there's no way around it (barring crazy coreboot stuff).
Also, it should be possible to create a synthetic EFI test-harness that runs in *userland*. EFI is basically just a bunch of tables of function pointers, no bios interrupts or anything. As long as you implement the interfaces, any loader should also run in your synthetic environment. I had plans to look into this after this work is done.
Of course EFI is not 'just a bunch of tables'. It might look so when you
have tunnel vision and all you do is writing code making calls, but it
is definitely not when you consider it as a part of platform.
From the standpoint of building a synthetic test environment to make it easy to test and debug boot and loader code, it is.
Post by Konstantin Belousov
UEFI makes it absurdly easy to distribute a code that gets executed on
every boot before boot loaders. The most straighforward is to put UEFI
driver binary into the UEFI FAT and register it into some variables (too
lazy to remember details). You get this way both boot- and runtime-
injection, officially supported. This was one of the reason for secure
boot.
To avoid trivial debunks, I put a note that of course drivers are not
the only way for such code to appear on the system, without
requiring any hardware modifications. The rich programming environment,
with flat memory and full control over hardware, with easily explorable
data structures, with documented and compatible ways to get code
persistent are the characteristics of it.
It is much easier to target such preboot env then to maintain dynamic
list of the userspace escalation code.
Ok fine. But this is a risk anyone using EFI has to assume, and it doesn't end at the boot environment. There are plenty of nasty tricks an EFI boot environment can play that affect the OS as well. It's simply impossible for an OS to provide reliable security when the hardware or firmware is compromised, and this isn't limited to the boot loader.

This kind of thing is the reason for projects like coreboot gaining traction. If you really don't trust EFI, then the right answer is to use something like coreboot, or else don't use a system with EFI. Trying to compensate for this by keeping stuff out of the boot loader (and exposing vital parts of your system in a powered-off state) is futile, as a determined attacker can just set things up to compromise the kernel anyway.
Post by Konstantin Belousov
Post by Konstantin Belousov
Post by Allan Jude
Hopefully the work I did to make sys/opencrypto and sys/geom/eli more
reusable outside of the kernel will make it easier for Eric to do the
same for the EFI version.
The motivation for the EFI version is the same, ZFS boot environments,
plus the obvious security advantages of having the kernel stored
encrypted rather than not.
Obvious security advantages ? Seriously ?
What is a single 'security' advantage of hiding the kernel ?
There are plenty.
Right up at the top, an attacker able to access /boot is free to tamper with anything, and can insert back-doors into the kernel, loader, or any module. If you assume that the attacker can't write, then they can still scan the kernel and modules for signatures for known vulnerabilities (since the kernel itself has a commit id and detailed version info, they can compare this against a CVE database). Even if they can't do that for some reason, they could still potentially exfilt a kernel address map for use in rootkit attacks against your system. Lastly, general security principles say to minimize the attack surface, which would definitely mean you should protect the core of the system.
I cannot believe that somebody considers hiding kernel binary even
remotely viable 'security' measure. But let me accompany that for a
second and see what attack surface does the attacker get from knowing
the kernel binary ?
What you completely ignore in all this is the capability for an attacker to tamper with the unencrypted kernel, loader, and drivers.
Post by Konstantin Belousov
From inspecting quirks in the syscalls it is (almost trivially) easy
to reconstruct the date of kernel sources up to probably month, without
causing much observable havoc in the system. The kern.osreldate is around
as well, not only as sysctl, but also having some impact on the runtime
behaviour of several syscalls and image activators.
Same fingerprints are available from the sizes of the objects in UMA
zones, readily available from vmstat -z. Changes in the basic kernel
structures layout are reflected in the size changes.
Facilities like procstat -kk would show code reorganization and refactoring
changes.
The list above was written after about 10 minutes spent on thinking how
to identify the system sources without having access to binaries. I
believe another 10 minutes would give even more suggestions.
This is all academic. Yes, maybe someone can piece together what version of things I'm running. Of course, they'd have no idea what my address map looks like, unless they can get my compiler version and custom kernel config. Maybe there's some way to do that too.

But they get all of this with 100% accuracy by scanning the unencrypted boot partition, AND they can tamper with any of it. It's *just* less secure, plain and simple.
Post by Konstantin Belousov
Post by Konstantin Belousov
Since you noted a 'security', I realized that your changes decrypt the
keys in the pre-kernel environment. In other words, very sensitive
material becoming accessible to strange and unknown code which is
managed by firmware.
The likelihood of such an attack, while something I considered, is very low. A key should look like random binary data (much like the GUIDs prevalent in EFI code). I seriously doubt someone could write a firmware module that could dig through the memory state of an arbitrary OS's boot loader and find keys. You'd basically have to put a full online binary analysis framework in the firmware, and have it run fast enough to not be noticed. That would be some serious Turing award-worthy work kept secret from the world solely to build firmware backdoors. I don't think even Lenovo would go that far.
(I know I mentioned scanning the kernel as a threat above; that's an offline attack that can be done on a copy. Online undetectable analysis of a running program is WAY harder.)
Nobody would scan for random data looking like keys. If attacker is
interested in keys from the freebsd loader or password decrypting the
keys, the address of the memory region where the material is stored and
region' layout are immediately available for any code collocated in the
common address space.
No, they don't necessarily know the memory location at all. The keys are stored either in static variables (i.e. no symbol to tell you where it is), stack frames, or malloc data structures (and the static variable ones can be moved if it's REALLY a concern).

Plus you've got other operating systems with their own full disk encryption methods, as well as every revision of the FreeBSD boot loader.

Unless you're specifically targeting an individual for attack (in which case, going by your proposal, I could just tamper with their unencrypted kernel, so why would I bother with EFI tricks), you'd have to have either a huge number of profiles for every version of every OS boot loader, or you'd have to have some kind of analysis framework.
Post by Konstantin Belousov
The hooks into the interfaces and pre-recorded sequence of calls for
the initialization of loader give unique execution profile which allow
to determine the password and key storage location.
And this changes on every platform, with every revision, and is wildly different for other OSes. Moreover, this sort of attack is in no way unique to GELI, and could just as easily be used to insert a backdoor into a kernel, or anything else.
Post by Konstantin Belousov
Exact attack scenario is not the point I am trying to make. Instead, I
point out that UEFI execution environment is shared one, with no walls
between software components from arbitrary sources. It is absolutely
unsuitable for exposing sensitive material. Even more laughtable to
simultaneosly hide kernel binary.
In contrast with the kernel environment, which even with ME/BMC/ACPI/UEFI
runtime components, is less penetrable by trying to own the execution
state of the machine.
I see no reason why. Sure, it's bigger, but any method that could recover a key from a boot loader should also work on a kernel. These sorts of things have been demonstrated all the time in conference presentations, academic publications, and other venues.
Post by Konstantin Belousov
Besides, if someone wants to do evil things in firmware, I think it's far more likely they'd just backdoor the network or USB controllers to let someone send an override packet and execute bundled code in kernel mode. That works every time for every OS and doesn't require surreptitiously picking apart arbitrary programs' data structures in real time.
Of course backdoring hardware is order of magnitude harder and requires
physical access to the machine. The realistic action by level of script
kiddie is getting UEFI driver installed.
It seems you're considering only one kind of attacker, and specifically not the kind that are relevant to disk encryption.

The whole point of disk encryption IS to deal with people who have varying levels of physical access to your machine. By definition, the script kiddie of which you speak would be running their attacks when the encrypted partitions are all attached. So they'd have access to all the data anyway. The same holds for a more sophisticated attacker. Why would they bother with a fancy EFI malware when they already have access to all the data anyway.

I'll admit there may be some kind of persistent threat scenario where someone plants EFI malware to sniff keys at a later date, but this seems extraordinary rare. By contrast, data protection is a real thing: many organizations have requirements for full disk encryption, and there are people in the world who have to deal with getting harassed and having their computers seized and searched.
Post by Konstantin Belousov
To close this branch, backdored busmasters (but not ME) are
trivially mitigated by enabling IOMMU, FWIW.
For what it's worth, I have considered possible hardening measures: using alias GUIDs to disguise interfaces and adding per-build padding or XOR masks to structures with keys to throw off scanners. However, I don't think the threat is realistic enough to warrant such measures.
I do not see a way to comment about the measures, without adding
the word 'theatre'.
Right, which is why I decided they aren't worth it.
Post by Konstantin Belousov
Post by Konstantin Belousov
Putting aside ineradicable evil of Intel ME or its
AMD twin, and SMM handler, you are exposing keys to whatever code happen
to inhabit the preboot env, not neccessary originating from the firmware
vendor. Secure Boot would not help there, since when the measurement
indicate that untrusted component was there, it is too late. I.e.,
you making much easier for malice hacker to steal the keys.
I mean, the same argument holds for the kernel, if not moreso. You have ACPI bytecode, SMM, device blobs, anything that the boot environment chose to keep around for runtime by marking that memory as "unavailable", and of course, the evil that is Intel ME. This is an unavoidable risk of having keys in main memory ever.
See above.
If you really want any kind of safety from this, you need to use a hardware crypto device that stores keys in a separate memory (which, I specifically designed things to make it easy to add support for one). Of course, you then have to trust the device...
No, what I want is avoiding bad choices which are seemingly made just
because code can be written. Code exposing sensitive material is written
for very weak and leaking environment, at least without secure boot
turned on. Arguments supporting that decision reference 'security' by
e.g. hiding kernel binary, and undesire to have /boot partition. Please
take a step outside and see bigger picture.
I'd say the same to you...

You are only considering one kind of scenario. Alan's and my work is aimed at protecting systems from attackers that have some level of physical access to the machines. There are people in the world who have to contend with this sort of thing, and the major competing OSes (Apple, Linux, MS, etc) all have their own full-disk encryption solutions.

Moreover, my work is aimed at tamper-resilience at the OS level. Yes, I know OS tamper-resistance can be undermined without trusted firmware, but we are seeing projects like coreboot and others working toward that end. Moreover, these kinds of efforts are themselves pointless when the OS does things like leaving the most sensitive part of the system wide open to tampering.

Speaking personally, I would like to see a system where I have full disk encryption combined with EFI secure boot with a unique platform key stored on my encrypted disk. Having an unencrypted boot partition in such a system just opens up more attacks, plain an simple. (I would also like to see an open source firmware and no ME, but that's out of scope here)

Finally, it's not like Alan's and my work *forces* anyone to use GELI. If you are really worried about some scenario where an attacker doesn't have physical access and needs to backdoor the firmware to sniff keys so they can access data they can't see despite being able to write to firmware, then fine, don't use GELI at boot. Better yet, use the compile flag to remove it from boot1 and loader completely. But if you want full disk encryption, you have the option of having it.
Konstantin Belousov
2016-05-31 12:04:18 UTC
Permalink
Post by Eric McCorkle
Ok fine. But this is a risk anyone using EFI has to assume, and it doesn't end at the boot environment. There are plenty of nasty tricks an EFI boot environment can play that affect the OS as well. It's simply impossible for an OS to provide reliable security when the hardware or firmware is compromised, and this isn't limited to the boot loader.
This statement, althought looking true, does not account for difference
in the level of efforts required to target the corresponding environment.
Post by Eric McCorkle
This kind of thing is the reason for projects like coreboot gaining traction. If you really don't trust EFI, then the right answer is to use something like coreboot, or else don't use a system with EFI. Trying to compensate for this by keeping stuff out of the boot loader (and exposing vital parts of your system in a powered-off state) is futile, as a determined attacker can just set things up to compromise the kernel anyway.
No, you do not understand, or went into the protective mode where the
broad statements should cover the place. I am fine with the security
implications of the UEFI environment activating the kernel. I am not
fine with exposing the sensitive material to UEFI boot. Same from the
classic BIOS.
Post by Eric McCorkle
What you completely ignore in all this is the capability for an attacker to tamper with the unencrypted kernel, loader, and drivers.
At which point would the attacker tamper ? Immediately after your
GELI UEFI code provides him with the keys to do so ?
Post by Eric McCorkle
This is all academic. Yes, maybe someone can piece together what version of things I'm running. Of course, they'd have no idea what my address map looks like, unless they can get my compiler version and custom kernel config. Maybe there's some way to do that too.
But they get all of this with 100% accuracy by scanning the unencrypted boot partition, AND they can tamper with any of it. It's *just* less secure, plain and simple.
Ok, another 'security' theatre.

Let me restate the question I aked in my first mail, but now after
having the discussion rolled forward. Is there any other 'security'
benefit from having /boot encrypted, other than obscuring the kernel
binary ?
Post by Eric McCorkle
You are only considering one kind of scenario. Alan's and my work is aimed at protecting systems from attackers that have some level of physical access to the machines. There are people in the world who have to contend with this sort of thing, and the major competing OSes (Apple, Linux, MS, etc) all have their own full-disk encryption solutions.
Moreover, my work is aimed at tamper-resilience at the OS level. Yes, I know OS tamper-resistance can be undermined without trusted firmware, but we are seeing projects like coreboot and others working toward that end. Moreover, these kinds of efforts are themselves pointless when the OS does things like leaving the most sensitive part of the system wide open to tampering.
Speaking personally, I would like to see a system where I have full disk encryption combined with EFI secure boot with a unique platform key stored on my encrypted disk. Having an unencrypted boot partition in such a system just opens up more attacks, plain an simple. (I would also like to see an open source firmware and no ME, but that's out of scope here)
What you describe makes even less sense. If secure boot is in action,
then kernel binary should be measured and its fingerprints compared with
the protected records in TPM. Then all the layers that you add are
useless.
Post by Eric McCorkle
Finally, it's not like Alan's and my work *forces* anyone to use GELI. If you are really worried about some scenario where an attacker doesn't have physical access and needs to backdoor the firmware to sniff keys so they can access data they can't see despite being able to write to firmware, then fine, don't use GELI at boot. Better yet, use the compile flag to remove it from boot1 and loader completely. But if you want full disk encryption, you have the option of having it.
It forces us to maintain that code. It pulls large amount of code into
environment that is hard to debug in the comfortable local setup, and is
absolutely impossible to inspect and diagnose in the wild, where the
problems occur on the user machine.

All that cost for the only 'security' provided not exposing the kernel
binary.
Eric McCorkle
2016-06-01 04:22:10 UTC
Permalink
Post by Konstantin Belousov
Post by Eric McCorkle
Ok fine. But this is a risk anyone using EFI has to assume, and it doesn't end at the boot environment. There are plenty of nasty tricks an EFI boot environment can play that affect the OS as well. It's simply impossible for an OS to provide reliable security when the hardware or firmware is compromised, and this isn't limited to the boot loader.
This statement, althought looking true, does not account for difference
in the level of efforts required to target the corresponding environment.
It is not any more difficult; BIOS/EFI based exploits against kernels /already exist/, have been demoed in multiple forums, and have been discovered in the wild. As a PoC, a simple kernel exploit might like this:

1) replace bios disk read/EFI block read with malware that tracks contiguous sections of memory written by disk reads.
2) look for ELF headers in any such sections
3) store runtime malware in a memory section disguised in the memory map as an option rom or something similar
4) insert a trap similar to what debuggers do at the start point of any elf file you detect, have the traps jump into the runtime malware
5) once you trap into the runtime malware, you have them. If you just want GELI keys, I'd say drop another debugging-style trap in geli_taste, but the possibilities are really endless (just deploy your favorite rootkit)

But the fact is, you can find this kind of thing on the dark web today (or referenced in leaked documents, or just go to DefCon or some other venue). Someone would have to actively sit down and write malware to sniff GELI keys in the boot loader, where they can just use what already exists if they want to back-door the kernel.
Post by Konstantin Belousov
Post by Eric McCorkle
What you completely ignore in all this is the capability for an attacker to tamper with the unencrypted kernel, loader, and drivers.
At which point would the attacker tamper ? Immediately after your
GELI UEFI code provides him with the keys to do so ?
No this attack is *offline*. I'm going to break down all the major attack scenarios here, because you don't seem to get what I'm talking about.

1) Attacker has physical access, tampers with machine while offline, possesses ability to tamper with all hardware. This is mentioned only for completeness. You're helpless with or without full disk encryption, as they just put a hardware keylogger in place (or anything else, really). A variation on this is the malevolent bios/EFI code scenario, in which they just deploy an already existing rootkit on you.

2) Attacker has physical access, tampers with machine while offline, only possesses ability to tamper with disk. Without full-disk encryption, they insert malware into the unprotected kernel, loader, or modules. They cannot do this with full-disk encryption, as they can't read the contents of /boot at all.

3) Attacker seizes/steals machine while offline. With or without full-disk encryption, there is no way to obtain most of the data. There is an information leak from examining unencrypted drivers, configs, and the kernel. This doesn't compromise this specific machine, as we assume we will never regain the machine. However, the attacker can potentially learn something about how we configure machines. In the worst case, they discover something that could be used to attack other machines (unpatched CVE, etc). Some organizations and people *do* consider this worth protecting against.

4) Attacker seizes/steals machine while online. Again, this is for completeness sake. They get all the data in either case.

5) Attacker accesses machine remotely while online, gains sufficient privileges to tamper with filesystems and disks. Total disclosure in either case. They just steal the data directly, or tamper with loader/kernel if they *really* want the keys.

6) Same as #5, but they are also able to flash firmware. No difference. They may actually mess with the firmware if they're mean or if they're doing some kind of persistent penetration, but in all likelihood they just steal the data or backdoor loader and kernel again.

Takeaway: there's no scenario where an attacker would be able to sniff GELI keys in the boot loader that they can't already get the keys today (or do worse), therefore, they gain no significant advantage from GELI keys being present at boot time. By contrast, a backdoor is defeated in scenario #2 and an information leak is defeated in scenario #3, meaning full disk encryption *does* provide an advantage.
Post by Konstantin Belousov
Let me restate the question I aked in my first mail, but now after
having the discussion rolled forward. Is there any other 'security'
benefit from having /boot encrypted, other than obscuring the kernel
binary ?
I will say that it denies them the ability to tamper with it offline, since you have not yet acknowledged that case yourself.

Aside from denying attackers the ability to read *and tamper with* the kernel, loader, modules, possible configurations, and other data given offline access to the machine, no there isn't any other advantage I can think of.
Post by Konstantin Belousov
Post by Eric McCorkle
You are only considering one kind of scenario. Alan's and my work is aimed at protecting systems from attackers that have some level of physical access to the machines. There are people in the world who have to contend with this sort of thing, and the major competing OSes (Apple, Linux, MS, etc) all have their own full-disk encryption solutions.
Moreover, my work is aimed at tamper-resilience at the OS level. Yes, I know OS tamper-resistance can be undermined without trusted firmware, but we are seeing projects like coreboot and others working toward that end. Moreover, these kinds of efforts are themselves pointless when the OS does things like leaving the most sensitive part of the system wide open to tampering.
Speaking personally, I would like to see a system where I have full disk encryption combined with EFI secure boot with a unique platform key stored on my encrypted disk. Having an unencrypted boot partition in such a system just opens up more attacks, plain an simple. (I would also like to see an open source firmware and no ME, but that's out of scope here)
What you describe makes even less sense. If secure boot is in action,
then kernel binary should be measured and its fingerprints compared with
the protected records in TPM. Then all the layers that you add are
useless.
There is still the information disclosure. Also, some people don't have hardware supporting secure boot.
Post by Konstantin Belousov
Post by Eric McCorkle
Finally, it's not like Alan's and my work *forces* anyone to use GELI. If you are really worried about some scenario where an attacker doesn't have physical access and needs to backdoor the firmware to sniff keys so they can access data they can't see despite being able to write to firmware, then fine, don't use GELI at boot. Better yet, use the compile flag to remove it from boot1 and loader completely. But if you want full disk encryption, you have the option of having it.
It forces us to maintain that code. It pulls large amount of code into
environment that is hard to debug in the comfortable local setup, and is
absolutely impossible to inspect and diagnose in the wild, where the
problems occur on the user machine.
That is a legitimate concern, though I think it's way overblown here. The GELI code in the boot loader is simply not that complicated, nor is it that large. It's mostly calling some crypto functions and reading some metadata. As for my changeset, the majority of it is just EFI boilerplate to implement various protocol interfaces (EFI is a rather tedious framework in some ways).

A more constructive direction for this, I think, would be to figure out how to reduce duplication and improve testability. The GELI functionality used in Alan's and my work ought to be pretty easily testable; all you need for a test suite is to make a few GELI volumes and turn their metadata blocks into a constant array. Additionally, things could probably be refactored such that there could be a single implementation of the metadata and crypto handling bits. (I was also asking in another branch if a similar thing couldn't be done for the crypto code itself). The userland EFI test framework I put forward is another way to deal with the difficulties of maintaining boot loader code...
Wojciech Puchar
2016-06-01 14:29:16 UTC
Permalink
Post by Eric McCorkle
It's undesirable because the whole point of ZFS is to have one ZFS volume for the whole system.
This sounds more like a religious dogma than anything else.

what if i run single disk (or mirrored 2 disk) system, no ZFS but i want
everything encrypted by GELI and want only ona partition?

Will you write special bootloader that would be hidden unencrypted on geli
volume?

Will you write 10000 special bootloaders to cope with 10000 cases of
configuration FreeBSD admins want to have in the world?

Or maybe - in the future admins would not be allowed to decide and there
will be only one allowed storage configuration - ZFS volume occupying all
disks, with bootloader designed for that one case?

Seems i made about year ago a right decision to stick to
FreeBSD-10.(between 0 and 1) and then manually apply only security patches
and once backport needed driver from newer one....
Eric McCorkle
2016-06-01 14:40:37 UTC
Permalink
Post by Wojciech Puchar
Post by Eric McCorkle
It's undesirable because the whole point of ZFS is to have one ZFS volume for the whole system.
This sounds more like a religious dogma than anything else.
what if i run single disk (or mirrored 2 disk) system, no ZFS but i want everything encrypted by GELI and want only ona partition?
So do it. I don't see the problem.
Post by Wojciech Puchar
Will you write special bootloader that would be hidden unencrypted on geli volume?
No, the boot block lives either on the ESP or the boot sector. Same as it always has.
Post by Wojciech Puchar
Will you write 10000 special bootloaders to cope with 10000 cases of configuration FreeBSD admins want to have in the world?
Or maybe - in the future admins would not be allowed to decide and there will be only one allowed storage configuration - ZFS volume occupying all disks, with bootloader designed for that one case?
These are just straw-man arguments, and nobody has suggested anything of the sort.
Joerg Sonnenberger
2016-06-01 14:47:38 UTC
Permalink
Post by Wojciech Puchar
Post by Eric McCorkle
It's undesirable because the whole point of ZFS is to have one ZFS
volume for the whole system.
This sounds more like a religious dogma than anything else.
If "ZFS volume" means "ZFS pool" here, it is also blatant bullshit.
There are a lot of reasons for having more than one ZFS pool, the
easiest being separating SSDs and HDDs for fast vs cheap storage.

Joerg
Allan Jude
2016-06-01 15:14:49 UTC
Permalink
Post by Joerg Sonnenberger
Post by Wojciech Puchar
Post by Eric McCorkle
It's undesirable because the whole point of ZFS is to have one ZFS
volume for the whole system.
This sounds more like a religious dogma than anything else.
If "ZFS volume" means "ZFS pool" here, it is also blatant bullshit.
There are a lot of reasons for having more than one ZFS pool, the
easiest being separating SSDs and HDDs for fast vs cheap storage.
Joerg
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
Again, my only motivation for adding GELI encryption support to
gptzfsboot was to allow ZFS Boot Environments, one of the biggest
selling features of ZFS-on-root, to work with GELI encrypted disks.

For boot environments to work, your kernel must reside in the / (root)
ZFS dataset, so it can be snapshotted and cloned along with the rest of
the base system.

You can still use multiple pools.

But for this useful feature to work, you need to be able to use a single
pool, so I made it so. I added support for UFS, because it was only ~10
more lines of code.

In my geliboot work, no new crypto code is introduced. It just reuses
GELI and OpenCrypto.

The entire geliboot codebase is only 450 lines including license and
comments, mostly of boilerplate, and 100 lines of .h file to bridge the
gap between the kernel and the boot2/loader environments.
--
Allan Jude
Joerg Sonnenberger
2016-06-01 15:39:03 UTC
Permalink
Again, my only motivation for adding GELI encryption support to gptzfsboot
was to allow ZFS Boot Environments, one of the biggest selling features of
ZFS-on-root, to work with GELI encrypted disks.
I'm not saying anything against your patch. We spoke about it before :)

Joerg
Karl Denninger
2016-06-01 15:34:08 UTC
Permalink
Post by Allan Jude
Post by Joerg Sonnenberger
Post by Wojciech Puchar
Post by Eric McCorkle
It's undesirable because the whole point of ZFS is to have one ZFS
volume for the whole system.
This sounds more like a religious dogma than anything else.
If "ZFS volume" means "ZFS pool" here, it is also blatant bullshit.
There are a lot of reasons for having more than one ZFS pool, the
easiest being separating SSDs and HDDs for fast vs cheap storage.
Joerg
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to
Again, my only motivation for adding GELI encryption support to
gptzfsboot was to allow ZFS Boot Environments, one of the biggest
selling features of ZFS-on-root, to work with GELI encrypted disks.
For boot environments to work, your kernel must reside in the / (root)
ZFS dataset, so it can be snapshotted and cloned along with the rest
of the base system.
You can still use multiple pools.
But for this useful feature to work, you need to be able to use a
single pool, so I made it so. I added support for UFS, because it was
only ~10 more lines of code.
In my geliboot work, no new crypto code is introduced. It just reuses
GELI and OpenCrypto.
The entire geliboot codebase is only 450 lines including license and
comments, mostly of boilerplate, and 100 lines of .h file to bridge
the gap between the kernel and the boot2/loader environments.
I just want to add to this -- using Geli-encrypted volumes is fine as
things sit now, _*but*_ you cannot do so _*and*_ have BEADM (boot
environments) work properly which is a huge problem from a standpoint of
deployment and maintainability for complex installations /where//kernel
and system updates are made from time to time to either fix bugs or roll
forward new versions.

/This becomes a quite-material issue as security problems are found and
fixed. With BE you clone the running environment, install the patch
onto the cloned copy and reboot. Further, the previous (unpatched) copy
remains available until you wish to dump it should there prove to be a
problem with the patch or update you deployed.
/
/BE is a big deal in this regard, as it makes reverting such a change a
near-instant operation if it goes sideways on you and sometimes these
sorts of things *do* go sideways. Without root-on-boot for the booting
pool, however, you have to manually sync things back and forth and the
risk of a mistake is quite high -- and a mistake can cost you data on a
production system.

Reducing the attack surface (somewhat) is a (convenient) side effect;
the real benefit is in maintainability as patches and new versions are
released.
--
Karl Denninger
***@denninger.net <mailto:***@denninger.net>
/The Market Ticker/
/[S/MIME encrypted email preferred]/
Wojciech Puchar
2016-06-04 05:51:52 UTC
Permalink
Post by Karl Denninger
I just want to add to this -- using Geli-encrypted volumes is fine as
things sit now, _*but*_ you cannot do so _*and*_ have BEADM (boot
environments) work properly which is a huge problem from a standpoint of
???


/dev/mirror/root.eli 3857667076 3059125276 798541800 79% /
/dev/mirror/boot 251544 87408 164136 35% /b

lrwxr-xr-x 1 root wheel 7 21 mar 08:28 boot -> /b/boot
Wojciech Puchar
2016-06-01 15:19:36 UTC
Permalink
Post by Joerg Sonnenberger
Post by Wojciech Puchar
This sounds more like a religious dogma than anything else.
If "ZFS volume" means "ZFS pool" here, it is also blatant bullshit.
There are a lot of reasons for having more than one ZFS pool, the
easiest being separating SSDs and HDDs for fast vs cheap storage.
assuming one would like to use ZFS - it is of course right. As with any
other filesystem.

Even more - no matter what filesystem i would use i would never want to
put tens of disks as one filesystem. for simple reason of recovery and
reliability.

And i consider FreeBSD loader already overcomplex. having separate
partition for boot stuff is just fine. After kernel is loaded it takes
care of all stuff.
Allan Jude
2016-06-01 15:24:45 UTC
Permalink
Post by Wojciech Puchar
Post by Joerg Sonnenberger
Post by Wojciech Puchar
This sounds more like a religious dogma than anything else.
If "ZFS volume" means "ZFS pool" here, it is also blatant bullshit.
There are a lot of reasons for having more than one ZFS pool, the
easiest being separating SSDs and HDDs for fast vs cheap storage.
assuming one would like to use ZFS - it is of course right. As with any
other filesystem.
Even more - no matter what filesystem i would use i would never want to
put tens of disks as one filesystem. for simple reason of recovery and
reliability.
And i consider FreeBSD loader already overcomplex. having separate
partition for boot stuff is just fine. After kernel is loaded it takes
care of all stuff.
_______________________________________________
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
Well, that is kind of the point of ZFS, to have a filesystem with more
than just a few disks, but reliably.

We are not taking anything away from you, just allowing you to have the
option to keep the kernel in a convenient place.
--
Allan Jude
Freddie Cash
2016-06-01 15:25:32 UTC
Permalink
Post by Joerg Sonnenberger
Post by Wojciech Puchar
Post by Eric McCorkle
It's undesirable because the whole point of ZFS is to have one ZFS
volume for the whole system.
This sounds more like a religious dogma than anything else.
If "ZFS volume" means "ZFS pool" here, it is also blatant bullshit.
There are a lot of reasons for having more than one ZFS pool, the
easiest being separating SSDs and HDDs for fast vs cheap storage.
​No one is saying you can't have multiple ZFS pools in a system. For
example, there's nothing wrong with having a "system" pool where the OS is
installed (say, on SSD), and a "storage" pool where all your data goes
(say, on a dozen hard drives).

But, in order to properly support ZFS Boot Environments, you *NEED* to have
/boot as a directory on the / (root) filesystem in a ZFS pool.​

​ When you create BEs, you snapshot and clone the root filesystem
(ideally, which includes the entire base OS install). If you have a
separate /boot partition outside of the BE, things get hairy, out-of-sync,
hard-to-manage, and cause all kinds of issues with versioning of boot
blocks, loader, kernel, modules, and OS.

If you want to encrypt a ZFS-on-root install *AND*​ use Boot Environments,
then you need to have a way to load the GELI stuff and access the ZFS pool
... without having a separate /boot; ie from the loader.
--
Freddie Cash
***@gmail.com
Joerg Sonnenberger
2016-06-01 15:40:41 UTC
Permalink
Post by Freddie Cash
Post by Joerg Sonnenberger
Post by Wojciech Puchar
Post by Eric McCorkle
It's undesirable because the whole point of ZFS is to have one ZFS
volume for the whole system.
This sounds more like a religious dogma than anything else.
If "ZFS volume" means "ZFS pool" here, it is also blatant bullshit.
There are a lot of reasons for having more than one ZFS pool, the
easiest being separating SSDs and HDDs for fast vs cheap storage.
No one is saying you can't have multiple ZFS pools in a system. For
example, there's nothing wrong with having a "system" pool where the OS is
installed (say, on SSD), and a "storage" pool where all your data goes
(say, on a dozen hard drives).
But, in order to properly support ZFS Boot Environments, you *NEED* to have
/boot as a directory on the / (root) filesystem in a ZFS pool.
I am fully aware of that. It is also quite different from what Wojciech
wrote. As such, Alan, just go on...

Joerg
Wojciech Puchar
2016-06-01 15:44:26 UTC
Permalink
Post by Freddie Cash
But, in order to properly support ZFS Boot Environments, you *NEED* to have
/boot as a directory on the / (root) filesystem in a ZFS pool.?
i didn't know that and .... boot reliably ;)
Wojciech Puchar
2016-06-01 14:23:30 UTC
Permalink
Post by Konstantin Belousov
And why it is simultaneously desirable to add a bunch of code to loader
to hide this ?
For me it is nonsense ending with having another copy of kernel as boot
loader ;), which will in turn require another normal boot loader to load
it ;)
Eric McCorkle
2016-06-01 14:32:08 UTC
Permalink
Post by Konstantin Belousov
And why it is simultaneously desirable to add a bunch of code to loader
to hide this ?
For me it is nonsense ending with having another copy of kernel as boot loader ;), which will in turn require another normal boot loader to load it ;)
What are you talking about? Nobody's added another stage to the boot loader, nor is anyone advocating doing so.
Wojciech Puchar
2016-06-01 15:16:17 UTC
Permalink
Post by Eric McCorkle
Post by Konstantin Belousov
to hide this ?
For me it is nonsense ending with having another copy of kernel as boot loader ;), which will in turn require another normal boot loader to load it ;)
What are you talking about?
about FreeBSD team doing nonsense,
Wojciech Puchar
2016-06-01 14:22:22 UTC
Permalink
To have /boot unencrypted, you have to have a separate partition for just /boot, which is undesirable.
what a problem?

it is standard on ALL my instalations - just to have booting independent
of configuration i make. i often put this (by using gmirror or making
copies) on all disks so i don't have to care about disk numbering etc.
Wojciech Puchar
2016-05-28 16:38:52 UTC
Permalink
Post by Konstantin Belousov
Post by Eric McCorkle
I am pleased to announce that my work to add support for GELI in the EFI boot loader (as well as perform more general refactoring) is now ready for testing. I am able to successfully detect multiple GELI partitions in boot1 and pass the keys into the kernel.
Can somebody explain in which way this is useful ?
Same question for the GELI code for non-EFI loader.
No idea.

simply keep /boot in separate partition no matter if booting with EFI or
not. that's all.
Continue reading on narkive:
Loading...