|
|
Subscribe / Log in / New account

Inline encryption for filesystems

By Jonathan Corbet
August 27, 2019
The encryption of data at rest is increasingly mandatory in a wide range of settings from mobile devices to data centers. Linux has supported encryption at both the filesystem and block-storage layers for some time, but that support comes with a cost: either the CPU must encrypt and decrypt vast amounts of data moving to and from persistent storage or it must orchestrate offloading that work to a separate device. It was thus only a matter of time before ways were found to offload that overhead to the storage hardware itself. Satya Tangirala's inline encryption patch set is intended to enable the kernel to take advantage of this hardware in a general manner.

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
KernelSecurity/Filesystem encryption
SecurityEncryption/Filesystems


to post comments

Inline encryption for filesystems

Posted Aug 27, 2019 20:39 UTC (Tue) by Spack (subscriber, #77556) [Link] (13 responses)

What device could specifically benefit from this support? Can we already find such drives on the market?

Inline encryption for filesystems

Posted Aug 27, 2019 20:55 UTC (Tue) by mjg59 (subscriber, #23239) [Link] (11 responses)

This is already common in phones, where the flash controller in the SoC has support for doing the encryption in hardware.

Inline encryption for filesystems

Posted Aug 27, 2019 21:48 UTC (Tue) by theonewolf (guest, #118690) [Link] (10 responses)

SSDs also usually implement it under the TCG OPAL standard. Most SSDs are full self-encrypting drives (SEDs) today.

Inline encryption for filesystems

Posted Aug 27, 2019 22:04 UTC (Tue) by mjg59 (subscriber, #23239) [Link] (9 responses)

The distinction is (to my understanding) the degree of control that the OS has over the encryption. In the Opal case, all that's exposed to the OS is the session management and authentication for encrypted regions. In the case being discussed here, you have the ability to define the encryption algorithm and even disable it - you still have direct access to the flash, which means you can read back the encrypted content and verify that the controller is encrypting in the expected manner.

Inline encryption for filesystems

Posted Aug 27, 2019 22:06 UTC (Tue) by theonewolf (guest, #118690) [Link]

Ah, you might be right on that. I haven't explored this deeply (honestly haven't ventured much into Opal).

I don't know about reading the raw data back!

Inline encryption for filesystems

Posted Aug 27, 2019 23:58 UTC (Tue) by quotemstr (subscriber, #45331) [Link] (7 responses)

> read back the encrypted content and verify that the controller is encrypting in the expected manner.

Preferably after a power cycle so the controller can't lie.

Inline encryption for filesystems

Posted Aug 27, 2019 23:58 UTC (Tue) by quotemstr (subscriber, #45331) [Link] (6 responses)

Oh, wait. Never mind. The controller can lie regardless, can't it? That is, can't it just store the plaintext and encrypt the data on the fly when you read back the "raw" contents?

Inline encryption for filesystems

Posted Aug 28, 2019 0:22 UTC (Wed) by Cyberax (✭ supporter ✭, #52523) [Link] (5 responses)

Even better, store all the keys and give them out if presented with a special NSA_HERE packet.

Inline encryption for filesystems

Posted Aug 28, 2019 0:24 UTC (Wed) by quotemstr (subscriber, #45331) [Link]

Yeah, but that approach doesn't help you win on benchmarks.

Inline encryption for filesystems

Posted Aug 29, 2019 3:02 UTC (Thu) by ebiggers (subscriber, #130760) [Link] (3 responses)

Sure, and the CPU could do the same when it sees an AES instruction.

Ultimately, you always need some level of trust in the hardware...

Inline encryption for filesystems

Posted Aug 29, 2019 3:09 UTC (Thu) by Cyberax (✭ supporter ✭, #52523) [Link]

It's a bit more difficult with AES-NI. You have to somehow store the keys at a pretty good rate, and there's simply not enough space on the CPU die for this.

But storing a handful of keys supplied for decryption of fairly large blocks of data? Easy.

Inline encryption for filesystems

Posted Aug 31, 2019 6:03 UTC (Sat) by ssmith32 (subscriber, #72404) [Link]

And I just sent a colleague Ken Thompson's trusting trust (to point out you need to trust the writers of software *cough* bitcoin *cough*, there's no magic algo that makes it go away altogether..).

Makes me smile that the paper stays relevant after all the years...!

Inline encryption for filesystems

Posted Sep 1, 2019 18:15 UTC (Sun) by robert_s (subscriber, #42402) [Link]

It would be many orders of magnitude harder to do this and not "get caught" at any point in the product's lifetime.

Inline encryption for filesystems

Posted Aug 27, 2019 21:47 UTC (Tue) by theonewolf (guest, #118690) [Link]

Technically I think SSDs already have this kind of technology: https://www.micron.com/-/media/documents/products/white-p...

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

Inline encryption for filesystems

Posted Aug 28, 2019 2:13 UTC (Wed) by sbates (subscriber, #106518) [Link] (1 responses)

AFAIK there is no vendor-neutral interface into the engines (compression, encryption etc) that some of these SSDs provide. There is some activity within SNIA to try and remedy this situation and define said interfaces for at least some of the most common engines. The expectation is that this would feed into standards like T10 and NVM Express. However that's going to take time and then the vendors will need to produce product that aligns to those standard interfaces.

https://www.snia.org/computational

Inline encryption for filesystems

Posted Aug 29, 2019 1:02 UTC (Thu) by ebiggers (subscriber, #130760) [Link]

Inline encryption has been part of the UFSHCI standard since 2016. See the patchset, which adds support for it to Linux's UFS host controller driver.

Inline encryption for filesystems

Posted Aug 28, 2019 7:38 UTC (Wed) by markh (subscriber, #33984) [Link] (10 responses)

Am I the only one that is horrified by this?

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.

Inline encryption for filesystems

Posted Aug 28, 2019 7:45 UTC (Wed) by mjg59 (subscriber, #23239) [Link] (3 responses)

The controller is on the SoC. If the SoC vendor can't be trusted, there are any number of ways they can extract private data already.

Inline encryption for filesystems

Posted Aug 28, 2019 10:47 UTC (Wed) by juliank (guest, #45896) [Link] (1 responses)

This does not apply to devices where the storage is replaceable.

Inline encryption for filesystems

Posted Aug 28, 2019 15:20 UTC (Wed) by mjg59 (subscriber, #23239) [Link]

Using this for devices where the storage is replaceable is already a bad idea - you've then got unencrypted information going over a bus that's trivial to interpose.

Inline encryption for filesystems

Posted Aug 29, 2019 11:02 UTC (Thu) by LtWorf (subscriber, #124958) [Link]

Yes but building a CPU that understands what is a key and what isn't is a bit complicated. If you have an instruction "set key" it's all suddenly very very easy.

Inline encryption for filesystems

Posted Aug 28, 2019 13:14 UTC (Wed) by grove (guest, #1721) [Link] (4 responses)

I don't see a need to be "horrified by this". It's a way to make a feature available in some modern hardware available to the end user. If you don't trust all the hardware your information will have to pass through to use this, you should abstain from using that feature of your hardware.

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.

Inline encryption for filesystems

Posted Aug 28, 2019 15:02 UTC (Wed) by iabervon (subscriber, #722) [Link] (2 responses)

Even so, the API shown has a surprising number of methods that take key data and seems to be using the key data itself as the identifier of the key, rather than something less secret. Will keyslot_find be implemented in a way that doesn't leak bits of other keys via timing attacks or leave key bits beyond the end of the stack or in memory that could be reused uninitialized?

Inline encryption for filesystems

Posted Aug 29, 2019 2:35 UTC (Thu) by ebiggers (subscriber, #130760) [Link] (1 responses)

Yes, the code always uses constant-time comparisons when comparing keys, and always zeroizes keys when they're no longer needed.

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.

Inline encryption for filesystems

Posted Aug 29, 2019 5:19 UTC (Thu) by iabervon (subscriber, #722) [Link]

Is there a single keyslot manager? I thought that was going to be up to each driver to implement, with the risk that some drivers wouldn't do as good a job of it as the implementation in the original patch set.

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.

Inline encryption for filesystems

Posted Aug 28, 2019 15:09 UTC (Wed) by markh (subscriber, #33984) [Link]

Trust is important but not the only concern; it is also about greatly increasing the attack surface. It's a lot easier to find a vulnerability if there are several possible software and hardware layers to choose from, many of which were not even designed with security in mind. It is only necessary to find a single weak spot to exploit.

Inline encryption for filesystems

Posted Aug 29, 2019 2:14 UTC (Thu) by ebiggers (subscriber, #130760) [Link]

As noted by another commenter, you need to trust the SoC vendor anyway.

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.

Usual vendor-firmware levels of quality and trustworthiness

Posted Aug 28, 2019 12:03 UTC (Wed) by hmh (subscriber, #3838) [Link] (2 responses)

Required reading:

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.

Usual vendor-firmware levels of quality and trustworthiness

Posted Aug 29, 2019 1:38 UTC (Thu) by ebiggers (subscriber, #130760) [Link]

Self-encrypting drives normally take a password, which can be changed later; they don't take the encryption key directly. Therefore, they have to implement key generation and wrapping themselves --- which is where the vulnerabilities actually are. It also means that software can't test the encryption for correctness.

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.

Final paper

Posted Aug 29, 2019 13:28 UTC (Thu) by CChittleborough (subscriber, #60775) [Link]

Here's the final paper, from the 40th IEEE Symposium on
Security and Privacy:
https://www.ieee-security.org/TC/SP2019/papers/310.pdf

Not good news.


Copyright © 2019, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds