public inbox for virtio-dev@lists.linux.dev
 help / color / mirror / Atom feed
* [PATCH v1] virtio-blk: Add inline encryption support
@ 2026-01-27 14:14 Linlin Zhang
  2026-01-27 14:20 ` Linlin Zhang
  0 siblings, 1 reply; 13+ messages in thread
From: Linlin Zhang @ 2026-01-27 14:14 UTC (permalink / raw)
  To: virtio-dev; +Cc: quic_dshaikhu, quic_spunacha

From: linlzhan <quic_linlzhan@quicinc.com>

Inline encryption on virtio block can only be supported when
the new feature bit VIRTIO_BLK_F_ICE is negotiated.

Extend struct virtio_blk_config and struct virtio_blk_req,
so that crypto capabilities can be got in the frontend and
encryption metadata can be sent to the backend, together with
each I/O transaction.

Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
---
 device-types/blk/description.tex | 69 ++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/device-types/blk/description.tex b/device-types/blk/description.tex
index 2712ada..23d8dc0 100644
--- a/device-types/blk/description.tex
+++ b/device-types/blk/description.tex
@@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
 	(ZNS). For brevity, these standard documents are referred as "ZBD standards"
 	from this point on in the text.
 
+\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported. When this
+     is negotiated, the device exposes crypto characteristics in configuration
+     space and the driver SHALL provide an extended request header containing a
+     crypto payload for block I/O.
+
 \end{description}
 
 \subsubsection{Legacy Interface: Feature bits}\label{sec:Device Types / Block Device / Feature bits / Legacy Interface: Feature bits}
@@ -128,6 +133,11 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
                 u8 model;
                 u8 unused2[3];
         } zoned;
+        struct virtio_blk_crypto_characteristics {
+                __virtio16 slot_info;
+                __virtio16 reserved;
+                __virtio32 capability;
+        } crypto;
 };
 \end{lstlisting}
 
@@ -215,6 +225,25 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
 terminated by the device with a "zone resources exceeded" error as defined for
 specific commands later.
 
+If the VIRTIO_BLK_F_ICE feature is negotiated, then in
+\field{virtio_blk_crypto_characteristics},
+\begin{itemize}
+\item \field{slot_info} value packs two 8-bits values:
+    \begin{itemize}
+        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number of supported
+            crypto key slots.
+        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied to slot numbering.
+    \end{itemize}
+\item \field{capability} value packs four 8-bits values:
+    \begin{itemize}
+        \item Bits~\[31:24]: crypto algorithm id.
+        \item Bits~\[23:16]: mask of data unit size.
+        \item Bits~\[15:8]: crypto key size.
+        \item Bits~\[7:0]: unused.
+    \end{itemize}
+\end{itemize}
+
+
 \subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Block Device / Device configuration layout / Legacy Interface: Device configuration layout}
 When using the legacy interface, transitional devices and drivers
 MUST format the fields in struct virtio_blk_config
@@ -278,6 +307,10 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
     \field{zoned} can be read by the driver to determine the zone
     characteristics of the device. All \field{zoned} fields are read-only.
 
+\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
+    \field{crypto} can be read by the driver to determine the inline crypto
+    characteristics of the device. All \field{crypto} fields are read-only.
+
 \end{enumerate}
 
 \drivernormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
@@ -317,6 +350,9 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
     driver SHOULD ignore all other fields in \field{zoned}.
 \end{itemize}
 
+If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver must validate
+    the max_slots in \field{slot_info} before the slot usage.
+
 \devicenormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
 
 Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it
@@ -402,6 +438,16 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
 \item the device MUST initialize padding bytes \field{unused2} to 0.
 \end{itemize}
 
+If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in \field{cryto}
+struct in the configuration space MUST be set by the device.
+\begin{itemize}
+\item the \field{slot_info} field of \field{crypto} MUST be set by the device to a
+    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
+
+\item the \field{capability} field of \field{crypto} MUST be set by the device
+    to a crypto capability read from the storage register.
+\end{itemize}
+
 \subsubsection{Legacy Interface: Device Initialization}\label{sec:Device Types / Block Device / Device Initialization / Legacy Interface: Device Initialization}
 
 Because legacy devices do not have FEATURES_OK, transitional devices
@@ -436,6 +482,13 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
         le32 type;
         le32 reserved;
         le64 sector;
+        struct virtio_blk_crypto_payload {
+            u8 slot;
+            u8 activate;
+            le16 reserved1;
+            le32 reserved2;
+            le64 data_unit_num;
+        } payload;
         u8 data[];
         u8 status;
 };
@@ -463,6 +516,20 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
 the read or write is to occur. This field is unused and set to 0 for
 commands other than read, write and some zone operations.
 
+The \field{payload} consists of the encryption information for current
+request. It need to be set by the driver only when the feature VIRTIO_BLK_F_ICE
+is negotiated.
+\begin{itemize}
+\item The \field{slot} filed in \field{payload} indicates the ICE
+  (Inline Crypto Encryption) slot index where the key resides in.
+
+\item The \field{activate} filed in \field{payload} implies this is a
+  encryption request.
+
+\item The \field{data_unit_num} filed in \field{payload} indicates the
+  starting block of the request.
+\end{itemize}
+
 VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
 read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
 requests write the contents of \field{data} to the block device (in multiples
@@ -912,6 +979,8 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
 successfully, failed, or were processed by the device at all if the request
 failed with VIRTIO_BLK_S_IOERR.
 
+A driver MUST set \field{activate} to 0 for a non VIRTIO_BLK_F_ICE request.
+
 The following requirements only apply if the VIRTIO_BLK_F_ZONED feature is
 negotiated.
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v1] virtio-blk: Add inline encryption support
  2026-01-27 14:14 [PATCH v1] virtio-blk: Add inline encryption support Linlin Zhang
@ 2026-01-27 14:20 ` Linlin Zhang
  2026-01-27 21:09   ` Stefan Hajnoczi
  0 siblings, 1 reply; 13+ messages in thread
From: Linlin Zhang @ 2026-01-27 14:20 UTC (permalink / raw)
  To: virtio-dev; +Cc: quic_dshaikhu

From: linlzhan <quic_linlzhan@quicinc.com>

Inline encryption on virtio block can only be supported when
the new feature bit VIRTIO_BLK_F_ICE is negotiated.

Extend struct virtio_blk_config and struct virtio_blk_req,
so that crypto capabilities can be got in the frontend and
encryption metadata can be sent to the backend, together with
each I/O transaction.

Fixes: https://github.com/oasis-tcs/virtio-spec/issues/238

Change-Id: Ic23b2137e5d9a599d826e06c279f1b614d79abdf
Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
---
 device-types/blk/description.tex | 69 ++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/device-types/blk/description.tex b/device-types/blk/description.tex
index 2712ada..23d8dc0 100644
--- a/device-types/blk/description.tex
+++ b/device-types/blk/description.tex
@@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
 	(ZNS). For brevity, these standard documents are referred as "ZBD standards"
 	from this point on in the text.
 
+\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported. When this
+     is negotiated, the device exposes crypto characteristics in configuration
+     space and the driver SHALL provide an extended request header containing a
+     crypto payload for block I/O.
+
 \end{description}
 
 \subsubsection{Legacy Interface: Feature bits}\label{sec:Device Types / Block Device / Feature bits / Legacy Interface: Feature bits}
@@ -128,6 +133,11 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
                 u8 model;
                 u8 unused2[3];
         } zoned;
+        struct virtio_blk_crypto_characteristics {
+                __virtio16 slot_info;
+                __virtio16 reserved;
+                __virtio32 capability;
+        } crypto;
 };
 \end{lstlisting}
 
@@ -215,6 +225,25 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
 terminated by the device with a "zone resources exceeded" error as defined for
 specific commands later.
 
+If the VIRTIO_BLK_F_ICE feature is negotiated, then in
+\field{virtio_blk_crypto_characteristics},
+\begin{itemize}
+\item \field{slot_info} value packs two 8-bits values:
+    \begin{itemize}
+        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number of supported
+            crypto key slots.
+        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied to slot numbering.
+    \end{itemize}
+\item \field{capability} value packs four 8-bits values:
+    \begin{itemize}
+        \item Bits~\[31:24]: crypto algorithm id.
+        \item Bits~\[23:16]: mask of data unit size.
+        \item Bits~\[15:8]: crypto key size.
+        \item Bits~\[7:0]: unused.
+    \end{itemize}
+\end{itemize}
+
+
 \subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Block Device / Device configuration layout / Legacy Interface: Device configuration layout}
 When using the legacy interface, transitional devices and drivers
 MUST format the fields in struct virtio_blk_config
@@ -278,6 +307,10 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
     \field{zoned} can be read by the driver to determine the zone
     characteristics of the device. All \field{zoned} fields are read-only.
 
+\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
+    \field{crypto} can be read by the driver to determine the inline crypto
+    characteristics of the device. All \field{crypto} fields are read-only.
+
 \end{enumerate}
 
 \drivernormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
@@ -317,6 +350,9 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
     driver SHOULD ignore all other fields in \field{zoned}.
 \end{itemize}
 
+If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver must validate
+    the max_slots in \field{slot_info} before the slot usage.
+
 \devicenormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
 
 Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it
@@ -402,6 +438,16 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
 \item the device MUST initialize padding bytes \field{unused2} to 0.
 \end{itemize}
 
+If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in \field{cryto}
+struct in the configuration space MUST be set by the device.
+\begin{itemize}
+\item the \field{slot_info} field of \field{crypto} MUST be set by the device to a
+    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
+
+\item the \field{capability} field of \field{crypto} MUST be set by the device
+    to a crypto capability read from the storage register.
+\end{itemize}
+
 \subsubsection{Legacy Interface: Device Initialization}\label{sec:Device Types / Block Device / Device Initialization / Legacy Interface: Device Initialization}
 
 Because legacy devices do not have FEATURES_OK, transitional devices
@@ -436,6 +482,13 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
         le32 type;
         le32 reserved;
         le64 sector;
+        struct virtio_blk_crypto_payload {
+            u8 slot;
+            u8 activate;
+            le16 reserved1;
+            le32 reserved2;
+            le64 data_unit_num;
+        } payload;
         u8 data[];
         u8 status;
 };
@@ -463,6 +516,20 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
 the read or write is to occur. This field is unused and set to 0 for
 commands other than read, write and some zone operations.
 
+The \field{payload} consists of the encryption information for current
+request. It need to be set by the driver only when the feature VIRTIO_BLK_F_ICE
+is negotiated.
+\begin{itemize}
+\item The \field{slot} filed in \field{payload} indicates the ICE
+  (Inline Crypto Encryption) slot index where the key resides in.
+
+\item The \field{activate} filed in \field{payload} implies this is a
+  encryption request.
+
+\item The \field{data_unit_num} filed in \field{payload} indicates the
+  starting block of the request.
+\end{itemize}
+
 VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
 read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
 requests write the contents of \field{data} to the block device (in multiples
@@ -912,6 +979,8 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
 successfully, failed, or were processed by the device at all if the request
 failed with VIRTIO_BLK_S_IOERR.
 
+A driver MUST set \field{activate} to 0 for a non VIRTIO_BLK_F_ICE request.
+
 The following requirements only apply if the VIRTIO_BLK_F_ZONED feature is
 negotiated.
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v1] virtio-blk: Add inline encryption support
  2026-01-27 14:20 ` Linlin Zhang
@ 2026-01-27 21:09   ` Stefan Hajnoczi
  2026-01-30 10:23     ` Linlin Zhang
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Hajnoczi @ 2026-01-27 21:09 UTC (permalink / raw)
  To: Linlin Zhang; +Cc: virtio-dev, quic_dshaikhu

[-- Attachment #1: Type: text/plain, Size: 9512 bytes --]

On Tue, Jan 27, 2026 at 10:20:32PM +0800, Linlin Zhang wrote:
> From: linlzhan <quic_linlzhan@quicinc.com>
> 
> Inline encryption on virtio block can only be supported when
> the new feature bit VIRTIO_BLK_F_ICE is negotiated.
> 
> Extend struct virtio_blk_config and struct virtio_blk_req,
> so that crypto capabilities can be got in the frontend and
> encryption metadata can be sent to the backend, together with
> each I/O transaction.

This looks like a Self-Encrypting Drives feature along the lines of TCG
Opal:
https://en.wikipedia.org/wiki/Opal_Storage_Specification

Would it make sense to implement TCG Opal instead of defining a new
interface? That would make this more familiar to users and simplify
integration into existing tools like sedutil and cryptsetup (e.g. by
supporting the <linux/sed-opal.h> ioctl interface).

> Fixes: https://github.com/oasis-tcs/virtio-spec/issues/238
> 
> Change-Id: Ic23b2137e5d9a599d826e06c279f1b614d79abdf
> Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
> ---
>  device-types/blk/description.tex | 69 ++++++++++++++++++++++++++++++++
>  1 file changed, 69 insertions(+)
> 
> diff --git a/device-types/blk/description.tex b/device-types/blk/description.tex
> index 2712ada..23d8dc0 100644
> --- a/device-types/blk/description.tex
> +++ b/device-types/blk/description.tex
> @@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
>  	(ZNS). For brevity, these standard documents are referred as "ZBD standards"
>  	from this point on in the text.
>  
> +\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported. When this
> +     is negotiated, the device exposes crypto characteristics in configuration
> +     space and the driver SHALL provide an extended request header containing a

SHALL, MUST, MAY, etc are only used in the normative sections of the
spec.

Why "SHALL"? Does this mean the device must be prepared to receive
requests without the payload field when VIRTIO_BLK_F_ICE is negotiated?
How should the device behave in that case: fail the request or perform
I/O without crypto?

> +     crypto payload for block I/O.
> +
>  \end{description}
>  
>  \subsubsection{Legacy Interface: Feature bits}\label{sec:Device Types / Block Device / Feature bits / Legacy Interface: Feature bits}
> @@ -128,6 +133,11 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
>                  u8 model;
>                  u8 unused2[3];
>          } zoned;
> +        struct virtio_blk_crypto_characteristics {
> +                __virtio16 slot_info;
> +                __virtio16 reserved;
> +                __virtio32 capability;
> +        } crypto;
>  };
>  \end{lstlisting}
>  
> @@ -215,6 +225,25 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
>  terminated by the device with a "zone resources exceeded" error as defined for
>  specific commands later.
>  
> +If the VIRTIO_BLK_F_ICE feature is negotiated, then in
> +\field{virtio_blk_crypto_characteristics},
> +\begin{itemize}
> +\item \field{slot_info} value packs two 8-bits values:
> +    \begin{itemize}
> +        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number of supported
> +            crypto key slots.
> +        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied to slot numbering.
> +    \end{itemize}
> +\item \field{capability} value packs four 8-bits values:
> +    \begin{itemize}
> +        \item Bits~\[31:24]: crypto algorithm id.
> +        \item Bits~\[23:16]: mask of data unit size.
> +        \item Bits~\[15:8]: crypto key size.
> +        \item Bits~\[7:0]: unused.
> +    \end{itemize}

Why are these fields packed? Configuration Space can have u8 fields.

These fields are not sufficiently documented. Where are the crypto
algorithm ids listed, etc?

How can a device support multiple algorithms? I think Configuration
Space may not be flexible enough for this. You could introduce a
GET_CRYPTO_INFO request type that allows the driver to fetch arrays of
crypto algorithm characteristics.

> +\end{itemize}
> +
> +
>  \subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Block Device / Device configuration layout / Legacy Interface: Device configuration layout}
>  When using the legacy interface, transitional devices and drivers
>  MUST format the fields in struct virtio_blk_config
> @@ -278,6 +307,10 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>      \field{zoned} can be read by the driver to determine the zone
>      characteristics of the device. All \field{zoned} fields are read-only.
>  
> +\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
> +    \field{crypto} can be read by the driver to determine the inline crypto
> +    characteristics of the device. All \field{crypto} fields are read-only.
> +
>  \end{enumerate}
>  
>  \drivernormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
> @@ -317,6 +350,9 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>      driver SHOULD ignore all other fields in \field{zoned}.
>  \end{itemize}
>  
> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver must validate
> +    the max_slots in \field{slot_info} before the slot usage.
> +
>  \devicenormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
>  
>  Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it
> @@ -402,6 +438,16 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>  \item the device MUST initialize padding bytes \field{unused2} to 0.
>  \end{itemize}
>  
> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in \field{cryto}

s/cryto/crypto/

> +struct in the configuration space MUST be set by the device.
> +\begin{itemize}
> +\item the \field{slot_info} field of \field{crypto} MUST be set by the device to a
> +    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
> +
> +\item the \field{capability} field of \field{crypto} MUST be set by the device
> +    to a crypto capability read from the storage register.
> +\end{itemize}
> +
>  \subsubsection{Legacy Interface: Device Initialization}\label{sec:Device Types / Block Device / Device Initialization / Legacy Interface: Device Initialization}
>  
>  Because legacy devices do not have FEATURES_OK, transitional devices
> @@ -436,6 +482,13 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>          le32 type;
>          le32 reserved;
>          le64 sector;
> +        struct virtio_blk_crypto_payload {
> +            u8 slot;
> +            u8 activate;
> +            le16 reserved1;
> +            le32 reserved2;
> +            le64 data_unit_num;
> +        } payload;
>          u8 data[];
>          u8 status;
>  };
> @@ -463,6 +516,20 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>  the read or write is to occur. This field is unused and set to 0 for
>  commands other than read, write and some zone operations.
>  
> +The \field{payload} consists of the encryption information for current
> +request. It need to be set by the driver only when the feature VIRTIO_BLK_F_ICE
> +is negotiated.

"set" is ambiguous: does it meaning filling in the fields or does it
mean the fields are only present when VIRTIO_BLK_F_ICE is negotiated
(this distinction is important if other features add more fields after
payload in the future).

The sentence could be reworded:

  It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
  \field{type} is VIRTIO_BLK_T_IN or VIRTIO_BLK_T_OUT.

(I'm not sure whether DISCARD, WRITE_ZEROES, or SECURE_ERASE also need
the payload field. It seems like GET_ID and GET_LIFETIME do not need the
payload field.)

> +\begin{itemize}
> +\item The \field{slot} filed in \field{payload} indicates the ICE

s/filed/field/

> +  (Inline Crypto Encryption) slot index where the key resides in.

s/where the key resides in/where the key resides/

> +
> +\item The \field{activate} filed in \field{payload} implies this is a

s/filed/field/

> +  encryption request.

Does "encryption" really mean just encryption or does it mean
encryption for writes and decryption for reads?

> +
> +\item The \field{data_unit_num} filed in \field{payload} indicates the

s/filed/field/

