Inline encryption for filesystems
The Linux storage stack consists of numerous layers, so it is unsurprising that an inline encryption implementation will require changes at a number of those layers. Hardware-offloaded encryption will clearly require support from the device driver to work, but the knowledge of which encryption keys to use typically comes from the filesystem running at the top of the stack. Communicating that information from the top to the bottom requires a certain amount of plumbing.
Low-level support
At the lowest level, device drivers that support inline encryption will have to provide an operations structure like this:
struct keyslot_mgmt_ll_ops { int (*keyslot_program)(void *ll_priv_data, const u8 *key, enum blk_crypto_mode_num crypto_mode, unsigned int data_unit_size, unsigned int slot); int (*keyslot_evict)(void *ll_priv_data, const u8 *key, enum blk_crypto_mode_num crypto_mode, unsigned int data_unit_size, unsigned int slot); bool (*crypto_mode_supported)(void *ll_priv_data, enum blk_crypto_mode_num crypto_mode, unsigned int data_unit_size); int (*keyslot_find)(void *ll_priv_data, const u8 *key, enum blk_crypto_mode_num crypto_mode, unsigned int data_unit_size); };
The interface is designed around hardware that provides a fixed number of "key slots", each of which can hold a cryptographic context — the algorithm to be used, associated parameters (the block size, for example), and the key. These functions exist to program a crypto context into the hardware, remove a crypto context from the hardware, determine whether a specific context is supported, and to determine which slot, if any, is already programmed for a given context. Drivers will register this structure and provide the total number of slots available.
Since the number of key slots provided by the hardware is fixed, it's entirely possible that there will not be enough to handle all of the I/O requests to a given device over a short period of time. That may not be a problem for a device that is occupied by a single, encrypted filesystem, but the situation could be different if there are a lot of filesystems present, or if per-directory encryption (as supported by the ext4 filesystem) is in use. So the kernel needs a way to arbitrate access to key slots, preferably one that limits the amount of (possibly expensive) slot reprogramming required.
That arbitration begins with a "key-slot manager" abstraction. It keeps track of which slots are available at any given time and, for those that are busy, how many references (held by in-flight I/O operations) exist to each. The key-slot manager can be used to allocate slots and program encryption contexts. In normal usage, many I/O requests will use the same context, so the key-slot manager tries to keep the most frequently used keys available to the hardware and avoids programming the same key into multiple slots.
Moving up a layer, the patch set adds a new bio_crypt_ctx structure to the BIO structure (which represents an I/O request). When filesystem code originates a request, it can add the relevant context information, and the BIO structure will carry that information through to the block device executing the request. Adding this information requires changes in other parts of the block layer; for example, two adjacent requests cannot be merged if they are using different encryption contexts.
blk-crypto
Adding key information to the BIO structure isn't quite enough, though. There is still the issue of slot management and actually programming crypto contexts into the hardware; while filesystems could arguably handle this work, it almost certainly makes sense to handle this common task within the block layer itself. But there is a further complication: the device to which a filesystem submits an I/O request may not be the device that ultimately handles that request. For example, a filesystem may be based on a RAID "device" created by the device-mapper layer; code at the filesystem level will be entirely unaware of the real physical devices that have been assembled into the virtual device it sees. So filesystems cannot directly handle details like key-slot management.
The solution to this problem is the blk-crypto subsystem, which handles the details of managing key slots and getting the key information through to the right device drivers. Whenever a BIO is submitted for execution, the blk-crypto code reacts to the presence of a crypto context by allocating a slot from the key-slot manager associated with the (immediate) target device. That implies, for reasons that we'll return to shortly, that subsystems like the device mapper must implement a simple key-slot manager, even though they perform no encryption themselves.
Layered devices like the device manager will make any necessary modifications to BIOs they receive (including possibly splitting them into multiple BIOs), then turn around and resubmit the resulting BIOs to the lower-level devices. When this happens, the blk-crypto layer will release the key slot allocated at the intermediate level and allocate a new slot for the lower-level device, propagating the key material downward. This procedure will happen as many times as necessary until the BIO reaches a device that actually performs I/O.
The blk-crypto code has one other useful feature: if the target device does not actually support the type of encryption requested by the filesystem (or any encryption at all), blk-crypto will fall back to using the kernel's crypto layer instead. So filesystems can request encrypted data storage without any knowledge of whether the underlying hardware supports inline encryption or not. This functionality may eventually replace the fscrypt code currently used by ext4 and F2FS to implement encryption.
The crypto-layer fallback explains why intermediate block layers must provide their own key-slot managers. The block layer never knows whether a given BIO will be resubmitted to a lower-level device later on, so it must assume that every submission is the final one. As a result, if encryption is being performed by the kernel's crypto layer, that must happen before submitting the BIO to the device; there will be no opportunity to do so afterward. The lack of a key-slot manager for any given device is a signal to the block layer that inline encryption is not supported, so the crypto-layer fallback will be performed in that case; thereafter there is no point in using inline encryption for that request even if turns out to be available. Adding a key-slot manager to layers like the device mapper is, among other things, a way of preventing the block layer from falling back too soon.
The patch set includes a low-level implementation for Universal Flash Storage devices and upper-level support for the F2FS filesystem. As one might expect, this work is being driven by Android use cases; encrypted filesystems are important for Android devices, and offloading the actual encryption to the hardware should save both CPU time and power.
Given the potential value of this feature, it is not surprising that there
have been a few attempts to add support to the kernel. The patch set
mentions three of them: a hardware-specific
solution that lacks generality, one that is implemented
within the crypto layer (seen as the wrong place, since it's not a
general cryptographic primitive), and one that requires
the device mapper to function. This implementation is an attempt to
avoid those problems and provide a more general solution. It is in its
fourth revision and appears to be getting close to being ready to head upstream.
Index entries for this article | |
---|---|
Kernel | Security/Filesystem encryption |
Security | Encryption/Filesystems |
Posted Aug 27, 2019 20:39 UTC (Tue)
by Spack (subscriber, #77556)
[Link] (13 responses)
Posted Aug 27, 2019 20:55 UTC (Tue)
by mjg59 (subscriber, #23239)
[Link] (11 responses)
Posted Aug 27, 2019 21:48 UTC (Tue)
by theonewolf (guest, #118690)
[Link] (10 responses)
Posted Aug 27, 2019 22:04 UTC (Tue)
by mjg59 (subscriber, #23239)
[Link] (9 responses)
Posted Aug 27, 2019 22:06 UTC (Tue)
by theonewolf (guest, #118690)
[Link]
I don't know about reading the raw data back!
Posted Aug 27, 2019 23:58 UTC (Tue)
by quotemstr (subscriber, #45331)
[Link] (7 responses)
Preferably after a power cycle so the controller can't lie.
Posted Aug 27, 2019 23:58 UTC (Tue)
by quotemstr (subscriber, #45331)
[Link] (6 responses)
Posted Aug 28, 2019 0:22 UTC (Wed)
by Cyberax (✭ supporter ✭, #52523)
[Link] (5 responses)
Posted Aug 28, 2019 0:24 UTC (Wed)
by quotemstr (subscriber, #45331)
[Link]
Posted Aug 29, 2019 3:02 UTC (Thu)
by ebiggers (subscriber, #130760)
[Link] (3 responses)
Ultimately, you always need some level of trust in the hardware...
Posted Aug 29, 2019 3:09 UTC (Thu)
by Cyberax (✭ supporter ✭, #52523)
[Link]
But storing a handful of keys supplied for decryption of fairly large blocks of data? Easy.
Posted Aug 31, 2019 6:03 UTC (Sat)
by ssmith32 (subscriber, #72404)
[Link]
Makes me smile that the paper stays relevant after all the years...!
Posted Sep 1, 2019 18:15 UTC (Sun)
by robert_s (subscriber, #42402)
[Link]
Posted Aug 27, 2019 21:47 UTC (Tue)
by theonewolf (guest, #118690)
[Link]
I think most SSDs ship with it now: https://www.samsung.com/semiconductor/insights/news-event...
They are typically based on the TCG OPAL standard for self-encrypting drives (SEDs): https://en.wikipedia.org/wiki/Opal_Storage_Specification
Posted Aug 28, 2019 2:13 UTC (Wed)
by sbates (subscriber, #106518)
[Link] (1 responses)
Posted Aug 29, 2019 1:02 UTC (Thu)
by ebiggers (subscriber, #130760)
[Link]
Posted Aug 28, 2019 7:38 UTC (Wed)
by markh (subscriber, #33984)
[Link] (10 responses)
I thought it would be common sense to expect that encryption keys and plaintext would be restricted to the minimum number of layers possible, and that certainly under no circumstances would encryption keys be sent through several software and hardware layers to another possibly external device with its own proprietary firmware. This seems like the perfect architecture, if your goal is to enlarge the attack surface well beyond the ability of any one entity to manage, and maximize the number of potential interception points where keys or plaintext can be stolen.
I really hope that I'm missing something and this is not as bad as it sounds.
Posted Aug 28, 2019 7:45 UTC (Wed)
by mjg59 (subscriber, #23239)
[Link] (3 responses)
Posted Aug 28, 2019 10:47 UTC (Wed)
by juliank (guest, #45896)
[Link] (1 responses)
Posted Aug 28, 2019 15:20 UTC (Wed)
by mjg59 (subscriber, #23239)
[Link]
Posted Aug 29, 2019 11:02 UTC (Thu)
by LtWorf (subscriber, #124958)
[Link]
Posted Aug 28, 2019 13:14 UTC (Wed)
by grove (guest, #1721)
[Link] (4 responses)
For that reason (and probably a couple more) I don't expect the pure software encryption options will go away (we are too many who can see the problems in giving secret information to our hardware), but allowing others to use this feature of their hardware seems fine.
Posted Aug 28, 2019 15:02 UTC (Wed)
by iabervon (subscriber, #722)
[Link] (2 responses)
Posted Aug 29, 2019 2:35 UTC (Thu)
by ebiggers (subscriber, #130760)
[Link] (1 responses)
We could try to implement something fancy where the keyslot manager only remembers a cryptographic hash of each programmed key. But that would add extra overhead, and for now wouldn't truly buy us anything since the key still needs to be in kernel memory anyway, in case it needs to be programmed into a keyslot again.
Posted Aug 29, 2019 5:19 UTC (Thu)
by iabervon (subscriber, #722)
[Link]
Why not remember a struct key * instead of the data directly? It'd still be a pointer to the secret in kernel memory, but my impression is that they're not generally duplicated, so you could do all your management based on pointer equality, and leaking the values that have to be in your data structures to userspace would be less immediately bad.
Posted Aug 28, 2019 15:09 UTC (Wed)
by markh (subscriber, #33984)
[Link]
Posted Aug 29, 2019 2:14 UTC (Thu)
by ebiggers (subscriber, #130760)
[Link]
I'll also note that inline encryption is, effectively, already standard practice on mobile devices. All iOS devices use it, and currently the major Android SoC vendors are providing their own inline encryption solutions, including out-of-tree kernel patches, which are already used on most new mid to high end Android devices.
It will be much better to have vendor-independent, well-reviewed, and well-tested upstream Linux kernel code to support inline encryption, and common tests that everyone has to pass, rather than continue the status quo of everyone using their own out-of-tree patches.
Posted Aug 28, 2019 12:03 UTC (Wed)
by hmh (subscriber, #3838)
[Link] (2 responses)
https://www.ru.nl/publish/pages/909282/draft-paper.pdf
I am not sure I would trust the SoC vendors would do any better than the SSD vendors named in the paper.
Posted Aug 29, 2019 1:38 UTC (Thu)
by ebiggers (subscriber, #130760)
[Link]
Inline encryption hardware is different, since for standards complaint (e.g. UFSHCI 2.1) inline encryption hardware, software provides the encryption key(s) directly. Thus, the hardware doesn't do any key generation or wrapping, and the results can be compared with a software implementation.
So it's simply not possible to screw up the UFSHCI 2.1 crypto in the same ways that ATA Security and TCG OPAL self-encrypting drives have been screwed up. And if someone does nevertheless screw it up somehow, it's easily detectable by some basic comparison tests, unless the vendor *really* went out of their way to very deliberately do something malicious.
Posted Aug 29, 2019 13:28 UTC (Thu)
by CChittleborough (subscriber, #60775)
[Link]
Not good news.
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Inline encryption for filesystems
Usual vendor-firmware levels of quality and trustworthiness
Usual vendor-firmware levels of quality and trustworthiness
Final paper
Security and Privacy:
https://www.ieee-security.org/TC/SP2019/papers/310.pdf