Thread (51 messages) 51 messages, 4 authors, 2026-09-03

Re: [PATCH v1 00/11] FBE virtualization: inline encryption for virtio-blk guests

flat view

From: Stefan Hajnoczi <stefanha@redhat.com>
Date: 2026-08-31 20:41:39
Also in: linux-arm-msm, linux-block, linux-crypto, linux-devicetree, linux-scsi, lkml

On Fri, Aug 28, 2026 at 11:37:57PM +0800, Linlin Zhang wrote:

On 8/28/2026 2:42 AM, Eric Biggers wrote:
quoted
On Thu, Aug 27, 2026 at 09:07:09AM -0700, Linlin Zhang wrote:
quoted
From: linlzhan <redacted>

Current virtio-blk does not provide a mechanism for a guest to
program hardware keys or submit encrypted I/O using pre-programmed
keyslots.  It drops the crypto context when issuing a bio request
to the virtio-blk queue, preventing inline-encryption-based FBE
on virtio block devices.

This series enables File-Based Encryption in guest VMs on Qualcomm
GVM platforms where the ICE inline encryption hardware is shared
between the host and guests.  In this environment the guest kernel
has no access to the ICE hardware directly; it supplies a virtual
keyslot index and data unit number with each encrypted I/O request
via VIRTIO_BLK_F_INLINE_ENCRYPTION, and the host must translate the
virtual slot to a physical ICE keyslot and submit the bio — without
transferring raw key material across the VM boundary.
This seems to be designed incorrectly by not making virtio-blk itself
support key programming and eviction.  That complicates things
significantly by then having to handle the key programming and eviction
out-of-band using Qualcomm-specific SCM calls.  It also means that
adding other implementations of this would be very difficult.

There are some claims that not transmitting keys across the VM boundary
is desirable.  But that doesn't seem meaningful, given that all the I/O
is transmitted across that boundary in plaintext anyway, and also it
seems that hardware-wrapped keys will be supported too.

Please make virtio-blk support the key programming, eviction, and
HW-wrapped key management operations that are needed for this to work.

- Eric
Thanks for your comments!

Not making virtio-blk itself support key programming and eviction is
something done deliberately. Based on that HW-wrapped key management
operations are also handled in the out-of-band path.

There are bellow 2 approaches I investigated to let virtio-blk programming
the key.

  1. virtio_blk implements blk_crypto_ll_ops interfaces, including program
     key and evict key interfaces.(Same to 'the virtio-blk interface standardized
     blk_crypto_ll_ops requests' mentioned by Stefan in the virtio SPEC thread)

     The guest's block crypto profile manages the keyslot in virtual slot
     format in this scenario.

      - block crypto key and virt_slot index it passed to the hypervisor's
       (EL2) device emulation (QEMU, using QEMU in the following) which
       runs in userspace of the host. Besides of transferring the virtual
       slot to the physical slot, a programming block crypto key UAPI need
       be added. Follow current blk-crypto design, it may be like
       BLKCRYPTOGENERATEKEY. I thought this results in a security risk that
       allows userspace process a key into a key slot.

     - For key eviction, it's similar to above key programming handling, also
       need a key eviction in blk IOCTLs, but leads to the security risk
       that allow userspace client to evict a key in a key slot.
Yes, userspace shouldn't have access to the entire physical key slot
range. The host kernel or other VMs may need key slots and an untrusted
QEMU process must not be able to modify those key slots or use them for
I/O.

The uapi design should include a solution for this. For example, there
could be an ioctl like BLKCRYPTOSEALKEYS that permanently restricts the
key range on this block device file descriptor and cannot be undone.
Libvirt or other management tooling would call this ioctl with
CAP_SYS_ADMIN before passing the file descriptor when launching QEMU
without CAP_SYS_ADMIN. This prevents QEMU from ever having access to the
full physical key range.

Just an idea. Those familiar with blk-crypto may have a better one. It
seems likely that we can find a design that matches the level of
security of the out-of-band approach.
    virt_slot, DUN and DUSize is appended to virtblk request during crypto
    I/O.

  2. virtio_blk implements blk_crypto_ll_ops interfaces, excluding program
     key and evict key interfaces.

     The guest's block crypto profile doesn't manage keyslot for the guest,
     the host's block crypto profile manages keyslot for both the guest and
     the host. The trigger of key programming operation is moved from the
     guest to the host.

       - The whole block crypto key (key size, key bytes, blk_crypto_config)
         and DUN are appended to the virtblk request during IO, a little
         high payload.

         The backend parses the crypto message in the virtio queue and
         construct a block crypto key and DUN for the bio_crypto_ctx
         set to the BIO. So that the IO flow in the host can program
         the key. 

         The question is that the blk-crypto-profile distinguishs the
         block crypto key via the key's address. But the host has
         different key addresses for the programming and eviction key
         operations of the same block crypto key from GVM, because the
         key is re-constructed in the host for the key program and
         eviction operations. 

         To fix it, the approach I thought is maintaining a new key
         hash table in the backend, and comparing the block crypto key
         content and DUN parsed from virtio queue with that in the key
         hash table. 
         My major concern is that this need keep the keys synchronization
         b/w this new hash table and the blk-crypto-profile's hash table
         carefully, avoiding that key is still present in the
         blk-crypto-profile's hash table, but removed in backend hash
         table. Another point is that the whole block crypto key and
         DUN are appended into virtio block request per crypto I/O.
This sounds like an approach that skips key programming and instead
sends the keys along with each I/O request. The device implementation is
responsible for managing key slots on the physical ICE. My main concern
with this would be whether the blk_crypto_ll_ops semantics can be
faithfully replicated (e.g. error reporting) without explicit key
programming operations.

Stefan
       - For key eviction, adding a key eviction in blk IOCTLs allows
         userspace client to evict a key in a key slot. I thought this
         is a security concern.


     This option doesn't need map virt_slot to physical one.


Taking all the above into account, I made a compromise to implement
blk_crypto_ll_ops interfaces in a out-of-band path, which lets the virtio
blk only need focus on the data path. I agree that it is complex than
the second option mentioned in the above, but small payload (only
virt_slot, DUN, DUSize) in the virtio block request and no security
risk of key eviction from userspace.


I would like to hear your thoughts about the above and am appreciated
if you could share your insights about the design of inline
encryption in virtio block.

Regards,
Linlin

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help