> +  starting block of the request.
> +\end{itemize}
> +
>  VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
>  read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
>  requests write the contents of \field{data} to the block device (in multiples
> @@ -912,6 +979,8 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>  successfully, failed, or were processed by the device at all if the request
>  failed with VIRTIO_BLK_S_IOERR.
>  
> +A driver MUST set \field{activate} to 0 for a non VIRTIO_BLK_F_ICE request.

Please explicitly list request types where the payload field is present
and where activate is optional.

> +
>  The following requirements only apply if the VIRTIO_BLK_F_ZONED feature is
>  negotiated.
>  
> -- 
> 2.34.1
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v1] virtio-blk: Add inline encryption support
  2026-01-27 21:09   ` Stefan Hajnoczi
@ 2026-01-30 10:23     ` Linlin Zhang
  2026-02-02 15:56       ` Stefan Hajnoczi
  0 siblings, 1 reply; 13+ messages in thread
From: Linlin Zhang @ 2026-01-30 10:23 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: virtio-dev, quic_dshaikhu

Thank you for the review. I’ve added some clarifications and potential updates.
Could you please take another look before I send a new patch?

On 1/28/2026 5:09 AM, Stefan Hajnoczi wrote:
> On Tue, Jan 27, 2026 at 10:20:32PM +0800, Linlin Zhang wrote:
>> From: linlzhan <quic_linlzhan@quicinc.com>
>>
>> Inline encryption on virtio block can only be supported when
>> the new feature bit VIRTIO_BLK_F_ICE is negotiated.
>>
>> Extend struct virtio_blk_config and struct virtio_blk_req,
>> so that crypto capabilities can be got in the frontend and
>> encryption metadata can be sent to the backend, together with
>> each I/O transaction.
> 
> This looks like a Self-Encrypting Drives feature along the lines of TCG
> Opal:
> https://en.wikipedia.org/wiki/Opal_Storage_Specification
> 
> Would it make sense to implement TCG Opal instead of defining a new
> interface? That would make this more familiar to users and simplify
> integration into existing tools like sedutil and cryptsetup (e.g. by
> supporting the <linux/sed-opal.h> ioctl interface).

This patch is for the FBE (File Based Encryption) support on UFS/EMMC
storage with ICE (Inline Crypto Engine) enabled. TCG Opal is only applicable
to SED (self-encrypting drives), not applicable to ICE (Inline Crypto Engine).

In Automotive or Embedded scenario, UFS/EMMC generally is used. The disk
encryption on them is supported by the ICE pipeline of SOC, rather SSD
controller, so we couldn't use TCG Opal here.

> 
>> Fixes: https://github.com/oasis-tcs/virtio-spec/issues/238
>>
>> Change-Id: Ic23b2137e5d9a599d826e06c279f1b614d79abdf
>> Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
>> ---
>>  device-types/blk/description.tex | 69 ++++++++++++++++++++++++++++++++
>>  1 file changed, 69 insertions(+)
>>
>> diff --git a/device-types/blk/description.tex b/device-types/blk/description.tex
>> index 2712ada..23d8dc0 100644
>> --- a/device-types/blk/description.tex
>> +++ b/device-types/blk/description.tex
>> @@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
>>  	(ZNS). For brevity, these standard documents are referred as "ZBD standards"
>>  	from this point on in the text.
>>  
>> +\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported. When this
>> +     is negotiated, the device exposes crypto characteristics in configuration
>> +     space and the driver SHALL provide an extended request header containing a
> 
> SHALL, MUST, MAY, etc are only used in the normative sections of the
> spec.
> 
> Why "SHALL"? Does this mean the device must be prepared to receive
> requests without the payload field when VIRTIO_BLK_F_ICE is negotiated?
> How should the device behave in that case: fail the request or perform
> I/O without crypto?

This section - 5.2.3 Feature bits - is a normative section.

What's expected for VIRTIO_BLK_F_ICE feature bit is that configuration space
must be prepared with the exposed crypto characteristics and the virtio block
frontend must sent a virtblk request with encryption metadata packed into
when VIRTIO_BLK_F_ICE is negotiated and hardware crypto is supported.

By replacing 'SHALL' with 'MUST' here, Is the following rewording fine?

  Inline Crypto Extensions are supported. When this is negotiated, the device MUST
  expose crypto characteristics in configuration space and the driver MUST provide
  an extended request header containing a crypto payload for block I/O if the
  hardware supports inline crypto. If this feature bit is negotiated, but hardware
  inline crypto doesn't support, the device SHOULD perform I/O without crypto.

I'll add hw_enabled (type: u8) to virtio_blk_crypto_characteristics to indicate
whether the host supports hardware inline encryption.

> 
>> +     crypto payload for block I/O.
>> +
>>  \end{description}
>>  
>>  \subsubsection{Legacy Interface: Feature bits}\label{sec:Device Types / Block Device / Feature bits / Legacy Interface: Feature bits}
>> @@ -128,6 +133,11 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
>>                  u8 model;
>>                  u8 unused2[3];
>>          } zoned;
>> +        struct virtio_blk_crypto_characteristics {
>> +                __virtio16 slot_info;
>> +                __virtio16 reserved;
>> +                __virtio32 capability;
>> +        } crypto;
>>  };
>>  \end{lstlisting}
>>  
>> @@ -215,6 +225,25 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
>>  terminated by the device with a "zone resources exceeded" error as defined for
>>  specific commands later.
>>  
>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then in
>> +\field{virtio_blk_crypto_characteristics},
>> +\begin{itemize}
>> +\item \field{slot_info} value packs two 8-bits values:
>> +    \begin{itemize}
>> +        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number of supported
>> +            crypto key slots.
>> +        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied to slot numbering.
>> +    \end{itemize}
>> +\item \field{capability} value packs four 8-bits values:
>> +    \begin{itemize}
>> +        \item Bits~\[31:24]: crypto algorithm id.
>> +        \item Bits~\[23:16]: mask of data unit size.
>> +        \item Bits~\[15:8]: crypto key size.
>> +        \item Bits~\[7:0]: unused.
>> +    \end{itemize}
> 
> Why are these fields packed? Configuration Space can have u8 fields.

Given that &sect. 4.2.2.2 saying "For the device-specific configuration space,
the driver MUST use 8 bit wide accesses for 8 bit wide fields, 16 bit wide
and aligned accesses for 16 bit wide fields and 32 bit wide and aligned
accesses for 32 and 64 bit wide fields.",  these fields are packed for a
efficient read from the configuration space.

> 
> These fields are not sufficiently documented. Where are the crypto
> algorithm ids listed, etc?

Can I reword it as the following?

  \item Bits~\[31:24]: crypto algorithm identifiers.
  The device SHALL support reporting and negotiating cryptographic
  algorithms using the following algorithm identifiers:
  \begin{lstlisting}
      CRYPTO_ALG_AES_XTS              = 0x0
      CRYPTO_ALG_BITLOCKER_AES_CBC    = 0x1
      CRYPTO_ALG_AES_ECB              = 0x2
      CRYPTO_ALG_ESSIV_AES_CBC        = 0x3
  \end{lstlisting}
  These identifiers abstract the underlying hardware crypto implementation
  and MUST NOT assume any operating‑system‑specific data structures or
  constants.
  \item Bits~\[23:16]: mask of data unit size. When bit j in this field
  (j=0......7)is set, a data unit size of 512*2^j bytes is slected.
  \item Bits~\[15:8]: crypto key size identifiers.
  \begin{lstlisting}
      CRYPTO_KEY_SIZE_INVALID     = 0x0
      CRYPTO_KEY_SIZE_128_BITS    = 0x1
      CRYPTO_KEY_SIZE_192_BITS    = 0x2
      CRYPTO_KEY_SIZE_256_BITS    = 0x3
      CRYPTO_KEY_SIZE_512_BITS    = 0x4
  \end{lstlisting}

> 
> How can a device support multiple algorithms? I think Configuration
> Space may not be flexible enough for this. You could introduce a
> GET_CRYPTO_INFO request type that allows the driver to fetch arrays of
> crypto algorithm characteristics.

Virtio block driver need register crypto capability for request_queue of
virtio block device. That means virtio block frontend need get crypto
capability before virtio block device is ready. But the request can only
be sent after the virtio block device is ready. Thus I think it's impossible
to get such capabilities from the backend via a new request type, event
though the hardware in the host may support a few algorithms (the actual
number of algorithms will change depending on the vendor manufacturer.).
Thus I assume the host only configure and expose one hardware crypto
capability to the virtual machine and virtio block frontend gets is
through configuration space.

> 
>> +\end{itemize}
>> +
>> +
>>  \subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Block Device / Device configuration layout / Legacy Interface: Device configuration layout}
>>  When using the legacy interface, transitional devices and drivers
>>  MUST format the fields in struct virtio_blk_config
>> @@ -278,6 +307,10 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>>      \field{zoned} can be read by the driver to determine the zone
>>      characteristics of the device. All \field{zoned} fields are read-only.
>>  
>> +\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
>> +    \field{crypto} can be read by the driver to determine the inline crypto
>> +    characteristics of the device. All \field{crypto} fields are read-only.
>> +
>>  \end{enumerate}
>>  
>>  \drivernormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
>> @@ -317,6 +350,9 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>>      driver SHOULD ignore all other fields in \field{zoned}.
>>  \end{itemize}
>>  
>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver must validate
>> +    the max_slots in \field{slot_info} before the slot usage.
>> +
>>  \devicenormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
>>  
>>  Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it
>> @@ -402,6 +438,16 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>>  \item the device MUST initialize padding bytes \field{unused2} to 0.
>>  \end{itemize}
>>  
>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in \field{cryto}
> 
> s/cryto/crypto/

Thanks for the correction. Update it in new patch.

> 
>> +struct in the configuration space MUST be set by the device.
>> +\begin{itemize}
>> +\item the \field{slot_info} field of \field{crypto} MUST be set by the device to a
>> +    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
>> +
>> +\item the \field{capability} field of \field{crypto} MUST be set by the device
>> +    to a crypto capability read from the storage register.
>> +\end{itemize}
>> +
>>  \subsubsection{Legacy Interface: Device Initialization}\label{sec:Device Types / Block Device / Device Initialization / Legacy Interface: Device Initialization}
>>  
>>  Because legacy devices do not have FEATURES_OK, transitional devices
>> @@ -436,6 +482,13 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>>          le32 type;
>>          le32 reserved;
>>          le64 sector;
>> +        struct virtio_blk_crypto_payload {
>> +            u8 slot;
>> +            u8 activate;
>> +            le16 reserved1;
>> +            le32 reserved2;
>> +            le64 data_unit_num;
>> +        } payload;
>>          u8 data[];
>>          u8 status;
>>  };
>> @@ -463,6 +516,20 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>>  the read or write is to occur. This field is unused and set to 0 for
>>  commands other than read, write and some zone operations.
>>  
>> +The \field{payload} consists of the encryption information for current
>> +request. It need to be set by the driver only when the feature VIRTIO_BLK_F_ICE
>> +is negotiated.
> 
> "set" is ambiguous: does it meaning filling in the fields or does it
> mean the fields are only present when VIRTIO_BLK_F_ICE is negotiated
> (this distinction is important if other features add more fields after
> payload in the future).
> 
> The sentence could be reworded:
> 
>   It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
>   \field{type} is VIRTIO_BLK_T_IN or VIRTIO_BLK_T_OUT.
> 
> (I'm not sure whether DISCARD, WRITE_ZEROES, or SECURE_ERASE also need
> the payload field. It seems like GET_ID and GET_LIFETIME do not need the
> payload field.)

Accept and update it as the following.

  It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
  +\field{type} is VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT or VIRTIO_BLK_T_FLUSH.

> 
>> +\begin{itemize}
>> +\item The \field{slot} filed in \field{payload} indicates the ICE
> 
> s/filed/field/

Thanks for the correction. Update it in new patch.

> 
>> +  (Inline Crypto Encryption) slot index where the key resides in.
> 
> s/where the key resides in/where the key resides/

Thanks for the correction. Update it in new patch.

> 
>> +
>> +\item The \field{activate} filed in \field{payload} implies this is a
> 
> s/filed/field/

Thanks for the correction. Update it in new patch.

> 
>> +  encryption request.
> 
> Does "encryption" really mean just encryption or does it mean
> encryption for writes and decryption for reads?

Actually encryption request here means both encryption for writes and
decryption for reads. Need I modify it as the following?

  \item The \field{activate} field in \field{payload} implies this is a
  encryption write request or decryption read request.

> 
>> +
>> +\item The \field{data_unit_num} filed in \field{payload} indicates the
> 
> s/filed/field/

Thanks for the correction. Update it in new patch.

> 
>> +  starting block of the request.
>> +\end{itemize}
>> +
>>  VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
>>  read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
>>  requests write the contents of \field{data} to the block device (in multiples
>> @@ -912,6 +979,8 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>>  successfully, failed, or were processed by the device at all if the request
>>  failed with VIRTIO_BLK_S_IOERR.
>>  
>> +A driver MUST set \field{activate} to 0 for a non VIRTIO_BLK_F_ICE request.
> 
> Please explicitly list request types where the payload field is present
> and where activate is optional.

How about adding the following supplement?

  \begin{itemize}
  \item only when the block request contains crypto context and the request type
      is one of VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT and VIRTIO_BLK_T_FLUSH,
      \field{activate} MUST be set to 1.

  \item \field{activate} should be set to 0 for all the other cases.
  \end{itemize}

> 
>> +
>>  The following requirements only apply if the VIRTIO_BLK_F_ZONED feature is
>>  negotiated.
>>  
>> -- 
>> 2.34.1
>>
>>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v1] virtio-blk: Add inline encryption support
  2026-01-30 10:23     ` Linlin Zhang
@ 2026-02-02 15:56       ` Stefan Hajnoczi
  2026-02-03 10:06         ` Linlin Zhang
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Hajnoczi @ 2026-02-02 15:56 UTC (permalink / raw)
  To: Linlin Zhang; +Cc: virtio-dev, quic_dshaikhu

[-- Attachment #1: Type: text/plain, Size: 18610 bytes --]

On Fri, Jan 30, 2026 at 06:23:55PM +0800, Linlin Zhang wrote:
> Thank you for the review. I’ve added some clarifications and potential updates.
> Could you please take another look before I send a new patch?
> 
> On 1/28/2026 5:09 AM, Stefan Hajnoczi wrote:
> > On Tue, Jan 27, 2026 at 10:20:32PM +0800, Linlin Zhang wrote:
> >> From: linlzhan <quic_linlzhan@quicinc.com>
> >>
> >> Inline encryption on virtio block can only be supported when
> >> the new feature bit VIRTIO_BLK_F_ICE is negotiated.
> >>
> >> Extend struct virtio_blk_config and struct virtio_blk_req,
> >> so that crypto capabilities can be got in the frontend and
> >> encryption metadata can be sent to the backend, together with
> >> each I/O transaction.
> > 
> > This looks like a Self-Encrypting Drives feature along the lines of TCG
> > Opal:
> > https://en.wikipedia.org/wiki/Opal_Storage_Specification
> > 
> > Would it make sense to implement TCG Opal instead of defining a new
> > interface? That would make this more familiar to users and simplify
> > integration into existing tools like sedutil and cryptsetup (e.g. by
> > supporting the <linux/sed-opal.h> ioctl interface).
> 
> This patch is for the FBE (File Based Encryption) support on UFS/EMMC
> storage with ICE (Inline Crypto Engine) enabled. TCG Opal is only applicable
> to SED (self-encrypting drives), not applicable to ICE (Inline Crypto Engine).
> 
> In Automotive or Embedded scenario, UFS/EMMC generally is used. The disk
> encryption on them is supported by the ICE pipeline of SOC, rather SSD
> controller, so we couldn't use TCG Opal here.

Okay. Is there a specification that this interface needs to comply with?

If not, you can include a link to the Linux inline encryption
documentation in the commit description:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/block/inline-encryption.rst

Having a reference will will help the discussion. That way we can be
confident the VIRTIO spec changes will be widely useful beyond a single
use case and easy to implement in drivers because they follow an
existing interface.

> 
> > 
> >> Fixes: https://github.com/oasis-tcs/virtio-spec/issues/238
> >>
> >> Change-Id: Ic23b2137e5d9a599d826e06c279f1b614d79abdf
> >> Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
> >> ---
> >>  device-types/blk/description.tex | 69 ++++++++++++++++++++++++++++++++
> >>  1 file changed, 69 insertions(+)
> >>
> >> diff --git a/device-types/blk/description.tex b/device-types/blk/description.tex
> >> index 2712ada..23d8dc0 100644
> >> --- a/device-types/blk/description.tex
> >> +++ b/device-types/blk/description.tex
> >> @@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
> >>  	(ZNS). For brevity, these standard documents are referred as "ZBD standards"
> >>  	from this point on in the text.
> >>  
> >> +\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported. When this
> >> +     is negotiated, the device exposes crypto characteristics in configuration
> >> +     space and the driver SHALL provide an extended request header containing a
> > 
> > SHALL, MUST, MAY, etc are only used in the normative sections of the
> > spec.
> > 
> > Why "SHALL"? Does this mean the device must be prepared to receive
> > requests without the payload field when VIRTIO_BLK_F_ICE is negotiated?
> > How should the device behave in that case: fail the request or perform
> > I/O without crypto?
> 
> This section - 5.2.3 Feature bits - is a normative section.

\section{Block Device}\label{sec:Device Types / Block Device}
...
\subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}

No, this is a non-normative section. The normative sections are the
"Device Requirements" (\devicenormative) and "Driver Requirements"
(\drivernormative) sections.

> 
> What's expected for VIRTIO_BLK_F_ICE feature bit is that configuration space
> must be prepared with the exposed crypto characteristics and the virtio block
> frontend must sent a virtblk request with encryption metadata packed into
> when VIRTIO_BLK_F_ICE is negotiated and hardware crypto is supported.
>
> By replacing 'SHALL' with 'MUST' here, Is the following rewording fine?
> 
>   Inline Crypto Extensions are supported. When this is negotiated, the device MUST
>   expose crypto characteristics in configuration space and the driver MUST provide
>   an extended request header containing a crypto payload for block I/O if the
>   hardware supports inline crypto. If this feature bit is negotiated, but hardware
>   inline crypto doesn't support, the device SHOULD perform I/O without crypto.
> 
> I'll add hw_enabled (type: u8) to virtio_blk_crypto_characteristics to indicate
> whether the host supports hardware inline encryption.

I still have a question about this: why would a device advertise
VIRTIO_BLK_F_ICE but report hw_enabled = 0? I'm not sure how this is
functionally different from a device that does not report
VIRTIO_BLK_F_ICE. It seems simpler for devices to only advertise
VIRTIO_BLK_F_ICE when they support inline encryption.

> > 
> >> +     crypto payload for block I/O.
> >> +
> >>  \end{description}
> >>  
> >>  \subsubsection{Legacy Interface: Feature bits}\label{sec:Device Types / Block Device / Feature bits / Legacy Interface: Feature bits}
> >> @@ -128,6 +133,11 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
> >>                  u8 model;
> >>                  u8 unused2[3];
> >>          } zoned;
> >> +        struct virtio_blk_crypto_characteristics {
> >> +                __virtio16 slot_info;
> >> +                __virtio16 reserved;
> >> +                __virtio32 capability;
> >> +        } crypto;
> >>  };
> >>  \end{lstlisting}
> >>  
> >> @@ -215,6 +225,25 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
> >>  terminated by the device with a "zone resources exceeded" error as defined for
> >>  specific commands later.
> >>  
> >> +If the VIRTIO_BLK_F_ICE feature is negotiated, then in
> >> +\field{virtio_blk_crypto_characteristics},
> >> +\begin{itemize}
> >> +\item \field{slot_info} value packs two 8-bits values:
> >> +    \begin{itemize}
> >> +        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number of supported
> >> +            crypto key slots.
> >> +        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied to slot numbering.
> >> +    \end{itemize}
> >> +\item \field{capability} value packs four 8-bits values:
> >> +    \begin{itemize}
> >> +        \item Bits~\[31:24]: crypto algorithm id.
> >> +        \item Bits~\[23:16]: mask of data unit size.
> >> +        \item Bits~\[15:8]: crypto key size.
> >> +        \item Bits~\[7:0]: unused.
> >> +    \end{itemize}
> > 
> > Why are these fields packed? Configuration Space can have u8 fields.
> 
> Given that &sect. 4.2.2.2 saying "For the device-specific configuration space,
> the driver MUST use 8 bit wide accesses for 8 bit wide fields, 16 bit wide
> and aligned accesses for 16 bit wide fields and 32 bit wide and aligned
> accesses for 32 and 64 bit wide fields.",  these fields are packed for a
> efficient read from the configuration space.

I see. I suggest mentioning this explicitly: "value packs two 8-bits
values to reduce the number of Configuration Space reads".

> > 
> > These fields are not sufficiently documented. Where are the crypto
> > algorithm ids listed, etc?
> 
> Can I reword it as the following?

Yes, looks good in general. I have some comments below.

> 
>   \item Bits~\[31:24]: crypto algorithm identifiers.
>   The device SHALL support reporting and negotiating cryptographic
>   algorithms using the following algorithm identifiers:
>   \begin{lstlisting}
>       CRYPTO_ALG_AES_XTS              = 0x0
>       CRYPTO_ALG_BITLOCKER_AES_CBC    = 0x1
>       CRYPTO_ALG_AES_ECB              = 0x2
>       CRYPTO_ALG_ESSIV_AES_CBC        = 0x3
>   \end{lstlisting}
>   These identifiers abstract the underlying hardware crypto implementation
>   and MUST NOT assume any operating‑system‑specific data structures or
>   constants.

(The MUST NOT part needs to be in a \devicenormative or \drivernormative
sections, but I think "MUST NOT" can be replaced with "does not" here
because it actually describes the design of the interface rather than
imposing requirements on device implementors.)

>   \item Bits~\[23:16]: mask of data unit size. When bit j in this field
>   (j=0......7)is set, a data unit size of 512*2^j bytes is slected.

s/)is set/) is set/
s/slected/selected/

How is the data unit size used? Does it affect the allowed request sizes
of the device?

For example, if the mask is 0x2, so that mean request sizes must be
multiples of 1 KiB?

By the way, I'm not sure whether "j=0......7" mean that a mask value of
0x2 has j=1 or j=6? Usually bits are numbered right-to-left from least
significant bit to most significant bit.

>   \item Bits~\[15:8]: crypto key size identifiers.
>   \begin{lstlisting}
>       CRYPTO_KEY_SIZE_INVALID     = 0x0
>       CRYPTO_KEY_SIZE_128_BITS    = 0x1
>       CRYPTO_KEY_SIZE_192_BITS    = 0x2
>       CRYPTO_KEY_SIZE_256_BITS    = 0x3
>       CRYPTO_KEY_SIZE_512_BITS    = 0x4
>   \end{lstlisting}
> 
> > 
> > How can a device support multiple algorithms? I think Configuration
> > Space may not be flexible enough for this. You could introduce a
> > GET_CRYPTO_INFO request type that allows the driver to fetch arrays of
> > crypto algorithm characteristics.
> 
> Virtio block driver need register crypto capability for request_queue of
> virtio block device. That means virtio block frontend need get crypto
> capability before virtio block device is ready. But the request can only
> be sent after the virtio block device is ready. Thus I think it's impossible
> to get such capabilities from the backend via a new request type, event
> though the hardware in the host may support a few algorithms (the actual
> number of algorithms will change depending on the vendor manufacturer.).
> Thus I assume the host only configure and expose one hardware crypto
> capability to the virtual machine and virtio block frontend gets is
> through configuration space.

The zoned storage feature also needs to use the virtqueues during driver
initialization in order to report zones. Here is the Linux virtio_blk.c
driver code:

static int virtblk_probe(struct virtio_device *vdev)
{
...
    virtio_device_ready(vdev);

    /*
     * All steps that follow use the VQs therefore they need to be
     * placed after the virtio_device_ready() call above.
     */
    if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
        (lim.features & BLK_FEAT_ZONED)) {
            err = blk_revalidate_disk_zones(vblk->disk);
            if (err)
                    goto out_cleanup_disk;
    }

    err = device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups);

Is it possible to call blk_crypto_register() between
virtio_device_read() and device_add_disk()?

