From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from imap.thunk.org ([74.207.234.97]:33798 "EHLO imap.thunk.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756549AbcLPRcX (ORCPT ); Fri, 16 Dec 2016 12:32:23 -0500 Date: Fri, 16 Dec 2016 12:32:19 -0500 From: Theodore Ts'o To: linux-fsdevel@vger.kernel.org Cc: lsf-pc@lists.linux-foundation.org Subject: [LSF/MM TOPIC] Inline encryption support for block devices Message-ID: <20161216173219.rbh6scyk3kpd6by6@thunk.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Sender: linux-fsdevel-owner@vger.kernel.org List-ID: Many embedded SOC's are using in-line encryption engines (ICE) to accelerate encryption to storage devices. The way they work is that the ICE unit is located between the memory and the flash or other storage device, and when the OS submits the I/O, it includes an encryption key identifier, indicating which key (out of a small number that have been loaded into the ICE hardware) should be used. The hardware then takes care of doing the encryption without needing to keep the CPU busy doing the encryption, and without needing to use bounce buffers when writing encrypted blocks. There have been proposals to add this before[1]. However, those changes were fatally flawed since they completely bypassed the block layer, assumed that the device driver could derference the page->private pointer passed to it via the bio structure, assume it was a buffer_head pointer, then dereference b_assoc_map pointer to find the underlying file system inode, and then assume the inode belonged to ecryptfs, and then grab the key to be used out of ecryptfs's specific inode structure. [1] https://lkml.org/lkml/2015/11/8/70 Support for file system based encryption[2] is in the Pixel and Pixel XL devices, Google's flagship Android devices, and it provides the basis for the Direct Boot API[3]. Originally, ICE was not intended to enabled for use in the Pixel and Pixel XL devices. Unfortunately, due to performance concerns, a crash implementation was needed[4], and so Android had to bypass its policy of preferring upstream first development for core kernel features. [2] https://source.android.com/security/encryption/file-based.html [3] http://www.androidcentral.com/android-70-what-direct-boot [4] https://android-developers.googleblog.com/2016/11/pixel-security-better-faster-stronger.html We had to take some short-cuts while implementing this support, but we at least passed the information about which encryption key to use via the struct bio, instead of peaking in private powers where device drivers had no business looking at. However, what landed for the Pixel devices was definitely not what I would consider a clean design, and it's time to try to clean this up for upstream use. Fortunately, Michael Halcrow has a team of eager programmers to work on this, and so I'd like to talk about what the design should look like when we try to get this work upstream. Passing a key slot identifer in the struct bio is relatively straightforward. The trick is in the API between the file system and the block device to determine which key slot should be used, given the desired key that the fs/crypto layer would like to use. Also, there is the question of how to negotiate which encryption suite should be used, for those ICE implementations that might allow the use of more than one encryption suite. Furthermore, I would like to future proof the design to handle scenarios where the OS does not have access to the keying information at all, but instead passes a key identifier to the block device, and then block device would then pass the key identifier to a secure hardware element such ARM Trustzone, which would then load the key into the Inline Crypto Engine. This would allow us to answer criticisms[5] that while the key is secure while the device is off, the key is still in the host OS memory while the device after the user has entered her password or PIN, and then has locked her phone. [5] https://blog.cryptographyengineering.com/2016/11/24/android-n-encryption/ Finally, since it may be challenging to get device drivers which support ICE upstream, and since it would be desireable to be able to test ICE support using KVM or GCE without having access to ICE hardware, I'd like to discuss adding support either dm-crypto or some dm-crypt like block device layer, and then moving the encryption code in fs/crypto into the block device layer. One thing that I would like, however, is to allow userspace to be able to mount the "bare" block device (e.g., /dev/sdc3), but then have the crypto-enabled block device layer be spliced into the storage stack without having to require userspace code to first run dmsetup, and then mount a /dev/dm-X device. I suspect this request will be at least somewhat controversial, but it would make for a much more pleasant user experience for fs/crypto users, so I'd very much like to see if we can accomplish this in a clean way. - Ted