> 
> > 
> >> +\end{itemize}
> >> +
> >> +
> >>  \subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Block Device / Device configuration layout / Legacy Interface: Device configuration layout}
> >>  When using the legacy interface, transitional devices and drivers
> >>  MUST format the fields in struct virtio_blk_config
> >> @@ -278,6 +307,10 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
> >>      \field{zoned} can be read by the driver to determine the zone
> >>      characteristics of the device. All \field{zoned} fields are read-only.
> >>  
> >> +\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
> >> +    \field{crypto} can be read by the driver to determine the inline crypto
> >> +    characteristics of the device. All \field{crypto} fields are read-only.
> >> +
> >>  \end{enumerate}
> >>  
> >>  \drivernormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
> >> @@ -317,6 +350,9 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
> >>      driver SHOULD ignore all other fields in \field{zoned}.
> >>  \end{itemize}
> >>  
> >> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver must validate
> >> +    the max_slots in \field{slot_info} before the slot usage.
> >> +
> >>  \devicenormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
> >>  
> >>  Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it
> >> @@ -402,6 +438,16 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
> >>  \item the device MUST initialize padding bytes \field{unused2} to 0.
> >>  \end{itemize}
> >>  
> >> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in \field{cryto}
> > 
> > s/cryto/crypto/
> 
> Thanks for the correction. Update it in new patch.
> 
> > 
> >> +struct in the configuration space MUST be set by the device.
> >> +\begin{itemize}
> >> +\item the \field{slot_info} field of \field{crypto} MUST be set by the device to a
> >> +    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
> >> +
> >> +\item the \field{capability} field of \field{crypto} MUST be set by the device
> >> +    to a crypto capability read from the storage register.
> >> +\end{itemize}
> >> +
> >>  \subsubsection{Legacy Interface: Device Initialization}\label{sec:Device Types / Block Device / Device Initialization / Legacy Interface: Device Initialization}
> >>  
> >>  Because legacy devices do not have FEATURES_OK, transitional devices
> >> @@ -436,6 +482,13 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
> >>          le32 type;
> >>          le32 reserved;
> >>          le64 sector;
> >> +        struct virtio_blk_crypto_payload {
> >> +            u8 slot;
> >> +            u8 activate;
> >> +            le16 reserved1;
> >> +            le32 reserved2;
> >> +            le64 data_unit_num;
> >> +        } payload;
> >>          u8 data[];
> >>          u8 status;
> >>  };
> >> @@ -463,6 +516,20 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
> >>  the read or write is to occur. This field is unused and set to 0 for
> >>  commands other than read, write and some zone operations.
> >>  
> >> +The \field{payload} consists of the encryption information for current
> >> +request. It need to be set by the driver only when the feature VIRTIO_BLK_F_ICE
> >> +is negotiated.
> > 
> > "set" is ambiguous: does it meaning filling in the fields or does it
> > mean the fields are only present when VIRTIO_BLK_F_ICE is negotiated
> > (this distinction is important if other features add more fields after
> > payload in the future).
> > 
> > The sentence could be reworded:
> > 
> >   It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
> >   \field{type} is VIRTIO_BLK_T_IN or VIRTIO_BLK_T_OUT.
> > 
> > (I'm not sure whether DISCARD, WRITE_ZEROES, or SECURE_ERASE also need
> > the payload field. It seems like GET_ID and GET_LIFETIME do not need the
> > payload field.)
> 
> Accept and update it as the following.
> 
>   It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
>   +\field{type} is VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT or VIRTIO_BLK_T_FLUSH.

Thanks.

> 
> > 
> >> +\begin{itemize}
> >> +\item The \field{slot} filed in \field{payload} indicates the ICE
> > 
> > s/filed/field/
> 
> Thanks for the correction. Update it in new patch.
> 
> > 
> >> +  (Inline Crypto Encryption) slot index where the key resides in.
> > 
> > s/where the key resides in/where the key resides/
> 
> Thanks for the correction. Update it in new patch.
> 
> > 
> >> +
> >> +\item The \field{activate} filed in \field{payload} implies this is a
> > 
> > s/filed/field/
> 
> Thanks for the correction. Update it in new patch.
> 
> > 
> >> +  encryption request.
> > 
> > Does "encryption" really mean just encryption or does it mean
> > encryption for writes and decryption for reads?
> 
> Actually encryption request here means both encryption for writes and
> decryption for reads. Need I modify it as the following?

If writing "encryption/decryption" is too tedious, maybe use the feature
name ("inline encryption"). That way it's clear we're talking about the
feature and not specifically about an encryption operation (vs a
decryption operation).

> 
>   \item The \field{activate} field in \field{payload} implies this is a
>   encryption write request or decryption read request.
> 
> > 
> >> +
> >> +\item The \field{data_unit_num} filed in \field{payload} indicates the
> > 
> > s/filed/field/
> 
> Thanks for the correction. Update it in new patch.
> 
> > 
> >> +  starting block of the request.
> >> +\end{itemize}
> >> +
> >>  VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
> >>  read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
> >>  requests write the contents of \field{data} to the block device (in multiples
> >> @@ -912,6 +979,8 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
> >>  successfully, failed, or were processed by the device at all if the request
> >>  failed with VIRTIO_BLK_S_IOERR.
> >>  
> >> +A driver MUST set \field{activate} to 0 for a non VIRTIO_BLK_F_ICE request.
> > 
> > Please explicitly list request types where the payload field is present
> > and where activate is optional.
> 
> How about adding the following supplement?
> 
>   \begin{itemize}
>   \item only when the block request contains crypto context and the request type

I'm not sure what "when the block request contains crypto context"
means. Is that the same as "when VIRTIO_BLK_F_ICE has been negotiated"?

>       is one of VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT and VIRTIO_BLK_T_FLUSH,
>       \field{activate} MUST be set to 1.
> 
>   \item \field{activate} should be set to 0 for all the other cases.
>   \end{itemize}
> 
> > 
> >> +
> >>  The following requirements only apply if the VIRTIO_BLK_F_ZONED feature is
> >>  negotiated.
> >>  
> >> -- 
> >> 2.34.1
> >>
> >>
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v1] virtio-blk: Add inline encryption support
  2026-02-02 15:56       ` Stefan Hajnoczi
@ 2026-02-03 10:06         ` Linlin Zhang
  2026-02-03 14:43           ` Stefan Hajnoczi
  0 siblings, 1 reply; 13+ messages in thread
From: Linlin Zhang @ 2026-02-03 10:06 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: virtio-dev, quic_dshaikhu



On 2/2/2026 11:56 PM, Stefan Hajnoczi wrote:
> On Fri, Jan 30, 2026 at 06:23:55PM +0800, Linlin Zhang wrote:
>> Thank you for the review. I’ve added some clarifications and potential updates.
>> Could you please take another look before I send a new patch?
>>
>> On 1/28/2026 5:09 AM, Stefan Hajnoczi wrote:
>>> On Tue, Jan 27, 2026 at 10:20:32PM +0800, Linlin Zhang wrote:
>>>> From: linlzhan <quic_linlzhan@quicinc.com>
>>>>
>>>> Inline encryption on virtio block can only be supported when
>>>> the new feature bit VIRTIO_BLK_F_ICE is negotiated.
>>>>
>>>> Extend struct virtio_blk_config and struct virtio_blk_req,
>>>> so that crypto capabilities can be got in the frontend and
>>>> encryption metadata can be sent to the backend, together with
>>>> each I/O transaction.
>>>
>>> This looks like a Self-Encrypting Drives feature along the lines of TCG
>>> Opal:
>>> https://en.wikipedia.org/wiki/Opal_Storage_Specification
>>>
>>> Would it make sense to implement TCG Opal instead of defining a new
>>> interface? That would make this more familiar to users and simplify
>>> integration into existing tools like sedutil and cryptsetup (e.g. by
>>> supporting the <linux/sed-opal.h> ioctl interface).
>>
>> This patch is for the FBE (File Based Encryption) support on UFS/EMMC
>> storage with ICE (Inline Crypto Engine) enabled. TCG Opal is only applicable
>> to SED (self-encrypting drives), not applicable to ICE (Inline Crypto Engine).
>>
>> In Automotive or Embedded scenario, UFS/EMMC generally is used. The disk
>> encryption on them is supported by the ICE pipeline of SOC, rather SSD
>> controller, so we couldn't use TCG Opal here.
> 
> Okay. Is there a specification that this interface needs to comply with?
> 
> If not, you can include a link to the Linux inline encryption
> documentation in the commit description:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/block/inline-encryption.rst
> 
> Having a reference will will help the discussion. That way we can be
> confident the VIRTIO spec changes will be widely useful beyond a single
> use case and easy to implement in drivers because they follow an
> existing interface.

ACK

> 
>>
>>>
>>>> Fixes: https://github.com/oasis-tcs/virtio-spec/issues/238
>>>>
>>>> Change-Id: Ic23b2137e5d9a599d826e06c279f1b614d79abdf
>>>> Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
>>>> ---
>>>>  device-types/blk/description.tex | 69 ++++++++++++++++++++++++++++++++
>>>>  1 file changed, 69 insertions(+)
>>>>
>>>> diff --git a/device-types/blk/description.tex b/device-types/blk/description.tex
>>>> index 2712ada..23d8dc0 100644
>>>> --- a/device-types/blk/description.tex
>>>> +++ b/device-types/blk/description.tex
>>>> @@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
>>>>  	(ZNS). For brevity, these standard documents are referred as "ZBD standards"
>>>>  	from this point on in the text.
>>>>  
>>>> +\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported. When this
>>>> +     is negotiated, the device exposes crypto characteristics in configuration
>>>> +     space and the driver SHALL provide an extended request header containing a
>>>
>>> SHALL, MUST, MAY, etc are only used in the normative sections of the
>>> spec.
>>>
>>> Why "SHALL"? Does this mean the device must be prepared to receive
>>> requests without the payload field when VIRTIO_BLK_F_ICE is negotiated?
>>> How should the device behave in that case: fail the request or perform
>>> I/O without crypto?
>>
>> This section - 5.2.3 Feature bits - is a normative section.
> 
> \section{Block Device}\label{sec:Device Types / Block Device}
> ...
> \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
> 
> No, this is a non-normative section. The normative sections are the
> "Device Requirements" (\devicenormative) and "Driver Requirements"
> (\drivernormative) sections.

OK, as this is a non-normative section, can I use lowercase 'shall', 'must'.etc here?

> 
>>
>> What's expected for VIRTIO_BLK_F_ICE feature bit is that configuration space
>> must be prepared with the exposed crypto characteristics and the virtio block
>> frontend must sent a virtblk request with encryption metadata packed into
>> when VIRTIO_BLK_F_ICE is negotiated and hardware crypto is supported.
>>
>> By replacing 'SHALL' with 'MUST' here, Is the following rewording fine?
>>
>>   Inline Crypto Extensions are supported. When this is negotiated, the device MUST
>>   expose crypto characteristics in configuration space and the driver MUST provide
>>   an extended request header containing a crypto payload for block I/O if the
>>   hardware supports inline crypto. If this feature bit is negotiated, but hardware
>>   inline crypto doesn't support, the device SHOULD perform I/O without crypto.
>>
>> I'll add hw_enabled (type: u8) to virtio_blk_crypto_characteristics to indicate
>> whether the host supports hardware inline encryption.
> 
> I still have a question about this: why would a device advertise
> VIRTIO_BLK_F_ICE but report hw_enabled = 0? I'm not sure how this is
> functionally different from a device that does not report
> VIRTIO_BLK_F_ICE. It seems simpler for devices to only advertise
> VIRTIO_BLK_F_ICE when they support inline encryption.

ACK.
Previously I assume VIRTIO_BLK_F_ICE is negotiated even ICE (Inline Crypto Engine)
isn't enabled. Seems it isn't needed. a device should only advertise
VIRTIO_BLK_F_ICE when ICE is enabled. Correct the statement as the following.

  Inline Crypto Extensions are supported. Only when this feature b is negotiated, the device need
  expose crypto characteristics in configuration space and the driver need provide
  an extended request header containing a crypto payload for block I/O. 

> 
>>>
>>>> +     crypto payload for block I/O.
>>>> +
>>>>  \end{description}
>>>>  
>>>>  \subsubsection{Legacy Interface: Feature bits}\label{sec:Device Types / Block Device / Feature bits / Legacy Interface: Feature bits}
>>>> @@ -128,6 +133,11 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
>>>>                  u8 model;
>>>>                  u8 unused2[3];
>>>>          } zoned;
>>>> +        struct virtio_blk_crypto_characteristics {
>>>> +                __virtio16 slot_info;
>>>> +                __virtio16 reserved;
>>>> +                __virtio32 capability;
>>>> +        } crypto;
>>>>  };
>>>>  \end{lstlisting}
>>>>  
>>>> @@ -215,6 +225,25 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
>>>>  terminated by the device with a "zone resources exceeded" error as defined for
>>>>  specific commands later.
>>>>  
>>>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then in
>>>> +\field{virtio_blk_crypto_characteristics},
>>>> +\begin{itemize}
>>>> +\item \field{slot_info} value packs two 8-bits values:
>>>> +    \begin{itemize}
>>>> +        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number of supported
>>>> +            crypto key slots.
>>>> +        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied to slot numbering.
>>>> +    \end{itemize}
>>>> +\item \field{capability} value packs four 8-bits values:
>>>> +    \begin{itemize}
>>>> +        \item Bits~\[31:24]: crypto algorithm id.
>>>> +        \item Bits~\[23:16]: mask of data unit size.
>>>> +        \item Bits~\[15:8]: crypto key size.
>>>> +        \item Bits~\[7:0]: unused.
>>>> +    \end{itemize}
>>>
>>> Why are these fields packed? Configuration Space can have u8 fields.
>>
>> Given that &sect. 4.2.2.2 saying "For the device-specific configuration space,
>> the driver MUST use 8 bit wide accesses for 8 bit wide fields, 16 bit wide
>> and aligned accesses for 16 bit wide fields and 32 bit wide and aligned
>> accesses for 32 and 64 bit wide fields.",  these fields are packed for a
>> efficient read from the configuration space.
> 
> I see. I suggest mentioning this explicitly: "value packs two 8-bits
> values to reduce the number of Configuration Space reads".

ACK

> 
>>>
>>> These fields are not sufficiently documented. Where are the crypto
>>> algorithm ids listed, etc?
>>
>> Can I reword it as the following?
> 
> Yes, looks good in general. I have some comments below.
> 
>>
>>   \item Bits~\[31:24]: crypto algorithm identifiers.
>>   The device SHALL support reporting and negotiating cryptographic
>>   algorithms using the following algorithm identifiers:
>>   \begin{lstlisting}
>>       CRYPTO_ALG_AES_XTS              = 0x0
>>       CRYPTO_ALG_BITLOCKER_AES_CBC    = 0x1
>>       CRYPTO_ALG_AES_ECB              = 0x2
>>       CRYPTO_ALG_ESSIV_AES_CBC        = 0x3
>>   \end{lstlisting}
>>   These identifiers abstract the underlying hardware crypto implementation
>>   and MUST NOT assume any operating‑system‑specific data structures or
>>   constants.
> 
> (The MUST NOT part needs to be in a \devicenormative or \drivernormative
> sections, but I think "MUST NOT" can be replaced with "does not" here
> because it actually describes the design of the interface rather than
> imposing requirements on device implementors.)

ACK

> 
>>   \item Bits~\[23:16]: mask of data unit size. When bit j in this field
>>   (j=0......7)is set, a data unit size of 512*2^j bytes is slected.
> 
> s/)is set/) is set/
> s/slected/selected/

ACK

> 
> How is the data unit size used? Does it affect the allowed request sizes
> of the device?
> 
> For example, if the mask is 0x2, so that mean request sizes must be
> multiples of 1 KiB?

The data unit size is only used in the control flow of programing a key into
ICE slot. It hasn't impact on the virtblk request size.
For instance, if the mask is 0x2, so that mean the encryption granularity is
(2^1 * 512 = ) 1024 bytes. I.e. ICE hardware increase DUN (Date Unit Number)
per 1024 bytes to do encryption/decryption.

> 
> By the way, I'm not sure whether "j=0......7" mean that a mask value of
> 0x2 has j=1 or j=6? Usually bits are numbered right-to-left from least
> significant bit to most significant bit.

A mask value of 0x2 has j=1. It comply with right-to-left number sequence.

> 
>>   \item Bits~\[15:8]: crypto key size identifiers.
>>   \begin{lstlisting}
>>       CRYPTO_KEY_SIZE_INVALID     = 0x0
>>       CRYPTO_KEY_SIZE_128_BITS    = 0x1
>>       CRYPTO_KEY_SIZE_192_BITS    = 0x2
>>       CRYPTO_KEY_SIZE_256_BITS    = 0x3
>>       CRYPTO_KEY_SIZE_512_BITS    = 0x4
>>   \end{lstlisting}
>>
>>>
>>> How can a device support multiple algorithms? I think Configuration
>>> Space may not be flexible enough for this. You could introduce a
>>> GET_CRYPTO_INFO request type that allows the driver to fetch arrays of
>>> crypto algorithm characteristics.
>>
>> Virtio block driver need register crypto capability for request_queue of
>> virtio block device. That means virtio block frontend need get crypto
>> capability before virtio block device is ready. But the request can only
>> be sent after the virtio block device is ready. Thus I think it's impossible
>> to get such capabilities from the backend via a new request type, event
>> though the hardware in the host may support a few algorithms (the actual
>> number of algorithms will change depending on the vendor manufacturer.).
>> Thus I assume the host only configure and expose one hardware crypto
>> capability to the virtual machine and virtio block frontend gets is
>> through configuration space.
> 
> The zoned storage feature also needs to use the virtqueues during driver
> initialization in order to report zones. Here is the Linux virtio_blk.c
> driver code:
> 
> static int virtblk_probe(struct virtio_device *vdev)
> {
> ...
>     virtio_device_ready(vdev);
> 
>     /*
>      * All steps that follow use the VQs therefore they need to be
>      * placed after the virtio_device_ready() call above.
>      */
>     if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
>         (lim.features & BLK_FEAT_ZONED)) {
>             err = blk_revalidate_disk_zones(vblk->disk);
>             if (err)
>                     goto out_cleanup_disk;
>     }
> 
>     err = device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups);
> 
> Is it possible to call blk_crypto_register() between
> virtio_device_read() and device_add_disk()?

Thanks! Referring to zoned storage feature, if we use the virtqueues to
get crypto capabilities, we need extend in_hdr in struct virtblk_req to
add new fields for crypto capability. Like the following field
crypto_append. Is it fine? 
we can not use a fixed-size array for crypto capabilities. Because the
number of the capabilities differs for different OEMs and storage devices.

  struct virtblk_req {
      /* Out header */
      struct virtio_blk_outhdr out_hdr;
  
      /* In header */
      union {
          u8 status;
  
          /*
          * The zone append command has an extended in header.
          * The status field in zone_append_in_hdr must always
          * be the last byte.
          */
          struct {
              __virtio64 sector;
              u8 status;
          } zone_append;

          struct {
              u8 num;
              __virtio32 *capabilities;
          } crypto_append;
      } in_hdr;
  
      size_t in_hdr_len;
  
      struct sg_table sg_table;
      struct scatterlist sg[];
  };

> 
>>
>>>
>>>> +\end{itemize}
>>>> +
>>>> +
>>>>  \subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Block Device / Device configuration layout / Legacy Interface: Device configuration layout}
>>>>  When using the legacy interface, transitional devices and drivers
>>>>  MUST format the fields in struct virtio_blk_config
>>>> @@ -278,6 +307,10 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>>>>      \field{zoned} can be read by the driver to determine the zone
>>>>      characteristics of the device. All \field{zoned} fields are read-only.
>>>>  
>>>> +\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
>>>> +    \field{crypto} can be read by the driver to determine the inline crypto
>>>> +    characteristics of the device. All \field{crypto} fields are read-only.
>>>> +
>>>>  \end{enumerate}
>>>>  
>>>>  \drivernormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
>>>> @@ -317,6 +350,9 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>>>>      driver SHOULD ignore all other fields in \field{zoned}.
>>>>  \end{itemize}
>>>>  
>>>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver must validate
>>>> +    the max_slots in \field{slot_info} before the slot usage.
>>>> +
>>>>  \devicenormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
>>>>  
>>>>  Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it
>>>> @@ -402,6 +438,16 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>>>>  \item the device MUST initialize padding bytes \field{unused2} to 0.
>>>>  \end{itemize}
>>>>  
>>>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in \field{cryto}
>>>
>>> s/cryto/crypto/
>>
>> Thanks for the correction. Update it in new patch.
>>
>>>
>>>> +struct in the configuration space MUST be set by the device.
>>>> +\begin{itemize}
>>>> +\item the \field{slot_info} field of \field{crypto} MUST be set by the device to a
>>>> +    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
>>>> +
>>>> +\item the \field{capability} field of \field{crypto} MUST be set by the device
>>>> +    to a crypto capability read from the storage register.
>>>> +\end{itemize}
>>>> +
>>>>  \subsubsection{Legacy Interface: Device Initialization}\label{sec:Device Types / Block Device / Device Initialization / Legacy Interface: Device Initialization}
>>>>  
>>>>  Because legacy devices do not have FEATURES_OK, transitional devices
>>>> @@ -436,6 +482,13 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>>>>          le32 type;
>>>>          le32 reserved;
>>>>          le64 sector;
>>>> +        struct virtio_blk_crypto_payload {
>>>> +            u8 slot;
>>>> +            u8 activate;
>>>> +            le16 reserved1;
>>>> +            le32 reserved2;
>>>> +            le64 data_unit_num;
>>>> +        } payload;
>>>>          u8 data[];
>>>>          u8 status;
>>>>  };
>>>> @@ -463,6 +516,20 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>>>>  the read or write is to occur. This field is unused and set to 0 for
>>>>  commands other than read, write and some zone operations.
>>>>  
>>>> +The \field{payload} consists of the encryption information for current
>>>> +request. It need to be set by the driver only when the feature VIRTIO_BLK_F_ICE
>>>> +is negotiated.
>>>
>>> "set" is ambiguous: does it meaning filling in the fields or does it
>>> mean the fields are only present when VIRTIO_BLK_F_ICE is negotiated
>>> (this distinction is important if other features add more fields after
>>> payload in the future).
>>>
>>> The sentence could be reworded:
>>>
>>>   It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
>>>   \field{type} is VIRTIO_BLK_T_IN or VIRTIO_BLK_T_OUT.
>>>
>>> (I'm not sure whether DISCARD, WRITE_ZEROES, or SECURE_ERASE also need
>>> the payload field. It seems like GET_ID and GET_LIFETIME do not need the
>>> payload field.)
>>
>> Accept and update it as the following.
>>
>>   It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
>>   +\field{type} is VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT or VIRTIO_BLK_T_FLUSH.
> 
> Thanks.
> 
>>
>>>
>>>> +\begin{itemize}
>>>> +\item The \field{slot} filed in \field{payload} indicates the ICE
>>>
>>> s/filed/field/
>>
>> Thanks for the correction. Update it in new patch.
>>
>>>
>>>> +  (Inline Crypto Encryption) slot index where the key resides in.
>>>
>>> s/where the key resides in/where the key resides/
>>
>> Thanks for the correction. Update it in new patch.
>>
>>>
>>>> +
>>>> +\item The \field{activate} filed in \field{payload} implies this is a
>>>
>>> s/filed/field/
>>
>> Thanks for the correction. Update it in new patch.
>>
>>>
>>>> +  encryption request.
>>>
>>> Does "encryption" really mean just encryption or does it mean
>>> encryption for writes and decryption for reads?
>>
>> Actually encryption request here means both encryption for writes and
>> decryption for reads. Need I modify it as the following?
> 
> If writing "encryption/decryption" is too tedious, maybe use the feature
> name ("inline encryption"). That way it's clear we're talking about the
> feature and not specifically about an encryption operation (vs a
> decryption operation).

ACK

> 
>>
>>   \item The \field{activate} field in \field{payload} implies this is a
>>   encryption write request or decryption read request.
>>
>>>
>>>> +
>>>> +\item The \field{data_unit_num} filed in \field{payload} indicates the
>>>
>>> s/filed/field/
>>
>> Thanks for the correction. Update it in new patch.
>>
>>>
>>>> +  starting block of the request.
>>>> +\end{itemize}
>>>> +
>>>>  VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
>>>>  read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
>>>>  requests write the contents of \field{data} to the block device (in multiples
>>>> @@ -912,6 +979,8 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>>>>  successfully, failed, or were processed by the device at all if the request
>>>>  failed with VIRTIO_BLK_S_IOERR.
>>>>  
>>>> +A driver MUST set \field{activate} to 0 for a non VIRTIO_BLK_F_ICE request.
>>>
>>> Please explicitly list request types where the payload field is present
>>> and where activate is optional.
>>
>> How about adding the following supplement?
>>
>>   \begin{itemize}
>>   \item only when the block request contains crypto context and the request type
> 
> I'm not sure what "when the block request contains crypto context"
> means. Is that the same as "when VIRTIO_BLK_F_ICE has been negotiated"?

No, crypto context means bio_crypt_ctx in BIO struct.
  struct bio {
  ...
  #ifdef CONFIG_BLK_INLINE_ENCRYPTION
	  struct bio_crypt_ctx	*bi_crypt_context;
  #endif
  ...
  }

When VIRTIO_BLK_F_ICE has been negotiated, virtio block backend receives crypto
payload from virtio block frontend, and the crypto payload, together with I/O
transaction, is sent to block layer of the host finally. The crypto payload is
used to construct the bio_crypt_ctx filed of BIO.

> 
>>       is one of VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT and VIRTIO_BLK_T_FLUSH,
>>       \field{activate} MUST be set to 1.
>>
>>   \item \field{activate} should be set to 0 for all the other cases.
>>   \end{itemize}
>>
>>>
>>>> +
>>>>  The following requirements only apply if the VIRTIO_BLK_F_ZONED feature is
>>>>  negotiated.
>>>>  
>>>> -- 
>>>> 2.34.1
>>>>
>>>>
>>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v1] virtio-blk: Add inline encryption support
  2026-02-03 10:06         ` Linlin Zhang
@ 2026-02-03 14:43           ` Stefan Hajnoczi
  2026-02-04 13:57             ` Linlin Zhang
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Hajnoczi @ 2026-02-03 14:43 UTC (permalink / raw)
  To: Linlin Zhang; +Cc: virtio-dev, quic_dshaikhu

[-- Attachment #1: Type: text/plain, Size: 24454 bytes --]

On Tue, Feb 03, 2026 at 06:06:33PM +0800, Linlin Zhang wrote:
> 
> 
> On 2/2/2026 11:56 PM, Stefan Hajnoczi wrote:
> > On Fri, Jan 30, 2026 at 06:23:55PM +0800, Linlin Zhang wrote:
> >> Thank you for the review. I’ve added some clarifications and potential updates.
> >> Could you please take another look before I send a new patch?
> >>
> >> On 1/28/2026 5:09 AM, Stefan Hajnoczi wrote:
> >>> On Tue, Jan 27, 2026 at 10:20:32PM +0800, Linlin Zhang wrote:
> >>>> From: linlzhan <quic_linlzhan@quicinc.com>
> >>>>
> >>>> Inline encryption on virtio block can only be supported when
> >>>> the new feature bit VIRTIO_BLK_F_ICE is negotiated.
> >>>>
> >>>> Extend struct virtio_blk_config and struct virtio_blk_req,
> >>>> so that crypto capabilities can be got in the frontend and
> >>>> encryption metadata can be sent to the backend, together with
> >>>> each I/O transaction.
> >>>
> >>> This looks like a Self-Encrypting Drives feature along the lines of TCG
> >>> Opal:
> >>> https://en.wikipedia.org/wiki/Opal_Storage_Specification
> >>>
> >>> Would it make sense to implement TCG Opal instead of defining a new
> >>> interface? That would make this more familiar to users and simplify
> >>> integration into existing tools like sedutil and cryptsetup (e.g. by
> >>> supporting the <linux/sed-opal.h> ioctl interface).
> >>
> >> This patch is for the FBE (File Based Encryption) support on UFS/EMMC
> >> storage with ICE (Inline Crypto Engine) enabled. TCG Opal is only applicable
> >> to SED (self-encrypting drives), not applicable to ICE (Inline Crypto Engine).
> >>
> >> In Automotive or Embedded scenario, UFS/EMMC generally is used. The disk
> >> encryption on them is supported by the ICE pipeline of SOC, rather SSD
> >> controller, so we couldn't use TCG Opal here.
> > 
> > Okay. Is there a specification that this interface needs to comply with?
> > 
> > If not, you can include a link to the Linux inline encryption
> > documentation in the commit description:
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/block/inline-encryption.rst
> > 
> > Having a reference will will help the discussion. That way we can be
> > confident the VIRTIO spec changes will be widely useful beyond a single
> > use case and easy to implement in drivers because they follow an
> > existing interface.
> 
> ACK
> 
> > 
> >>
> >>>
> >>>> Fixes: https://github.com/oasis-tcs/virtio-spec/issues/238
> >>>>
> >>>> Change-Id: Ic23b2137e5d9a599d826e06c279f1b614d79abdf
> >>>> Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
> >>>> ---
> >>>>  device-types/blk/description.tex | 69 ++++++++++++++++++++++++++++++++
> >>>>  1 file changed, 69 insertions(+)
> >>>>
> >>>> diff --git a/device-types/blk/description.tex b/device-types/blk/description.tex
> >>>> index 2712ada..23d8dc0 100644
> >>>> --- a/device-types/blk/description.tex
> >>>> +++ b/device-types/blk/description.tex
> >>>> @@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
> >>>>  	(ZNS). For brevity, these standard documents are referred as "ZBD standards"
> >>>>  	from this point on in the text.
> >>>>  
> >>>> +\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported. When this
> >>>> +     is negotiated, the device exposes crypto characteristics in configuration
> >>>> +     space and the driver SHALL provide an extended request header containing a
> >>>
> >>> SHALL, MUST, MAY, etc are only used in the normative sections of the
> >>> spec.
> >>>
> >>> Why "SHALL"? Does this mean the device must be prepared to receive
> >>> requests without the payload field when VIRTIO_BLK_F_ICE is negotiated?
> >>> How should the device behave in that case: fail the request or perform
> >>> I/O without crypto?
> >>
> >> This section - 5.2.3 Feature bits - is a normative section.
> > 
> > \section{Block Device}\label{sec:Device Types / Block Device}
> > ...
> > \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
> > 
> > No, this is a non-normative section. The normative sections are the
> > "Device Requirements" (\devicenormative) and "Driver Requirements"
> > (\drivernormative) sections.
> 
> OK, as this is a non-normative section, can I use lowercase 'shall', 'must'.etc here?

I think that is discouraged to prevent confusion. It can be phrased in a
descriptive way instead:

  and the driver provides an extended request header containing a ...

> 
> > 
> >>
> >> What's expected for VIRTIO_BLK_F_ICE feature bit is that configuration space
> >> must be prepared with the exposed crypto characteristics and the virtio block
> >> frontend must sent a virtblk request with encryption metadata packed into
> >> when VIRTIO_BLK_F_ICE is negotiated and hardware crypto is supported.
> >>
> >> By replacing 'SHALL' with 'MUST' here, Is the following rewording fine?
> >>
> >>   Inline Crypto Extensions are supported. When this is negotiated, the device MUST
> >>   expose crypto characteristics in configuration space and the driver MUST provide
> >>   an extended request header containing a crypto payload for block I/O if the
> >>   hardware supports inline crypto. If this feature bit is negotiated, but hardware
> >>   inline crypto doesn't support, the device SHOULD perform I/O without crypto.
> >>
> >> I'll add hw_enabled (type: u8) to virtio_blk_crypto_characteristics to indicate
> >> whether the host supports hardware inline encryption.
> > 
> > I still have a question about this: why would a device advertise
> > VIRTIO_BLK_F_ICE but report hw_enabled = 0? I'm not sure how this is
> > functionally different from a device that does not report
> > VIRTIO_BLK_F_ICE. It seems simpler for devices to only advertise
> > VIRTIO_BLK_F_ICE when they support inline encryption.
> 
> ACK.
> Previously I assume VIRTIO_BLK_F_ICE is negotiated even ICE (Inline Crypto Engine)
> isn't enabled. Seems it isn't needed. a device should only advertise
> VIRTIO_BLK_F_ICE when ICE is enabled. Correct the statement as the following.
> 
>   Inline Crypto Extensions are supported. Only when this feature b is negotiated, the device need
>   expose crypto characteristics in configuration space and the driver need provide
>   an extended request header containing a crypto payload for block I/O. 

Good.

> 
> > 
> >>>
> >>>> +     crypto payload for block I/O.
> >>>> +
> >>>>  \end{description}
> >>>>  
> >>>>  \subsubsection{Legacy Interface: Feature bits}\label{sec:Device Types / Block Device / Feature bits / Legacy Interface: Feature bits}
> >>>> @@ -128,6 +133,11 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
> >>>>                  u8 model;
> >>>>                  u8 unused2[3];
> >>>>          } zoned;
> >>>> +        struct virtio_blk_crypto_characteristics {
> >>>> +                __virtio16 slot_info;
> >>>> +                __virtio16 reserved;
> >>>> +                __virtio32 capability;
> >>>> +        } crypto;
> >>>>  };
> >>>>  \end{lstlisting}
> >>>>  
> >>>> @@ -215,6 +225,25 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
> >>>>  terminated by the device with a "zone resources exceeded" error as defined for
> >>>>  specific commands later.
> >>>>  
> >>>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then in
> >>>> +\field{virtio_blk_crypto_characteristics},
> >>>> +\begin{itemize}
> >>>> +\item \field{slot_info} value packs two 8-bits values:
> >>>> +    \begin{itemize}
> >>>> +        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number of supported
> >>>> +            crypto key slots.
> >>>> +        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied to slot numbering.
> >>>> +    \end{itemize}
> >>>> +\item \field{capability} value packs four 8-bits values:
> >>>> +    \begin{itemize}
> >>>> +        \item Bits~\[31:24]: crypto algorithm id.
> >>>> +        \item Bits~\[23:16]: mask of data unit size.
> >>>> +        \item Bits~\[15:8]: crypto key size.
> >>>> +        \item Bits~\[7:0]: unused.
> >>>> +    \end{itemize}
> >>>
> >>> Why are these fields packed? Configuration Space can have u8 fields.
> >>
> >> Given that &sect. 4.2.2.2 saying "For the device-specific configuration space,
> >> the driver MUST use 8 bit wide accesses for 8 bit wide fields, 16 bit wide
> >> and aligned accesses for 16 bit wide fields and 32 bit wide and aligned
> >> accesses for 32 and 64 bit wide fields.",  these fields are packed for a
> >> efficient read from the configuration space.
> > 
> > I see. I suggest mentioning this explicitly: "value packs two 8-bits
> > values to reduce the number of Configuration Space reads".
> 
> ACK
> 
> > 
> >>>
> >>> These fields are not sufficiently documented. Where are the crypto
> >>> algorithm ids listed, etc?
> >>
> >> Can I reword it as the following?
> > 
> > Yes, looks good in general. I have some comments below.
> > 
> >>
> >>   \item Bits~\[31:24]: crypto algorithm identifiers.
> >>   The device SHALL support reporting and negotiating cryptographic
> >>   algorithms using the following algorithm identifiers:
> >>   \begin{lstlisting}
> >>       CRYPTO_ALG_AES_XTS              = 0x0
> >>       CRYPTO_ALG_BITLOCKER_AES_CBC    = 0x1
> >>       CRYPTO_ALG_AES_ECB              = 0x2
> >>       CRYPTO_ALG_ESSIV_AES_CBC        = 0x3
> >>   \end{lstlisting}
> >>   These identifiers abstract the underlying hardware crypto implementation
> >>   and MUST NOT assume any operating‑system‑specific data structures or
> >>   constants.
> > 
> > (The MUST NOT part needs to be in a \devicenormative or \drivernormative
> > sections, but I think "MUST NOT" can be replaced with "does not" here
> > because it actually describes the design of the interface rather than
> > imposing requirements on device implementors.)
> 
> ACK
> 
> > 
> >>   \item Bits~\[23:16]: mask of data unit size. When bit j in this field
> >>   (j=0......7)is set, a data unit size of 512*2^j bytes is slected.
> > 
> > s/)is set/) is set/
> > s/slected/selected/
> 
> ACK
> 
> > 
> > How is the data unit size used? Does it affect the allowed request sizes
> > of the device?
> > 
> > For example, if the mask is 0x2, so that mean request sizes must be
> > multiples of 1 KiB?
> 
> The data unit size is only used in the control flow of programing a key into
> ICE slot. It hasn't impact on the virtblk request size.
> For instance, if the mask is 0x2, so that mean the encryption granularity is
> (2^1 * 512 = ) 1024 bytes. I.e. ICE hardware increase DUN (Date Unit Number)
> per 1024 bytes to do encryption/decryption.

Okay.

> 
> > 
> > By the way, I'm not sure whether "j=0......7" mean that a mask value of
> > 0x2 has j=1 or j=6? Usually bits are numbered right-to-left from least
> > significant bit to most significant bit.
> 
> A mask value of 0x2 has j=1. It comply with right-to-left number sequence.

Okay. It might be clearer to write "j=7......0" so the right-to-left
numbering is shown.

> 
> > 
> >>   \item Bits~\[15:8]: crypto key size identifiers.
> >>   \begin{lstlisting}
> >>       CRYPTO_KEY_SIZE_INVALID     = 0x0
> >>       CRYPTO_KEY_SIZE_128_BITS    = 0x1
> >>       CRYPTO_KEY_SIZE_192_BITS    = 0x2
> >>       CRYPTO_KEY_SIZE_256_BITS    = 0x3
> >>       CRYPTO_KEY_SIZE_512_BITS    = 0x4
> >>   \end{lstlisting}
> >>
> >>>
> >>> How can a device support multiple algorithms? I think Configuration
> >>> Space may not be flexible enough for this. You could introduce a
> >>> GET_CRYPTO_INFO request type that allows the driver to fetch arrays of
> >>> crypto algorithm characteristics.
> >>
> >> Virtio block driver need register crypto capability for request_queue of
> >> virtio block device. That means virtio block frontend need get crypto
> >> capability before virtio block device is ready. But the request can only
> >> be sent after the virtio block device is ready. Thus I think it's impossible
> >> to get such capabilities from the backend via a new request type, event
> >> though the hardware in the host may support a few algorithms (the actual
> >> number of algorithms will change depending on the vendor manufacturer.).
> >> Thus I assume the host only configure and expose one hardware crypto
> >> capability to the virtual machine and virtio block frontend gets is
> >> through configuration space.
> > 
> > The zoned storage feature also needs to use the virtqueues during driver
> > initialization in order to report zones. Here is the Linux virtio_blk.c
> > driver code:
> > 
> > static int virtblk_probe(struct virtio_device *vdev)
> > {
> > ...
> >     virtio_device_ready(vdev);
> > 
> >     /*
> >      * All steps that follow use the VQs therefore they need to be
> >      * placed after the virtio_device_ready() call above.
> >      */
> >     if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
> >         (lim.features & BLK_FEAT_ZONED)) {
> >             err = blk_revalidate_disk_zones(vblk->disk);
> >             if (err)
> >                     goto out_cleanup_disk;
> >     }
> > 
> >     err = device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups);
> > 
> > Is it possible to call blk_crypto_register() between
> > virtio_device_read() and device_add_disk()?
> 
> Thanks! Referring to zoned storage feature, if we use the virtqueues to
> get crypto capabilities, we need extend in_hdr in struct virtblk_req to
> add new fields for crypto capability. Like the following field
> crypto_append. Is it fine? 
> we can not use a fixed-size array for crypto capabilities. Because the
> number of the capabilities differs for different OEMs and storage devices.
> 
>   struct virtblk_req {
>       /* Out header */
>       struct virtio_blk_outhdr out_hdr;
>   
>       /* In header */
>       union {
>           u8 status;
>   
>           /*
>           * The zone append command has an extended in header.
>           * The status field in zone_append_in_hdr must always
>           * be the last byte.
>           */
>           struct {
>               __virtio64 sector;
>               u8 status;
>           } zone_append;
> 
>           struct {
>               u8 num;
>               __virtio32 *capabilities;
>           } crypto_append;

This is not necessary. Take a look at virtblk_get_id(). It maps the
id_str buffer so the device can DMA the disk's serial number. The serial
number field is treated as a data read buffer, not as an in_hdr field.

Here is how it could work:

  struct virtio_blk_outhdr {
      .type = VIRTIO_BLK_T_GET_CRYPTO_PROFILES,
      .ioprio = 0,
      .sector = 0
  };

  struct virtio_blk_crypto_profile profiles[MAX_PROFILES];

  u8 status;

The device fills in profiles[], sets the used buffer element's len field
to the number of bytes filled in, and sets the status field to
VIRTIO_BLK_S_OK.

If profiles[] is too short, it sets status to BLK_S_IO_ERR. The driver
is expected to increase the size (e.g. double the buffer) and try again.
Alternatively there could be a num_crypto_profiles field in
Configuration Space.

(Many variations are possible. For example, virtio_blk_outhdr's sector
field could be an offset into the list of profiles, allowing the driver
to page through profiles without allocating a buffer large enough to
hold all profiles at a time. But that's probably unnecessary, so I would
keep it simple.)

>       } in_hdr;
>   
>       size_t in_hdr_len;
>   
>       struct sg_table sg_table;
>       struct scatterlist sg[];
>   };
> 
> > 
> >>
> >>>
> >>>> +\end{itemize}
> >>>> +
> >>>> +
> >>>>  \subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Block Device / Device configuration layout / Legacy Interface: Device configuration layout}
> >>>>  When using the legacy interface, transitional devices and drivers
> >>>>  MUST format the fields in struct virtio_blk_config
> >>>> @@ -278,6 +307,10 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
> >>>>      \field{zoned} can be read by the driver to determine the zone
> >>>>      characteristics of the device. All \field{zoned} fields are read-only.
> >>>>  
> >>>> +\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
> >>>> +    \field{crypto} can be read by the driver to determine the inline crypto
> >>>> +    characteristics of the device. All \field{crypto} fields are read-only.
> >>>> +
> >>>>  \end{enumerate}
> >>>>  
> >>>>  \drivernormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
> >>>> @@ -317,6 +350,9 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
> >>>>      driver SHOULD ignore all other fields in \field{zoned}.
> >>>>  \end{itemize}
> >>>>  
> >>>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver must validate
> >>>> +    the max_slots in \field{slot_info} before the slot usage.
> >>>> +
> >>>>  \devicenormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
> >>>>  
> >>>>  Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it
> >>>> @@ -402,6 +438,16 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
> >>>>  \item the device MUST initialize padding bytes \field{unused2} to 0.
> >>>>  \end{itemize}
> >>>>  
> >>>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in \field{cryto}
> >>>
> >>> s/cryto/crypto/
> >>
> >> Thanks for the correction. Update it in new patch.
> >>
> >>>
> >>>> +struct in the configuration space MUST be set by the device.
> >>>> +\begin{itemize}
> >>>> +\item the \field{slot_info} field of \field{crypto} MUST be set by the device to a
> >>>> +    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
> >>>> +
> >>>> +\item the \field{capability} field of \field{crypto} MUST be set by the device
> >>>> +    to a crypto capability read from the storage register.
> >>>> +\end{itemize}
> >>>> +
> >>>>  \subsubsection{Legacy Interface: Device Initialization}\label{sec:Device Types / Block Device / Device Initialization / Legacy Interface: Device Initialization}
> >>>>  
> >>>>  Because legacy devices do not have FEATURES_OK, transitional devices
> >>>> @@ -436,6 +482,13 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
> >>>>          le32 type;
> >>>>          le32 reserved;
> >>>>          le64 sector;
> >>>> +        struct virtio_blk_crypto_payload {
> >>>> +            u8 slot;
> >>>> +            u8 activate;
> >>>> +            le16 reserved1;
> >>>> +            le32 reserved2;
> >>>> +            le64 data_unit_num;
> >>>> +        } payload;
> >>>>          u8 data[];
> >>>>          u8 status;
> >>>>  };
> >>>> @@ -463,6 +516,20 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
> >>>>  the read or write is to occur. This field is unused and set to 0 for
> >>>>  commands other than read, write and some zone operations.
> >>>>  
> >>>> +The \field{payload} consists of the encryption information for current
> >>>> +request. It need to be set by the driver only when the feature VIRTIO_BLK_F_ICE
> >>>> +is negotiated.
> >>>
> >>> "set" is ambiguous: does it meaning filling in the fields or does it
> >>> mean the fields are only present when VIRTIO_BLK_F_ICE is negotiated
> >>> (this distinction is important if other features add more fields after
> >>> payload in the future).
> >>>
> >>> The sentence could be reworded:
> >>>
> >>>   It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
> >>>   \field{type} is VIRTIO_BLK_T_IN or VIRTIO_BLK_T_OUT.
> >>>
> >>> (I'm not sure whether DISCARD, WRITE_ZEROES, or SECURE_ERASE also need
> >>> the payload field. It seems like GET_ID and GET_LIFETIME do not need the
> >>> payload field.)
> >>
> >> Accept and update it as the following.
> >>
> >>   It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
> >>   +\field{type} is VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT or VIRTIO_BLK_T_FLUSH.
> > 
> > Thanks.
> > 
> >>
> >>>
> >>>> +\begin{itemize}
> >>>> +\item The \field{slot} filed in \field{payload} indicates the ICE
> >>>
> >>> s/filed/field/
> >>
> >> Thanks for the correction. Update it in new patch.
> >>
> >>>
> >>>> +  (Inline Crypto Encryption) slot index where the key resides in.
> >>>
> >>> s/where the key resides in/where the key resides/
> >>
> >> Thanks for the correction. Update it in new patch.
> >>
> >>>
> >>>> +
> >>>> +\item The \field{activate} filed in \field{payload} implies this is a
> >>>
> >>> s/filed/field/
> >>
> >> Thanks for the correction. Update it in new patch.
> >>
> >>>
> >>>> +  encryption request.
> >>>
> >>> Does "encryption" really mean just encryption or does it mean
> >>> encryption for writes and decryption for reads?
> >>
> >> Actually encryption request here means both encryption for writes and
> >> decryption for reads. Need I modify it as the following?
> > 
> > If writing "encryption/decryption" is too tedious, maybe use the feature
> > name ("inline encryption"). That way it's clear we're talking about the
> > feature and not specifically about an encryption operation (vs a
> > decryption operation).
> 
> ACK
> 
> > 
> >>
> >>   \item The \field{activate} field in \field{payload} implies this is a
> >>   encryption write request or decryption read request.
> >>
> >>>
> >>>> +
> >>>> +\item The \field{data_unit_num} filed in \field{payload} indicates the
> >>>
> >>> s/filed/field/
> >>
> >> Thanks for the correction. Update it in new patch.
> >>
> >>>
> >>>> +  starting block of the request.
> >>>> +\end{itemize}
> >>>> +
> >>>>  VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
> >>>>  read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
> >>>>  requests write the contents of \field{data} to the block device (in multiples
> >>>> @@ -912,6 +979,8 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
> >>>>  successfully, failed, or were processed by the device at all if the request
> >>>>  failed with VIRTIO_BLK_S_IOERR.
> >>>>  
> >>>> +A driver MUST set \field{activate} to 0 for a non VIRTIO_BLK_F_ICE request.
> >>>
> >>> Please explicitly list request types where the payload field is present
> >>> and where activate is optional.
> >>
> >> How about adding the following supplement?
> >>
> >>   \begin{itemize}
> >>   \item only when the block request contains crypto context and the request type
> > 
> > I'm not sure what "when the block request contains crypto context"
> > means. Is that the same as "when VIRTIO_BLK_F_ICE has been negotiated"?
> 
> No, crypto context means bio_crypt_ctx in BIO struct.
>   struct bio {
>   ...
>   #ifdef CONFIG_BLK_INLINE_ENCRYPTION
> 	  struct bio_crypt_ctx	*bi_crypt_context;
>   #endif
>   ...
>   }
> 
> When VIRTIO_BLK_F_ICE has been negotiated, virtio block backend receives crypto
> payload from virtio block frontend, and the crypto payload, together with I/O
> transaction, is sent to block layer of the host finally. The crypto payload is
> used to construct the bio_crypt_ctx filed of BIO.

Is that equivalent to struct virtio_blk_crypto_payload in this patch? If
yes, then I suggest only talking about the payload or slots - concepts
that are part of the virtio-blk inline crypto interface - instead of
Linux's bio_crypt_ctx.

If that's not possible, then the crypto context needs to be defined in
the spec so that readers know what it means.

> 
> > 
> >>       is one of VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT and VIRTIO_BLK_T_FLUSH,
> >>       \field{activate} MUST be set to 1.
> >>
> >>   \item \field{activate} should be set to 0 for all the other cases.
> >>   \end{itemize}
> >>
> >>>
> >>>> +
> >>>>  The following requirements only apply if the VIRTIO_BLK_F_ZONED feature is
> >>>>  negotiated.
> >>>>  
> >>>> -- 
> >>>> 2.34.1
> >>>>
> >>>>
> >>
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v1] virtio-blk: Add inline encryption support
  2026-02-03 14:43           ` Stefan Hajnoczi
@ 2026-02-04 13:57             ` Linlin Zhang
  2026-02-04 17:27               ` Stefan Hajnoczi
  0 siblings, 1 reply; 13+ messages in thread
From: Linlin Zhang @ 2026-02-04 13:57 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: virtio-dev, quic_dshaikhu



On 2/3/2026 10:43 PM, Stefan Hajnoczi wrote:
> On Tue, Feb 03, 2026 at 06:06:33PM +0800, Linlin Zhang wrote:
>>
>>
>> On 2/2/2026 11:56 PM, Stefan Hajnoczi wrote:
>>> On Fri, Jan 30, 2026 at 06:23:55PM +0800, Linlin Zhang wrote:
>>>> Thank you for the review. I’ve added some clarifications and potential updates.
>>>> Could you please take another look before I send a new patch?
>>>>
>>>> On 1/28/2026 5:09 AM, Stefan Hajnoczi wrote:
>>>>> On Tue, Jan 27, 2026 at 10:20:32PM +0800, Linlin Zhang wrote:
>>>>>> From: linlzhan <quic_linlzhan@quicinc.com>
>>>>>>
>>>>>> Inline encryption on virtio block can only be supported when
>>>>>> the new feature bit VIRTIO_BLK_F_ICE is negotiated.
>>>>>>
>>>>>> Extend struct virtio_blk_config and struct virtio_blk_req,
>>>>>> so that crypto capabilities can be got in the frontend and
>>>>>> encryption metadata can be sent to the backend, together with
>>>>>> each I/O transaction.
>>>>>
>>>>> This looks like a Self-Encrypting Drives feature along the lines of TCG
>>>>> Opal:
>>>>> https://en.wikipedia.org/wiki/Opal_Storage_Specification
>>>>>
>>>>> Would it make sense to implement TCG Opal instead of defining a new
>>>>> interface? That would make this more familiar to users and simplify
>>>>> integration into existing tools like sedutil and cryptsetup (e.g. by
>>>>> supporting the <linux/sed-opal.h> ioctl interface).
>>>>
>>>> This patch is for the FBE (File Based Encryption) support on UFS/EMMC
>>>> storage with ICE (Inline Crypto Engine) enabled. TCG Opal is only applicable
>>>> to SED (self-encrypting drives), not applicable to ICE (Inline Crypto Engine).
>>>>
>>>> In Automotive or Embedded scenario, UFS/EMMC generally is used. The disk
>>>> encryption on them is supported by the ICE pipeline of SOC, rather SSD
>>>> controller, so we couldn't use TCG Opal here.
>>>
>>> Okay. Is there a specification that this interface needs to comply with?
>>>
>>> If not, you can include a link to the Linux inline encryption
>>> documentation in the commit description:
>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/block/inline-encryption.rst
>>>
>>> Having a reference will will help the discussion. That way we can be
>>> confident the VIRTIO spec changes will be widely useful beyond a single
>>> use case and easy to implement in drivers because they follow an
>>> existing interface.
>>
>> ACK
>>
>>>
>>>>
>>>>>
>>>>>> Fixes: https://github.com/oasis-tcs/virtio-spec/issues/238
>>>>>>
>>>>>> Change-Id: Ic23b2137e5d9a599d826e06c279f1b614d79abdf
>>>>>> Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
>>>>>> ---
>>>>>>  device-types/blk/description.tex | 69 ++++++++++++++++++++++++++++++++
>>>>>>  1 file changed, 69 insertions(+)
>>>>>>
>>>>>> diff --git a/device-types/blk/description.tex b/device-types/blk/description.tex
>>>>>> index 2712ada..23d8dc0 100644
>>>>>> --- a/device-types/blk/description.tex
>>>>>> +++ b/device-types/blk/description.tex
>>>>>> @@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
>>>>>>  	(ZNS). For brevity, these standard documents are referred as "ZBD standards"
>>>>>>  	from this point on in the text.
>>>>>>  
>>>>>> +\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported. When this
>>>>>> +     is negotiated, the device exposes crypto characteristics in configuration
>>>>>> +     space and the driver SHALL provide an extended request header containing a
>>>>>
>>>>> SHALL, MUST, MAY, etc are only used in the normative sections of the
>>>>> spec.
>>>>>
>>>>> Why "SHALL"? Does this mean the device must be prepared to receive
>>>>> requests without the payload field when VIRTIO_BLK_F_ICE is negotiated?
>>>>> How should the device behave in that case: fail the request or perform
>>>>> I/O without crypto?
>>>>
>>>> This section - 5.2.3 Feature bits - is a normative section.
>>>
>>> \section{Block Device}\label{sec:Device Types / Block Device}
>>> ...
>>> \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
>>>
>>> No, this is a non-normative section. The normative sections are the
>>> "Device Requirements" (\devicenormative) and "Driver Requirements"
>>> (\drivernormative) sections.
>>
>> OK, as this is a non-normative section, can I use lowercase 'shall', 'must'.etc here?
> 
> I think that is discouraged to prevent confusion. It can be phrased in a
> descriptive way instead:
> 
>   and the driver provides an extended request header containing a ...
> 
>>
>>>
>>>>
>>>> What's expected for VIRTIO_BLK_F_ICE feature bit is that configuration space
>>>> must be prepared with the exposed crypto characteristics and the virtio block
>>>> frontend must sent a virtblk request with encryption metadata packed into
>>>> when VIRTIO_BLK_F_ICE is negotiated and hardware crypto is supported.
>>>>
>>>> By replacing 'SHALL' with 'MUST' here, Is the following rewording fine?
>>>>
>>>>   Inline Crypto Extensions are supported. When this is negotiated, the device MUST
>>>>   expose crypto characteristics in configuration space and the driver MUST provide
>>>>   an extended request header containing a crypto payload for block I/O if the
>>>>   hardware supports inline crypto. If this feature bit is negotiated, but hardware
>>>>   inline crypto doesn't support, the device SHOULD perform I/O without crypto.
>>>>
>>>> I'll add hw_enabled (type: u8) to virtio_blk_crypto_characteristics to indicate
>>>> whether the host supports hardware inline encryption.
>>>
>>> I still have a question about this: why would a device advertise
>>> VIRTIO_BLK_F_ICE but report hw_enabled = 0? I'm not sure how this is
>>> functionally different from a device that does not report
>>> VIRTIO_BLK_F_ICE. It seems simpler for devices to only advertise
>>> VIRTIO_BLK_F_ICE when they support inline encryption.
>>
>> ACK.
>> Previously I assume VIRTIO_BLK_F_ICE is negotiated even ICE (Inline Crypto Engine)
>> isn't enabled. Seems it isn't needed. a device should only advertise
>> VIRTIO_BLK_F_ICE when ICE is enabled. Correct the statement as the following.
>>
>>   Inline Crypto Extensions are supported. Only when this feature b is negotiated, the device need
>>   expose crypto characteristics in configuration space and the driver need provide
>>   an extended request header containing a crypto payload for block I/O. 
> 
> Good.
> 
>>
>>>
>>>>>
>>>>>> +     crypto payload for block I/O.
>>>>>> +
>>>>>>  \end{description}
>>>>>>  
>>>>>>  \subsubsection{Legacy Interface: Feature bits}\label{sec:Device Types / Block Device / Feature bits / Legacy Interface: Feature bits}
>>>>>> @@ -128,6 +133,11 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
>>>>>>                  u8 model;
>>>>>>                  u8 unused2[3];
>>>>>>          } zoned;
>>>>>> +        struct virtio_blk_crypto_characteristics {
>>>>>> +                __virtio16 slot_info;
>>>>>> +                __virtio16 reserved;
>>>>>> +                __virtio32 capability;
>>>>>> +        } crypto;
>>>>>>  };
>>>>>>  \end{lstlisting}
>>>>>>  
>>>>>> @@ -215,6 +225,25 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
>>>>>>  terminated by the device with a "zone resources exceeded" error as defined for
>>>>>>  specific commands later.
>>>>>>  
>>>>>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then in
>>>>>> +\field{virtio_blk_crypto_characteristics},
>>>>>> +\begin{itemize}
>>>>>> +\item \field{slot_info} value packs two 8-bits values:
>>>>>> +    \begin{itemize}
>>>>>> +        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number of supported
>>>>>> +            crypto key slots.
>>>>>> +        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied to slot numbering.
>>>>>> +    \end{itemize}
>>>>>> +\item \field{capability} value packs four 8-bits values:
>>>>>> +    \begin{itemize}
>>>>>> +        \item Bits~\[31:24]: crypto algorithm id.
>>>>>> +        \item Bits~\[23:16]: mask of data unit size.
>>>>>> +        \item Bits~\[15:8]: crypto key size.
>>>>>> +        \item Bits~\[7:0]: unused.
>>>>>> +    \end{itemize}
>>>>>
>>>>> Why are these fields packed? Configuration Space can have u8 fields.
>>>>
>>>> Given that &sect. 4.2.2.2 saying "For the device-specific configuration space,
>>>> the driver MUST use 8 bit wide accesses for 8 bit wide fields, 16 bit wide
>>>> and aligned accesses for 16 bit wide fields and 32 bit wide and aligned
>>>> accesses for 32 and 64 bit wide fields.",  these fields are packed for a
>>>> efficient read from the configuration space.
>>>
>>> I see. I suggest mentioning this explicitly: "value packs two 8-bits
>>> values to reduce the number of Configuration Space reads".
>>
>> ACK
>>
>>>
>>>>>
>>>>> These fields are not sufficiently documented. Where are the crypto
>>>>> algorithm ids listed, etc?
>>>>
>>>> Can I reword it as the following?
>>>
>>> Yes, looks good in general. I have some comments below.
>>>
>>>>
>>>>   \item Bits~\[31:24]: crypto algorithm identifiers.
>>>>   The device SHALL support reporting and negotiating cryptographic
>>>>   algorithms using the following algorithm identifiers:
>>>>   \begin{lstlisting}
>>>>       CRYPTO_ALG_AES_XTS              = 0x0
>>>>       CRYPTO_ALG_BITLOCKER_AES_CBC    = 0x1
>>>>       CRYPTO_ALG_AES_ECB              = 0x2
>>>>       CRYPTO_ALG_ESSIV_AES_CBC        = 0x3
>>>>   \end{lstlisting}
>>>>   These identifiers abstract the underlying hardware crypto implementation
>>>>   and MUST NOT assume any operating‑system‑specific data structures or
>>>>   constants.
>>>
>>> (The MUST NOT part needs to be in a \devicenormative or \drivernormative
>>> sections, but I think "MUST NOT" can be replaced with "does not" here
>>> because it actually describes the design of the interface rather than
>>> imposing requirements on device implementors.)
>>
>> ACK
>>
>>>
>>>>   \item Bits~\[23:16]: mask of data unit size. When bit j in this field
>>>>   (j=0......7)is set, a data unit size of 512*2^j bytes is slected.
>>>
>>> s/)is set/) is set/
>>> s/slected/selected/
>>
>> ACK
>>
>>>
>>> How is the data unit size used? Does it affect the allowed request sizes
>>> of the device?
>>>
>>> For example, if the mask is 0x2, so that mean request sizes must be
>>> multiples of 1 KiB?
>>
>> The data unit size is only used in the control flow of programing a key into
>> ICE slot. It hasn't impact on the virtblk request size.
>> For instance, if the mask is 0x2, so that mean the encryption granularity is
>> (2^1 * 512 = ) 1024 bytes. I.e. ICE hardware increase DUN (Date Unit Number)
>> per 1024 bytes to do encryption/decryption.
> 
> Okay.
> 
>>
>>>
>>> By the way, I'm not sure whether "j=0......7" mean that a mask value of
>>> 0x2 has j=1 or j=6? Usually bits are numbered right-to-left from least
>>> significant bit to most significant bit.
>>
>> A mask value of 0x2 has j=1. It comply with right-to-left number sequence.
> 
> Okay. It might be clearer to write "j=7......0" so the right-to-left
> numbering is shown.

Okay

> 
>>
>>>
>>>>   \item Bits~\[15:8]: crypto key size identifiers.
>>>>   \begin{lstlisting}
>>>>       CRYPTO_KEY_SIZE_INVALID     = 0x0
>>>>       CRYPTO_KEY_SIZE_128_BITS    = 0x1
>>>>       CRYPTO_KEY_SIZE_192_BITS    = 0x2
>>>>       CRYPTO_KEY_SIZE_256_BITS    = 0x3
>>>>       CRYPTO_KEY_SIZE_512_BITS    = 0x4
>>>>   \end{lstlisting}
>>>>
>>>>>
>>>>> How can a device support multiple algorithms? I think Configuration
>>>>> Space may not be flexible enough for this. You could introduce a
>>>>> GET_CRYPTO_INFO request type that allows the driver to fetch arrays of
>>>>> crypto algorithm characteristics.
>>>>
>>>> Virtio block driver need register crypto capability for request_queue of
>>>> virtio block device. That means virtio block frontend need get crypto
>>>> capability before virtio block device is ready. But the request can only
>>>> be sent after the virtio block device is ready. Thus I think it's impossible
>>>> to get such capabilities from the backend via a new request type, event
>>>> though the hardware in the host may support a few algorithms (the actual
>>>> number of algorithms will change depending on the vendor manufacturer.).
>>>> Thus I assume the host only configure and expose one hardware crypto
>>>> capability to the virtual machine and virtio block frontend gets is
>>>> through configuration space.
>>>
>>> The zoned storage feature also needs to use the virtqueues during driver
>>> initialization in order to report zones. Here is the Linux virtio_blk.c
>>> driver code:
>>>
>>> static int virtblk_probe(struct virtio_device *vdev)
>>> {
>>> ...
>>>     virtio_device_ready(vdev);
>>>
>>>     /*
>>>      * All steps that follow use the VQs therefore they need to be
>>>      * placed after the virtio_device_ready() call above.
>>>      */
>>>     if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
>>>         (lim.features & BLK_FEAT_ZONED)) {
>>>             err = blk_revalidate_disk_zones(vblk->disk);
>>>             if (err)
>>>                     goto out_cleanup_disk;
>>>     }
>>>
>>>     err = device_add_disk(&vdev->dev, vblk->disk, virtblk_attr_groups);
>>>
>>> Is it possible to call blk_crypto_register() between
>>> virtio_device_read() and device_add_disk()?
>>
>> Thanks! Referring to zoned storage feature, if we use the virtqueues to
>> get crypto capabilities, we need extend in_hdr in struct virtblk_req to
>> add new fields for crypto capability. Like the following field
>> crypto_append. Is it fine? 
>> we can not use a fixed-size array for crypto capabilities. Because the
>> number of the capabilities differs for different OEMs and storage devices.
>>
>>   struct virtblk_req {
>>       /* Out header */
>>       struct virtio_blk_outhdr out_hdr;
>>   
>>       /* In header */
>>       union {
>>           u8 status;
>>   
>>           /*
>>           * The zone append command has an extended in header.
>>           * The status field in zone_append_in_hdr must always
>>           * be the last byte.
>>           */
>>           struct {
>>               __virtio64 sector;
>>               u8 status;
>>           } zone_append;
>>
>>           struct {
>>               u8 num;
>>               __virtio32 *capabilities;
>>           } crypto_append;
> 
> This is not necessary. Take a look at virtblk_get_id(). It maps the
> id_str buffer so the device can DMA the disk's serial number. The serial
> number field is treated as a data read buffer, not as an in_hdr field.
> 
> Here is how it could work:
> 
>   struct virtio_blk_outhdr {
>       .type = VIRTIO_BLK_T_GET_CRYPTO_PROFILES,
>       .ioprio = 0,
>       .sector = 0
>   };
> 
>   struct virtio_blk_crypto_profile profiles[MAX_PROFILES];
> 
>   u8 status;
> 
> The device fills in profiles[], sets the used buffer element's len field
> to the number of bytes filled in, and sets the status field to
> VIRTIO_BLK_S_OK.
> 
> If profiles[] is too short, it sets status to BLK_S_IO_ERR. The driver
> is expected to increase the size (e.g. double the buffer) and try again.
> Alternatively there could be a num_crypto_profiles field in
> Configuration Space.
> 
> (Many variations are possible. For example, virtio_blk_outhdr's sector
> field could be an offset into the list of profiles, allowing the driver
> to page through profiles without allocating a buffer large enough to
> hold all profiles at a time. But that's probably unnecessary, so I would
> keep it simple.)

Thanks for the clarification! I'll update it in the next patch.

> 
>>       } in_hdr;
>>   
>>       size_t in_hdr_len;
>>   
>>       struct sg_table sg_table;
>>       struct scatterlist sg[];
>>   };
>>
>>>
>>>>
>>>>>
>>>>>> +\end{itemize}
>>>>>> +
>>>>>> +
>>>>>>  \subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Block Device / Device configuration layout / Legacy Interface: Device configuration layout}
>>>>>>  When using the legacy interface, transitional devices and drivers
>>>>>>  MUST format the fields in struct virtio_blk_config
>>>>>> @@ -278,6 +307,10 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>>>>>>      \field{zoned} can be read by the driver to determine the zone
>>>>>>      characteristics of the device. All \field{zoned} fields are read-only.
>>>>>>  
>>>>>> +\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
>>>>>> +    \field{crypto} can be read by the driver to determine the inline crypto
>>>>>> +    characteristics of the device. All \field{crypto} fields are read-only.
>>>>>> +
>>>>>>  \end{enumerate}
>>>>>>  
>>>>>>  \drivernormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
>>>>>> @@ -317,6 +350,9 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>>>>>>      driver SHOULD ignore all other fields in \field{zoned}.
>>>>>>  \end{itemize}
>>>>>>  
>>>>>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver must validate
>>>>>> +    the max_slots in \field{slot_info} before the slot usage.
>>>>>> +
>>>>>>  \devicenormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
>>>>>>  
>>>>>>  Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it
>>>>>> @@ -402,6 +438,16 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
>>>>>>  \item the device MUST initialize padding bytes \field{unused2} to 0.
>>>>>>  \end{itemize}
>>>>>>  
>>>>>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in \field{cryto}
>>>>>
>>>>> s/cryto/crypto/
>>>>
>>>> Thanks for the correction. Update it in new patch.
>>>>
>>>>>
>>>>>> +struct in the configuration space MUST be set by the device.
>>>>>> +\begin{itemize}
>>>>>> +\item the \field{slot_info} field of \field{crypto} MUST be set by the device to a
>>>>>> +    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
>>>>>> +
>>>>>> +\item the \field{capability} field of \field{crypto} MUST be set by the device
>>>>>> +    to a crypto capability read from the storage register.
>>>>>> +\end{itemize}
>>>>>> +
>>>>>>  \subsubsection{Legacy Interface: Device Initialization}\label{sec:Device Types / Block Device / Device Initialization / Legacy Interface: Device Initialization}
>>>>>>  
>>>>>>  Because legacy devices do not have FEATURES_OK, transitional devices
>>>>>> @@ -436,6 +482,13 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>>>>>>          le32 type;
>>>>>>          le32 reserved;
>>>>>>          le64 sector;
>>>>>> +        struct virtio_blk_crypto_payload {
>>>>>> +            u8 slot;
>>>>>> +            u8 activate;
>>>>>> +            le16 reserved1;
>>>>>> +            le32 reserved2;
>>>>>> +            le64 data_unit_num;
>>>>>> +        } payload;
>>>>>>          u8 data[];
>>>>>>          u8 status;
>>>>>>  };
>>>>>> @@ -463,6 +516,20 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>>>>>>  the read or write is to occur. This field is unused and set to 0 for
>>>>>>  commands other than read, write and some zone operations.
>>>>>>  
>>>>>> +The \field{payload} consists of the encryption information for current
>>>>>> +request. It need to be set by the driver only when the feature VIRTIO_BLK_F_ICE
>>>>>> +is negotiated.
>>>>>
>>>>> "set" is ambiguous: does it meaning filling in the fields or does it
>>>>> mean the fields are only present when VIRTIO_BLK_F_ICE is negotiated
>>>>> (this distinction is important if other features add more fields after
>>>>> payload in the future).
>>>>>
>>>>> The sentence could be reworded:
>>>>>
>>>>>   It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
>>>>>   \field{type} is VIRTIO_BLK_T_IN or VIRTIO_BLK_T_OUT.
>>>>>
>>>>> (I'm not sure whether DISCARD, WRITE_ZEROES, or SECURE_ERASE also need
>>>>> the payload field. It seems like GET_ID and GET_LIFETIME do not need the
>>>>> payload field.)
>>>>
>>>> Accept and update it as the following.
>>>>
>>>>   It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
>>>>   +\field{type} is VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT or VIRTIO_BLK_T_FLUSH.
>>>
>>> Thanks.
>>>
>>>>
>>>>>
>>>>>> +\begin{itemize}
>>>>>> +\item The \field{slot} filed in \field{payload} indicates the ICE
>>>>>
>>>>> s/filed/field/
>>>>
>>>> Thanks for the correction. Update it in new patch.
>>>>
>>>>>
>>>>>> +  (Inline Crypto Encryption) slot index where the key resides in.
>>>>>
>>>>> s/where the key resides in/where the key resides/
>>>>
>>>> Thanks for the correction. Update it in new patch.
>>>>
>>>>>
>>>>>> +
>>>>>> +\item The \field{activate} filed in \field{payload} implies this is a
>>>>>
>>>>> s/filed/field/
>>>>
>>>> Thanks for the correction. Update it in new patch.
>>>>
>>>>>
>>>>>> +  encryption request.
>>>>>
>>>>> Does "encryption" really mean just encryption or does it mean
>>>>> encryption for writes and decryption for reads?
>>>>
>>>> Actually encryption request here means both encryption for writes and
>>>> decryption for reads. Need I modify it as the following?
>>>
>>> If writing "encryption/decryption" is too tedious, maybe use the feature
>>> name ("inline encryption"). That way it's clear we're talking about the
>>> feature and not specifically about an encryption operation (vs a
>>> decryption operation).
>>
>> ACK
>>
>>>
>>>>
>>>>   \item The \field{activate} field in \field{payload} implies this is a
>>>>   encryption write request or decryption read request.
>>>>
>>>>>
>>>>>> +
>>>>>> +\item The \field{data_unit_num} filed in \field{payload} indicates the
>>>>>
>>>>> s/filed/field/
>>>>
>>>> Thanks for the correction. Update it in new patch.
>>>>
>>>>>
>>>>>> +  starting block of the request.
>>>>>> +\end{itemize}
>>>>>> +
>>>>>>  VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
>>>>>>  read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
>>>>>>  requests write the contents of \field{data} to the block device (in multiples
>>>>>> @@ -912,6 +979,8 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
>>>>>>  successfully, failed, or were processed by the device at all if the request
>>>>>>  failed with VIRTIO_BLK_S_IOERR.
>>>>>>  
>>>>>> +A driver MUST set \field{activate} to 0 for a non VIRTIO_BLK_F_ICE request.
>>>>>
>>>>> Please explicitly list request types where the payload field is present
>>>>> and where activate is optional.
>>>>
>>>> How about adding the following supplement?
>>>>
>>>>   \begin{itemize}
>>>>   \item only when the block request contains crypto context and the request type
>>>
>>> I'm not sure what "when the block request contains crypto context"
>>> means. Is that the same as "when VIRTIO_BLK_F_ICE has been negotiated"?
>>
>> No, crypto context means bio_crypt_ctx in BIO struct.
>>   struct bio {
>>   ...
>>   #ifdef CONFIG_BLK_INLINE_ENCRYPTION
>> 	  struct bio_crypt_ctx	*bi_crypt_context;
>>   #endif
>>   ...
>>   }
>>
>> When VIRTIO_BLK_F_ICE has been negotiated, virtio block backend receives crypto
>> payload from virtio block frontend, and the crypto payload, together with I/O
>> transaction, is sent to block layer of the host finally. The crypto payload is
>> used to construct the bio_crypt_ctx filed of BIO.
> 
> Is that equivalent to struct virtio_blk_crypto_payload in this patch? If
> yes, then I suggest only talking about the payload or slots - concepts
> that are part of the virtio-blk inline crypto interface - instead of
> Linux's bio_crypt_ctx.
> 
> If that's not possible, then the crypto context needs to be defined in
> the spec so that readers know what it means.

Crypto context - bio_crypt_ctx structure - is different with virtio_blk_crypto_payload.
bio_crypt_ctx is the struct bound to BIO and request structs in Linux to imply this is
a inline encryption bio/request. While virtio_blk_crypto_payload is a new struct in this
patch, it is used to issue the inline encryption metadata (slot, activate, DUN) to the
virtio backend, so that the backend virtio device can use such inline encryption metadata
to initialized the crypto info of Storage protocol. For instance, the CCI in DW0 of UTP
Transfer Request Descriptor.

Change it to the following.
  \begin{itemize}
  \item only when the block request contains a valid bio_crypt_ctx and the request type
  is one of VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT and VIRTIO_BLK_T_FLUSH,\field{activate} MUST
  be set to 1. bio_crypt_ctx is defined in linux/blk-crypto.h.
    \begin{lstlisting}
    struct bio_crypt_ctx {
        const struct blk_crypto_key     *bc_key;
        u64                             bc_dun[BLK_CRYPTO_DUN_ARRAY_SIZE];
    };
    \end{lstlisting}

> 
>>
>>>
>>>>       is one of VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT and VIRTIO_BLK_T_FLUSH,
>>>>       \field{activate} MUST be set to 1.
>>>>
>>>>   \item \field{activate} should be set to 0 for all the other cases.
>>>>   \end{itemize}
>>>>
>>>>>
>>>>>> +
>>>>>>  The following requirements only apply if the VIRTIO_BLK_F_ZONED feature is
>>>>>>  negotiated.
>>>>>>  
>>>>>> -- 
>>>>>> 2.34.1
>>>>>>
>>>>>>
>>>>
>>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v1] virtio-blk: Add inline encryption support
  2026-02-04 13:57             ` Linlin Zhang
@ 2026-02-04 17:27               ` Stefan Hajnoczi
  2026-02-06 17:12                 ` [PATCH v2] " Linlin Zhang
  0 siblings, 1 reply; 13+ messages in thread
From: Stefan Hajnoczi @ 2026-02-04 17:27 UTC (permalink / raw)
  To: Linlin Zhang; +Cc: virtio-dev, quic_dshaikhu

[-- Attachment #1: Type: text/plain, Size: 4016 bytes --]

On Wed, Feb 04, 2026 at 09:57:11PM +0800, Linlin Zhang wrote:
> On 2/3/2026 10:43 PM, Stefan Hajnoczi wrote:
> > On Tue, Feb 03, 2026 at 06:06:33PM +0800, Linlin Zhang wrote:
> >> On 2/2/2026 11:56 PM, Stefan Hajnoczi wrote:
> >>> On Fri, Jan 30, 2026 at 06:23:55PM +0800, Linlin Zhang wrote:
> >>>> On 1/28/2026 5:09 AM, Stefan Hajnoczi wrote:
> >>>>> On Tue, Jan 27, 2026 at 10:20:32PM +0800, Linlin Zhang wrote:
> >>>>>> +  starting block of the request.
> >>>>>> +\end{itemize}
> >>>>>> +
> >>>>>>  VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
> >>>>>>  read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
> >>>>>>  requests write the contents of \field{data} to the block device (in multiples
> >>>>>> @@ -912,6 +979,8 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
> >>>>>>  successfully, failed, or were processed by the device at all if the request
> >>>>>>  failed with VIRTIO_BLK_S_IOERR.
> >>>>>>  
> >>>>>> +A driver MUST set \field{activate} to 0 for a non VIRTIO_BLK_F_ICE request.
> >>>>>
> >>>>> Please explicitly list request types where the payload field is present
> >>>>> and where activate is optional.
> >>>>
> >>>> How about adding the following supplement?
> >>>>
> >>>>   \begin{itemize}
> >>>>   \item only when the block request contains crypto context and the request type
> >>>
> >>> I'm not sure what "when the block request contains crypto context"
> >>> means. Is that the same as "when VIRTIO_BLK_F_ICE has been negotiated"?
> >>
> >> No, crypto context means bio_crypt_ctx in BIO struct.
> >>   struct bio {
> >>   ...
> >>   #ifdef CONFIG_BLK_INLINE_ENCRYPTION
> >> 	  struct bio_crypt_ctx	*bi_crypt_context;
> >>   #endif
> >>   ...
> >>   }
> >>
> >> When VIRTIO_BLK_F_ICE has been negotiated, virtio block backend receives crypto
> >> payload from virtio block frontend, and the crypto payload, together with I/O
> >> transaction, is sent to block layer of the host finally. The crypto payload is
> >> used to construct the bio_crypt_ctx filed of BIO.
> > 
> > Is that equivalent to struct virtio_blk_crypto_payload in this patch? If
> > yes, then I suggest only talking about the payload or slots - concepts
> > that are part of the virtio-blk inline crypto interface - instead of
> > Linux's bio_crypt_ctx.
> > 
> > If that's not possible, then the crypto context needs to be defined in
> > the spec so that readers know what it means.
> 
> Crypto context - bio_crypt_ctx structure - is different with virtio_blk_crypto_payload.
> bio_crypt_ctx is the struct bound to BIO and request structs in Linux to imply this is
> a inline encryption bio/request. While virtio_blk_crypto_payload is a new struct in this
> patch, it is used to issue the inline encryption metadata (slot, activate, DUN) to the
> virtio backend, so that the backend virtio device can use such inline encryption metadata
> to initialized the crypto info of Storage protocol. For instance, the CCI in DW0 of UTP
> Transfer Request Descriptor.
> 
> Change it to the following.
>   \begin{itemize}
>   \item only when the block request contains a valid bio_crypt_ctx and the request type
>   is one of VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT and VIRTIO_BLK_T_FLUSH,\field{activate} MUST
>   be set to 1. bio_crypt_ctx is defined in linux/blk-crypto.h.
>     \begin{lstlisting}
>     struct bio_crypt_ctx {
>         const struct blk_crypto_key     *bc_key;
>         u64                             bc_dun[BLK_CRYPTO_DUN_ARRAY_SIZE];
>     };
>     \end{lstlisting}

bio_crypt_ctx is Linux-specific. Can you phrase this in a way that does
not rely on Linux block layer concepts?

For example:

  The \field{activate} field is set to 1 on VIRTIO_BLK_T_IN,
  VIRTIO_BLK_T_OUT, and VIRTIO_BLK_T_FLUSH requests that require inline
  encryption. For other request types or when inline encryption is not
  required, it is set to 0.

Thanks,
Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v2] virtio-blk: Add inline encryption support
  2026-02-04 17:27               ` Stefan Hajnoczi
@ 2026-02-06 17:12                 ` Linlin Zhang
  2026-02-19 14:35                   ` Sebastian Mauritsson
  0 siblings, 1 reply; 13+ messages in thread
From: Linlin Zhang @ 2026-02-06 17:12 UTC (permalink / raw)
  To: virtio-dev, stefanha; +Cc: quic_dshaikhu

From: linlzhan <quic_linlzhan@quicinc.com>

Inline encryption on virtio block can only be supported when
the new feature bit VIRTIO_BLK_F_ICE is negotiated.

Extend struct virtio_blk_config and struct virtio_blk_req,
so that crypto capabilities can be got in the frontend and
encryption metadata can be sent to the backend, together with
each I/O transaction.

About the inline encryption on UFS or eMMC storage, please
refer to the Linux inline encryption documentation:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/block/inline-encryption.rst

Fixes: https://github.com/oasis-tcs/virtio-spec/issues/238
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
Signed-off-by: Linlin Zhang <linlin.zhang@oss.qualcomm.com>
---

changes from v2:
 - Add inline encryption link in commit message for a better
   backgrond descryption
 - Add sufficient descryption for the fields of crypto
   capability
 - Delete crypto capability in configuration layout, instead
   add a new request command to get it
 - Correct the terminology in non-normative and normative
   sections
 - Correct the mail for open source upstream
---

 device-types/blk/description.tex | 110 ++++++++++++++++++++++++++++++-
 1 file changed, 108 insertions(+), 2 deletions(-)

diff --git a/device-types/blk/description.tex b/device-types/blk/description.tex
index 2712ada..60f46af 100644
--- a/device-types/blk/description.tex
+++ b/device-types/blk/description.tex
@@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types / Block Device / Feature bits}
 	(ZNS). For brevity, these standard documents are referred as "ZBD standards"
 	from this point on in the text.
 
+\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported. Only when this
+     feature bit is negotiated, the device need expose crypto characteristics in
+     configuration space and the driver need provide an extended request header
+     containing a crypto payload for block I/O.
+
 \end{description}
 
 \subsubsection{Legacy Interface: Feature bits}\label{sec:Device Types / Block Device / Feature bits / Legacy Interface: Feature bits}
@@ -128,6 +133,10 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
                 u8 model;
                 u8 unused2[3];
         } zoned;
+        struct virtio_blk_crypto_characteristics {
+                __virtio16 slot_info;
+                __virtio16 reserved;
+        } crypto;
 };
 \end{lstlisting}
 
@@ -215,6 +224,18 @@ \subsection{Device configuration layout}\label{sec:Device Types / Block Device /
 terminated by the device with a "zone resources exceeded" error as defined for
 specific commands later.
 
+If the VIRTIO_BLK_F_ICE feature is negotiated, then in
+\field{virtio_blk_crypto_characteristics},
+\begin{itemize}
+\item \field{slot_info} value packs two 8-bits values to reduce the number of
+    Configuration Space reads.
+    \begin{itemize}
+        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number of supported
+            crypto key slots.
+        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied to slot numbering.
+    \end{itemize}
+\end{itemize}
+
 \subsubsection{Legacy Interface: Device configuration layout}\label{sec:Device Types / Block Device / Device configuration layout / Legacy Interface: Device configuration layout}
 When using the legacy interface, transitional devices and drivers
 MUST format the fields in struct virtio_blk_config
@@ -278,6 +299,10 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
     \field{zoned} can be read by the driver to determine the zone
     characteristics of the device. All \field{zoned} fields are read-only.
 
+\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
+    \field{crypto} can be read by the driver to determine the inline crypto
+    characteristics of the device. All \field{crypto} fields are read-only.
+
 \end{enumerate}
 
 \drivernormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
@@ -317,6 +342,9 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
     driver SHOULD ignore all other fields in \field{zoned}.
 \end{itemize}
 
+If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver MUST validate
+    the max_slots in \field{slot_info} before the slot usage.
+
 \devicenormative{\subsubsection}{Device Initialization}{Device Types / Block Device / Device Initialization}
 
 Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it
@@ -402,6 +430,13 @@ \subsection{Device Initialization}\label{sec:Device Types / Block Device / Devic
 \item the device MUST initialize padding bytes \field{unused2} to 0.
 \end{itemize}
 
+If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in \field{crypto}
+struct in the configuration space MUST be set by the device.
+\begin{itemize}
+\item the \field{slot_info} field of \field{crypto} MUST be set by the device to a
+    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
+\end{itemize}
+
 \subsubsection{Legacy Interface: Device Initialization}\label{sec:Device Types / Block Device / Device Initialization / Legacy Interface: Device Initialization}
 
 Because legacy devices do not have FEATURES_OK, transitional devices
@@ -436,6 +471,13 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
         le32 type;
         le32 reserved;
         le64 sector;
+        struct virtio_blk_crypto_payload {
+            u8 slot;
+            u8 activate;
+            le16 reserved1;
+            le32 reserved2;
+            le64 data_unit_num;
+        } payload;
         u8 data[];
         u8 status;
 };
@@ -445,8 +487,9 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
 (VIRTIO_BLK_T_OUT), a discard (VIRTIO_BLK_T_DISCARD), a write zeroes
 (VIRTIO_BLK_T_WRITE_ZEROES), a flush (VIRTIO_BLK_T_FLUSH), a get device ID
 string command (VIRTIO_BLK_T_GET_ID), a secure erase
-(VIRTIO_BLK_T_SECURE_ERASE), or a get device lifetime command
-(VIRTIO_BLK_T_GET_LIFETIME).
+(VIRTIO_BLK_T_SECURE_ERASE), a get device lifetime command
+(VIRTIO_BLK_T_GET_LIFETIME), or a get device crypto capabilities command
+(VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES).
 
 \begin{lstlisting}
 #define VIRTIO_BLK_T_IN           0
@@ -457,12 +500,27 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
 #define VIRTIO_BLK_T_DISCARD      11
 #define VIRTIO_BLK_T_WRITE_ZEROES 13
 #define VIRTIO_BLK_T_SECURE_ERASE   14
+#define VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES   27
 \end{lstlisting}
 
 The \field{sector} number indicates the offset (multiplied by 512) where
 the read or write is to occur. This field is unused and set to 0 for
 commands other than read, write and some zone operations.
 
+The \field{payload} consists of the encryption information for current
+request. It is only present when the VIRTIO_BLK_F_ICE feature is negotiated and
+\field{type} is VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT or VIRTIO_BLK_T_FLUSH.
+\begin{itemize}
+\item The \field{slot} field in \field{payload} indicates the ICE
+  (Inline Crypto Encryption) slot index where the key resides.
+
+\item The \field{activate} field in \field{payload} implies this is a
+  inline encryption request.
+
+\item The \field{data_unit_num} field in \field{payload} indicates the
+  starting block of the request.
+\end{itemize}
+
 VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
 read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
 requests write the contents of \field{data} to the block device (in multiples
@@ -530,6 +588,47 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
 The \field{device_lifetime_est_typ_b} refers to wear of MLC cells and is provided
 with the same semantics as \field{device_lifetime_est_typ_a}.
 
+VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES requests fetch the storage hardware crypto
+capabilities into \field{data}. And the \field{data} is of the form
+
+\begin{lstlisting}
+struct virtio_blk_crypto_caps {
+  u8 size;
+  le32 crypto_capabilities[];
+};
+\end{lstlisting}
+
+The \field{size} specifies the size of array \field{crypto_capabilities}.
+The \field{crypto_capabilities} indicates the crypto capabilities supported by the
+hardware storage for inline encryption.
+
+A crypto capability packs four 8-bits values:
+\begin{itemize}
+    \item Bits~\[31:24]: crypto algorithm identifiers.
+    The device supports reporting and negotiating cryptographic algorithms
+    using the following algorithm identifiers:
+    \begin{lstlisting}
+        CRYPTO_ALG_AES_XTS              = 0x0
+        CRYPTO_ALG_BITLOCKER_AES_CBC    = 0x1
+        CRYPTO_ALG_AES_ECB              = 0x2
+        CRYPTO_ALG_ESSIV_AES_CBC        = 0x3
+    \end{lstlisting}
+    These identifiers abstract the underlying hardware crypto implementation
+    and does not assume any operating‑system‑specific data structures or
+    constants.
+    \item Bits~\[23:16]: mask of data unit size. When bit j in this field
+    (j=7......0) is set, a data unit size of 512*2^j bytes is selected.
+    \item Bits~\[15:8]: crypto key size identifiers.
+    \begin{lstlisting}
+        CRYPTO_KEY_SIZE_INVALID     = 0x0
+        CRYPTO_KEY_SIZE_128_BITS    = 0x1
+        CRYPTO_KEY_SIZE_192_BITS    = 0x2
+        CRYPTO_KEY_SIZE_256_BITS    = 0x3
+        CRYPTO_KEY_SIZE_512_BITS    = 0x4
+    \end{lstlisting}
+    \item Bits~\[7:0]: unused.
+\end{itemize}
+
 The final \field{status} byte is written by the device: either
 VIRTIO_BLK_S_OK for success, VIRTIO_BLK_S_IOERR for device or driver
 error or VIRTIO_BLK_S_UNSUPP for a request unsupported by device:
@@ -912,6 +1011,13 @@ \subsection{Device Operation}\label{sec:Device Types / Block Device / Device Ope
 successfully, failed, or were processed by the device at all if the request
 failed with VIRTIO_BLK_S_IOERR.
 
+The length of \field{data} MUST be a multiple of 4 bytes plus 1 for
+VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES requests.
+
+A driver MUST set \field{activate} to 1 for VIRTIO_BLK_T_IN,VIRTIO_BLK_T_OUT,
+    and VIRTIO_BLK_T_FLUSH requests that require inline encryption. For other
+    request types or when inline encryption is not required, it is set to 0.
+
 The following requirements only apply if the VIRTIO_BLK_F_ZONED feature is
 negotiated.
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* RE: [PATCH v2] virtio-blk: Add inline encryption support
  2026-02-06 17:12                 ` [PATCH v2] " Linlin Zhang
@ 2026-02-19 14:35                   ` Sebastian Mauritsson
  2026-02-22  6:09                     ` Linlin Zhang
  0 siblings, 1 reply; 13+ messages in thread
From: Sebastian Mauritsson @ 2026-02-19 14:35 UTC (permalink / raw)
  To: Linlin Zhang, virtio-dev@lists.linux.dev, stefanha@redhat.com
  Cc: quic_dshaikhu@quicinc.com

I understand there might be compatibility considerations, but I'm wondering the exact reason for making CRYPTO_ALG_AES_ECB an option? This does not use an IV and is unsuitable for anything other than single-use & single-block encryption.

Best regards, Sebastian

> -----Original Message-----
> From: Linlin Zhang <quic_linlzhan@quicinc.com>
> Sent: Friday, February 6, 2026 6:12 PM
> To: virtio-dev@lists.linux.dev; stefanha@redhat.com
> Cc: quic_dshaikhu@quicinc.com
> Subject: [PATCH v2] virtio-blk: Add inline encryption support
>
> From: linlzhan <quic_linlzhan@quicinc.com>
>
> Inline encryption on virtio block can only be supported when the new feature
> bit VIRTIO_BLK_F_ICE is negotiated.
>
> Extend struct virtio_blk_config and struct virtio_blk_req, so that crypto
> capabilities can be got in the frontend and encryption metadata can be sent
> to the backend, together with each I/O transaction.
>
> About the inline encryption on UFS or eMMC storage, please refer to the
> Linux inline encryption documentation:
> https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fgit.kernel.org%2fpub
> %2fscm%2flinux%2fkernel%2fgit%2ftorvalds%2flinux.git%2ftree%2fDocumen
> tation%2fblock%2finline-encryption.rst&c=E,1,nhL3zMxYwxuFP4QQ8SLhLjz-
> MYwQ3RGD-PYXU71uhC-OBnxDeaefVyDYQH1A0KvX70THXfl-SWjj-
> JcDntGGie3bSTNAri0H4_0CtCqU3kyCWRoDg1_N&typo=1
>
> Fixes: https://github.com/oasis-tcs/virtio-spec/issues/238
> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
> Signed-off-by: Linlin Zhang <linlin.zhang@oss.qualcomm.com>
> ---
>
> changes from v2:
>  - Add inline encryption link in commit message for a better
>    backgrond descryption
>  - Add sufficient descryption for the fields of crypto
>    capability
>  - Delete crypto capability in configuration layout, instead
>    add a new request command to get it
>  - Correct the terminology in non-normative and normative
>    sections
>  - Correct the mail for open source upstream
> ---
>
>  device-types/blk/description.tex | 110 ++++++++++++++++++++++++++++++-
>  1 file changed, 108 insertions(+), 2 deletions(-)
>
> diff --git a/device-types/blk/description.tex b/device-
> types/blk/description.tex
> index 2712ada..60f46af 100644
> --- a/device-types/blk/description.tex
> +++ b/device-types/blk/description.tex
> @@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types /
> Block Device / Feature bits}
>       (ZNS). For brevity, these standard documents are referred as "ZBD
> standards"
>       from this point on in the text.
>
> +\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported. Only
> when this
> +     feature bit is negotiated, the device need expose crypto characteristics in
> +     configuration space and the driver need provide an extended request
> header
> +     containing a crypto payload for block I/O.
> +
>  \end{description}
>
>  \subsubsection{Legacy Interface: Feature bits}\label{sec:Device Types / Block
> Device / Feature bits / Legacy Interface: Feature bits} @@ -128,6 +133,10 @@
> \subsection{Device configuration layout}\label{sec:Device Types / Block
> Device /
>                  u8 model;
>                  u8 unused2[3];
>          } zoned;
> +        struct virtio_blk_crypto_characteristics {
> +                __virtio16 slot_info;
> +                __virtio16 reserved;
> +        } crypto;
>  };
>  \end{lstlisting}
>
> @@ -215,6 +224,18 @@ \subsection{Device configuration
> layout}\label{sec:Device Types / Block Device /  terminated by the device with
> a "zone resources exceeded" error as defined for  specific commands later.
>
> +If the VIRTIO_BLK_F_ICE feature is negotiated, then in
> +\field{virtio_blk_crypto_characteristics},
> +\begin{itemize}
> +\item \field{slot_info} value packs two 8-bits values to reduce the number of
> +    Configuration Space reads.
> +    \begin{itemize}
> +        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number of
> supported
> +            crypto key slots.
> +        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied to slot
> numbering.
> +    \end{itemize}
> +\end{itemize}
> +
>  \subsubsection{Legacy Interface: Device configuration
> layout}\label{sec:Device Types / Block Device / Device configuration layout /
> Legacy Interface: Device configuration layout}  When using the legacy
> interface, transitional devices and drivers  MUST format the fields in struct
> virtio_blk_config @@ -278,6 +299,10 @@ \subsection{Device
> Initialization}\label{sec:Device Types / Block Device / Devic
>      \field{zoned} can be read by the driver to determine the zone
>      characteristics of the device. All \field{zoned} fields are read-only.
>
> +\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
> +    \field{crypto} can be read by the driver to determine the inline crypto
> +    characteristics of the device. All \field{crypto} fields are read-only.
> +
>  \end{enumerate}
>
>  \drivernormative{\subsubsection}{Device Initialization}{Device Types / Block
> Device / Device Initialization} @@ -317,6 +342,9 @@ \subsection{Device
> Initialization}\label{sec:Device Types / Block Device / Devic
>      driver SHOULD ignore all other fields in \field{zoned}.
>  \end{itemize}
>
> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver MUST
> validate
> +    the max_slots in \field{slot_info} before the slot usage.
> +
>  \devicenormative{\subsubsection}{Device Initialization}{Device Types / Block
> Device / Device Initialization}
>
>  Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it @@ -
> 402,6 +430,13 @@ \subsection{Device Initialization}\label{sec:Device Types /
> Block Device / Devic  \item the device MUST initialize padding bytes
> \field{unused2} to 0.
>  \end{itemize}
>
> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in
> +\field{crypto} struct in the configuration space MUST be set by the device.
> +\begin{itemize}
> +\item the \field{slot_info} field of \field{crypto} MUST be set by the device to
> a
> +    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
> +\end{itemize}
> +
>  \subsubsection{Legacy Interface: Device Initialization}\label{sec:Device Types
> / Block Device / Device Initialization / Legacy Interface: Device Initialization}
>
>  Because legacy devices do not have FEATURES_OK, transitional devices @@ -
> 436,6 +471,13 @@ \subsection{Device Operation}\label{sec:Device Types /
> Block Device / Device Ope
>          le32 type;
>          le32 reserved;
>          le64 sector;
> +        struct virtio_blk_crypto_payload {
> +            u8 slot;
> +            u8 activate;
> +            le16 reserved1;
> +            le32 reserved2;
> +            le64 data_unit_num;
> +        } payload;
>          u8 data[];
>          u8 status;
>  };
> @@ -445,8 +487,9 @@ \subsection{Device Operation}\label{sec:Device
> Types / Block Device / Device Ope  (VIRTIO_BLK_T_OUT), a discard
> (VIRTIO_BLK_T_DISCARD), a write zeroes  (VIRTIO_BLK_T_WRITE_ZEROES), a
> flush (VIRTIO_BLK_T_FLUSH), a get device ID  string command
> (VIRTIO_BLK_T_GET_ID), a secure erase -(VIRTIO_BLK_T_SECURE_ERASE), or
> a get device lifetime command -(VIRTIO_BLK_T_GET_LIFETIME).
> +(VIRTIO_BLK_T_SECURE_ERASE), a get device lifetime command
> +(VIRTIO_BLK_T_GET_LIFETIME), or a get device crypto capabilities
> +command (VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES).
>
>  \begin{lstlisting}
>  #define VIRTIO_BLK_T_IN           0
> @@ -457,12 +500,27 @@ \subsection{Device Operation}\label{sec:Device
> Types / Block Device / Device Ope
>  #define VIRTIO_BLK_T_DISCARD      11
>  #define VIRTIO_BLK_T_WRITE_ZEROES 13
>  #define VIRTIO_BLK_T_SECURE_ERASE   14
> +#define VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES   27
>  \end{lstlisting}
>
>  The \field{sector} number indicates the offset (multiplied by 512) where  the
> read or write is to occur. This field is unused and set to 0 for  commands
> other than read, write and some zone operations.
>
> +The \field{payload} consists of the encryption information for current
> +request. It is only present when the VIRTIO_BLK_F_ICE feature is
> +negotiated and \field{type} is VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT or
> VIRTIO_BLK_T_FLUSH.
> +\begin{itemize}
> +\item The \field{slot} field in \field{payload} indicates the ICE
> +  (Inline Crypto Encryption) slot index where the key resides.
> +
> +\item The \field{activate} field in \field{payload} implies this is a
> +  inline encryption request.
> +
> +\item The \field{data_unit_num} field in \field{payload} indicates the
> +  starting block of the request.
> +\end{itemize}
> +
>  VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
> read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
> requests write the contents of \field{data} to the block device (in multiples
> @@ -530,6 +588,47 @@ \subsection{Device Operation}\label{sec:Device
> Types / Block Device / Device Ope  The \field{device_lifetime_est_typ_b}
> refers to wear of MLC cells and is provided  with the same semantics as
> \field{device_lifetime_est_typ_a}.
>
> +VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES requests fetch the storage
> +hardware crypto capabilities into \field{data}. And the \field{data} is
> +of the form
> +
> +\begin{lstlisting}
> +struct virtio_blk_crypto_caps {
> +  u8 size;
> +  le32 crypto_capabilities[];
> +};
> +\end{lstlisting}
> +
> +The \field{size} specifies the size of array \field{crypto_capabilities}.
> +The \field{crypto_capabilities} indicates the crypto capabilities
> +supported by the hardware storage for inline encryption.
> +
> +A crypto capability packs four 8-bits values:
> +\begin{itemize}
> +    \item Bits~\[31:24]: crypto algorithm identifiers.
> +    The device supports reporting and negotiating cryptographic algorithms
> +    using the following algorithm identifiers:
> +    \begin{lstlisting}
> +        CRYPTO_ALG_AES_XTS              = 0x0
> +        CRYPTO_ALG_BITLOCKER_AES_CBC    = 0x1
> +        CRYPTO_ALG_AES_ECB              = 0x2
> +        CRYPTO_ALG_ESSIV_AES_CBC        = 0x3
> +    \end{lstlisting}
> +    These identifiers abstract the underlying hardware crypto
> implementation
> +    and does not assume any operating‑system‑specific data structures or
> +    constants.
> +    \item Bits~\[23:16]: mask of data unit size. When bit j in this field
> +    (j=7......0) is set, a data unit size of 512*2^j bytes is selected.
> +    \item Bits~\[15:8]: crypto key size identifiers.
> +    \begin{lstlisting}
> +        CRYPTO_KEY_SIZE_INVALID     = 0x0
> +        CRYPTO_KEY_SIZE_128_BITS    = 0x1
> +        CRYPTO_KEY_SIZE_192_BITS    = 0x2
> +        CRYPTO_KEY_SIZE_256_BITS    = 0x3
> +        CRYPTO_KEY_SIZE_512_BITS    = 0x4
> +    \end{lstlisting}
> +    \item Bits~\[7:0]: unused.
> +\end{itemize}
> +
>  The final \field{status} byte is written by the device: either  VIRTIO_BLK_S_OK
> for success, VIRTIO_BLK_S_IOERR for device or driver  error or
> VIRTIO_BLK_S_UNSUPP for a request unsupported by device:
> @@ -912,6 +1011,13 @@ \subsection{Device Operation}\label{sec:Device
> Types / Block Device / Device Ope  successfully, failed, or were processed by
> the device at all if the request  failed with VIRTIO_BLK_S_IOERR.
>
> +The length of \field{data} MUST be a multiple of 4 bytes plus 1 for
> +VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES requests.
> +
> +A driver MUST set \field{activate} to 1 for
> VIRTIO_BLK_T_IN,VIRTIO_BLK_T_OUT,
> +    and VIRTIO_BLK_T_FLUSH requests that require inline encryption. For
> other
> +    request types or when inline encryption is not required, it is set to 0.
> +
>  The following requirements only apply if the VIRTIO_BLK_F_ZONED feature is
> negotiated.
>
> --
> 2.34.1
>

Disclaimer: This email and any files transmitted with it may contain confidential information intended for the addressee(s) only. The information is not to be surrendered or copied to unauthorized persons. If you have received this communication in error, please notify the sender immediately and delete this e-mail from your system.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2] virtio-blk: Add inline encryption support
  2026-02-19 14:35                   ` Sebastian Mauritsson
@ 2026-02-22  6:09                     ` Linlin Zhang
  2026-02-26 11:08                       ` Sebastian Mauritsson
  0 siblings, 1 reply; 13+ messages in thread
From: Linlin Zhang @ 2026-02-22  6:09 UTC (permalink / raw)
  To: Sebastian Mauritsson, virtio-dev@lists.linux.dev,
	stefanha@redhat.com
  Cc: quic_dshaikhu@quicinc.com



On 2/19/2026 10:35 PM, Sebastian Mauritsson wrote:
> I understand there might be compatibility considerations, but I'm wondering the exact reason for making CRYPTO_ALG_AES_ECB an option? This does not use an IV and is unsuitable for anything other than single-use & single-block encryption.
Would you please share your exact compatibility concerns? I believe the change in this patch only works for that the beckend and virtio block frontend negociates VIRTIO_BLK_F_ICE feature bit. Previous implementation doesn't have such
feature bit, so no impact on the backward compatibility.

With respect to CRYPTO_ALG_AES_ECB, it's just one possible enum of algoritms storage hardware supports. IV in additional
metadate encryption is mainly used by CBC mode.

By the way, please help review the patch in bellow thread sent by OSS mail id due to Qualcomm internal requirement for upstream.
  https://lore.kernel.org/virtio-dev/20260210083208.472824-1-linlin.zhang@oss.qualcomm.com/T/#t

> 
> Best regards, Sebastian
> 
>> -----Original Message-----
>> From: Linlin Zhang <quic_linlzhan@quicinc.com>
>> Sent: Friday, February 6, 2026 6:12 PM
>> To: virtio-dev@lists.linux.dev; stefanha@redhat.com
>> Cc: quic_dshaikhu@quicinc.com
>> Subject: [PATCH v2] virtio-blk: Add inline encryption support
>>
>> From: linlzhan <quic_linlzhan@quicinc.com>
>>
>> Inline encryption on virtio block can only be supported when the new feature
>> bit VIRTIO_BLK_F_ICE is negotiated.
>>
>> Extend struct virtio_blk_config and struct virtio_blk_req, so that crypto
>> capabilities can be got in the frontend and encryption metadata can be sent
>> to the backend, together with each I/O transaction.
>>
>> About the inline encryption on UFS or eMMC storage, please refer to the
>> Linux inline encryption documentation:
>> https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fgit.kernel.org%2fpub
>> %2fscm%2flinux%2fkernel%2fgit%2ftorvalds%2flinux.git%2ftree%2fDocumen
>> tation%2fblock%2finline-encryption.rst&c=E,1,nhL3zMxYwxuFP4QQ8SLhLjz-
>> MYwQ3RGD-PYXU71uhC-OBnxDeaefVyDYQH1A0KvX70THXfl-SWjj-
>> JcDntGGie3bSTNAri0H4_0CtCqU3kyCWRoDg1_N&typo=1
>>
>> Fixes: https://github.com/oasis-tcs/virtio-spec/issues/238
>> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
>> Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
>> Signed-off-by: Linlin Zhang <linlin.zhang@oss.qualcomm.com>
>> ---
>>
>> changes from v2:
>>  - Add inline encryption link in commit message for a better
>>    backgrond descryption
>>  - Add sufficient descryption for the fields of crypto
>>    capability
>>  - Delete crypto capability in configuration layout, instead
>>    add a new request command to get it
>>  - Correct the terminology in non-normative and normative
>>    sections
>>  - Correct the mail for open source upstream
>> ---
>>
>>  device-types/blk/description.tex | 110 ++++++++++++++++++++++++++++++-
>>  1 file changed, 108 insertions(+), 2 deletions(-)
>>
>> diff --git a/device-types/blk/description.tex b/device-
>> types/blk/description.tex
>> index 2712ada..60f46af 100644
>> --- a/device-types/blk/description.tex
>> +++ b/device-types/blk/description.tex
>> @@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types /
>> Block Device / Feature bits}
>>       (ZNS). For brevity, these standard documents are referred as "ZBD
>> standards"
>>       from this point on in the text.
>>
>> +\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported. Only
>> when this
>> +     feature bit is negotiated, the device need expose crypto characteristics in
>> +     configuration space and the driver need provide an extended request
>> header
>> +     containing a crypto payload for block I/O.
>> +
>>  \end{description}
>>
>>  \subsubsection{Legacy Interface: Feature bits}\label{sec:Device Types / Block
>> Device / Feature bits / Legacy Interface: Feature bits} @@ -128,6 +133,10 @@
>> \subsection{Device configuration layout}\label{sec:Device Types / Block
>> Device /
>>                  u8 model;
>>                  u8 unused2[3];
>>          } zoned;
>> +        struct virtio_blk_crypto_characteristics {
>> +                __virtio16 slot_info;
>> +                __virtio16 reserved;
>> +        } crypto;
>>  };
>>  \end{lstlisting}
>>
>> @@ -215,6 +224,18 @@ \subsection{Device configuration
>> layout}\label{sec:Device Types / Block Device /  terminated by the device with
>> a "zone resources exceeded" error as defined for  specific commands later.
>>
>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then in
>> +\field{virtio_blk_crypto_characteristics},
>> +\begin{itemize}
>> +\item \field{slot_info} value packs two 8-bits values to reduce the number of
>> +    Configuration Space reads.
>> +    \begin{itemize}
>> +        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number of
>> supported
>> +            crypto key slots.
>> +        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied to slot
>> numbering.
>> +    \end{itemize}
>> +\end{itemize}
>> +
>>  \subsubsection{Legacy Interface: Device configuration
>> layout}\label{sec:Device Types / Block Device / Device configuration layout /
>> Legacy Interface: Device configuration layout}  When using the legacy
>> interface, transitional devices and drivers  MUST format the fields in struct
>> virtio_blk_config @@ -278,6 +299,10 @@ \subsection{Device
>> Initialization}\label{sec:Device Types / Block Device / Devic
>>      \field{zoned} can be read by the driver to determine the zone
>>      characteristics of the device. All \field{zoned} fields are read-only.
>>
>> +\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
>> +    \field{crypto} can be read by the driver to determine the inline crypto
>> +    characteristics of the device. All \field{crypto} fields are read-only.
>> +
>>  \end{enumerate}
>>
>>  \drivernormative{\subsubsection}{Device Initialization}{Device Types / Block
>> Device / Device Initialization} @@ -317,6 +342,9 @@ \subsection{Device
>> Initialization}\label{sec:Device Types / Block Device / Devic
>>      driver SHOULD ignore all other fields in \field{zoned}.
>>  \end{itemize}
>>
>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver MUST
>> validate
>> +    the max_slots in \field{slot_info} before the slot usage.
>> +
>>  \devicenormative{\subsubsection}{Device Initialization}{Device Types / Block
>> Device / Device Initialization}
>>
>>  Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it @@ -
>> 402,6 +430,13 @@ \subsection{Device Initialization}\label{sec:Device Types /
>> Block Device / Devic  \item the device MUST initialize padding bytes
>> \field{unused2} to 0.
>>  \end{itemize}
>>
>> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in
>> +\field{crypto} struct in the configuration space MUST be set by the device.
>> +\begin{itemize}
>> +\item the \field{slot_info} field of \field{crypto} MUST be set by the device to
>> a
>> +    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
>> +\end{itemize}
>> +
>>  \subsubsection{Legacy Interface: Device Initialization}\label{sec:Device Types
>> / Block Device / Device Initialization / Legacy Interface: Device Initialization}
>>
>>  Because legacy devices do not have FEATURES_OK, transitional devices @@ -
>> 436,6 +471,13 @@ \subsection{Device Operation}\label{sec:Device Types /
>> Block Device / Device Ope
>>          le32 type;
>>          le32 reserved;
>>          le64 sector;
>> +        struct virtio_blk_crypto_payload {
>> +            u8 slot;
>> +            u8 activate;
>> +            le16 reserved1;
>> +            le32 reserved2;
>> +            le64 data_unit_num;
>> +        } payload;
>>          u8 data[];
>>          u8 status;
>>  };
>> @@ -445,8 +487,9 @@ \subsection{Device Operation}\label{sec:Device
>> Types / Block Device / Device Ope  (VIRTIO_BLK_T_OUT), a discard
>> (VIRTIO_BLK_T_DISCARD), a write zeroes  (VIRTIO_BLK_T_WRITE_ZEROES), a
>> flush (VIRTIO_BLK_T_FLUSH), a get device ID  string command
>> (VIRTIO_BLK_T_GET_ID), a secure erase -(VIRTIO_BLK_T_SECURE_ERASE), or
>> a get device lifetime command -(VIRTIO_BLK_T_GET_LIFETIME).
>> +(VIRTIO_BLK_T_SECURE_ERASE), a get device lifetime command
>> +(VIRTIO_BLK_T_GET_LIFETIME), or a get device crypto capabilities
>> +command (VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES).
>>
>>  \begin{lstlisting}
>>  #define VIRTIO_BLK_T_IN           0
>> @@ -457,12 +500,27 @@ \subsection{Device Operation}\label{sec:Device
>> Types / Block Device / Device Ope
>>  #define VIRTIO_BLK_T_DISCARD      11
>>  #define VIRTIO_BLK_T_WRITE_ZEROES 13
>>  #define VIRTIO_BLK_T_SECURE_ERASE   14
>> +#define VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES   27
>>  \end{lstlisting}
>>
>>  The \field{sector} number indicates the offset (multiplied by 512) where  the
>> read or write is to occur. This field is unused and set to 0 for  commands
>> other than read, write and some zone operations.
>>
>> +The \field{payload} consists of the encryption information for current
>> +request. It is only present when the VIRTIO_BLK_F_ICE feature is
>> +negotiated and \field{type} is VIRTIO_BLK_T_IN, VIRTIO_BLK_T_OUT or
>> VIRTIO_BLK_T_FLUSH.
>> +\begin{itemize}
>> +\item The \field{slot} field in \field{payload} indicates the ICE
>> +  (Inline Crypto Encryption) slot index where the key resides.
>> +
>> +\item The \field{activate} field in \field{payload} implies this is a
>> +  inline encryption request.
>> +
>> +\item The \field{data_unit_num} field in \field{payload} indicates the
>> +  starting block of the request.
>> +\end{itemize}
>> +
>>  VIRTIO_BLK_T_IN requests populate \field{data} with the contents of sectors
>> read from the block device (in multiples of 512 bytes).  VIRTIO_BLK_T_OUT
>> requests write the contents of \field{data} to the block device (in multiples
>> @@ -530,6 +588,47 @@ \subsection{Device Operation}\label{sec:Device
>> Types / Block Device / Device Ope  The \field{device_lifetime_est_typ_b}
>> refers to wear of MLC cells and is provided  with the same semantics as
>> \field{device_lifetime_est_typ_a}.
>>
>> +VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES requests fetch the storage
>> +hardware crypto capabilities into \field{data}. And the \field{data} is
>> +of the form
>> +
>> +\begin{lstlisting}
>> +struct virtio_blk_crypto_caps {
>> +  u8 size;
>> +  le32 crypto_capabilities[];
>> +};
>> +\end{lstlisting}
>> +
>> +The \field{size} specifies the size of array \field{crypto_capabilities}.
>> +The \field{crypto_capabilities} indicates the crypto capabilities
>> +supported by the hardware storage for inline encryption.
>> +
>> +A crypto capability packs four 8-bits values:
>> +\begin{itemize}
>> +    \item Bits~\[31:24]: crypto algorithm identifiers.
>> +    The device supports reporting and negotiating cryptographic algorithms
>> +    using the following algorithm identifiers:
>> +    \begin{lstlisting}
>> +        CRYPTO_ALG_AES_XTS              = 0x0
>> +        CRYPTO_ALG_BITLOCKER_AES_CBC    = 0x1
>> +        CRYPTO_ALG_AES_ECB              = 0x2
>> +        CRYPTO_ALG_ESSIV_AES_CBC        = 0x3
>> +    \end{lstlisting}
>> +    These identifiers abstract the underlying hardware crypto
>> implementation
>> +    and does not assume any operating‑system‑specific data structures or
>> +    constants.
>> +    \item Bits~\[23:16]: mask of data unit size. When bit j in this field
>> +    (j=7......0) is set, a data unit size of 512*2^j bytes is selected.
>> +    \item Bits~\[15:8]: crypto key size identifiers.
>> +    \begin{lstlisting}
>> +        CRYPTO_KEY_SIZE_INVALID     = 0x0
>> +        CRYPTO_KEY_SIZE_128_BITS    = 0x1
>> +        CRYPTO_KEY_SIZE_192_BITS    = 0x2
>> +        CRYPTO_KEY_SIZE_256_BITS    = 0x3
>> +        CRYPTO_KEY_SIZE_512_BITS    = 0x4
>> +    \end{lstlisting}
>> +    \item Bits~\[7:0]: unused.
>> +\end{itemize}
>> +
>>  The final \field{status} byte is written by the device: either  VIRTIO_BLK_S_OK
>> for success, VIRTIO_BLK_S_IOERR for device or driver  error or
>> VIRTIO_BLK_S_UNSUPP for a request unsupported by device:
>> @@ -912,6 +1011,13 @@ \subsection{Device Operation}\label{sec:Device
>> Types / Block Device / Device Ope  successfully, failed, or were processed by
>> the device at all if the request  failed with VIRTIO_BLK_S_IOERR.
>>
>> +The length of \field{data} MUST be a multiple of 4 bytes plus 1 for
>> +VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES requests.
>> +
>> +A driver MUST set \field{activate} to 1 for
>> VIRTIO_BLK_T_IN,VIRTIO_BLK_T_OUT,
>> +    and VIRTIO_BLK_T_FLUSH requests that require inline encryption. For
>> other
>> +    request types or when inline encryption is not required, it is set to 0.
>> +
>>  The following requirements only apply if the VIRTIO_BLK_F_ZONED feature is
>> negotiated.
>>
>> --
>> 2.34.1
>>
> 
> Disclaimer: This email and any files transmitted with it may contain confidential information intended for the addressee(s) only. The information is not to be surrendered or copied to unauthorized persons. If you have received this communication in error, please notify the sender immediately and delete this e-mail from your system.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH v2] virtio-blk: Add inline encryption support
  2026-02-22  6:09                     ` Linlin Zhang
@ 2026-02-26 11:08                       ` Sebastian Mauritsson
  0 siblings, 0 replies; 13+ messages in thread
From: Sebastian Mauritsson @ 2026-02-26 11:08 UTC (permalink / raw)
  To: Linlin Zhang, virtio-dev@lists.linux.dev, stefanha@redhat.com
  Cc: quic_dshaikhu@quicinc.com



> -----Original Message-----
> From: Linlin Zhang <quic_linlzhan@quicinc.com>
> Sent: Sunday, February 22, 2026 7:10 AM
> To: Sebastian Mauritsson <sma@napatech.com>; virtio-dev@lists.linux.dev;
> stefanha@redhat.com
> Cc: quic_dshaikhu@quicinc.com
> Subject: Re: [PATCH v2] virtio-blk: Add inline encryption support
>
>
>
> On 2/19/2026 10:35 PM, Sebastian Mauritsson wrote:
> > I understand there might be compatibility considerations, but I'm
> wondering the exact reason for making CRYPTO_ALG_AES_ECB an option?
> This does not use an IV and is unsuitable for anything other than single-use &
> single-block encryption.
> Would you please share your exact compatibility concerns? I believe the
> change in this patch only works for that the beckend and virtio block
> frontend negociates VIRTIO_BLK_F_ICE feature bit. Previous implementation
> doesn't have such feature bit, so no impact on the backward compatibility.
>
> With respect to CRYPTO_ALG_AES_ECB, it's just one possible enum of
> algoritms storage hardware supports. IV in additional metadate encryption is
> mainly used by CBC mode.
>
> By the way, please help review the patch in bellow thread sent by OSS mail id
> due to Qualcomm internal requirement for upstream.
>
> https://linkprotect.cudasvc.com/url?a=https%3a%2f%2flore.kernel.org%2fvir
> tio-dev%2f20260210083208.472824-1-
> linlin.zhang%40oss.qualcomm.com%2fT%2f%23t&c=E,1,oqW3rU1GxX_nvciF
> mhfWjET2wtttDFJuei_uUVYQbe_0DvBZtGb5wIRCCTSQxBkrzYC0StwOr7LaaYrI
> GfOinQs1UiLbd3QzNPRetNmv-w,,&typo=1

My compatibility concerns were with the hardware algorithm support - if AES in ECB mode would be the only common denominator, then it would be the only option and thereby have some reason for existence. However, I do not see this use case, and providing support for a very insecure choice is not good. All other modes use IV one way or the other.

If comparing with the Linux blk-crypto for Inline Encryption, https://github.com/torvalds/linux/blob/master/block/blk-crypto.c, only AES_256_XTS, AES_128_CBC_ESSIV, Adiantum and SM4-XTS is supported.

Also compare with the thread " crypto: virtio: Add ecb aes algo support" where the patch was denied. The use case was questioned, as well as it's backend support in Qemu and OPenSSL.

>
> >
> > Best regards, Sebastian
> >
> >> -----Original Message-----
> >> From: Linlin Zhang <quic_linlzhan@quicinc.com>
> >> Sent: Friday, February 6, 2026 6:12 PM
> >> To: virtio-dev@lists.linux.dev; stefanha@redhat.com
> >> Cc: quic_dshaikhu@quicinc.com
> >> Subject: [PATCH v2] virtio-blk: Add inline encryption support
> >>
> >> From: linlzhan <quic_linlzhan@quicinc.com>
> >>
> >> Inline encryption on virtio block can only be supported when the new
> >> feature bit VIRTIO_BLK_F_ICE is negotiated.
> >>
> >> Extend struct virtio_blk_config and struct virtio_blk_req, so that
> >> crypto capabilities can be got in the frontend and encryption
> >> metadata can be sent to the backend, together with each I/O transaction.
> >>
> >> About the inline encryption on UFS or eMMC storage, please refer to
> >> the Linux inline encryption documentation:
> >> https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fgit.kernel.org%2f
> >> pub
> >>
> %2fscm%2flinux%2fkernel%2fgit%2ftorvalds%2flinux.git%2ftree%2fDocumen
> >> tation%2fblock%2finline-
> encryption.rst&c=E,1,nhL3zMxYwxuFP4QQ8SLhLjz-
> >> MYwQ3RGD-PYXU71uhC-OBnxDeaefVyDYQH1A0KvX70THXfl-SWjj-
> >> JcDntGGie3bSTNAri0H4_0CtCqU3kyCWRoDg1_N&typo=1
> >>
> >> Fixes: https://github.com/oasis-tcs/virtio-spec/issues/238
> >> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
> >> Signed-off-by: linlzhan <quic_linlzhan@quicinc.com>
> >> Signed-off-by: Linlin Zhang <linlin.zhang@oss.qualcomm.com>
> >> ---
> >>
> >> changes from v2:
> >>  - Add inline encryption link in commit message for a better
> >>    backgrond descryption
> >>  - Add sufficient descryption for the fields of crypto
> >>    capability
> >>  - Delete crypto capability in configuration layout, instead
> >>    add a new request command to get it
> >>  - Correct the terminology in non-normative and normative
> >>    sections
> >>  - Correct the mail for open source upstream
> >> ---
> >>
> >>  device-types/blk/description.tex | 110
> >> ++++++++++++++++++++++++++++++-
> >>  1 file changed, 108 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/device-types/blk/description.tex b/device-
> >> types/blk/description.tex index 2712ada..60f46af 100644
> >> --- a/device-types/blk/description.tex
> >> +++ b/device-types/blk/description.tex
> >> @@ -66,6 +66,11 @@ \subsection{Feature bits}\label{sec:Device Types /
> >> Block Device / Feature bits}
> >>       (ZNS). For brevity, these standard documents are referred as
> >> "ZBD standards"
> >>       from this point on in the text.
> >>
> >> +\item[VIRTIO_BLK_F_ICE(22)] Inline Crypto Extensions are supported.
> >> +Only
> >> when this
> >> +     feature bit is negotiated, the device need expose crypto characteristics
> in
> >> +     configuration space and the driver need provide an extended
> >> + request
> >> header
> >> +     containing a crypto payload for block I/O.
> >> +
> >>  \end{description}
> >>
> >>  \subsubsection{Legacy Interface: Feature bits}\label{sec:Device
> >> Types / Block Device / Feature bits / Legacy Interface: Feature bits}
> >> @@ -128,6 +133,10 @@ \subsection{Device configuration
> >> layout}\label{sec:Device Types / Block Device /
> >>                  u8 model;
> >>                  u8 unused2[3];
> >>          } zoned;
> >> +        struct virtio_blk_crypto_characteristics {
> >> +                __virtio16 slot_info;
> >> +                __virtio16 reserved;
> >> +        } crypto;
> >>  };
> >>  \end{lstlisting}
> >>
> >> @@ -215,6 +224,18 @@ \subsection{Device configuration
> >> layout}\label{sec:Device Types / Block Device /  terminated by the
> >> device with a "zone resources exceeded" error as defined for  specific
> commands later.
> >>
> >> +If the VIRTIO_BLK_F_ICE feature is negotiated, then in
> >> +\field{virtio_blk_crypto_characteristics},
> >> +\begin{itemize}
> >> +\item \field{slot_info} value packs two 8-bits values to reduce the
> number of
> >> +    Configuration Space reads.
> >> +    \begin{itemize}
> >> +        \item Bits~\[15:8] (\emph{max\_slots}): the maximum number
> >> +of
> >> supported
> >> +            crypto key slots.
> >> +        \item Bits~\[7:0] (\emph{slot\_offset}): an offset applied
> >> + to slot
> >> numbering.
> >> +    \end{itemize}
> >> +\end{itemize}
> >> +
> >>  \subsubsection{Legacy Interface: Device configuration
> >> layout}\label{sec:Device Types / Block Device / Device configuration
> >> layout / Legacy Interface: Device configuration layout}  When using
> >> the legacy interface, transitional devices and drivers  MUST format
> >> the fields in struct virtio_blk_config @@ -278,6 +299,10 @@
> >> \subsection{Device Initialization}\label{sec:Device Types / Block Device /
> Devic
> >>      \field{zoned} can be read by the driver to determine the zone
> >>      characteristics of the device. All \field{zoned} fields are read-only.
> >>
> >> +\item If the VIRTIO_BLK_F_ICE feature is negotiated, the fields in
> >> +    \field{crypto} can be read by the driver to determine the inline crypto
> >> +    characteristics of the device. All \field{crypto} fields are read-only.
> >> +
> >>  \end{enumerate}
> >>
> >>  \drivernormative{\subsubsection}{Device Initialization}{Device Types
> >> / Block Device / Device Initialization} @@ -317,6 +342,9 @@
> >> \subsection{Device Initialization}\label{sec:Device Types / Block Device /
> Devic
> >>      driver SHOULD ignore all other fields in \field{zoned}.
> >>  \end{itemize}
> >>
> >> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the driver MUST
> >> validate
> >> +    the max_slots in \field{slot_info} before the slot usage.
> >> +
> >>  \devicenormative{\subsubsection}{Device Initialization}{Device Types
> >> / Block Device / Device Initialization}
> >>
> >>  Devices SHOULD always offer VIRTIO_BLK_F_FLUSH, and MUST offer it
> @@
> >> -
> >> 402,6 +430,13 @@ \subsection{Device Initialization}\label{sec:Device
> >> Types / Block Device / Devic  \item the device MUST initialize
> >> padding bytes \field{unused2} to 0.
> >>  \end{itemize}
> >>
> >> +If the VIRTIO_BLK_F_ICE feature is negotiated, then the fields in
> >> +\field{crypto} struct in the configuration space MUST be set by the
> device.
> >> +\begin{itemize}
> >> +\item the \field{slot_info} field of \field{crypto} MUST be set by
> >> +the device to
> >> a
> >> +    max_slots in the higher 8 bits and slot_offset in the lower 8 bits.
> >> +\end{itemize}
> >> +
> >>  \subsubsection{Legacy Interface: Device
> >> Initialization}\label{sec:Device Types / Block Device / Device
> >> Initialization / Legacy Interface: Device Initialization}
> >>
> >>  Because legacy devices do not have FEATURES_OK, transitional devices
> >> @@ -
> >> 436,6 +471,13 @@ \subsection{Device Operation}\label{sec:Device Types
> >> / Block Device / Device Ope
> >>          le32 type;
> >>          le32 reserved;
> >>          le64 sector;
> >> +        struct virtio_blk_crypto_payload {
> >> +            u8 slot;
> >> +            u8 activate;
> >> +            le16 reserved1;
> >> +            le32 reserved2;
> >> +            le64 data_unit_num;
> >> +        } payload;
> >>          u8 data[];
> >>          u8 status;
> >>  };
> >> @@ -445,8 +487,9 @@ \subsection{Device Operation}\label{sec:Device
> >> Types / Block Device / Device Ope  (VIRTIO_BLK_T_OUT), a discard
> >> (VIRTIO_BLK_T_DISCARD), a write zeroes  (VIRTIO_BLK_T_WRITE_ZEROES),
> >> a flush (VIRTIO_BLK_T_FLUSH), a get device ID  string command
> >> (VIRTIO_BLK_T_GET_ID), a secure erase -(VIRTIO_BLK_T_SECURE_ERASE),
> >> or a get device lifetime command -(VIRTIO_BLK_T_GET_LIFETIME).
> >> +(VIRTIO_BLK_T_SECURE_ERASE), a get device lifetime command
> >> +(VIRTIO_BLK_T_GET_LIFETIME), or a get device crypto capabilities
> >> +command (VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES).
> >>
> >>  \begin{lstlisting}
> >>  #define VIRTIO_BLK_T_IN           0
> >> @@ -457,12 +500,27 @@ \subsection{Device Operation}\label{sec:Device
> >> Types / Block Device / Device Ope
> >>  #define VIRTIO_BLK_T_DISCARD      11
> >>  #define VIRTIO_BLK_T_WRITE_ZEROES 13
> >>  #define VIRTIO_BLK_T_SECURE_ERASE   14
> >> +#define VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES   27
> >>  \end{lstlisting}
> >>
> >>  The \field{sector} number indicates the offset (multiplied by 512)
> >> where  the read or write is to occur. This field is unused and set to
> >> 0 for  commands other than read, write and some zone operations.
> >>
> >> +The \field{payload} consists of the encryption information for
> >> +current request. It is only present when the VIRTIO_BLK_F_ICE
> >> +feature is negotiated and \field{type} is VIRTIO_BLK_T_IN,
> >> +VIRTIO_BLK_T_OUT or
> >> VIRTIO_BLK_T_FLUSH.
> >> +\begin{itemize}
> >> +\item The \field{slot} field in \field{payload} indicates the ICE
> >> +  (Inline Crypto Encryption) slot index where the key resides.
> >> +
> >> +\item The \field{activate} field in \field{payload} implies this is
> >> +a
> >> +  inline encryption request.
> >> +
> >> +\item The \field{data_unit_num} field in \field{payload} indicates
> >> +the
> >> +  starting block of the request.
> >> +\end{itemize}
> >> +
> >>  VIRTIO_BLK_T_IN requests populate \field{data} with the contents of
> >> sectors read from the block device (in multiples of 512 bytes).
> >> VIRTIO_BLK_T_OUT requests write the contents of \field{data} to the
> >> block device (in multiples @@ -530,6 +588,47 @@ \subsection{Device
> >> Operation}\label{sec:Device Types / Block Device / Device Ope  The
> >> \field{device_lifetime_est_typ_b} refers to wear of MLC cells and is
> >> provided  with the same semantics as \field{device_lifetime_est_typ_a}.
> >>
> >> +VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES requests fetch the storage
> >> +hardware crypto capabilities into \field{data}. And the \field{data}
> >> +is of the form
> >> +
> >> +\begin{lstlisting}
> >> +struct virtio_blk_crypto_caps {
> >> +  u8 size;
> >> +  le32 crypto_capabilities[];
> >> +};
> >> +\end{lstlisting}
> >> +
> >> +The \field{size} specifies the size of array \field{crypto_capabilities}.
> >> +The \field{crypto_capabilities} indicates the crypto capabilities
> >> +supported by the hardware storage for inline encryption.
> >> +
> >> +A crypto capability packs four 8-bits values:
> >> +\begin{itemize}
> >> +    \item Bits~\[31:24]: crypto algorithm identifiers.
> >> +    The device supports reporting and negotiating cryptographic
> algorithms
> >> +    using the following algorithm identifiers:
> >> +    \begin{lstlisting}
> >> +        CRYPTO_ALG_AES_XTS              = 0x0
> >> +        CRYPTO_ALG_BITLOCKER_AES_CBC    = 0x1
> >> +        CRYPTO_ALG_AES_ECB              = 0x2
> >> +        CRYPTO_ALG_ESSIV_AES_CBC        = 0x3
> >> +    \end{lstlisting}
> >> +    These identifiers abstract the underlying hardware crypto
> >> implementation
> >> +    and does not assume any operating‑system‑specific data structures or
> >> +    constants.
> >> +    \item Bits~\[23:16]: mask of data unit size. When bit j in this field
> >> +    (j=7......0) is set, a data unit size of 512*2^j bytes is selected.
> >> +    \item Bits~\[15:8]: crypto key size identifiers.
> >> +    \begin{lstlisting}
> >> +        CRYPTO_KEY_SIZE_INVALID     = 0x0
> >> +        CRYPTO_KEY_SIZE_128_BITS    = 0x1
> >> +        CRYPTO_KEY_SIZE_192_BITS    = 0x2
> >> +        CRYPTO_KEY_SIZE_256_BITS    = 0x3
> >> +        CRYPTO_KEY_SIZE_512_BITS    = 0x4
> >> +    \end{lstlisting}
> >> +    \item Bits~\[7:0]: unused.
> >> +\end{itemize}
> >> +
> >>  The final \field{status} byte is written by the device: either
> >> VIRTIO_BLK_S_OK for success, VIRTIO_BLK_S_IOERR for device or driver
> >> error or VIRTIO_BLK_S_UNSUPP for a request unsupported by device:
> >> @@ -912,6 +1011,13 @@ \subsection{Device Operation}\label{sec:Device
> >> Types / Block Device / Device Ope  successfully, failed, or were
> >> processed by the device at all if the request  failed with
> VIRTIO_BLK_S_IOERR.
> >>
> >> +The length of \field{data} MUST be a multiple of 4 bytes plus 1 for
> >> +VIRTIO_BLK_T_GET_CRYPTO_CAPABILITIES requests.
> >> +
> >> +A driver MUST set \field{activate} to 1 for
> >> VIRTIO_BLK_T_IN,VIRTIO_BLK_T_OUT,
> >> +    and VIRTIO_BLK_T_FLUSH requests that require inline encryption.
> >> + For
> >> other
> >> +    request types or when inline encryption is not required, it is set to 0.
> >> +
> >>  The following requirements only apply if the VIRTIO_BLK_F_ZONED
> >> feature is negotiated.
> >>
> >> --
> >> 2.34.1
> >>
> >
> > Disclaimer: This email and any files transmitted with it may contain
> confidential information intended for the addressee(s) only. The information
> is not to be surrendered or copied to unauthorized persons. If you have
> received this communication in error, please notify the sender immediately
> and delete this e-mail from your system.

Disclaimer: This email and any files transmitted with it may contain confidential information intended for the addressee(s) only. The information is not to be surrendered or copied to unauthorized persons. If you have received this communication in error, please notify the sender immediately and delete this e-mail from your system.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-02-26 11:08 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-27 14:14 [PATCH v1] virtio-blk: Add inline encryption support Linlin Zhang
2026-01-27 14:20 ` Linlin Zhang
2026-01-27 21:09   ` Stefan Hajnoczi
2026-01-30 10:23     ` Linlin Zhang
2026-02-02 15:56       ` Stefan Hajnoczi
2026-02-03 10:06         ` Linlin Zhang
2026-02-03 14:43           ` Stefan Hajnoczi
2026-02-04 13:57             ` Linlin Zhang
2026-02-04 17:27               ` Stefan Hajnoczi
2026-02-06 17:12                 ` [PATCH v2] " Linlin Zhang
2026-02-19 14:35                   ` Sebastian Mauritsson
2026-02-22  6:09                     ` Linlin Zhang
2026-02-26 11:08                       ` Sebastian Mauritsson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox