diff mbox

[v17,1/2] virtio-crypto: Add virtio crypto device specification

Message ID 1492074674-124192-2-git-send-email-arei.gonglei@huawei.com
State New
Headers show

Commit Message

Gonglei (Arei) April 13, 2017, 9:11 a.m. UTC
The virtio crypto device is a virtual crypto device (ie. hardware
crypto accelerator card). Currently, the virtio crypto device provides
the following crypto services: CIPHER, MAC, HASH, and AEAD.

In this patch, CIPHER, MAC, HASH, AEAD services are introduced.

VIRTIO-153

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
CC: Michael S. Tsirkin <mst@redhat.com>
CC: Cornelia Huck <cornelia.huck@de.ibm.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
CC: Lingli Deng <denglingli@chinamobile.com>
CC: Jani Kokkonen <Jani.Kokkonen@huawei.com>
CC: Ola Liljedahl <Ola.Liljedahl@arm.com>
CC: Varun Sethi <Varun.Sethi@freescale.com>
CC: Zeng Xin <xin.zeng@intel.com>
CC: Keating Brian <brian.a.keating@intel.com>
CC: Ma Liang J <liang.j.ma@intel.com>
CC: Griffin John <john.griffin@intel.com>
CC: Mihai Claudiu Caraman <mike.caraman@nxp.com>
CC: Halil Pasic <pasic@linux.vnet.ibm.com>
---
 acknowledgements.tex |    1 +
 content.tex          |    2 +
 virtio-crypto.tex    | 1305 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1308 insertions(+)
 create mode 100644 virtio-crypto.tex

Comments

Stefan Hajnoczi April 18, 2017, 5:01 p.m. UTC | #1
On Thu, Apr 13, 2017 at 05:11:13PM +0800, Gonglei wrote:

More grammar fixes and the reasoning behind my suggestions.  I've only
reviewed 1/3rd of this patch so far.

> The virtio crypto device is a virtual crypto device (ie. hardware
> crypto accelerator card). Currently, the virtio crypto device provides
> the following crypto services: CIPHER, MAC, HASH, and AEAD.
> 
> In this patch, CIPHER, MAC, HASH, AEAD services are introduced.
> 
> VIRTIO-153
> 
> Signed-off-by: Gonglei <arei.gonglei@huawei.com>
> CC: Michael S. Tsirkin <mst@redhat.com>
> CC: Cornelia Huck <cornelia.huck@de.ibm.com>
> CC: Stefan Hajnoczi <stefanha@redhat.com>
> CC: Lingli Deng <denglingli@chinamobile.com>
> CC: Jani Kokkonen <Jani.Kokkonen@huawei.com>
> CC: Ola Liljedahl <Ola.Liljedahl@arm.com>
> CC: Varun Sethi <Varun.Sethi@freescale.com>
> CC: Zeng Xin <xin.zeng@intel.com>
> CC: Keating Brian <brian.a.keating@intel.com>
> CC: Ma Liang J <liang.j.ma@intel.com>
> CC: Griffin John <john.griffin@intel.com>
> CC: Mihai Claudiu Caraman <mike.caraman@nxp.com>
> CC: Halil Pasic <pasic@linux.vnet.ibm.com>
> ---
>  acknowledgements.tex |    1 +
>  content.tex          |    2 +
>  virtio-crypto.tex    | 1305 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 1308 insertions(+)
>  create mode 100644 virtio-crypto.tex
> 
> diff --git a/acknowledgements.tex b/acknowledgements.tex
> index 53942b0..6714544 100644
> --- a/acknowledgements.tex
> +++ b/acknowledgements.tex
> @@ -44,4 +44,5 @@ Patrick Durusau,	Technical Advisory Board, OASIS	\newline
>  Thomas Huth,	Red Hat	\newline
>  Yan Vugenfirer, Red Hat / Daynix	\newline
>  Kevin Lo,	MSI	\newline
> +Halil Pasic, IBM  \newline
>  \end{oasistitlesection}
> diff --git a/content.tex b/content.tex
> index 4b45678..ab75f78 100644
> --- a/content.tex
> +++ b/content.tex
> @@ -5750,6 +5750,8 @@ descriptor for the \field{sense_len}, \field{residual},
>  \field{status_qualifier}, \field{status}, \field{response} and
>  \field{sense} fields.
>  
> +\input{virtio-crypto.tex}
> +
>  \chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits}
>  
>  Currently there are three device-independent feature bits defined:
> diff --git a/virtio-crypto.tex b/virtio-crypto.tex
> new file mode 100644
> index 0000000..c73a1ef
> --- /dev/null
> +++ b/virtio-crypto.tex
> @@ -0,0 +1,1305 @@
> +\section{Crypto Device}\label{sec:Device Types / Crypto Device}
> +
> +The virtio crypto device is a virtual cryptography device as well as a kind of
> +virtual hardware accelerator for virtual machines. The encryption and
> +decryption requests are placed in any of the data queues and are ultimately handled by the
> +backend crypto accelerators. The second kind of queue is the control queue used to create 
> +or destroy sessions for symmetric algorithms and will control some advanced
> +features in the future. The virtio crypto device provides the following crypto
> +services: CIPHER, MAC, HASH, and AEAD.
> +
> +
> +\subsection{Device ID}\label{sec:Device Types / Crypto Device / Device ID}
> +
> +20
> +
> +\subsection{Virtqueues}\label{sec:Device Types / Crypto Device / Virtqueues}
> +
> +\begin{description}
> +\item[0] dataq1
> +\item[\ldots]
> +\item[N-1] dataqN
> +\item[N] controlq
> +\end{description}
> +
> +N is set by \field{max_dataqueues}.
> +
> +\subsection{Feature bits}\label{sec:Device Types / Crypto Device / Feature bits}
> +
> +VIRTIO_CRYPTO_F_STATELESS_MODE (0) stateless mode is available.
> +VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE (1) stateless mode is available for CIPHER service.
> +VIRTIO_CRYPTO_F_HASH_STATELESS_MODE (2) stateless mode is available for HASH service.
> +VIRTIO_CRYPTO_F_MAC_STATELESS_MODE (3) stateless mode is available for MAC service.
> +VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE (4) stateless mode is available for AEAD service.
> +
> +\subsubsection{Feature bit requirements}\label{sec:Device Types / Crypto Device / Feature bits}
> +
> +Some crypto feature bits require other crypto feature bits
> +(see \ref{drivernormative:Basic Facilities of a Virtio Device / Feature Bits}):
> +
> +\begin{description}
> +\item[VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
> +\item[VIRTIO_CRYPTO_F_HASH_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
> +\item[VIRTIO_CRYPTO_F_MAC_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
> +\item[VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
> +\end{description}
> +
> +\subsection{Supported crypto services}\label{sec:Device Types / Crypto Device / Supported crypto services}
> +
> +The virtio crypto device provides the following crypto services: CIPHER, MAC, HASH, and AEAD.
> +
> +\begin{lstlisting}
> +/* CIPHER service */
> +#define VIRTIO_CRYPTO_SERVICE_CIPHER 0
> +/* HASH service */
> +#define VIRTIO_CRYPTO_SERVICE_HASH   1
> +/* MAC (Message Authentication Codes) service */
> +#define VIRTIO_CRYPTO_SERVICE_MAC    2
> +/* AEAD (Authenticated Encryption with Associated Data) service */
> +#define VIRTIO_CRYPTO_SERVICE_AEAD   3
> +\end{lstlisting}
> +
> +The above constants are bit numbers, which used to tell the driver which crypto services

"which are used" but it can be shortened:

s/which used to tell/which tell/

> +are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
> +
> +\subsubsection{CIPHER services}\label{sec:Device Types / Crypto Device / Supported crypto services / CIPHER services}
> +
> +The following CIPHER algorithms are defined:
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_NO_CIPHER                 0
> +#define VIRTIO_CRYPTO_CIPHER_ARC4               1
> +#define VIRTIO_CRYPTO_CIPHER_AES_ECB            2
> +#define VIRTIO_CRYPTO_CIPHER_AES_CBC            3
> +#define VIRTIO_CRYPTO_CIPHER_AES_CTR            4
> +#define VIRTIO_CRYPTO_CIPHER_DES_ECB            5
> +#define VIRTIO_CRYPTO_CIPHER_DES_CBC            6
> +#define VIRTIO_CRYPTO_CIPHER_3DES_ECB           7
> +#define VIRTIO_CRYPTO_CIPHER_3DES_CBC           8
> +#define VIRTIO_CRYPTO_CIPHER_3DES_CTR           9
> +#define VIRTIO_CRYPTO_CIPHER_KASUMI_F8          10
> +#define VIRTIO_CRYPTO_CIPHER_SNOW3G_UEA2        11
> +#define VIRTIO_CRYPTO_CIPHER_AES_F8             12
> +#define VIRTIO_CRYPTO_CIPHER_AES_XTS            13
> +#define VIRTIO_CRYPTO_CIPHER_ZUC_EEA3           14
> +\end{lstlisting}
> +
> +The above constants have two usages:
> +\begin{enumerate}
> +\item As bit numbers, which used to tell the driver which CIPHER algorithms
> +are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
> +\item As values, which used to tell the device which CIPHER algorithm
> +a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.

s/request require by the driver/request from the driver requires/

> +\end{enumerate}
> +
> +\subsubsection{HASH services}\label{sec:Device Types / Crypto Device / Supported crypto services / HASH services}
> +
> +The following HASH algorithms are defined:
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_NO_HASH            0
> +#define VIRTIO_CRYPTO_HASH_MD5           1
> +#define VIRTIO_CRYPTO_HASH_SHA1          2
> +#define VIRTIO_CRYPTO_HASH_SHA_224       3
> +#define VIRTIO_CRYPTO_HASH_SHA_256       4
> +#define VIRTIO_CRYPTO_HASH_SHA_384       5
> +#define VIRTIO_CRYPTO_HASH_SHA_512       6
> +#define VIRTIO_CRYPTO_HASH_SHA3_224      7
> +#define VIRTIO_CRYPTO_HASH_SHA3_256      8
> +#define VIRTIO_CRYPTO_HASH_SHA3_384      9
> +#define VIRTIO_CRYPTO_HASH_SHA3_512      10
> +#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE128      11
> +#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE256      12
> +\end{lstlisting}
> +
> +The above constants have two usages:
> +\begin{enumerate}
> +\item As bit numbers, which used to tell the driver which HASH algorithms

s/which used/used/

> +are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
> +\item As values, which used to tell the device which HASH algorithm

s/which used/used/

> +a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.

s/request require by the driver/request from the driver requires/

(It's "I require" and "you require" but "he/she/it requires")

> +\end{enumerate}
> +
> +\subsubsection{MAC services}\label{sec:Device Types / Crypto Device / Supported crypto services / MAC services}
> +
> +The following MAC algorithms are defined:
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_NO_MAC                       0
> +#define VIRTIO_CRYPTO_MAC_HMAC_MD5                 1
> +#define VIRTIO_CRYPTO_MAC_HMAC_SHA1                2
> +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_224             3
> +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_256             4
> +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_384             5
> +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_512             6
> +#define VIRTIO_CRYPTO_MAC_CMAC_3DES                25
> +#define VIRTIO_CRYPTO_MAC_CMAC_AES                 26
> +#define VIRTIO_CRYPTO_MAC_KASUMI_F9                27
> +#define VIRTIO_CRYPTO_MAC_SNOW3G_UIA2              28
> +#define VIRTIO_CRYPTO_MAC_GMAC_AES                 41
> +#define VIRTIO_CRYPTO_MAC_GMAC_TWOFISH             42
> +#define VIRTIO_CRYPTO_MAC_CBCMAC_AES               49
> +#define VIRTIO_CRYPTO_MAC_CBCMAC_KASUMI_F9         50
> +#define VIRTIO_CRYPTO_MAC_XCBC_AES                 53
> +#define VIRTIO_CRYPTO_MAC_ZUC_EIA3                 54
> +\end{lstlisting}
> +
> +The above constants have two usages:
> +\begin{enumerate}
> +\item As bit numbers, which used to tell the driver which MAC algorithms
> +are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
> +\item As values, which used to tell the device which MAC algorithm
> +a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
> +\end{enumerate}

Same as above.

> +
> +\subsubsection{AEAD services}\label{sec:Device Types / Crypto Device / Supported crypto services / AEAD services}
> +
> +The following AEAD algorithms are defined:
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_NO_AEAD     0
> +#define VIRTIO_CRYPTO_AEAD_GCM    1
> +#define VIRTIO_CRYPTO_AEAD_CCM    2
> +#define VIRTIO_CRYPTO_AEAD_CHACHA20_POLY1305  3
> +\end{lstlisting}
> +
> +The above constants have two usages:
> +\begin{enumerate}
> +\item As bit numbers, which used to tell the driver which AEAD algorithms
> +are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
> +\item As values, which used to tell the device what AEAD algorithm
> +a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
> +\end{enumerate}

Same as above.

> +
> +\subsection{Device configuration layout}\label{sec:Device Types / Crypto Device / Device configuration layout}
> +
> +\begin{lstlisting}
> +struct virtio_crypto_config {
> +    le32 status;
> +    le32 max_dataqueues;
> +    le32 crypto_services;
> +    /* Detailed algorithms mask */
> +    le32 cipher_algo_l;
> +    le32 cipher_algo_h;
> +    le32 hash_algo;
> +    le32 mac_algo_l;
> +    le32 mac_algo_h;
> +    le32 aead_algo;
> +    /* Maximum length of cipher key in bytes */
> +    le32 max_cipher_key_len;
> +    /* Maximum length of authenticated key in bytes */
> +    le32 max_auth_key_len;
> +    le32 reserved;
> +    /* Maximum size of each crypto request's content in bytes */
> +    le64 max_size;
> +};
> +\end{lstlisting}
> +
> +\begin{description}
> +\item[\field{status}] is used to show whether the device is ready to work or not, it can be either zero or have one or more flags
> +    Only one read-only bit (for the driver) is currently defined for the \field{status} field: VIRTIO_CRYPTO_S_HW_READY:
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_S_HW_READY  (1 << 0)
> +\end{lstlisting}
> +
> +\item[\field{max_dataqueues}] is the maximum number of data virtqueues exposed by
> +    the device. The driver MAY use only one data queue,
> +    or it can use more to achieve better performance.
> +
> +\item[\field{crypto_services}] is a 32-bit mask which indicates the crypto services supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services}.
> +
> +\item[\field{cipher_algo_l}] is the low 32-bit mask wihich indicates the CIPHER algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / CIPHER services}.
> +
> +\item[\field{cipher_algo_h}] is the high 32-bit mask wihich indicates the CIPHER algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / CIPHER services}.
> +
> +\item[\field{hash_algo}] is a 32-bit mask wihich indicates the HASH algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / HASH services}.
> +
> +\item[\field{mac_algo_l}] is the low 32-bit mask wihich indicates the MAC algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / MAC services}.
> +
> +\item[\field{mac_algo_h}] is the high 32-bit mask wihich indicates the MAC algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / MAC services}.
> +
> +\item[\field{aead_algo}] is a 32-bit mask wihich indicates the AEAD algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / AEAD services}.
> +
> +\item[\field{max_cipher_key_len}] is the maximum length of cipher key supported by the device.
> +
> +\item[\field{max_auth_key_len}] is the maximum length of authenticated key supported by the device.
> +
> +\item[\field{reserved}] is reserved for future use.
> +
> +\item[\field{max_size}] is the maximum size of each crypto request's content supported by the device
> +\end{description}
> +
> +\begin{note}
> +Unless explicitly stated otherwise all lengths and sizes are in bytes.
> +\end{note}
> +
> +\devicenormative{\subsubsection}{Device configuration layout}{Device Types / Crypto Device / Device configuration layout}
> +
> +\begin{itemize*}
> +\item The device MUST set \field{max_dataqueues} to between 1 and 65535 inclusive.
> +\item The device MUST set \field{status} based on the status of the backend crypto accelerator. 
> +\item The device MUST accept and handle requests after \field{status} is set to VIRTIO_CRYPTO_S_HW_READY.
> +\item The device MUST set \field{crypto_services} based on the crypto services the device offers.
> +\item The device MUST set detailed algorithms masks based on the \field{crypto_services} field.
> +\item The device MUST set \field{max_size} to show the maximum size of crypto request the device supports.
> +\item The device MUST set \field{max_cipher_key_len} to show the maximum length of cipher key if the device supports CIPHER service.
> +\item The device MUST set \field{max_auth_key_len} to show the maximum length of authenticated key if the device supports MAC service.
> +\end{itemize*}
> +
> +\drivernormative{\subsubsection}{Device configuration layout}{Device Types / Crypto Device / Device configuration layout}
> +
> +\begin{itemize*}
> +\item The driver MUST read the ready \field{status} from the bottom bit of status to check whether the backend crypto accelerator
> +      is ready or not, and the driver MUST reread it after the device reset. 

"after the device resets" ("he/she/it resets" since "reset" is a verb
here).  But the following is shorter:

s/after the device reset/after device reset/

Here "reset" is a noun.

> +\item The driver MUST NOT transmit any requests to the device if the ready \field{status} is not set.
> +\item The driver MUST read \field{max_dataqueues} field to discover the number of data queues the device supports.
> +\item The driver MUST read \field{crypto_services} field to discover which services the device is able to offer.
> +\item The driver MUST read the detailed algorithms fields based on \field{crypto_services} field.
> +\item The driver SHOULD read \field{max_size} to discover the maximum size of crypto request the device supports.
> +\item The driver SHOULD read \field{max_cipher_key_len} to discover the maximum length of cipher key the device supports.
> +\item The driver SHOULD read \field{max_auth_key_len} to discover the maximum length of authenticated key the device supports.
> +\end{itemize*}
> +
> +\subsection{Device Initialization}\label{sec:Device Types / Crypto Device / Device Initialization}
> +
> +\drivernormative{\subsubsection}{Device Initialization}{Device Types / Crypto Device / Device Initialization}
> +
> +\begin{itemize*}
> +\item The driver MUST identify and initialize all virtqueues.
> +\item The driver MUST read the supported crypto services from bits of \field{crypto_services}. 
> +\item The driver MUST read the supported algorithms based on \field{crypto_services} field.
> +\end{itemize*}
> +
> +\subsection{Device Operation}\label{sec:Device Types / Crypto Device / Device Operation}
> +
> +Requests can be transmitted by placing them in both the controlq and dataq.

s/both the controlq and dataq/the controlq or dataq/

This way it's clear that 1 request does not need to be placed into the
controlq *and* the dataq.

> +Requests consist of a queue-type specific header specifying among
> +others the operation, and an operation specific payload.
> +Where the payload are composed of operation parameter + output data + input data in general.

"payload" is singular so it should be "the payload is" instead of "the
payload are".  Here is a different way of phrasing this:

The payload is generally composed of operation parameters, output data,
and input data.

> +Operation parameters are algorithm-specific parameters, output data is the
> +data that should be utilized in operations, and input data is equal to
> +"operation result + result data".
> +
> +The device can support both session mode (See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}) and stateless mode.
> +As VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is negotiated, the driver can use stateless mode for CIPHER service, otherwise it can only use session mode.

"As" is used in the same way as "since" here.  "As" and "Since" are
unconditional.  Using "if" or "when" is more appropriate because they
are conditional.  They express that something applies when a condition
is met:

s/As/If the/

I also added "the" because "VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE" is a
member of a group of "feature bits" so a definite article is needed:
https://en.wikipedia.org/wiki/Article_(grammar)#Definite_article

(The alternative is to just say "If
VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE is negotiated" without "feature
bit" so that no definite article is needed.)

> +
> +The header for controlq is as follows:
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_OPCODE(service, op)   (((service) << 8) | (op))
> +
> +struct virtio_crypto_ctrl_header {
> +#define VIRTIO_CRYPTO_CIPHER_CREATE_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x02)
> +#define VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x03)
> +#define VIRTIO_CRYPTO_HASH_CREATE_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x02)
> +#define VIRTIO_CRYPTO_HASH_DESTROY_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x03)
> +#define VIRTIO_CRYPTO_MAC_CREATE_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x02)
> +#define VIRTIO_CRYPTO_MAC_DESTROY_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x03)
> +#define VIRTIO_CRYPTO_AEAD_CREATE_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x02)
> +#define VIRTIO_CRYPTO_AEAD_DESTROY_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x03)
> +    le32 opcode;
> +    /* algo should be service-specific algorithms */
> +    le32 algo;
> +    le32 flag;
> +    /* data virtqueue id */
> +    le32 queue_id;
> +};
> +\end{lstlisting}
> +
> +The header of dataq is as follows:

s/of/for/

> +
> +\begin{lstlisting}
> +struct virtio_crypto_op_header {
> +#define VIRTIO_CRYPTO_CIPHER_ENCRYPT \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x00)
> +#define VIRTIO_CRYPTO_CIPHER_DECRYPT \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x01)
> +#define VIRTIO_CRYPTO_HASH \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x00)
> +#define VIRTIO_CRYPTO_MAC \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x00)
> +#define VIRTIO_CRYPTO_AEAD_ENCRYPT \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x00)
> +#define VIRTIO_CRYPTO_AEAD_DECRYPT \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x01)
> +    le32 opcode;
> +    /* algo should be service-specific algorithms */
> +    le32 algo;
> +    /* session_id should be service-specific algorithms */

I'm surprised that a general field like session_id has
algorithm-specific meaning.

> +    le64 session_id;VIRTIO_CRYPTO_F_STATELESS_MODE

?

> +#define VIRTIO_CRYPTO_FLAG_STATE_MODE 1
> +#define VIRTIO_CRYPTO_FLAG_STATELESS_MODE 2
> +    /* control flag to control the request */
> +    le32 flag;
> +    le32 padding;
> +};
> +\end{lstlisting}
> +
> +The device can set the operation status as follows: VIRTIO_CRYPTO_OK: success;
> +VIRTIO_CRYPTO_ERR: failure or device error; VIRTIO_CRYPTO_NOTSUPP: not supported;
> +VIRTIO_CRYPTO_INVSESS: invalid session ID when executing crypto operations.
> +
> +\begin{lstlisting}
> +enum VIRITO_CRYPTO_STATUS {
> +    VIRTIO_CRYPTO_OK = 0,
> +    VIRTIO_CRYPTO_ERR = 1,
> +    VIRTIO_CRYPTO_BADMSG = 2,
> +    VIRTIO_CRYPTO_NOTSUPP = 3,
> +    VIRTIO_CRYPTO_INVSESS = 4,
> +    VIRTIO_CRYPTO_MAX
> +};
> +\end{lstlisting}
> +
> +\subsubsection{Control Virtqueue}\label{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue}
> +
> +The driver uses the control virtqueue to send control commands to the
> +device, such as session operations (See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}).
> +
> +The request of controlq is as below:

"controlq requests are as follows:"
Gonglei (Arei) April 19, 2017, 6:01 a.m. UTC | #2
Hi Stefan,

Thanks for your comments firstly. :)

>
> From: Stefan Hajnoczi [mailto:stefanha@gmail.com]
> Sent: Wednesday, April 19, 2017 1:02 AM
> Subject: Re: [Qemu-devel] [PATCH v17 1/2] virtio-crypto: Add virtio crypto
> device specification
> 
> On Thu, Apr 13, 2017 at 05:11:13PM +0800, Gonglei wrote:
> 
> More grammar fixes and the reasoning behind my suggestions.  I've only
> reviewed 1/3rd of this patch so far.
> 
OK, please go ahead if you can, thanks :)

> > The virtio crypto device is a virtual crypto device (ie. hardware
> > crypto accelerator card). Currently, the virtio crypto device provides
> > the following crypto services: CIPHER, MAC, HASH, and AEAD.
> >
> > In this patch, CIPHER, MAC, HASH, AEAD services are introduced.
> >
> > VIRTIO-153
> >
> > Signed-off-by: Gonglei <arei.gonglei@huawei.com>
> > CC: Michael S. Tsirkin <mst@redhat.com>
> > CC: Cornelia Huck <cornelia.huck@de.ibm.com>
> > CC: Stefan Hajnoczi <stefanha@redhat.com>
> > CC: Lingli Deng <denglingli@chinamobile.com>
> > CC: Jani Kokkonen <Jani.Kokkonen@huawei.com>
> > CC: Ola Liljedahl <Ola.Liljedahl@arm.com>
> > CC: Varun Sethi <Varun.Sethi@freescale.com>
> > CC: Zeng Xin <xin.zeng@intel.com>
> > CC: Keating Brian <brian.a.keating@intel.com>
> > CC: Ma Liang J <liang.j.ma@intel.com>
> > CC: Griffin John <john.griffin@intel.com>
> > CC: Mihai Claudiu Caraman <mike.caraman@nxp.com>
> > CC: Halil Pasic <pasic@linux.vnet.ibm.com>
> > ---
> >  acknowledgements.tex |    1 +
> >  content.tex          |    2 +
> >  virtio-crypto.tex    | 1305
> ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 1308 insertions(+)
> >  create mode 100644 virtio-crypto.tex
> >
> > diff --git a/acknowledgements.tex b/acknowledgements.tex
> > index 53942b0..6714544 100644
> > --- a/acknowledgements.tex
> > +++ b/acknowledgements.tex
> > @@ -44,4 +44,5 @@ Patrick Durusau,	Technical Advisory Board, OASIS
> 	\newline
> >  Thomas Huth,	Red Hat	\newline
> >  Yan Vugenfirer, Red Hat / Daynix	\newline
> >  Kevin Lo,	MSI	\newline
> > +Halil Pasic, IBM  \newline
> >  \end{oasistitlesection}
> > diff --git a/content.tex b/content.tex
> > index 4b45678..ab75f78 100644
> > --- a/content.tex
> > +++ b/content.tex
> > @@ -5750,6 +5750,8 @@ descriptor for the \field{sense_len},
> \field{residual},
> >  \field{status_qualifier}, \field{status}, \field{response} and
> >  \field{sense} fields.
> >
> > +\input{virtio-crypto.tex}
> > +
> >  \chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits}
> >
> >  Currently there are three device-independent feature bits defined:
> > diff --git a/virtio-crypto.tex b/virtio-crypto.tex
> > new file mode 100644
> > index 0000000..c73a1ef
> > --- /dev/null
> > +++ b/virtio-crypto.tex
> > @@ -0,0 +1,1305 @@
> > +\section{Crypto Device}\label{sec:Device Types / Crypto Device}
> > +
> > +The virtio crypto device is a virtual cryptography device as well as a kind of
> > +virtual hardware accelerator for virtual machines. The encryption and
> > +decryption requests are placed in any of the data queues and are ultimately
> handled by the
> > +backend crypto accelerators. The second kind of queue is the control queue
> used to create
> > +or destroy sessions for symmetric algorithms and will control some
> advanced
> > +features in the future. The virtio crypto device provides the following crypto
> > +services: CIPHER, MAC, HASH, and AEAD.
> > +
> > +
> > +\subsection{Device ID}\label{sec:Device Types / Crypto Device / Device ID}
> > +
> > +20
> > +
> > +\subsection{Virtqueues}\label{sec:Device Types / Crypto Device /
> Virtqueues}
> > +
> > +\begin{description}
> > +\item[0] dataq1
> > +\item[\ldots]
> > +\item[N-1] dataqN
> > +\item[N] controlq
> > +\end{description}
> > +
> > +N is set by \field{max_dataqueues}.
> > +
> > +\subsection{Feature bits}\label{sec:Device Types / Crypto Device / Feature
> bits}
> > +
> > +VIRTIO_CRYPTO_F_STATELESS_MODE (0) stateless mode is available.
> > +VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE (1) stateless mode is
> available for CIPHER service.
> > +VIRTIO_CRYPTO_F_HASH_STATELESS_MODE (2) stateless mode is available
> for HASH service.
> > +VIRTIO_CRYPTO_F_MAC_STATELESS_MODE (3) stateless mode is available
> for MAC service.
> > +VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE (4) stateless mode is available
> for AEAD service.
> > +
> > +\subsubsection{Feature bit requirements}\label{sec:Device Types / Crypto
> Device / Feature bits}
> > +
> > +Some crypto feature bits require other crypto feature bits
> > +(see \ref{drivernormative:Basic Facilities of a Virtio Device / Feature Bits}):
> > +
> > +\begin{description}
> > +\item[VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE] Requires
> VIRTIO_CRYPTO_F_STATELESS_MODE.
> > +\item[VIRTIO_CRYPTO_F_HASH_STATELESS_MODE] Requires
> VIRTIO_CRYPTO_F_STATELESS_MODE.
> > +\item[VIRTIO_CRYPTO_F_MAC_STATELESS_MODE] Requires
> VIRTIO_CRYPTO_F_STATELESS_MODE.
> > +\item[VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE] Requires
> VIRTIO_CRYPTO_F_STATELESS_MODE.
> > +\end{description}
> > +
> > +\subsection{Supported crypto services}\label{sec:Device Types / Crypto
> Device / Supported crypto services}
> > +
> > +The virtio crypto device provides the following crypto services: CIPHER, MAC,
> HASH, and AEAD.
> > +
> > +\begin{lstlisting}
> > +/* CIPHER service */
> > +#define VIRTIO_CRYPTO_SERVICE_CIPHER 0
> > +/* HASH service */
> > +#define VIRTIO_CRYPTO_SERVICE_HASH   1
> > +/* MAC (Message Authentication Codes) service */
> > +#define VIRTIO_CRYPTO_SERVICE_MAC    2
> > +/* AEAD (Authenticated Encryption with Associated Data) service */
> > +#define VIRTIO_CRYPTO_SERVICE_AEAD   3
> > +\end{lstlisting}
> > +
> > +The above constants are bit numbers, which used to tell the driver which
> crypto services
> 
> "which are used" but it can be shortened:
> 
> s/which used to tell/which tell/
> 
OK

> > +are supported by the device, see \ref{sec:Device Types / Crypto Device /
> Device configuration layout}.
> > +
> > +\subsubsection{CIPHER services}\label{sec:Device Types / Crypto Device /
> Supported crypto services / CIPHER services}
> > +
> > +The following CIPHER algorithms are defined:
> > +
> > +\begin{lstlisting}
> > +#define VIRTIO_CRYPTO_NO_CIPHER                 0
> > +#define VIRTIO_CRYPTO_CIPHER_ARC4               1
> > +#define VIRTIO_CRYPTO_CIPHER_AES_ECB            2
> > +#define VIRTIO_CRYPTO_CIPHER_AES_CBC            3
> > +#define VIRTIO_CRYPTO_CIPHER_AES_CTR            4
> > +#define VIRTIO_CRYPTO_CIPHER_DES_ECB            5
> > +#define VIRTIO_CRYPTO_CIPHER_DES_CBC            6
> > +#define VIRTIO_CRYPTO_CIPHER_3DES_ECB           7
> > +#define VIRTIO_CRYPTO_CIPHER_3DES_CBC           8
> > +#define VIRTIO_CRYPTO_CIPHER_3DES_CTR           9
> > +#define VIRTIO_CRYPTO_CIPHER_KASUMI_F8          10
> > +#define VIRTIO_CRYPTO_CIPHER_SNOW3G_UEA2        11
> > +#define VIRTIO_CRYPTO_CIPHER_AES_F8             12
> > +#define VIRTIO_CRYPTO_CIPHER_AES_XTS            13
> > +#define VIRTIO_CRYPTO_CIPHER_ZUC_EEA3           14
> > +\end{lstlisting}
> > +
> > +The above constants have two usages:
> > +\begin{enumerate}
> > +\item As bit numbers, which used to tell the driver which CIPHER algorithms
> > +are supported by the device, see \ref{sec:Device Types / Crypto Device /
> Device configuration layout}.
> > +\item As values, which used to tell the device which CIPHER algorithm
> > +a crypto request require by the driver, see \ref{sec:Device Types / Crypto
> Device / Device Operation / Control Virtqueue / Session operation}.
> 
> s/request require by the driver/request from the driver requires/
> 
OK.

> > +\end{enumerate}
> > +
> > +\subsubsection{HASH services}\label{sec:Device Types / Crypto Device /
> Supported crypto services / HASH services}
> > +
> > +The following HASH algorithms are defined:
> > +
> > +\begin{lstlisting}
> > +#define VIRTIO_CRYPTO_NO_HASH            0
> > +#define VIRTIO_CRYPTO_HASH_MD5           1
> > +#define VIRTIO_CRYPTO_HASH_SHA1          2
> > +#define VIRTIO_CRYPTO_HASH_SHA_224       3
> > +#define VIRTIO_CRYPTO_HASH_SHA_256       4
> > +#define VIRTIO_CRYPTO_HASH_SHA_384       5
> > +#define VIRTIO_CRYPTO_HASH_SHA_512       6
> > +#define VIRTIO_CRYPTO_HASH_SHA3_224      7
> > +#define VIRTIO_CRYPTO_HASH_SHA3_256      8
> > +#define VIRTIO_CRYPTO_HASH_SHA3_384      9
> > +#define VIRTIO_CRYPTO_HASH_SHA3_512      10
> > +#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE128      11
> > +#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE256      12
> > +\end{lstlisting}
> > +
> > +The above constants have two usages:
> > +\begin{enumerate}
> > +\item As bit numbers, which used to tell the driver which HASH algorithms
> 
> s/which used/used/
> 
> > +are supported by the device, see \ref{sec:Device Types / Crypto Device /
> Device configuration layout}.
> > +\item As values, which used to tell the device which HASH algorithm
> 
> s/which used/used/
> 
> > +a crypto request require by the driver, see \ref{sec:Device Types / Crypto
> Device / Device Operation / Control Virtqueue / Session operation}.
> 
> s/request require by the driver/request from the driver requires/
> 
> (It's "I require" and "you require" but "he/she/it requires")
> 
Yes, fixed.

> > +\end{enumerate}
> > +
> > +\subsubsection{MAC services}\label{sec:Device Types / Crypto Device /
> Supported crypto services / MAC services}
> > +
> > +The following MAC algorithms are defined:
> > +
> > +\begin{lstlisting}
> > +#define VIRTIO_CRYPTO_NO_MAC                       0
> > +#define VIRTIO_CRYPTO_MAC_HMAC_MD5                 1
> > +#define VIRTIO_CRYPTO_MAC_HMAC_SHA1                2
> > +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_224             3
> > +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_256             4
> > +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_384             5
> > +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_512             6
> > +#define VIRTIO_CRYPTO_MAC_CMAC_3DES                25
> > +#define VIRTIO_CRYPTO_MAC_CMAC_AES                 26
> > +#define VIRTIO_CRYPTO_MAC_KASUMI_F9                27
> > +#define VIRTIO_CRYPTO_MAC_SNOW3G_UIA2              28
> > +#define VIRTIO_CRYPTO_MAC_GMAC_AES                 41
> > +#define VIRTIO_CRYPTO_MAC_GMAC_TWOFISH             42
> > +#define VIRTIO_CRYPTO_MAC_CBCMAC_AES               49
> > +#define VIRTIO_CRYPTO_MAC_CBCMAC_KASUMI_F9         50
> > +#define VIRTIO_CRYPTO_MAC_XCBC_AES                 53
> > +#define VIRTIO_CRYPTO_MAC_ZUC_EIA3                 54
> > +\end{lstlisting}
> > +
> > +The above constants have two usages:
> > +\begin{enumerate}
> > +\item As bit numbers, which used to tell the driver which MAC algorithms
> > +are supported by the device, see \ref{sec:Device Types / Crypto Device /
> Device configuration layout}.
> > +\item As values, which used to tell the device which MAC algorithm
> > +a crypto request require by the driver, see \ref{sec:Device Types / Crypto
> Device / Device Operation / Control Virtqueue / Session operation}.
> > +\end{enumerate}
> 
> Same as above.
> 
> > +
> > +\subsubsection{AEAD services}\label{sec:Device Types / Crypto Device /
> Supported crypto services / AEAD services}
> > +
> > +The following AEAD algorithms are defined:
> > +
> > +\begin{lstlisting}
> > +#define VIRTIO_CRYPTO_NO_AEAD     0
> > +#define VIRTIO_CRYPTO_AEAD_GCM    1
> > +#define VIRTIO_CRYPTO_AEAD_CCM    2
> > +#define VIRTIO_CRYPTO_AEAD_CHACHA20_POLY1305  3
> > +\end{lstlisting}
> > +
> > +The above constants have two usages:
> > +\begin{enumerate}
> > +\item As bit numbers, which used to tell the driver which AEAD algorithms
> > +are supported by the device, see \ref{sec:Device Types / Crypto Device /
> Device configuration layout}.
> > +\item As values, which used to tell the device what AEAD algorithm
> > +a crypto request require by the driver, see \ref{sec:Device Types / Crypto
> Device / Device Operation / Control Virtqueue / Session operation}.
> > +\end{enumerate}
> 
> Same as above.
> 
Fixed.

> > +
> > +\subsection{Device configuration layout}\label{sec:Device Types / Crypto
> Device / Device configuration layout}
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_config {
> > +    le32 status;
> > +    le32 max_dataqueues;
> > +    le32 crypto_services;
> > +    /* Detailed algorithms mask */
> > +    le32 cipher_algo_l;
> > +    le32 cipher_algo_h;
> > +    le32 hash_algo;
> > +    le32 mac_algo_l;
> > +    le32 mac_algo_h;
> > +    le32 aead_algo;
> > +    /* Maximum length of cipher key in bytes */
> > +    le32 max_cipher_key_len;
> > +    /* Maximum length of authenticated key in bytes */
> > +    le32 max_auth_key_len;
> > +    le32 reserved;
> > +    /* Maximum size of each crypto request's content in bytes */
> > +    le64 max_size;
> > +};
> > +\end{lstlisting}
> > +
> > +\begin{description}
> > +\item[\field{status}] is used to show whether the device is ready to work or
> not, it can be either zero or have one or more flags
> > +    Only one read-only bit (for the driver) is currently defined for the
> \field{status} field: VIRTIO_CRYPTO_S_HW_READY:
> > +\begin{lstlisting}
> > +#define VIRTIO_CRYPTO_S_HW_READY  (1 << 0)
> > +\end{lstlisting}
> > +
> > +\item[\field{max_dataqueues}] is the maximum number of data virtqueues
> exposed by
> > +    the device. The driver MAY use only one data queue,
> > +    or it can use more to achieve better performance.
> > +
> > +\item[\field{crypto_services}] is a 32-bit mask which indicates the crypto
> services supported by
> > +    the device, see \ref{sec:Device Types / Crypto Device / Supported
> crypto services}.
> > +
> > +\item[\field{cipher_algo_l}] is the low 32-bit mask wihich indicates the
> CIPHER algorithms supported by
> > +    the device, see \ref{sec:Device Types / Crypto Device / Supported
> crypto services  / CIPHER services}.
> > +
> > +\item[\field{cipher_algo_h}] is the high 32-bit mask wihich indicates the
> CIPHER algorithms supported by
> > +    the device, see \ref{sec:Device Types / Crypto Device / Supported
> crypto services  / CIPHER services}.
> > +
> > +\item[\field{hash_algo}] is a 32-bit mask wihich indicates the HASH
> algorithms supported by
> > +    the device, see \ref{sec:Device Types / Crypto Device / Supported
> crypto services  / HASH services}.
> > +
> > +\item[\field{mac_algo_l}] is the low 32-bit mask wihich indicates the MAC
> algorithms supported by
> > +    the device, see \ref{sec:Device Types / Crypto Device / Supported
> crypto services  / MAC services}.
> > +
> > +\item[\field{mac_algo_h}] is the high 32-bit mask wihich indicates the MAC
> algorithms supported by
> > +    the device, see \ref{sec:Device Types / Crypto Device / Supported
> crypto services  / MAC services}.
> > +
> > +\item[\field{aead_algo}] is a 32-bit mask wihich indicates the AEAD
> algorithms supported by
> > +    the device, see \ref{sec:Device Types / Crypto Device / Supported
> crypto services  / AEAD services}.
> > +
> > +\item[\field{max_cipher_key_len}] is the maximum length of cipher key
> supported by the device.
> > +
> > +\item[\field{max_auth_key_len}] is the maximum length of authenticated
> key supported by the device.
> > +
> > +\item[\field{reserved}] is reserved for future use.
> > +
> > +\item[\field{max_size}] is the maximum size of each crypto request's
> content supported by the device
> > +\end{description}
> > +
> > +\begin{note}
> > +Unless explicitly stated otherwise all lengths and sizes are in bytes.
> > +\end{note}
> > +
> > +\devicenormative{\subsubsection}{Device configuration layout}{Device Types
> / Crypto Device / Device configuration layout}
> > +
> > +\begin{itemize*}
> > +\item The device MUST set \field{max_dataqueues} to between 1 and 65535
> inclusive.
> > +\item The device MUST set \field{status} based on the status of the backend
> crypto accelerator.
> > +\item The device MUST accept and handle requests after \field{status} is set
> to VIRTIO_CRYPTO_S_HW_READY.
> > +\item The device MUST set \field{crypto_services} based on the crypto
> services the device offers.
> > +\item The device MUST set detailed algorithms masks based on the
> \field{crypto_services} field.
> > +\item The device MUST set \field{max_size} to show the maximum size of
> crypto request the device supports.
> > +\item The device MUST set \field{max_cipher_key_len} to show the
> maximum length of cipher key if the device supports CIPHER service.
> > +\item The device MUST set \field{max_auth_key_len} to show the maximum
> length of authenticated key if the device supports MAC service.
> > +\end{itemize*}
> > +
> > +\drivernormative{\subsubsection}{Device configuration layout}{Device Types
> / Crypto Device / Device configuration layout}
> > +
> > +\begin{itemize*}
> > +\item The driver MUST read the ready \field{status} from the bottom bit of
> status to check whether the backend crypto accelerator
> > +      is ready or not, and the driver MUST reread it after the device reset.
> 
> "after the device resets" ("he/she/it resets" since "reset" is a verb
> here).  But the following is shorter:
> 
> s/after the device reset/after device reset/
> 
> Here "reset" is a noun.
> 
Nice, fixed.

> > +\item The driver MUST NOT transmit any requests to the device if the ready
> \field{status} is not set.
> > +\item The driver MUST read \field{max_dataqueues} field to discover the
> number of data queues the device supports.
> > +\item The driver MUST read \field{crypto_services} field to discover which
> services the device is able to offer.
> > +\item The driver MUST read the detailed algorithms fields based on
> \field{crypto_services} field.
> > +\item The driver SHOULD read \field{max_size} to discover the maximum
> size of crypto request the device supports.
> > +\item The driver SHOULD read \field{max_cipher_key_len} to discover the
> maximum length of cipher key the device supports.
> > +\item The driver SHOULD read \field{max_auth_key_len} to discover the
> maximum length of authenticated key the device supports.
> > +\end{itemize*}
> > +
> > +\subsection{Device Initialization}\label{sec:Device Types / Crypto Device /
> Device Initialization}
> > +
> > +\drivernormative{\subsubsection}{Device Initialization}{Device Types /
> Crypto Device / Device Initialization}
> > +
> > +\begin{itemize*}
> > +\item The driver MUST identify and initialize all virtqueues.
> > +\item The driver MUST read the supported crypto services from bits of
> \field{crypto_services}.
> > +\item The driver MUST read the supported algorithms based on
> \field{crypto_services} field.
> > +\end{itemize*}
> > +
> > +\subsection{Device Operation}\label{sec:Device Types / Crypto Device /
> Device Operation}
> > +
> > +Requests can be transmitted by placing them in both the controlq and
> dataq.
> 
> s/both the controlq and dataq/the controlq or dataq/
> 
> This way it's clear that 1 request does not need to be placed into the
> controlq *and* the dataq.
> 
OK, fixed.

> > +Requests consist of a queue-type specific header specifying among
> > +others the operation, and an operation specific payload.
> > +Where the payload are composed of operation parameter + output data +
> input data in general.
> 
> "payload" is singular so it should be "the payload is" instead of "the
> payload are".  Here is a different way of phrasing this:
> 
> The payload is generally composed of operation parameters, output data,
> and input data.
> 
OK, it's better. 

> > +Operation parameters are algorithm-specific parameters, output data is the
> > +data that should be utilized in operations, and input data is equal to
> > +"operation result + result data".
> > +
> > +The device can support both session mode (See \ref{sec:Device Types /
> Crypto Device / Device Operation / Control Virtqueue / Session operation}) and
> stateless mode.
> > +As VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is negotiated,
> the driver can use stateless mode for CIPHER service, otherwise it can only use
> session mode.
> 
> "As" is used in the same way as "since" here.  "As" and "Since" are
> unconditional.  Using "if" or "when" is more appropriate because they
> are conditional.  They express that something applies when a condition
> is met:
> 
> s/As/If the/
> 
> I also added "the" because "VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE" is
> a
> member of a group of "feature bits" so a definite article is needed:
> https://en.wikipedia.org/wiki/Article_(grammar)#Definite_article
> 
> (The alternative is to just say "If
> VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE is negotiated" without "feature
> bit" so that no definite article is needed.)
> 
OK, Fixed.

> > +
> > +The header for controlq is as follows:
> > +
> > +\begin{lstlisting}
> > +#define VIRTIO_CRYPTO_OPCODE(service, op)   (((service) << 8) | (op))
> > +
> > +struct virtio_crypto_ctrl_header {
> > +#define VIRTIO_CRYPTO_CIPHER_CREATE_SESSION \
> > +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER,
> 0x02)
> > +#define VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION \
> > +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER,
> 0x03)
> > +#define VIRTIO_CRYPTO_HASH_CREATE_SESSION \
> > +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x02)
> > +#define VIRTIO_CRYPTO_HASH_DESTROY_SESSION \
> > +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x03)
> > +#define VIRTIO_CRYPTO_MAC_CREATE_SESSION \
> > +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x02)
> > +#define VIRTIO_CRYPTO_MAC_DESTROY_SESSION \
> > +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x03)
> > +#define VIRTIO_CRYPTO_AEAD_CREATE_SESSION \
> > +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x02)
> > +#define VIRTIO_CRYPTO_AEAD_DESTROY_SESSION \
> > +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x03)
> > +    le32 opcode;
> > +    /* algo should be service-specific algorithms */
> > +    le32 algo;
> > +    le32 flag;
> > +    /* data virtqueue id */
> > +    le32 queue_id;
> > +};
> > +\end{lstlisting}
> > +
> > +The header of dataq is as follows:
> 
> s/of/for/
> 
Fixed.

> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_op_header {
> > +#define VIRTIO_CRYPTO_CIPHER_ENCRYPT \
> > +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x00)
> > +#define VIRTIO_CRYPTO_CIPHER_DECRYPT \
> > +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x01)
> > +#define VIRTIO_CRYPTO_HASH \
> > +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x00)
> > +#define VIRTIO_CRYPTO_MAC \
> > +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x00)
> > +#define VIRTIO_CRYPTO_AEAD_ENCRYPT \
> > +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x00)
> > +#define VIRTIO_CRYPTO_AEAD_DECRYPT \
> > +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x01)
> > +    le32 opcode;
> > +    /* algo should be service-specific algorithms */
> > +    le32 algo;
> > +    /* session_id should be service-specific algorithms */
> 
> I'm surprised that a general field like session_id has
> algorithm-specific meaning.
> 
Good catch, It's a typo because of copy.
Let me drop it.

> > +    le64 session_id;VIRTIO_CRYPTO_F_STATELESS_MODE
> 
> ?
> 
Sorry, It's a typo too. Drop it.

> > +#define VIRTIO_CRYPTO_FLAG_STATE_MODE 1
> > +#define VIRTIO_CRYPTO_FLAG_STATELESS_MODE 2
> > +    /* control flag to control the request */
> > +    le32 flag;
> > +    le32 padding;
> > +};
> > +\end{lstlisting}
> > +
> > +The device can set the operation status as follows: VIRTIO_CRYPTO_OK:
> success;
> > +VIRTIO_CRYPTO_ERR: failure or device error; VIRTIO_CRYPTO_NOTSUPP:
> not supported;
> > +VIRTIO_CRYPTO_INVSESS: invalid session ID when executing crypto
> operations.
> > +
> > +\begin{lstlisting}
> > +enum VIRITO_CRYPTO_STATUS {
> > +    VIRTIO_CRYPTO_OK = 0,
> > +    VIRTIO_CRYPTO_ERR = 1,
> > +    VIRTIO_CRYPTO_BADMSG = 2,
> > +    VIRTIO_CRYPTO_NOTSUPP = 3,
> > +    VIRTIO_CRYPTO_INVSESS = 4,
> > +    VIRTIO_CRYPTO_MAX
> > +};
> > +\end{lstlisting}
> > +
> > +\subsubsection{Control Virtqueue}\label{sec:Device Types / Crypto Device /
> Device Operation / Control Virtqueue}
> > +
> > +The driver uses the control virtqueue to send control commands to the
> > +device, such as session operations (See \ref{sec:Device Types / Crypto
> Device / Device Operation / Control Virtqueue / Session operation}).
> > +
> > +The request of controlq is as below:
> 
> "controlq requests are as follows:"

Fixed.

Thanks,
-Gonglei
Stefan Hajnoczi April 20, 2017, 10:04 a.m. UTC | #3
On Thu, Apr 13, 2017 at 05:11:13PM +0800, Gonglei wrote:

More review, not done yet.

> The virtio crypto device is a virtual crypto device (ie. hardware
> crypto accelerator card). Currently, the virtio crypto device provides
> the following crypto services: CIPHER, MAC, HASH, and AEAD.
> 
> In this patch, CIPHER, MAC, HASH, AEAD services are introduced.
> 
> VIRTIO-153
> 
> Signed-off-by: Gonglei <arei.gonglei@huawei.com>
> CC: Michael S. Tsirkin <mst@redhat.com>
> CC: Cornelia Huck <cornelia.huck@de.ibm.com>
> CC: Stefan Hajnoczi <stefanha@redhat.com>
> CC: Lingli Deng <denglingli@chinamobile.com>
> CC: Jani Kokkonen <Jani.Kokkonen@huawei.com>
> CC: Ola Liljedahl <Ola.Liljedahl@arm.com>
> CC: Varun Sethi <Varun.Sethi@freescale.com>
> CC: Zeng Xin <xin.zeng@intel.com>
> CC: Keating Brian <brian.a.keating@intel.com>
> CC: Ma Liang J <liang.j.ma@intel.com>
> CC: Griffin John <john.griffin@intel.com>
> CC: Mihai Claudiu Caraman <mike.caraman@nxp.com>
> CC: Halil Pasic <pasic@linux.vnet.ibm.com>
> ---
>  acknowledgements.tex |    1 +
>  content.tex          |    2 +
>  virtio-crypto.tex    | 1305 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 1308 insertions(+)
>  create mode 100644 virtio-crypto.tex
> 
> diff --git a/acknowledgements.tex b/acknowledgements.tex
> index 53942b0..6714544 100644
> --- a/acknowledgements.tex
> +++ b/acknowledgements.tex
> @@ -44,4 +44,5 @@ Patrick Durusau,	Technical Advisory Board, OASIS	\newline
>  Thomas Huth,	Red Hat	\newline
>  Yan Vugenfirer, Red Hat / Daynix	\newline
>  Kevin Lo,	MSI	\newline
> +Halil Pasic, IBM  \newline
>  \end{oasistitlesection}
> diff --git a/content.tex b/content.tex
> index 4b45678..ab75f78 100644
> --- a/content.tex
> +++ b/content.tex
> @@ -5750,6 +5750,8 @@ descriptor for the \field{sense_len}, \field{residual},
>  \field{status_qualifier}, \field{status}, \field{response} and
>  \field{sense} fields.
>  
> +\input{virtio-crypto.tex}
> +
>  \chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits}
>  
>  Currently there are three device-independent feature bits defined:
> diff --git a/virtio-crypto.tex b/virtio-crypto.tex
> new file mode 100644
> index 0000000..c73a1ef
> --- /dev/null
> +++ b/virtio-crypto.tex
> @@ -0,0 +1,1305 @@
> +\section{Crypto Device}\label{sec:Device Types / Crypto Device}
> +
> +The virtio crypto device is a virtual cryptography device as well as a kind of
> +virtual hardware accelerator for virtual machines. The encryption and
> +decryption requests are placed in any of the data queues and are ultimately handled by the
> +backend crypto accelerators. The second kind of queue is the control queue used to create 
> +or destroy sessions for symmetric algorithms and will control some advanced
> +features in the future. The virtio crypto device provides the following crypto
> +services: CIPHER, MAC, HASH, and AEAD.
> +
> +
> +\subsection{Device ID}\label{sec:Device Types / Crypto Device / Device ID}
> +
> +20
> +
> +\subsection{Virtqueues}\label{sec:Device Types / Crypto Device / Virtqueues}
> +
> +\begin{description}
> +\item[0] dataq1
> +\item[\ldots]
> +\item[N-1] dataqN
> +\item[N] controlq
> +\end{description}
> +
> +N is set by \field{max_dataqueues}.
> +
> +\subsection{Feature bits}\label{sec:Device Types / Crypto Device / Feature bits}
> +
> +VIRTIO_CRYPTO_F_STATELESS_MODE (0) stateless mode is available.
> +VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE (1) stateless mode is available for CIPHER service.
> +VIRTIO_CRYPTO_F_HASH_STATELESS_MODE (2) stateless mode is available for HASH service.
> +VIRTIO_CRYPTO_F_MAC_STATELESS_MODE (3) stateless mode is available for MAC service.
> +VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE (4) stateless mode is available for AEAD service.
> +
> +\subsubsection{Feature bit requirements}\label{sec:Device Types / Crypto Device / Feature bits}
> +
> +Some crypto feature bits require other crypto feature bits
> +(see \ref{drivernormative:Basic Facilities of a Virtio Device / Feature Bits}):
> +
> +\begin{description}
> +\item[VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
> +\item[VIRTIO_CRYPTO_F_HASH_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
> +\item[VIRTIO_CRYPTO_F_MAC_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
> +\item[VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
> +\end{description}
> +
> +\subsection{Supported crypto services}\label{sec:Device Types / Crypto Device / Supported crypto services}
> +
> +The virtio crypto device provides the following crypto services: CIPHER, MAC, HASH, and AEAD.
> +
> +\begin{lstlisting}
> +/* CIPHER service */
> +#define VIRTIO_CRYPTO_SERVICE_CIPHER 0
> +/* HASH service */
> +#define VIRTIO_CRYPTO_SERVICE_HASH   1
> +/* MAC (Message Authentication Codes) service */
> +#define VIRTIO_CRYPTO_SERVICE_MAC    2
> +/* AEAD (Authenticated Encryption with Associated Data) service */
> +#define VIRTIO_CRYPTO_SERVICE_AEAD   3
> +\end{lstlisting}
> +
> +The above constants are bit numbers, which used to tell the driver which crypto services
> +are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
> +
> +\subsubsection{CIPHER services}\label{sec:Device Types / Crypto Device / Supported crypto services / CIPHER services}
> +
> +The following CIPHER algorithms are defined:
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_NO_CIPHER                 0
> +#define VIRTIO_CRYPTO_CIPHER_ARC4               1
> +#define VIRTIO_CRYPTO_CIPHER_AES_ECB            2
> +#define VIRTIO_CRYPTO_CIPHER_AES_CBC            3
> +#define VIRTIO_CRYPTO_CIPHER_AES_CTR            4
> +#define VIRTIO_CRYPTO_CIPHER_DES_ECB            5
> +#define VIRTIO_CRYPTO_CIPHER_DES_CBC            6
> +#define VIRTIO_CRYPTO_CIPHER_3DES_ECB           7
> +#define VIRTIO_CRYPTO_CIPHER_3DES_CBC           8
> +#define VIRTIO_CRYPTO_CIPHER_3DES_CTR           9
> +#define VIRTIO_CRYPTO_CIPHER_KASUMI_F8          10
> +#define VIRTIO_CRYPTO_CIPHER_SNOW3G_UEA2        11
> +#define VIRTIO_CRYPTO_CIPHER_AES_F8             12
> +#define VIRTIO_CRYPTO_CIPHER_AES_XTS            13
> +#define VIRTIO_CRYPTO_CIPHER_ZUC_EEA3           14
> +\end{lstlisting}
> +
> +The above constants have two usages:
> +\begin{enumerate}
> +\item As bit numbers, which used to tell the driver which CIPHER algorithms
> +are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
> +\item As values, which used to tell the device which CIPHER algorithm
> +a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
> +\end{enumerate}
> +
> +\subsubsection{HASH services}\label{sec:Device Types / Crypto Device / Supported crypto services / HASH services}
> +
> +The following HASH algorithms are defined:
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_NO_HASH            0
> +#define VIRTIO_CRYPTO_HASH_MD5           1
> +#define VIRTIO_CRYPTO_HASH_SHA1          2
> +#define VIRTIO_CRYPTO_HASH_SHA_224       3
> +#define VIRTIO_CRYPTO_HASH_SHA_256       4
> +#define VIRTIO_CRYPTO_HASH_SHA_384       5
> +#define VIRTIO_CRYPTO_HASH_SHA_512       6
> +#define VIRTIO_CRYPTO_HASH_SHA3_224      7
> +#define VIRTIO_CRYPTO_HASH_SHA3_256      8
> +#define VIRTIO_CRYPTO_HASH_SHA3_384      9
> +#define VIRTIO_CRYPTO_HASH_SHA3_512      10
> +#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE128      11
> +#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE256      12
> +\end{lstlisting}
> +
> +The above constants have two usages:
> +\begin{enumerate}
> +\item As bit numbers, which used to tell the driver which HASH algorithms
> +are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
> +\item As values, which used to tell the device which HASH algorithm
> +a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
> +\end{enumerate}
> +
> +\subsubsection{MAC services}\label{sec:Device Types / Crypto Device / Supported crypto services / MAC services}
> +
> +The following MAC algorithms are defined:
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_NO_MAC                       0
> +#define VIRTIO_CRYPTO_MAC_HMAC_MD5                 1
> +#define VIRTIO_CRYPTO_MAC_HMAC_SHA1                2
> +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_224             3
> +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_256             4
> +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_384             5
> +#define VIRTIO_CRYPTO_MAC_HMAC_SHA_512             6
> +#define VIRTIO_CRYPTO_MAC_CMAC_3DES                25
> +#define VIRTIO_CRYPTO_MAC_CMAC_AES                 26
> +#define VIRTIO_CRYPTO_MAC_KASUMI_F9                27
> +#define VIRTIO_CRYPTO_MAC_SNOW3G_UIA2              28
> +#define VIRTIO_CRYPTO_MAC_GMAC_AES                 41
> +#define VIRTIO_CRYPTO_MAC_GMAC_TWOFISH             42
> +#define VIRTIO_CRYPTO_MAC_CBCMAC_AES               49
> +#define VIRTIO_CRYPTO_MAC_CBCMAC_KASUMI_F9         50
> +#define VIRTIO_CRYPTO_MAC_XCBC_AES                 53
> +#define VIRTIO_CRYPTO_MAC_ZUC_EIA3                 54
> +\end{lstlisting}
> +
> +The above constants have two usages:
> +\begin{enumerate}
> +\item As bit numbers, which used to tell the driver which MAC algorithms
> +are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
> +\item As values, which used to tell the device which MAC algorithm
> +a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
> +\end{enumerate}
> +
> +\subsubsection{AEAD services}\label{sec:Device Types / Crypto Device / Supported crypto services / AEAD services}
> +
> +The following AEAD algorithms are defined:
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_NO_AEAD     0
> +#define VIRTIO_CRYPTO_AEAD_GCM    1
> +#define VIRTIO_CRYPTO_AEAD_CCM    2
> +#define VIRTIO_CRYPTO_AEAD_CHACHA20_POLY1305  3
> +\end{lstlisting}
> +
> +The above constants have two usages:
> +\begin{enumerate}
> +\item As bit numbers, which used to tell the driver which AEAD algorithms
> +are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
> +\item As values, which used to tell the device what AEAD algorithm
> +a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
> +\end{enumerate}
> +
> +\subsection{Device configuration layout}\label{sec:Device Types / Crypto Device / Device configuration layout}
> +
> +\begin{lstlisting}
> +struct virtio_crypto_config {
> +    le32 status;
> +    le32 max_dataqueues;
> +    le32 crypto_services;
> +    /* Detailed algorithms mask */
> +    le32 cipher_algo_l;
> +    le32 cipher_algo_h;
> +    le32 hash_algo;
> +    le32 mac_algo_l;
> +    le32 mac_algo_h;
> +    le32 aead_algo;
> +    /* Maximum length of cipher key in bytes */
> +    le32 max_cipher_key_len;
> +    /* Maximum length of authenticated key in bytes */
> +    le32 max_auth_key_len;
> +    le32 reserved;
> +    /* Maximum size of each crypto request's content in bytes */
> +    le64 max_size;
> +};
> +\end{lstlisting}
> +
> +\begin{description}
> +\item[\field{status}] is used to show whether the device is ready to work or not, it can be either zero or have one or more flags
> +    Only one read-only bit (for the driver) is currently defined for the \field{status} field: VIRTIO_CRYPTO_S_HW_READY:
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_S_HW_READY  (1 << 0)
> +\end{lstlisting}
> +
> +\item[\field{max_dataqueues}] is the maximum number of data virtqueues exposed by
> +    the device. The driver MAY use only one data queue,
> +    or it can use more to achieve better performance.
> +
> +\item[\field{crypto_services}] is a 32-bit mask which indicates the crypto services supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services}.
> +
> +\item[\field{cipher_algo_l}] is the low 32-bit mask wihich indicates the CIPHER algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / CIPHER services}.
> +
> +\item[\field{cipher_algo_h}] is the high 32-bit mask wihich indicates the CIPHER algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / CIPHER services}.
> +
> +\item[\field{hash_algo}] is a 32-bit mask wihich indicates the HASH algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / HASH services}.
> +
> +\item[\field{mac_algo_l}] is the low 32-bit mask wihich indicates the MAC algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / MAC services}.
> +
> +\item[\field{mac_algo_h}] is the high 32-bit mask wihich indicates the MAC algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / MAC services}.
> +
> +\item[\field{aead_algo}] is a 32-bit mask wihich indicates the AEAD algorithms supported by
> +    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / AEAD services}.
> +
> +\item[\field{max_cipher_key_len}] is the maximum length of cipher key supported by the device.
> +
> +\item[\field{max_auth_key_len}] is the maximum length of authenticated key supported by the device.
> +
> +\item[\field{reserved}] is reserved for future use.
> +
> +\item[\field{max_size}] is the maximum size of each crypto request's content supported by the device
> +\end{description}
> +
> +\begin{note}
> +Unless explicitly stated otherwise all lengths and sizes are in bytes.
> +\end{note}
> +
> +\devicenormative{\subsubsection}{Device configuration layout}{Device Types / Crypto Device / Device configuration layout}
> +
> +\begin{itemize*}
> +\item The device MUST set \field{max_dataqueues} to between 1 and 65535 inclusive.
> +\item The device MUST set \field{status} based on the status of the backend crypto accelerator. 
> +\item The device MUST accept and handle requests after \field{status} is set to VIRTIO_CRYPTO_S_HW_READY.
> +\item The device MUST set \field{crypto_services} based on the crypto services the device offers.
> +\item The device MUST set detailed algorithms masks based on the \field{crypto_services} field.
> +\item The device MUST set \field{max_size} to show the maximum size of crypto request the device supports.
> +\item The device MUST set \field{max_cipher_key_len} to show the maximum length of cipher key if the device supports CIPHER service.
> +\item The device MUST set \field{max_auth_key_len} to show the maximum length of authenticated key if the device supports MAC service.
> +\end{itemize*}
> +
> +\drivernormative{\subsubsection}{Device configuration layout}{Device Types / Crypto Device / Device configuration layout}
> +
> +\begin{itemize*}
> +\item The driver MUST read the ready \field{status} from the bottom bit of status to check whether the backend crypto accelerator
> +      is ready or not, and the driver MUST reread it after the device reset. 
> +\item The driver MUST NOT transmit any requests to the device if the ready \field{status} is not set.
> +\item The driver MUST read \field{max_dataqueues} field to discover the number of data queues the device supports.
> +\item The driver MUST read \field{crypto_services} field to discover which services the device is able to offer.
> +\item The driver MUST read the detailed algorithms fields based on \field{crypto_services} field.
> +\item The driver SHOULD read \field{max_size} to discover the maximum size of crypto request the device supports.
> +\item The driver SHOULD read \field{max_cipher_key_len} to discover the maximum length of cipher key the device supports.
> +\item The driver SHOULD read \field{max_auth_key_len} to discover the maximum length of authenticated key the device supports.
> +\end{itemize*}
> +
> +\subsection{Device Initialization}\label{sec:Device Types / Crypto Device / Device Initialization}
> +
> +\drivernormative{\subsubsection}{Device Initialization}{Device Types / Crypto Device / Device Initialization}
> +
> +\begin{itemize*}
> +\item The driver MUST identify and initialize all virtqueues.
> +\item The driver MUST read the supported crypto services from bits of \field{crypto_services}. 
> +\item The driver MUST read the supported algorithms based on \field{crypto_services} field.
> +\end{itemize*}
> +
> +\subsection{Device Operation}\label{sec:Device Types / Crypto Device / Device Operation}
> +
> +Requests can be transmitted by placing them in both the controlq and dataq.
> +Requests consist of a queue-type specific header specifying among
> +others the operation, and an operation specific payload.
> +Where the payload are composed of operation parameter + output data + input data in general.
> +Operation parameters are algorithm-specific parameters, output data is the
> +data that should be utilized in operations, and input data is equal to
> +"operation result + result data".
> +
> +The device can support both session mode (See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}) and stateless mode.
> +As VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is negotiated, the driver can use stateless mode for CIPHER service, otherwise it can only use session mode.
> +
> +The header for controlq is as follows:
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_OPCODE(service, op)   (((service) << 8) | (op))
> +
> +struct virtio_crypto_ctrl_header {
> +#define VIRTIO_CRYPTO_CIPHER_CREATE_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x02)
> +#define VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x03)
> +#define VIRTIO_CRYPTO_HASH_CREATE_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x02)
> +#define VIRTIO_CRYPTO_HASH_DESTROY_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x03)
> +#define VIRTIO_CRYPTO_MAC_CREATE_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x02)
> +#define VIRTIO_CRYPTO_MAC_DESTROY_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x03)
> +#define VIRTIO_CRYPTO_AEAD_CREATE_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x02)
> +#define VIRTIO_CRYPTO_AEAD_DESTROY_SESSION \
> +       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x03)
> +    le32 opcode;
> +    /* algo should be service-specific algorithms */
> +    le32 algo;
> +    le32 flag;
> +    /* data virtqueue id */
> +    le32 queue_id;
> +};
> +\end{lstlisting}
> +
> +The header of dataq is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_op_header {
> +#define VIRTIO_CRYPTO_CIPHER_ENCRYPT \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x00)
> +#define VIRTIO_CRYPTO_CIPHER_DECRYPT \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x01)
> +#define VIRTIO_CRYPTO_HASH \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x00)
> +#define VIRTIO_CRYPTO_MAC \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x00)
> +#define VIRTIO_CRYPTO_AEAD_ENCRYPT \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x00)
> +#define VIRTIO_CRYPTO_AEAD_DECRYPT \
> +    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x01)
> +    le32 opcode;
> +    /* algo should be service-specific algorithms */
> +    le32 algo;
> +    /* session_id should be service-specific algorithms */
> +    le64 session_id;VIRTIO_CRYPTO_F_STATELESS_MODE
> +#define VIRTIO_CRYPTO_FLAG_STATE_MODE 1
> +#define VIRTIO_CRYPTO_FLAG_STATELESS_MODE 2
> +    /* control flag to control the request */
> +    le32 flag;
> +    le32 padding;
> +};
> +\end{lstlisting}
> +
> +The device can set the operation status as follows: VIRTIO_CRYPTO_OK: success;
> +VIRTIO_CRYPTO_ERR: failure or device error; VIRTIO_CRYPTO_NOTSUPP: not supported;
> +VIRTIO_CRYPTO_INVSESS: invalid session ID when executing crypto operations.
> +
> +\begin{lstlisting}
> +enum VIRITO_CRYPTO_STATUS {

s/VIRITO/VIRTIO/

> +    VIRTIO_CRYPTO_OK = 0,
> +    VIRTIO_CRYPTO_ERR = 1,
> +    VIRTIO_CRYPTO_BADMSG = 2,
> +    VIRTIO_CRYPTO_NOTSUPP = 3,
> +    VIRTIO_CRYPTO_INVSESS = 4,
> +    VIRTIO_CRYPTO_MAX
> +};
> +\end{lstlisting}
> +
> +\subsubsection{Control Virtqueue}\label{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue}
> +
> +The driver uses the control virtqueue to send control commands to the
> +device, such as session operations (See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}).
> +
> +The request of controlq is as below:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_op_ctrl_req {
> +    struct virtio_crypto_ctrl_header header;
> +
> +    union {
> +        struct virtio_crypto_sym_create_session_req   sym_create_session;
> +        struct virtio_crypto_hash_create_session_req  hash_create_session;
> +        struct virtio_crypto_mac_create_session_req   mac_create_session;
> +        struct virtio_crypto_aead_create_session_req  aead_create_session;
> +        struct virtio_crypto_destroy_session_req      destroy_session;
> +    } u;
> +};
> +\end{lstlisting}
> +
> +struct virtio_crypto_op_ctrl_req is the only loading form of controlq requests.

Does "loading" mean "allowed"?

"struct virtio_crypto_op_ctrl_req is the only allowed control request"

> +The header is the general header, and the union is of the algorithm-specific type,
> +which is set by the driver. All the properties in the union are shown as follows.
> +
> +\paragraph{Session operation}\label{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}
> +
> +The symmetric algorithms involve the concept of sessions. A session is a
> +handle which describes the cryptographic parameters to be applied to
> +a number of buffers. The data within a session handle includes:
> +
> +\begin{enumerate}
> +\item The operation (CIPHER, HASH/MAC or both, and if both, the order in
> +      which the algorithms should be applied).
> +\item The CIPHER set data, including the CIPHER algorithm and mode,
> +      the key and its length, and the direction (encryption or decryption).
> +\item The HASH/MAC set data, including the HASH algorithm or MAC algorithm,
> +      and hash result length (to allow for truncation).
> +\begin{itemize*}
> +\item Authenticated mode can refer to MAC, which requires that the key and
> +      its length are also specified.
> +\item For nested mode, the inner and outer prefix data and length are specified,
> +      as well as the outer HASH algorithm.
> +\end{itemize*}
> +\end{enumerate}
> +
> +The following structure stores the result of session creation set by the device:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_session_input {
> +    /* Device-writable part */
> +    le64 session_id;
> +    le32 status;
> +    le32 padding;
> +};
> +\end{lstlisting}
> +
> +A request to destroy a session includes the following information:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_destroy_session_req {
> +    /* Device-readable part */
> +    le64  session_id;
> +    /* Device-writable part */
> +    le32  status;
> +    le32  padding;
> +};
> +\end{lstlisting}
> +
> +\subparagraph{Session operation: HASH session}\label{sec:Device Types / Crypto Device / Device
> +Operation / Control Virtqueue / Session operation / Session operation: HASH session}
> +
> +The request of HASH session is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_hash_session_para {
> +    /* See VIRTIO_CRYPTO_HASH_* above */
> +    le32 algo;
> +    /* hash result length */
> +    le32 hash_result_len;
> +};
> +struct virtio_crypto_hash_create_session_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_hash_session_para para;
> +    /* Device-writable part */
> +    struct virtio_crypto_session_input input;
> +};
> +\end{lstlisting}
> +
> +\subparagraph{Session operation: MAC session}\label{sec:Device Types / Crypto Device / Device
> +Operation / Control Virtqueue / Session operation / Session operation: MAC session}
> +
> +The request of MAC session is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_mac_session_para {
> +    /* See VIRTIO_CRYPTO_MAC_* above */
> +    le32 algo;
> +    /* hash result length */
> +    le32 hash_result_len;
> +    /* length of authenticated key */
> +    le32 auth_key_len;
> +    le32 padding;
> +};
> +
> +struct virtio_crypto_mac_create_session_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_mac_session_para para;
> +    /* The authenticated key */
> +    u8 auth_key[auth_key_len];
> +
> +    /* Device-writable part */
> +    struct virtio_crypto_session_input input;
> +};
> +\end{lstlisting}
> +
> +\subparagraph{Session operation: Symmetric algorithms session}\label{sec:Device Types / Crypto Device / Device
> +Operation / Control Virtqueue / Session operation / Session operation: Symmetric algorithms session}
> +
> +The request of symmetric session includes two parts, CIPHER algorithms and chain
> +algorithms (chaining CIPHER and HASH/MAC). The request for CIPHER session is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_cipher_session_para {
> +    /* See VIRTIO_CRYPTO_CIPHER* above */
> +    le32 algo;
> +    /* length of key */
> +    le32 keylen;
> +#define VIRTIO_CRYPTO_OP_ENCRYPT  1
> +#define VIRTIO_CRYPTO_OP_DECRYPT  2
> +    /* encryption or decryption */
> +    le32 op;
> +    le32 padding;
> +};
> +
> +struct virtio_crypto_cipher_session_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_cipher_session_para para;
> +    /* The cipher key */
> +    u8 cipher_key[keylen];
> +
> +    /* Device-writable part */
> +    struct virtio_crypto_session_input input;
> +};
> +\end{lstlisting}
> +
> +The request for algorithm chaining is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_alg_chain_session_para {
> +#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER  1
> +#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH  2
> +    le32 alg_chain_order;
> +/* Plain hash */
> +#define VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN    1
> +/* Authenticated hash (mac) */
> +#define VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH     2
> +/* Nested hash */
> +#define VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED   3
> +    le32 hash_mode;
> +    struct virtio_crypto_cipher_session_para cipher_param;
> +    union {
> +        struct virtio_crypto_hash_session_para hash_param;
> +        struct virtio_crypto_mac_session_para mac_param;
> +    } u;
> +    /* length of the additional authenticated data (AAD) in bytes */
> +    le32 aad_len;
> +    le32 padding;
> +};
> +
> +struct virtio_crypto_alg_chain_session_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_alg_chain_session_para para;
> +    /* The cipher key */
> +    u8 cipher_key[keylen];
> +    /* The authenticated key */
> +    u8 auth_key[auth_key_len];
> +
> +    /* Device-writable part */
> +    struct virtio_crypto_session_input input;
> +};
> +\end{lstlisting}
> +
> +The request for symmetric algorithm is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_sym_create_session_req {
> +    union {
> +        struct virtio_crypto_cipher_session_req cipher;
> +        struct virtio_crypto_alg_chain_session_req chain;
> +    } u;
> +
> +    /* Device-readable part */
> +
> +/* No operation */
> +#define VIRTIO_CRYPTO_SYM_OP_NONE  0

This operation is not defined by the spec.  QEMU returns
VIRTIO_CRYPTO_NOTSUPP.

The spec should cover the behavior of every constant.  Otherwise there
is a risk that implementations of the spec will differ.

> +/* Cipher only operation on the data */
> +#define VIRTIO_CRYPTO_SYM_OP_CIPHER  1
> +/* Chain any cipher with any hash or mac operation. The order
> +   depends on the value of alg_chain_order param */
> +#define VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING  2
> +    le32 op_type;
> +    le32 padding;
> +};
> +\end{lstlisting}
> +
> +\subparagraph{Session operation: AEAD session}\label{sec:Device Types / Crypto Device / Device
> +Operation / Control Virtqueue / Session operation / Session operation: AEAD session}
> +
> +The request for AEAD session is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_aead_session_para {
> +    /* See VIRTIO_CRYPTO_AEAD_* above */
> +    le32 algo;
> +    /* length of key */
> +    le32 key_len;
> +    /* Authentication tag length */
> +    le32 tag_len;
> +    /* The length of the additional authenticated data (AAD) in bytes */
> +    le32 aad_len;
> +    /* encryption or decryption, See above VIRTIO_CRYPTO_OP_* */
> +    le32 op;
> +    le32 padding;
> +};
> +
> +struct virtio_crypto_aead_create_session_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_aead_session_para para;
> +    u8 key[key_len];
> +
> +    /* Device-writeable part */
> +    struct virtio_crypto_session_input input;
> +};
> +\end{lstlisting}
> +
> +\drivernormative{\subparagraph}{Session operation: create session}{Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation / Session operation: create session}
> +
> +\begin{itemize*}
> +\item The driver MUST set the control general header and corresponding properties of the union in structure virtio_crypto_op_ctrl_req. See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue}.
> +\item The driver MUST set \field{opcode} field based on service type: CIPHER, HASH, MAC, or AEAD.

Missing definite article:

"MUST set the \field{opcode} field"

> +\item The driver MUST set \field{queue_id} field to show used dataq.

More missing definite articles:

"MUST set the \field{queue_id} field"

(This applies to all "MUST set \field{X} field" below too)

"to identify the dataq"

> +\end{itemize*}
> +
> +\devicenormative{\subparagraph}{Session operation: create session}{Device Types / Crypto Device / Device
> +Operation / Control Virtqueue / Session operation / Session operation: create session}
> +
> +\begin{itemize*}
> +\item The device MUST set \field{session_id} field as a session identifier return to the driver when the device finishes processing session creation.

The phrase is "set X to Y" instead of "set X as Y":

s/as a session identifier return to the driver/to a unique session
identifier/

I dropped the "return to the driver" concept since it should be clear
from the context that the device is filling out fields that the driver
reads.

> +\item The device MUST set \field{status} field to one of the values of enum VIRITO_CRYPTO_STATUS.

VIRTIO typo.

> +\end{itemize*}
> +
> +\drivernormative{\subparagraph}{Session operation: destroy session}{Device Types / Crypto Device / Device
> +Operation / Control Virtqueue / Session operation / Session operation: destroy session}
> +
> +\begin{itemize*}
> +\item The driver MUST set \field{opcode} field based on service type: CIPHER, HASH, MAC, or AEAD.
> +\item The driver MUST set the \field{session_id} to a valid value which assigned by the device when a session is created.

An explanation is beyond my grammar knowledge :) but the following
sounds correct:

"to a valid value assigned by the device when the session was created"

> +\end{itemize*}
> +
> +\devicenormative{\subparagraph}{Session operation: destroy session}{Device Types / Crypto Device / Device
> +Operation / Control Virtqueue / Session operation / Session operation: destroy session}
> +
> +\begin{itemize*}
> +\item The device MUST set \field{status} field to one of the values of enum VIRITO_CRYPTO_STATUS.

VIRTIO typo.

> +\end{itemize*}
> +
> +\subsubsection{Data Virtqueue}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue}
> +
> +The driver uses the data virtqueue to transmit the requests of crypto operation to the device,

s/transmit the requests of crypto operation/to transmit crypto operation requests/

> +and completes the data plane operations (such as crypto operation).

"data plane operations" is plural so "such as crypto operation" must
also be plural:

"such as crypto operations"

> +
> +The session mode request of dataq is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_op_data_req {
> +    struct virtio_crypto_op_header header;
> +
> +    union {
> +        struct virtio_crypto_sym_data_req   sym_req;
> +        struct virtio_crypto_hash_data_req  hash_req;
> +        struct virtio_crypto_mac_data_req   mac_req;
> +        struct virtio_crypto_aead_data_req  aead_req;
> +    } u;
> +};
> +\end{lstlisting}
> +
> +The request of dataq, mixing both session and stateless mode is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_op_data_req_mux {
> +    struct virtio_crypto_op_header header;
> +
> +    union {
> +        struct virtio_crypto_sym_data_req   sym_req;
> +        struct virtio_crypto_hash_data_req  hash_req;
> +        struct virtio_crypto_mac_data_req   mac_req;
> +        struct virtio_crypto_aead_data_req  aead_req;
> +        struct virtio_crypto_sym_data_req_stateless   sym_stateless_req;
> +        struct virtio_crypto_hash_data_req_stateless  hash_stateless_req;
> +        struct virtio_crypto_mac_data_req_stateless   mac_stateless_req;
> +        struct virtio_crypto_aead_data_req_stateless  aead_stateless_req;
> +    } u;
> +};
> +\end{lstlisting}
> +
> +The header is the general header and the union is of the algorithm-specific type,
> +which is set by the driver. All properties in the union are shown as follows.
> +
> +There is a unified input header structure for all crypto services.
> +
> +The structure is defined as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_inhdr {
> +    u8 status;
> +};
> +\end{lstlisting}
> +
> +\subsubsection{HASH Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / HASH Service Operation}
> +
> +The session mode request of HASH service:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_hash_para {
> +    /* length of source data */
> +    le32 src_data_len;
> +    /* hash result length */
> +    le32 hash_result_len;
> +};
> +
> +struct virtio_crypto_hash_data_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_hash_para para;
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +
> +    /* Device-writable part */
> +    /* Hash result data */
> +    u8 hash_result[hash_result_len];
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +Each data request uses virtio_crypto_hash_data_req structure to store information
> +used to run the HASH operations. 
> +
> +The information includes the hash parameters stored by \field{para}, output data and input data.
> +The output data here includes the source data and the input data includes the hash result data used to save the results of the HASH operations.
> +\field{inhdr} stores status of executing the HASH operations.
> +
> +The stateless mode request of HASH service is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_hash_para_statelesss {
> +    struct {
> +        /* See VIRTIO_CRYPTO_HASH_* above */
> +        le32 algo;
> +    } sess_para;
> +
> +    /* length of source data */
> +    le32 src_data_len;
> +    /* hash result length */
> +    le32 hash_result_len;
> +    le32 reserved;
> +};
> +struct virtio_crypto_hash_data_req_stateless {
> +    /* Device-readable part */
> +    struct virtio_crypto_hash_para_stateless para;
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +
> +    /* Device-writable part */
> +    /* Hash result data */
> +    u8 hash_result[hash_result_len];
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +\drivernormative{\paragraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / HASH Service Operation}
> +
> +\begin{itemize*}
> +\item If the driver uses the session mode, then the driver MUST set the \field{session_id} in struct virtio_crypto_op_header
> +      to a valid value which assigned by the device when a session is created.
> +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto requests. Otherwise, the driver MUST use the struct virtio_crypto_op_data_req.
> +\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is negotiated, 1) if the driver use the stateless mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header
> +      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in struct virtio_crypto_hash_para_statelession.sess_para, 2) if the driver still uses the session mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
> +\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_HASH.
> +\end{itemize*}
> +
> +\devicenormative{\paragraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / HASH Service Operation}
> +
> +\begin{itemize*}
> +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto requests. Otherwise, the device MUST parse the struct virtio_crypto_op_data_req.
> +\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is negotiated, the device MUST parse \field{flag} field in struct virtio_crypto_op_header in order to decide which mode the driver uses.
> +\item The device MUST copy the results of HASH operations to the hash_result[] if HASH operations success.
> +\item The device MUST set \field{status} in struct virtio_crypto_inhdr to one of the values of enum VIRITO_CRYPTO_STATUS.

VIRTIO typo.

> +\end{itemize*}
> +
> +\subsubsection{MAC Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / MAC Service Operation}
> +
> +The session mode request of MAC service is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_mac_para {
> +    struct virtio_crypto_hash_para hash;
> +};
> +
> +struct virtio_crypto_mac_data_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_mac_para para;
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +
> +    /* Device-writable part */
> +    /* Hash result data */
> +    u8 hash_result[hash_result_len];
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +Each data request uses virtio_crypto_mac_data_req structure to store information
> +used to run the MAC operations. 
> +
> +The information includes the hash parameters stored by \field{para}, output data and input data.
> +The output data here includes the source data and the input data includes the hash result data used to save the results of the MAC operations.
> +\field{inhdr} stores status of executing the MAC operations.
> +
> +The stateless mode request of MAC service:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_mac_para_stateless {
> +    struct {
> +        /* See VIRTIO_CRYPTO_MAC_* above */
> +        le32 algo;
> +        /* length of authenticated key */
> +        le32 auth_key_len;
> +    } sess_para;
> +
> +    /* length of source data */
> +    le32 src_data_len;
> +    /* hash result length */
> +    le32 hash_result_len;
> +};
> +
> +struct virtio_crypto_mac_data_req_stateless {
> +    /* Device-readable part */
> +    struct virtio_crypto_mac_para_stateless para;
> +    /* The authenticated key */
> +    u8 auth_key[auth_key_len];
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +
> +    /* Device-writable part */
> +    /* Hash result data */
> +    u8 hash_result[hash_result_len];
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +\drivernormative{\paragraph}{MAC Service Operation}{Device Types / Crypto Device / Device Operation / MAC Service Operation}
> +
> +\begin{itemize*}
> +\item If the driver uses the session mode, then the driver MUST set the \field{session_id} in struct virtio_crypto_op_header
> +      to a valid value which assigned by the device when a session is created.
> +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto requests. Otherwise, the driver MUST use the struct virtio_crypto_op_data_req.
> +\item If the VIRTIO_CRYPTO_F_MAC_STATELESS_MODE feature bit is negotiated, 1) if the driver use the stateless mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header
> +      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in struct virtio_crypto_mac_para_statelession.sess_para, 2) if the driver still uses the session mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
> +\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_MAC.
> +\end{itemize*}
> +
> +\devicenormative{\paragraph}{MAC Service Operation}{Device Types / Crypto Device / Device Operation / MAC Service Operation}
> +
> +\begin{itemize*}
> +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto requests. Otherwise, the device MUST parse the struct virtio_crypto_op_data_req.
> +\item If the VIRTIO_CRYPTO_F_MAC_STATELESS_MODE feature bit is negotiated, the device MUST parse \field{flag} field in struct virtio_crypto_op_header in order to decide which mode the driver uses.
> +\item The device MUST copy the results of MAC operations to the hash_result[] if HASH operations success.
> +\item The device MUST set \field{status} in struct virtio_crypto_inhdr to one of the values of enum VIRITO_CRYPTO_STATUS.

VIRTIO typo.

> +\end{itemize*}
> +
> +\subsubsection{Symmetric algorithms Operation}\label{sec:Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation}
> +
> +The session mode request of plain CIPHER service is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_cipher_para {
> +    /*
> +     * Byte Length of valid IV/Counter data pointed to by the below iv data.
> +     *
> +     * For block ciphers in CBC or F8 mode, or for Kasumi in F8 mode, or for
> +     *   SNOW3G in UEA2 mode, this is the length of the IV (which
> +     *   must be the same as the block length of the cipher).
> +     * For block ciphers in CTR mode, this is the length of the counter
> +     *   (which must be the same as the block length of the cipher).
> +     */
> +    le32 iv_len;
> +    /* length of source data */
> +    le32 src_data_len;
> +    /* length of destination data */
> +    le32 dst_data_len;
> +    le32 padding;
> +};
> +
> +struct virtio_crypto_cipher_data_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_cipher_para para;
> +    /*
> +     * Initialization Vector or Counter data.
> +     *
> +     * For block ciphers in CBC or F8 mode, or for Kasumi in F8 mode, or for
> +     *   SNOW3G in UEA2 mode, this is the Initialization Vector (IV)
> +     *   value.
> +     * For block ciphers in CTR mode, this is the counter.
> +     * For AES-XTS, this is the 128bit tweak, i, from IEEE Std 1619-2007.
> +     *
> +     * The IV/Counter will be updated after every partial cryptographic
> +     * operation.
> +     */
> +    u8 iv[iv_len];
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +
> +    /* Device-writable part */
> +    /* Destination data */
> +    u8 dst_data[dst_data_len];
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +The session mode request of algorithm chaining is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_alg_chain_data_para {
> +    le32 iv_len;
> +    /* Length of source data */
> +    le32 src_data_len;
> +    /* Length of destination data */
> +    le32 dst_data_len;
> +    /* Starting point for cipher processing in source data */
> +    le32 cipher_start_src_offset;
> +    /* Length of the source data that the cipher will be computed on */
> +    le32 len_to_cipher;
> +    /* Starting point for hash processing in source data */
> +    le32 hash_start_src_offset;
> +    /* Length of the source data that the hash will be computed on */
> +    le32 len_to_hash;
> +    /* Length of the additional auth data */
> +    le32 aad_len;
> +    /* Length of the hash result */
> +    le32 hash_result_len;
> +    le32 reserved;
> +};
> +
> +struct virtio_crypto_alg_chain_data_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_alg_chain_data_para para;
> +    /* Initialization Vector or Counter data */
> +    u8 iv[iv_len];
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +    /* Additional authenticated data if exists  */
> +    u8 aad[aad_len];
> +
> +    /* Device-writable part */
> +    /* Destination data */
> +    u8 dst_data[dst_data_len];
> +    /* Hash result data */
> +    u8 hash_result[hash_result_len];
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +The session mode request of symmetric algorithm is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_sym_data_req {
> +    union {
> +        struct virtio_crypto_cipher_data_req cipher;
> +        struct virtio_crypto_alg_chain_data_req chain;
> +    } u;
> +
> +    /* Device-readable part */
> +
> +    /* See above VIRTIO_CRYPTO_SYM_OP_* */
> +    le32 op_type;
> +    le32 padding;
> +};
> +\end{lstlisting}
> +
> +Each data request uses virtio_crypto_sym_data_req structure to store information
> +used to run the CIPHER operations. 
> +
> +The information includes the cipher parameters stored by \field{para}, output data and input data.
> +In the first virtio_crypto_cipher_para structure, \field{iv_len} specifies the length of the initialization vector or counter,
> +\field{src_data_len} specifies the length of the source data, and \field{dst_data_len} specifies the
> +length of the destination data. 
> +For plain CIPHER operations, the output data here includes the IV/Counter data and source data, and the input data includes the destination data used to save the results of the CIPHER operations. 
> +
> +For algorithms chain, the output data here includes the IV/Counter data, source data and additional authenticated data if exists.
> +The input data includes both destination data and hash result data used to store the results of the HASH/MAC operations.
> +\field{inhdr} stores status of executing the crypto operations.
> +
> +The stateless mode request of plain CIPHER service is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_cipher_para_stateless {
> +    struct {
> +        /* See VIRTIO_CRYPTO_CIPHER* above */
> +        le32 algo;
> +        /* length of key */
> +        le32 keylen;
> +
> +        /* See VIRTIO_CRYPTO_OP_* above */
> +        le32 op;
> +    } sess_para;
> +
> +    /*
> +     * Byte Length of valid IV/Counter data pointed to by the below iv data.
> +     */
> +    le32 iv_len;
> +    /* length of source data */
> +    le32 src_data_len;
> +    /* length of destination data */
> +    le32 dst_data_len;
> +};
> +
> +struct virtio_crypto_cipher_data_req_stateless {
> +    /* Device-readable part */
> +    struct virtio_crypto_cipher_para_stateless para;
> +    /* The cipher key */
> +    u8 cipher_key[keylen];
> +
> +    /* Initialization Vector or Counter data. */
> +    u8 iv[iv_len];
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +
> +    /* Device-writable part */
> +    /* Destination data */
> +    u8 dst_data[dst_data_len];
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +The stateless mode request of algorithm chaining is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_alg_chain_data_para_stateless {
> +    struct {
> +        /* See VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_* above */
> +        le32 alg_chain_order;
> +        /* length of the additional authenticated data in bytes */
> +        le32 aad_len;
> +
> +        struct {
> +            /* See VIRTIO_CRYPTO_CIPHER* above */
> +            le32 algo;
> +            /* length of key */
> +            le32 keylen;
> +            /* See VIRTIO_CRYPTO_OP_* above */
> +            le32 op;
> +        } cipher;
> +
> +        struct {
> +            /* See VIRTIO_CRYPTO_HASH_* or VIRTIO_CRYPTO_MAC_* above */
> +            le32 algo;
> +            /* length of authenticated key */
> +            le32 auth_key_len;
> +            /* See VIRTIO_CRYPTO_SYM_HASH_MODE_* above */
> +            le32 hash_mode;
> +        } hash;
> +    } sess_para;
> +
> +    le32 iv_len;
> +    /* Length of source data */
> +    le32 src_data_len;
> +    /* Length of destination data */
> +    le32 dst_data_len;
> +    /* Starting point for cipher processing in source data */
> +    le32 cipher_start_src_offset;
> +    /* Length of the source data that the cipher will be computed on */
> +    le32 len_to_cipher;
> +    /* Starting point for hash processing in source data */
> +    le32 hash_start_src_offset;
> +    /* Length of the source data that the hash will be computed on */
> +    le32 len_to_hash;
> +    /* Length of the additional auth data */
> +    le32 aad_len;
> +    /* Length of the hash result */
> +    le32 hash_result_len;
> +    le32 reserved;
> +};
> +
> +struct virtio_crypto_alg_chain_data_req_stateless {
> +    /* Device-readable part */
> +    struct virtio_crypto_alg_chain_data_para_stateless para;
> +    /* The cipher key */
> +    u8 cipher_key[keylen];
> +    /* The auth key */
> +    u8 auth_key[auth_key_len];
> +    /* Initialization Vector or Counter data */
> +    u8 iv[iv_len];
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +    /* Additional authenticated data if exists  */
> +    u8 aad[aad_len];
> +
> +    /* Device-writable part */
> +    /* Destination data */
> +    u8 dst_data[dst_data_len];
> +    /* Hash result data */
> +    u8 hash_result[hash_result_len];
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +The stateless mode request of symmetric algorithm is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_sym_data_req_stateless {
> +    union {
> +        struct virtio_crypto_cipher_data_req_stateless cipher;
> +        struct virtio_crypto_alg_chain_data_req_stateless chain;
> +    } u;
> +
> +    /* Device-readable part */
> +
> +    /* See above VIRTIO_CRYPTO_SYM_OP_* */
> +    le32 op_type;
> +    le32 padding;
> +};
> +\end{lstlisting}
> +
> +\drivernormative{\paragraph}{Symmetric algorithms Operation}{Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation}
> +
> +\begin{itemize*}
> +\item If the driver uses the session mode, then the driver MUST set the \field{session_id} in struct virtio_crypto_op_header
> +      to a valid value which assigned by the device when a session is created.
> +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto requests. Otherwise, the driver MUST use the struct virtio_crypto_op_data_req.
> +\item If the VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is negotiated, 1) if the driver use the stateless mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header
> +      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in struct virtio_crypto_cipher_para_statelession.sess_para or struct virtio_crypto_alg_chain_data_para_stateless.sess_para, 2) if the driver still uses the session mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
> +\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_CIPHER_ENCRYPT or VIRTIO_CRYPTO_CIPHER_DECRYPT.
> +\item The driver MUST specify the fields of struct virtio_crypto_cipher_data_req in struct virtio_crypto_sym_data_req if the request is based on VIRTIO_CRYPTO_SYM_OP_CIPHER.
> +\item The driver MUST specify the fields of both struct virtio_crypto_cipher_data_req and struct virtio_crypto_mac_data_req in struct virtio_crypto_sym_data_req if the request
> +      is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING type and in the VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode.
> +\end{itemize*}
> +
> +\devicenormative{\paragraph}{Symmetric algorithms Operation}{Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation}
> +
> +\begin{itemize*}
> +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto requests. Otherwise, the device MUST parse the struct virtio_crypto_op_data_req.
> +\item If the VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is negotiated, the device MUST parse \field{flag} field in struct virtio_crypto_op_header in order to decide which mode the driver uses.
> +\item The device MUST parse the virtio_crypto_sym_data_req based on the \field{opcode} in general header.
> +\item The device SHOULD only parse fields of struct virtio_crypto_cipher_data_req in struct virtio_crypto_sym_data_req if the request is VIRTIO_CRYPTO_SYM_OP_CIPHER type.
> +\item The device MUST parse fields of both struct virtio_crypto_cipher_data_req and struct virtio_crypto_mac_data_req in struct virtio_crypto_sym_data_req if the request
> +      is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING operation type and in the VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode.
> +\item The device MUST copy the result of cryptographic operation to the dst_data[] in both plain CIPHER mode and algorithms chain mode.
> +\item The device MUST check the \field{para}.\field{add_len} is bigger than 0 before parse the additional authenticated data in plain algorithms chain mode.
> +\item The device MUST copy the result of HASH/MAC operation to the hash_result[] is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING type.
> +\item The device MUST set the \field{status} field in struct virtio_crypto_inhdr to one of the values of enum VIRITO_CRYPTO_STATUS.

VIRTIO typo

> +\end{itemize*}
> +
> +\paragraph{Steps of Operation}\label{sec:Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation / Steps of Operation}
> +
> +\subparagraph{Step1: Create session}\label{sec:Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation / Steps of Operation / Step1: Create session on session mode}
> +
> +\begin{enumerate}
> +\item The driver specifies information in struct virtio_crypto_op_ctrl_req, including the algorithm name, key, keylen etc;
> +\item The driver adds the request of session creation into the controlq's Vring Descriptor Table;
> +\item The driver kicks the device;
> +\item The device receives the request from controlq;
> +\item The device parses information about the request, and determines the information concerning the backend crypto accelerator;
> +\item The device packs information based on the APIs of the backend crypto accelerator;
> +\item The device invokes the session creation APIs of the backend crypto accelerator to create a session;
> +\item The device returns the session id to the driver.
> +\end{enumerate}
> +
> +\subparagraph{Step2: Execute cryptographic operation}\label{sec:Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation / Steps of Operation / Step2: Execute cryptographic operation}
> +
> +\begin{enumerate}
> +\item The driver specifies information in struct virtio_crypto_op_data_req, including struct virtio_crypto_op_header and struct virtio_crypto_sym_data_req, see \ref{sec:Device Types / Crypto Device / Device
> +      Operation / Symmetric algorithms Operation};
> +\item The driver adds the request for cryptographic operation into the dataq's Vring Descriptor Table;
> +\item The driver kicks the device (Or the device actively polls the dataq's Vring Descriptor Table);
> +\item The device receives the request from dataq;
> +\item The device parses information about the request, and determines the identification information for the backend crypto accelerator. For example, converting guest physical addresses to host physical addresses;
> +\item The device packs identification information based on the API of the backend crypto accelerator;
> +\item The device invokes the cryptographic APIs of the backend crypto accelerator;
> +\item The backend crypto accelerator executes the cryptographic operation implicitly;
> +\item The device receives the cryptographic results from the backend crypto accelerator (synchronous or asynchronous);
> +\item The device sets the \field{status} in struct virtio_crypto_inhdr;
> +\item The device updates and flushes the Used Ring to return the cryptographic results to the driver;
> +\item The device notifies the driver (Or the driver actively polls the dataq's Used Ring);
> +\item The driver saves the cryptographic results.
> +\end{enumerate}
> +
> +\begin{note}
> +\begin{itemize*}
> +\item For better performance, the device should by preference use vhost scheme (user space or kernel space)
> +      as the backend crypto accelerator in the real production environment.
> +\end{itemize*}
> +\end{note}
> +
> +\subsubsection{AEAD Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / AEAD Service Operation}
> +
> +The session mode request of symmetric algorithm is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_aead_para {
> +    /*
> +     * Byte Length of valid IV data.
> +     *
> +     * For GCM mode, this is either 12 (for 96-bit IVs) or 16, in which
> +     *   case iv points to J0.
> +     * For CCM mode, this is the length of the nonce, which can be in the
> +     *   range 7 to 13 inclusive.
> +     */
> +    le32 iv_len;
> +    /* length of additional auth data */
> +    le32 aad_len;
> +    /* length of source data */
> +    le32 src_data_len;
> +    /* length of dst data, this should be at least src_data_len + tag_len */
> +    le32 dst_data_len;
> +    /* Authentication tag length */
> +    le32 tag_len;
> +    le32 reserved;
> +};
> +
> +struct virtio_crypto_aead_data_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_aead_para para;
> +    /*
> +     * Initialization Vector data.
> +     *
> +     * For GCM mode, this is either the IV (if the length is 96 bits) or J0
> +     *   (for other sizes), where J0 is as defined by NIST SP800-38D.
> +     *   Regardless of the IV length, a full 16 bytes needs to be allocated.
> +     * For CCM mode, the first byte is reserved, and the nonce should be
> +     *   written starting at &iv[1] (to allow space for the implementation
> +     *   to write in the flags in the first byte).  Note that a full 16 bytes
> +     *   should be allocated, even though the iv_len field will have
> +     *   a value less than this.
> +     *
> +     * The IV will be updated after every partial cryptographic operation.
> +     */
> +    u8 iv[iv_len];
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +    /* Additional authenticated data if exists  */
> +    u8 aad[aad_len];
> +
> +    /* Device-writable part */
> +    /* Pointer to output data */
> +    u8 dst_data[dst_data_len];
> +
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +Each data request uses virtio_crypto_aead_data_req structure to store information
> +used to run the AEAD operations. 
> +
> +The information includes the hash parameters stored by \field{para}, output data and input data.
> +In the first virtio_crypto_aead_para structure, \field{iv_len} specifies the length of the initialization vector. \field{tag_len} specifies the length of the authentication tag;
> +\field{aad_len} specifies the length of additional authentication data, \field{src_data_len} specifies the
> +length of the source data; \field{dst_data_len} specifies the length of the destination data, which is at least \field{src_data_len} + \field{tag_len}.
> +
> +The output data here includes the IV/Counter data, source data and additional authenticated data if exists.
> +The input data includes both destination data used to save the results of the AEAD operations.
> +\field{inhdr} stores status of executing the AEAD operations.
> +
> +The stateless mode request of AEAD service is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_aead_para_stateless {
> +    struct {
> +        /* See VIRTIO_CRYPTO_AEAD_* above */
> +        le32 algo;
> +        /* length of key */
> +        le32 key_len;
> +        /* encrypt or decrypt, See above VIRTIO_CRYPTO_OP_* */
> +        le32 op;
> +    } sess_para;
> +
> +    /* Byte Length of valid IV data. */
> +    le32 iv_len;
> +    /* Authentication tag length */
> +    le32 tag_len;
> +    /* length of additional auth data */
> +    le32 aad_len;
> +    /* length of source data */
> +    le32 src_data_len;
> +    /* length of dst data, this should be at least src_data_len + tag_len */
> +    le32 dst_data_len;
> +};
> +
> +struct virtio_crypto_aead_data_req_stateless {
> +    /* Device-readable part */
> +    struct virtio_crypto_aead_para_stateless para;
> +    /* The cipher key */
> +    u8 key[key_len];
> +    /* Initialization Vector data. */
> +    u8 iv[iv_len];
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +    /* Additional authenticated data if exists  */
> +    u8 aad[aad_len];
> +
> +    /* Device-writable part */
> +    /* Pointer to output data */
> +    u8 dst_data[dst_data_len];
> +
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +\drivernormative{\paragraph}{AEAD Service Operation}{Device Types / Crypto Device / Device Operation / AEAD Service Operation}
> +
> +\begin{itemize*}
> +\item If the driver uses the session mode, then the driver MUST set the \field{session_id} in struct virtio_crypto_op_header
> +      to a valid value which assigned by the device when a session is created.
> +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto requests. Otherwise, the driver MUST use the struct virtio_crypto_op_data_req.
> +\item If the VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE feature bit is negotiated, 1) if the driver use the stateless mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header
> +      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in struct virtio_crypto_aead_para_statelession.sess_para, 2) if the driver still uses the session mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
> +\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_AEAD_ENCRYPT or VIRTIO_CRYPTO_AEAD_DECRYPT.
> +\end{itemize*}
> +
> +\devicenormative{\paragraph}{AEAD Service Operation}{Device Types / Crypto Device / Device Operation / AEAD Service Operation}
> +
> +\begin{itemize*}
> +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto requests. Otherwise, the device MUST parse the struct virtio_crypto_op_data_req.
> +\item If the VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE feature bit is negotiated, the device MUST parse the virtio_crypto_aead_data_req based on the \field{opcode} in general header.
> +\item The device MUST copy the result of cryptographic operation to the dst_data[].
> +\item The device MUST copy the authentication tag to the dst_data[] offset the cipher result.
> +\item The device MUST set the \field{status} field in struct virtio_crypto_inhdr to one of the values of enum VIRITO_CRYPTO_STATUS.

VIRTIO typo

> +\item When the \field{opcode} is VIRTIO_CRYPTO_AEAD_DECRYPT, the device MUST verify and return the verification result to the driver, and if the verification result is incorrect, VIRTIO_CRYPTO_BADMSG (bad message) MUST be returned to the driver.
> +\end{itemize*}
> \ No newline at end of file
> -- 
> 1.7.12.4
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
> For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org
>
Gonglei (Arei) April 20, 2017, 1:11 p.m. UTC | #4
Hi Stefan,


>
> Subject: Re: [virtio-dev] [PATCH v17 1/2] virtio-crypto: Add virtio crypto device
> specification
> 
> On Thu, Apr 13, 2017 at 05:11:13PM +0800, Gonglei wrote:
> 
> More review, not done yet.
> 
Thanks a lot!

[snip]

> > +The device can set the operation status as follows: VIRTIO_CRYPTO_OK:
> success;
> > +VIRTIO_CRYPTO_ERR: failure or device error; VIRTIO_CRYPTO_NOTSUPP:
> not supported;
> > +VIRTIO_CRYPTO_INVSESS: invalid session ID when executing crypto
> operations.
> > +
> > +\begin{lstlisting}
> > +enum VIRITO_CRYPTO_STATUS {
> 
> s/VIRITO/VIRTIO/
> 
Oops, good catch. Fortunately I hadn't define this name in source code.
Will fix it in the next version.

> > +    VIRTIO_CRYPTO_OK = 0,
> > +    VIRTIO_CRYPTO_ERR = 1,
> > +    VIRTIO_CRYPTO_BADMSG = 2,
> > +    VIRTIO_CRYPTO_NOTSUPP = 3,
> > +    VIRTIO_CRYPTO_INVSESS = 4,
> > +    VIRTIO_CRYPTO_MAX
> > +};
> > +\end{lstlisting}
> > +
> > +\subsubsection{Control Virtqueue}\label{sec:Device Types / Crypto Device /
> Device Operation / Control Virtqueue}
> > +
> > +The driver uses the control virtqueue to send control commands to the
> > +device, such as session operations (See \ref{sec:Device Types / Crypto
> Device / Device Operation / Control Virtqueue / Session operation}).
> > +
> > +The request of controlq is as below:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_op_ctrl_req {
> > +    struct virtio_crypto_ctrl_header header;
> > +
> > +    union {
> > +        struct virtio_crypto_sym_create_session_req
> sym_create_session;
> > +        struct virtio_crypto_hash_create_session_req
> hash_create_session;
> > +        struct virtio_crypto_mac_create_session_req
> mac_create_session;
> > +        struct virtio_crypto_aead_create_session_req
> aead_create_session;
> > +        struct virtio_crypto_destroy_session_req      destroy_session;
> > +    } u;
> > +};
> > +\end{lstlisting}
> > +
> > +struct virtio_crypto_op_ctrl_req is the only loading form of controlq
> requests.
> 
> Does "loading" mean "allowed"?
> 
> "struct virtio_crypto_op_ctrl_req is the only allowed control request"
> 
Hmm.. It's better.

> > +The header is the general header, and the union is of the algorithm-specific
> type,
> > +which is set by the driver. All the properties in the union are shown as
> follows.
> > +
> > +\paragraph{Session operation}\label{sec:Device Types / Crypto Device /
> Device Operation / Control Virtqueue / Session operation}
> > +
> > +The symmetric algorithms involve the concept of sessions. A session is a
> > +handle which describes the cryptographic parameters to be applied to
> > +a number of buffers. The data within a session handle includes:
> > +
> > +\begin{enumerate}
> > +\item The operation (CIPHER, HASH/MAC or both, and if both, the order in
> > +      which the algorithms should be applied).
> > +\item The CIPHER set data, including the CIPHER algorithm and mode,
> > +      the key and its length, and the direction (encryption or decryption).
> > +\item The HASH/MAC set data, including the HASH algorithm or MAC
> algorithm,
> > +      and hash result length (to allow for truncation).
> > +\begin{itemize*}
> > +\item Authenticated mode can refer to MAC, which requires that the key
> and
> > +      its length are also specified.
> > +\item For nested mode, the inner and outer prefix data and length are
> specified,
> > +      as well as the outer HASH algorithm.
> > +\end{itemize*}
> > +\end{enumerate}
> > +
> > +The following structure stores the result of session creation set by the
> device:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_session_input {
> > +    /* Device-writable part */
> > +    le64 session_id;
> > +    le32 status;
> > +    le32 padding;
> > +};
> > +\end{lstlisting}
> > +
> > +A request to destroy a session includes the following information:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_destroy_session_req {
> > +    /* Device-readable part */
> > +    le64  session_id;
> > +    /* Device-writable part */
> > +    le32  status;
> > +    le32  padding;
> > +};
> > +\end{lstlisting}
> > +
> > +\subparagraph{Session operation: HASH session}\label{sec:Device Types /
> Crypto Device / Device
> > +Operation / Control Virtqueue / Session operation / Session operation: HASH
> session}
> > +
> > +The request of HASH session is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_hash_session_para {
> > +    /* See VIRTIO_CRYPTO_HASH_* above */
> > +    le32 algo;
> > +    /* hash result length */
> > +    le32 hash_result_len;
> > +};
> > +struct virtio_crypto_hash_create_session_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_hash_session_para para;
> > +    /* Device-writable part */
> > +    struct virtio_crypto_session_input input;
> > +};
> > +\end{lstlisting}
> > +
> > +\subparagraph{Session operation: MAC session}\label{sec:Device Types /
> Crypto Device / Device
> > +Operation / Control Virtqueue / Session operation / Session operation: MAC
> session}
> > +
> > +The request of MAC session is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_mac_session_para {
> > +    /* See VIRTIO_CRYPTO_MAC_* above */
> > +    le32 algo;
> > +    /* hash result length */
> > +    le32 hash_result_len;
> > +    /* length of authenticated key */
> > +    le32 auth_key_len;
> > +    le32 padding;
> > +};
> > +
> > +struct virtio_crypto_mac_create_session_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_mac_session_para para;
> > +    /* The authenticated key */
> > +    u8 auth_key[auth_key_len];
> > +
> > +    /* Device-writable part */
> > +    struct virtio_crypto_session_input input;
> > +};
> > +\end{lstlisting}
> > +
> > +\subparagraph{Session operation: Symmetric algorithms
> session}\label{sec:Device Types / Crypto Device / Device
> > +Operation / Control Virtqueue / Session operation / Session operation:
> Symmetric algorithms session}
> > +
> > +The request of symmetric session includes two parts, CIPHER algorithms
> and chain
> > +algorithms (chaining CIPHER and HASH/MAC). The request for CIPHER
> session is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_cipher_session_para {
> > +    /* See VIRTIO_CRYPTO_CIPHER* above */
> > +    le32 algo;
> > +    /* length of key */
> > +    le32 keylen;
> > +#define VIRTIO_CRYPTO_OP_ENCRYPT  1
> > +#define VIRTIO_CRYPTO_OP_DECRYPT  2
> > +    /* encryption or decryption */
> > +    le32 op;
> > +    le32 padding;
> > +};
> > +
> > +struct virtio_crypto_cipher_session_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_cipher_session_para para;
> > +    /* The cipher key */
> > +    u8 cipher_key[keylen];
> > +
> > +    /* Device-writable part */
> > +    struct virtio_crypto_session_input input;
> > +};
> > +\end{lstlisting}
> > +
> > +The request for algorithm chaining is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_alg_chain_session_para {
> > +#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER
> 1
> > +#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH
> 2
> > +    le32 alg_chain_order;
> > +/* Plain hash */
> > +#define VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN    1
> > +/* Authenticated hash (mac) */
> > +#define VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH     2
> > +/* Nested hash */
> > +#define VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED   3
> > +    le32 hash_mode;
> > +    struct virtio_crypto_cipher_session_para cipher_param;
> > +    union {
> > +        struct virtio_crypto_hash_session_para hash_param;
> > +        struct virtio_crypto_mac_session_para mac_param;
> > +    } u;
> > +    /* length of the additional authenticated data (AAD) in bytes */
> > +    le32 aad_len;
> > +    le32 padding;
> > +};
> > +
> > +struct virtio_crypto_alg_chain_session_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_alg_chain_session_para para;
> > +    /* The cipher key */
> > +    u8 cipher_key[keylen];
> > +    /* The authenticated key */
> > +    u8 auth_key[auth_key_len];
> > +
> > +    /* Device-writable part */
> > +    struct virtio_crypto_session_input input;
> > +};
> > +\end{lstlisting}
> > +
> > +The request for symmetric algorithm is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_sym_create_session_req {
> > +    union {
> > +        struct virtio_crypto_cipher_session_req cipher;
> > +        struct virtio_crypto_alg_chain_session_req chain;
> > +    } u;
> > +
> > +    /* Device-readable part */
> > +
> > +/* No operation */
> > +#define VIRTIO_CRYPTO_SYM_OP_NONE  0
> 
> This operation is not defined by the spec.  QEMU returns
> VIRTIO_CRYPTO_NOTSUPP.
> 
> The spec should cover the behavior of every constant.  Otherwise there
> is a risk that implementations of the spec will differ.
> 
OK, I'll add explanation for this operation type. It means don't do cipher
operations for a request, the device can directly return results.

> > +/* Cipher only operation on the data */
> > +#define VIRTIO_CRYPTO_SYM_OP_CIPHER  1
> > +/* Chain any cipher with any hash or mac operation. The order
> > +   depends on the value of alg_chain_order param */
> > +#define VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING  2
> > +    le32 op_type;
> > +    le32 padding;
> > +};
> > +\end{lstlisting}
> > +
> > +\subparagraph{Session operation: AEAD session}\label{sec:Device Types /
> Crypto Device / Device
> > +Operation / Control Virtqueue / Session operation / Session operation: AEAD
> session}
> > +
> > +The request for AEAD session is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_aead_session_para {
> > +    /* See VIRTIO_CRYPTO_AEAD_* above */
> > +    le32 algo;
> > +    /* length of key */
> > +    le32 key_len;
> > +    /* Authentication tag length */
> > +    le32 tag_len;
> > +    /* The length of the additional authenticated data (AAD) in bytes */
> > +    le32 aad_len;
> > +    /* encryption or decryption, See above VIRTIO_CRYPTO_OP_* */
> > +    le32 op;
> > +    le32 padding;
> > +};
> > +
> > +struct virtio_crypto_aead_create_session_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_aead_session_para para;
> > +    u8 key[key_len];
> > +
> > +    /* Device-writeable part */
> > +    struct virtio_crypto_session_input input;
> > +};
> > +\end{lstlisting}
> > +
> > +\drivernormative{\subparagraph}{Session operation: create session}{Device
> Types / Crypto Device / Device Operation / Control Virtqueue / Session
> operation / Session operation: create session}
> > +
> > +\begin{itemize*}
> > +\item The driver MUST set the control general header and corresponding
> properties of the union in structure virtio_crypto_op_ctrl_req. See
> \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue}.
> > +\item The driver MUST set \field{opcode} field based on service type: CIPHER,
> HASH, MAC, or AEAD.
> 
> Missing definite article:
> 
> "MUST set the \field{opcode} field"
> 
> > +\item The driver MUST set \field{queue_id} field to show used dataq.
> 
> More missing definite articles:
> 
> "MUST set the \field{queue_id} field"
> 
> (This applies to all "MUST set \field{X} field" below too)
> 
OK, will do.

> "to identify the dataq"
> 
> > +\end{itemize*}
> > +
> > +\devicenormative{\subparagraph}{Session operation: create session}{Device
> Types / Crypto Device / Device
> > +Operation / Control Virtqueue / Session operation / Session operation:
> create session}
> > +
> > +\begin{itemize*}
> > +\item The device MUST set \field{session_id} field as a session identifier
> return to the driver when the device finishes processing session creation.
> 
> The phrase is "set X to Y" instead of "set X as Y":
> 
> s/as a session identifier return to the driver/to a unique session
> identifier/
> 
> I dropped the "return to the driver" concept since it should be clear
> from the context that the device is filling out fields that the driver
> reads.
> 
OK. I agree.

> > +\item The device MUST set \field{status} field to one of the values of enum
> VIRITO_CRYPTO_STATUS.
> 
> VIRTIO typo.
> 
Fixed.

> > +\end{itemize*}
> > +
> > +\drivernormative{\subparagraph}{Session operation: destroy
> session}{Device Types / Crypto Device / Device
> > +Operation / Control Virtqueue / Session operation / Session operation:
> destroy session}
> > +
> > +\begin{itemize*}
> > +\item The driver MUST set \field{opcode} field based on service type: CIPHER,
> HASH, MAC, or AEAD.
> > +\item The driver MUST set the \field{session_id} to a valid value which
> assigned by the device when a session is created.
> 
> An explanation is beyond my grammar knowledge :) but the following
> sounds correct:
> 
> "to a valid value assigned by the device when the session was created"
> 
Sounds good. ;)

> > +\end{itemize*}
> > +
> > +\devicenormative{\subparagraph}{Session operation: destroy
> session}{Device Types / Crypto Device / Device
> > +Operation / Control Virtqueue / Session operation / Session operation:
> destroy session}
> > +
> > +\begin{itemize*}
> > +\item The device MUST set \field{status} field to one of the values of enum
> VIRITO_CRYPTO_STATUS.
> 
> VIRTIO typo.
> 
Fixed.

> > +\end{itemize*}
> > +
> > +\subsubsection{Data Virtqueue}\label{sec:Device Types / Crypto Device /
> Device Operation / Data Virtqueue}
> > +
> > +The driver uses the data virtqueue to transmit the requests of crypto
> operation to the device,
> 
> s/transmit the requests of crypto operation/to transmit crypto operation
> requests/
> 
> > +and completes the data plane operations (such as crypto operation).
> 
> "data plane operations" is plural so "such as crypto operation" must
> also be plural:
> 
> "such as crypto operations"
> 
Er, I should drop all 'data plane' phrases as Halil's suggestion, this is a leak.

> > +
> > +The session mode request of dataq is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_op_data_req {
> > +    struct virtio_crypto_op_header header;
> > +
> > +    union {
> > +        struct virtio_crypto_sym_data_req   sym_req;
> > +        struct virtio_crypto_hash_data_req  hash_req;
> > +        struct virtio_crypto_mac_data_req   mac_req;
> > +        struct virtio_crypto_aead_data_req  aead_req;
> > +    } u;
> > +};
> > +\end{lstlisting}
> > +
> > +The request of dataq, mixing both session and stateless mode is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_op_data_req_mux {
> > +    struct virtio_crypto_op_header header;
> > +
> > +    union {
> > +        struct virtio_crypto_sym_data_req   sym_req;
> > +        struct virtio_crypto_hash_data_req  hash_req;
> > +        struct virtio_crypto_mac_data_req   mac_req;
> > +        struct virtio_crypto_aead_data_req  aead_req;
> > +        struct virtio_crypto_sym_data_req_stateless
> sym_stateless_req;
> > +        struct virtio_crypto_hash_data_req_stateless
> hash_stateless_req;
> > +        struct virtio_crypto_mac_data_req_stateless
> mac_stateless_req;
> > +        struct virtio_crypto_aead_data_req_stateless
> aead_stateless_req;
> > +    } u;
> > +};
> > +\end{lstlisting}
> > +
> > +The header is the general header and the union is of the algorithm-specific
> type,
> > +which is set by the driver. All properties in the union are shown as follows.
> > +
> > +There is a unified input header structure for all crypto services.
> > +
> > +The structure is defined as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_inhdr {
> > +    u8 status;
> > +};
> > +\end{lstlisting}
> > +
> > +\subsubsection{HASH Service Operation}\label{sec:Device Types / Crypto
> Device / Device Operation / HASH Service Operation}
> > +
> > +The session mode request of HASH service:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_hash_para {
> > +    /* length of source data */
> > +    le32 src_data_len;
> > +    /* hash result length */
> > +    le32 hash_result_len;
> > +};
> > +
> > +struct virtio_crypto_hash_data_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_hash_para para;
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +
> > +    /* Device-writable part */
> > +    /* Hash result data */
> > +    u8 hash_result[hash_result_len];
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +Each data request uses virtio_crypto_hash_data_req structure to store
> information
> > +used to run the HASH operations.
> > +
> > +The information includes the hash parameters stored by \field{para}, output
> data and input data.
> > +The output data here includes the source data and the input data includes
> the hash result data used to save the results of the HASH operations.
> > +\field{inhdr} stores status of executing the HASH operations.
> > +
> > +The stateless mode request of HASH service is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_hash_para_statelesss {
> > +    struct {
> > +        /* See VIRTIO_CRYPTO_HASH_* above */
> > +        le32 algo;
> > +    } sess_para;
> > +
> > +    /* length of source data */
> > +    le32 src_data_len;
> > +    /* hash result length */
> > +    le32 hash_result_len;
> > +    le32 reserved;
> > +};
> > +struct virtio_crypto_hash_data_req_stateless {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_hash_para_stateless para;
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +
> > +    /* Device-writable part */
> > +    /* Hash result data */
> > +    u8 hash_result[hash_result_len];
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +\drivernormative{\paragraph}{HASH Service Operation}{Device Types /
> Crypto Device / Device Operation / HASH Service Operation}
> > +
> > +\begin{itemize*}
> > +\item If the driver uses the session mode, then the driver MUST set the
> \field{session_id} in struct virtio_crypto_op_header
> > +      to a valid value which assigned by the device when a session is
> created.
> > +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated,
> the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto
> requests. Otherwise, the driver MUST use the struct
> virtio_crypto_op_data_req.
> > +\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is
> negotiated, 1) if the driver use the stateless mode, then the driver MUST set
> \field{flag} field in struct virtio_crypto_op_header
> > +      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in
> struct virtio_crypto_hash_para_statelession.sess_para, 2) if the driver still
> uses the session mode, then the driver MUST set \field{flag} field in struct
> virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
> > +\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header
> to VIRTIO_CRYPTO_HASH.
> > +\end{itemize*}
> > +
> > +\devicenormative{\paragraph}{HASH Service Operation}{Device Types /
> Crypto Device / Device Operation / HASH Service Operation}
> > +
> > +\begin{itemize*}
> > +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated,
> the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto
> requests. Otherwise, the device MUST parse the struct
> virtio_crypto_op_data_req.
> > +\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is
> negotiated, the device MUST parse \field{flag} field in struct
> virtio_crypto_op_header in order to decide which mode the driver uses.
> > +\item The device MUST copy the results of HASH operations to the
> hash_result[] if HASH operations success.
> > +\item The device MUST set \field{status} in struct virtio_crypto_inhdr to one
> of the values of enum VIRITO_CRYPTO_STATUS.
> 
> VIRTIO typo.
> 
Fixed.

> > +\end{itemize*}
> > +
> > +\subsubsection{MAC Service Operation}\label{sec:Device Types / Crypto
> Device / Device Operation / MAC Service Operation}
> > +
> > +The session mode request of MAC service is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_mac_para {
> > +    struct virtio_crypto_hash_para hash;
> > +};
> > +
> > +struct virtio_crypto_mac_data_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_mac_para para;
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +
> > +    /* Device-writable part */
> > +    /* Hash result data */
> > +    u8 hash_result[hash_result_len];
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +Each data request uses virtio_crypto_mac_data_req structure to store
> information
> > +used to run the MAC operations.
> > +
> > +The information includes the hash parameters stored by \field{para}, output
> data and input data.
> > +The output data here includes the source data and the input data includes
> the hash result data used to save the results of the MAC operations.
> > +\field{inhdr} stores status of executing the MAC operations.
> > +
> > +The stateless mode request of MAC service:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_mac_para_stateless {
> > +    struct {
> > +        /* See VIRTIO_CRYPTO_MAC_* above */
> > +        le32 algo;
> > +        /* length of authenticated key */
> > +        le32 auth_key_len;
> > +    } sess_para;
> > +
> > +    /* length of source data */
> > +    le32 src_data_len;
> > +    /* hash result length */
> > +    le32 hash_result_len;
> > +};
> > +
> > +struct virtio_crypto_mac_data_req_stateless {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_mac_para_stateless para;
> > +    /* The authenticated key */
> > +    u8 auth_key[auth_key_len];
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +
> > +    /* Device-writable part */
> > +    /* Hash result data */
> > +    u8 hash_result[hash_result_len];
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +\drivernormative{\paragraph}{MAC Service Operation}{Device Types /
> Crypto Device / Device Operation / MAC Service Operation}
> > +
> > +\begin{itemize*}
> > +\item If the driver uses the session mode, then the driver MUST set the
> \field{session_id} in struct virtio_crypto_op_header
> > +      to a valid value which assigned by the device when a session is
> created.
> > +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated,
> the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto
> requests. Otherwise, the driver MUST use the struct
> virtio_crypto_op_data_req.
> > +\item If the VIRTIO_CRYPTO_F_MAC_STATELESS_MODE feature bit is
> negotiated, 1) if the driver use the stateless mode, then the driver MUST set
> \field{flag} field in struct virtio_crypto_op_header
> > +      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in
> struct virtio_crypto_mac_para_statelession.sess_para, 2) if the driver still uses
> the session mode, then the driver MUST set \field{flag} field in struct
> virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
> > +\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header
> to VIRTIO_CRYPTO_MAC.
> > +\end{itemize*}
> > +
> > +\devicenormative{\paragraph}{MAC Service Operation}{Device Types /
> Crypto Device / Device Operation / MAC Service Operation}
> > +
> > +\begin{itemize*}
> > +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated,
> the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto
> requests. Otherwise, the device MUST parse the struct
> virtio_crypto_op_data_req.
> > +\item If the VIRTIO_CRYPTO_F_MAC_STATELESS_MODE feature bit is
> negotiated, the device MUST parse \field{flag} field in struct
> virtio_crypto_op_header in order to decide which mode the driver uses.
> > +\item The device MUST copy the results of MAC operations to the
> hash_result[] if HASH operations success.
> > +\item The device MUST set \field{status} in struct virtio_crypto_inhdr to one
> of the values of enum VIRITO_CRYPTO_STATUS.
> 
> VIRTIO typo.
> 
Fixed.

> > +\end{itemize*}
> > +
> > +\subsubsection{Symmetric algorithms Operation}\label{sec:Device Types /
> Crypto Device / Device Operation / Symmetric algorithms Operation}
> > +
> > +The session mode request of plain CIPHER service is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_cipher_para {
> > +    /*
> > +     * Byte Length of valid IV/Counter data pointed to by the below iv data.
> > +     *
> > +     * For block ciphers in CBC or F8 mode, or for Kasumi in F8 mode, or for
> > +     *   SNOW3G in UEA2 mode, this is the length of the IV (which
> > +     *   must be the same as the block length of the cipher).
> > +     * For block ciphers in CTR mode, this is the length of the counter
> > +     *   (which must be the same as the block length of the cipher).
> > +     */
> > +    le32 iv_len;
> > +    /* length of source data */
> > +    le32 src_data_len;
> > +    /* length of destination data */
> > +    le32 dst_data_len;
> > +    le32 padding;
> > +};
> > +
> > +struct virtio_crypto_cipher_data_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_cipher_para para;
> > +    /*
> > +     * Initialization Vector or Counter data.
> > +     *
> > +     * For block ciphers in CBC or F8 mode, or for Kasumi in F8 mode, or for
> > +     *   SNOW3G in UEA2 mode, this is the Initialization Vector (IV)
> > +     *   value.
> > +     * For block ciphers in CTR mode, this is the counter.
> > +     * For AES-XTS, this is the 128bit tweak, i, from IEEE Std 1619-2007.
> > +     *
> > +     * The IV/Counter will be updated after every partial cryptographic
> > +     * operation.
> > +     */
> > +    u8 iv[iv_len];
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +
> > +    /* Device-writable part */
> > +    /* Destination data */
> > +    u8 dst_data[dst_data_len];
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +The session mode request of algorithm chaining is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_alg_chain_data_para {
> > +    le32 iv_len;
> > +    /* Length of source data */
> > +    le32 src_data_len;
> > +    /* Length of destination data */
> > +    le32 dst_data_len;
> > +    /* Starting point for cipher processing in source data */
> > +    le32 cipher_start_src_offset;
> > +    /* Length of the source data that the cipher will be computed on */
> > +    le32 len_to_cipher;
> > +    /* Starting point for hash processing in source data */
> > +    le32 hash_start_src_offset;
> > +    /* Length of the source data that the hash will be computed on */
> > +    le32 len_to_hash;
> > +    /* Length of the additional auth data */
> > +    le32 aad_len;
> > +    /* Length of the hash result */
> > +    le32 hash_result_len;
> > +    le32 reserved;
> > +};
> > +
> > +struct virtio_crypto_alg_chain_data_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_alg_chain_data_para para;
> > +    /* Initialization Vector or Counter data */
> > +    u8 iv[iv_len];
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +    /* Additional authenticated data if exists  */
> > +    u8 aad[aad_len];
> > +
> > +    /* Device-writable part */
> > +    /* Destination data */
> > +    u8 dst_data[dst_data_len];
> > +    /* Hash result data */
> > +    u8 hash_result[hash_result_len];
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +The session mode request of symmetric algorithm is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_sym_data_req {
> > +    union {
> > +        struct virtio_crypto_cipher_data_req cipher;
> > +        struct virtio_crypto_alg_chain_data_req chain;
> > +    } u;
> > +
> > +    /* Device-readable part */
> > +
> > +    /* See above VIRTIO_CRYPTO_SYM_OP_* */
> > +    le32 op_type;
> > +    le32 padding;
> > +};
> > +\end{lstlisting}
> > +
> > +Each data request uses virtio_crypto_sym_data_req structure to store
> information
> > +used to run the CIPHER operations.
> > +
> > +The information includes the cipher parameters stored by \field{para},
> output data and input data.
> > +In the first virtio_crypto_cipher_para structure, \field{iv_len} specifies the
> length of the initialization vector or counter,
> > +\field{src_data_len} specifies the length of the source data, and
> \field{dst_data_len} specifies the
> > +length of the destination data.
> > +For plain CIPHER operations, the output data here includes the IV/Counter
> data and source data, and the input data includes the destination data used to
> save the results of the CIPHER operations.
> > +
> > +For algorithms chain, the output data here includes the IV/Counter data,
> source data and additional authenticated data if exists.
> > +The input data includes both destination data and hash result data used to
> store the results of the HASH/MAC operations.
> > +\field{inhdr} stores status of executing the crypto operations.
> > +
> > +The stateless mode request of plain CIPHER service is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_cipher_para_stateless {
> > +    struct {
> > +        /* See VIRTIO_CRYPTO_CIPHER* above */
> > +        le32 algo;
> > +        /* length of key */
> > +        le32 keylen;
> > +
> > +        /* See VIRTIO_CRYPTO_OP_* above */
> > +        le32 op;
> > +    } sess_para;
> > +
> > +    /*
> > +     * Byte Length of valid IV/Counter data pointed to by the below iv data.
> > +     */
> > +    le32 iv_len;
> > +    /* length of source data */
> > +    le32 src_data_len;
> > +    /* length of destination data */
> > +    le32 dst_data_len;
> > +};
> > +
> > +struct virtio_crypto_cipher_data_req_stateless {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_cipher_para_stateless para;
> > +    /* The cipher key */
> > +    u8 cipher_key[keylen];
> > +
> > +    /* Initialization Vector or Counter data. */
> > +    u8 iv[iv_len];
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +
> > +    /* Device-writable part */
> > +    /* Destination data */
> > +    u8 dst_data[dst_data_len];
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +The stateless mode request of algorithm chaining is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_alg_chain_data_para_stateless {
> > +    struct {
> > +        /* See VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_* above */
> > +        le32 alg_chain_order;
> > +        /* length of the additional authenticated data in bytes */
> > +        le32 aad_len;
> > +
> > +        struct {
> > +            /* See VIRTIO_CRYPTO_CIPHER* above */
> > +            le32 algo;
> > +            /* length of key */
> > +            le32 keylen;
> > +            /* See VIRTIO_CRYPTO_OP_* above */
> > +            le32 op;
> > +        } cipher;
> > +
> > +        struct {
> > +            /* See VIRTIO_CRYPTO_HASH_* or VIRTIO_CRYPTO_MAC_*
> above */
> > +            le32 algo;
> > +            /* length of authenticated key */
> > +            le32 auth_key_len;
> > +            /* See VIRTIO_CRYPTO_SYM_HASH_MODE_* above */
> > +            le32 hash_mode;
> > +        } hash;
> > +    } sess_para;
> > +
> > +    le32 iv_len;
> > +    /* Length of source data */
> > +    le32 src_data_len;
> > +    /* Length of destination data */
> > +    le32 dst_data_len;
> > +    /* Starting point for cipher processing in source data */
> > +    le32 cipher_start_src_offset;
> > +    /* Length of the source data that the cipher will be computed on */
> > +    le32 len_to_cipher;
> > +    /* Starting point for hash processing in source data */
> > +    le32 hash_start_src_offset;
> > +    /* Length of the source data that the hash will be computed on */
> > +    le32 len_to_hash;
> > +    /* Length of the additional auth data */
> > +    le32 aad_len;
> > +    /* Length of the hash result */
> > +    le32 hash_result_len;
> > +    le32 reserved;
> > +};
> > +
> > +struct virtio_crypto_alg_chain_data_req_stateless {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_alg_chain_data_para_stateless para;
> > +    /* The cipher key */
> > +    u8 cipher_key[keylen];
> > +    /* The auth key */
> > +    u8 auth_key[auth_key_len];
> > +    /* Initialization Vector or Counter data */
> > +    u8 iv[iv_len];
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +    /* Additional authenticated data if exists  */
> > +    u8 aad[aad_len];
> > +
> > +    /* Device-writable part */
> > +    /* Destination data */
> > +    u8 dst_data[dst_data_len];
> > +    /* Hash result data */
> > +    u8 hash_result[hash_result_len];
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +The stateless mode request of symmetric algorithm is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_sym_data_req_stateless {
> > +    union {
> > +        struct virtio_crypto_cipher_data_req_stateless cipher;
> > +        struct virtio_crypto_alg_chain_data_req_stateless chain;
> > +    } u;
> > +
> > +    /* Device-readable part */
> > +
> > +    /* See above VIRTIO_CRYPTO_SYM_OP_* */
> > +    le32 op_type;
> > +    le32 padding;
> > +};
> > +\end{lstlisting}
> > +
> > +\drivernormative{\paragraph}{Symmetric algorithms Operation}{Device
> Types / Crypto Device / Device Operation / Symmetric algorithms Operation}
> > +
> > +\begin{itemize*}
> > +\item If the driver uses the session mode, then the driver MUST set the
> \field{session_id} in struct virtio_crypto_op_header
> > +      to a valid value which assigned by the device when a session is
> created.
> > +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated,
> the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto
> requests. Otherwise, the driver MUST use the struct
> virtio_crypto_op_data_req.
> > +\item If the VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is
> negotiated, 1) if the driver use the stateless mode, then the driver MUST set
> \field{flag} field in struct virtio_crypto_op_header
> > +      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in
> struct virtio_crypto_cipher_para_statelession.sess_para or struct
> virtio_crypto_alg_chain_data_para_stateless.sess_para, 2) if the driver still
> uses the session mode, then the driver MUST set \field{flag} field in struct
> virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
> > +\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header
> to VIRTIO_CRYPTO_CIPHER_ENCRYPT or VIRTIO_CRYPTO_CIPHER_DECRYPT.
> > +\item The driver MUST specify the fields of struct
> virtio_crypto_cipher_data_req in struct virtio_crypto_sym_data_req if the
> request is based on VIRTIO_CRYPTO_SYM_OP_CIPHER.
> > +\item The driver MUST specify the fields of both struct
> virtio_crypto_cipher_data_req and struct virtio_crypto_mac_data_req in struct
> virtio_crypto_sym_data_req if the request
> > +      is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING type
> and in the VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode.
> > +\end{itemize*}
> > +
> > +\devicenormative{\paragraph}{Symmetric algorithms Operation}{Device
> Types / Crypto Device / Device Operation / Symmetric algorithms Operation}
> > +
> > +\begin{itemize*}
> > +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated,
> the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto
> requests. Otherwise, the device MUST parse the struct
> virtio_crypto_op_data_req.
> > +\item If the VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is
> negotiated, the device MUST parse \field{flag} field in struct
> virtio_crypto_op_header in order to decide which mode the driver uses.
> > +\item The device MUST parse the virtio_crypto_sym_data_req based on the
> \field{opcode} in general header.
> > +\item The device SHOULD only parse fields of struct
> virtio_crypto_cipher_data_req in struct virtio_crypto_sym_data_req if the
> request is VIRTIO_CRYPTO_SYM_OP_CIPHER type.
> > +\item The device MUST parse fields of both struct
> virtio_crypto_cipher_data_req and struct virtio_crypto_mac_data_req in struct
> virtio_crypto_sym_data_req if the request
> > +      is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING
> operation type and in the VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode.
> > +\item The device MUST copy the result of cryptographic operation to the
> dst_data[] in both plain CIPHER mode and algorithms chain mode.
> > +\item The device MUST check the \field{para}.\field{add_len} is bigger than 0
> before parse the additional authenticated data in plain algorithms chain mode.
> > +\item The device MUST copy the result of HASH/MAC operation to the
> hash_result[] is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING
> type.
> > +\item The device MUST set the \field{status} field in struct
> virtio_crypto_inhdr to one of the values of enum VIRITO_CRYPTO_STATUS.
> 
> VIRTIO typo
> 
Fixed.

> > +\end{itemize*}
> > +
> > +\paragraph{Steps of Operation}\label{sec:Device Types / Crypto Device /
> Device Operation / Symmetric algorithms Operation / Steps of Operation}
> > +
> > +\subparagraph{Step1: Create session}\label{sec:Device Types / Crypto
> Device / Device Operation / Symmetric algorithms Operation / Steps of
> Operation / Step1: Create session on session mode}
> > +
> > +\begin{enumerate}
> > +\item The driver specifies information in struct virtio_crypto_op_ctrl_req,
> including the algorithm name, key, keylen etc;
> > +\item The driver adds the request of session creation into the controlq's
> Vring Descriptor Table;
> > +\item The driver kicks the device;
> > +\item The device receives the request from controlq;
> > +\item The device parses information about the request, and determines the
> information concerning the backend crypto accelerator;
> > +\item The device packs information based on the APIs of the backend crypto
> accelerator;
> > +\item The device invokes the session creation APIs of the backend crypto
> accelerator to create a session;
> > +\item The device returns the session id to the driver.
> > +\end{enumerate}
> > +
> > +\subparagraph{Step2: Execute cryptographic operation}\label{sec:Device
> Types / Crypto Device / Device Operation / Symmetric algorithms Operation /
> Steps of Operation / Step2: Execute cryptographic operation}
> > +
> > +\begin{enumerate}
> > +\item The driver specifies information in struct virtio_crypto_op_data_req,
> including struct virtio_crypto_op_header and struct
> virtio_crypto_sym_data_req, see \ref{sec:Device Types / Crypto Device /
> Device
> > +      Operation / Symmetric algorithms Operation};
> > +\item The driver adds the request for cryptographic operation into the
> dataq's Vring Descriptor Table;
> > +\item The driver kicks the device (Or the device actively polls the dataq's
> Vring Descriptor Table);
> > +\item The device receives the request from dataq;
> > +\item The device parses information about the request, and determines the
> identification information for the backend crypto accelerator. For example,
> converting guest physical addresses to host physical addresses;
> > +\item The device packs identification information based on the API of the
> backend crypto accelerator;
> > +\item The device invokes the cryptographic APIs of the backend crypto
> accelerator;
> > +\item The backend crypto accelerator executes the cryptographic operation
> implicitly;
> > +\item The device receives the cryptographic results from the backend crypto
> accelerator (synchronous or asynchronous);
> > +\item The device sets the \field{status} in struct virtio_crypto_inhdr;
> > +\item The device updates and flushes the Used Ring to return the
> cryptographic results to the driver;
> > +\item The device notifies the driver (Or the driver actively polls the dataq's
> Used Ring);
> > +\item The driver saves the cryptographic results.
> > +\end{enumerate}
> > +
> > +\begin{note}
> > +\begin{itemize*}
> > +\item For better performance, the device should by preference use vhost
> scheme (user space or kernel space)
> > +      as the backend crypto accelerator in the real production
> environment.
> > +\end{itemize*}
> > +\end{note}
> > +
> > +\subsubsection{AEAD Service Operation}\label{sec:Device Types / Crypto
> Device / Device Operation / AEAD Service Operation}
> > +
> > +The session mode request of symmetric algorithm is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_aead_para {
> > +    /*
> > +     * Byte Length of valid IV data.
> > +     *
> > +     * For GCM mode, this is either 12 (for 96-bit IVs) or 16, in which
> > +     *   case iv points to J0.
> > +     * For CCM mode, this is the length of the nonce, which can be in the
> > +     *   range 7 to 13 inclusive.
> > +     */
> > +    le32 iv_len;
> > +    /* length of additional auth data */
> > +    le32 aad_len;
> > +    /* length of source data */
> > +    le32 src_data_len;
> > +    /* length of dst data, this should be at least src_data_len + tag_len */
> > +    le32 dst_data_len;
> > +    /* Authentication tag length */
> > +    le32 tag_len;
> > +    le32 reserved;
> > +};
> > +
> > +struct virtio_crypto_aead_data_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_aead_para para;
> > +    /*
> > +     * Initialization Vector data.
> > +     *
> > +     * For GCM mode, this is either the IV (if the length is 96 bits) or J0
> > +     *   (for other sizes), where J0 is as defined by NIST SP800-38D.
> > +     *   Regardless of the IV length, a full 16 bytes needs to be allocated.
> > +     * For CCM mode, the first byte is reserved, and the nonce should be
> > +     *   written starting at &iv[1] (to allow space for the implementation
> > +     *   to write in the flags in the first byte).  Note that a full 16 bytes
> > +     *   should be allocated, even though the iv_len field will have
> > +     *   a value less than this.
> > +     *
> > +     * The IV will be updated after every partial cryptographic operation.
> > +     */
> > +    u8 iv[iv_len];
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +    /* Additional authenticated data if exists  */
> > +    u8 aad[aad_len];
> > +
> > +    /* Device-writable part */
> > +    /* Pointer to output data */
> > +    u8 dst_data[dst_data_len];
> > +
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +Each data request uses virtio_crypto_aead_data_req structure to store
> information
> > +used to run the AEAD operations.
> > +
> > +The information includes the hash parameters stored by \field{para}, output
> data and input data.
> > +In the first virtio_crypto_aead_para structure, \field{iv_len} specifies the
> length of the initialization vector. \field{tag_len} specifies the length of the
> authentication tag;
> > +\field{aad_len} specifies the length of additional authentication data,
> \field{src_data_len} specifies the
> > +length of the source data; \field{dst_data_len} specifies the length of the
> destination data, which is at least \field{src_data_len} + \field{tag_len}.
> > +
> > +The output data here includes the IV/Counter data, source data and
> additional authenticated data if exists.
> > +The input data includes both destination data used to save the results of the
> AEAD operations.
> > +\field{inhdr} stores status of executing the AEAD operations.
> > +
> > +The stateless mode request of AEAD service is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_aead_para_stateless {
> > +    struct {
> > +        /* See VIRTIO_CRYPTO_AEAD_* above */
> > +        le32 algo;
> > +        /* length of key */
> > +        le32 key_len;
> > +        /* encrypt or decrypt, See above VIRTIO_CRYPTO_OP_* */
> > +        le32 op;
> > +    } sess_para;
> > +
> > +    /* Byte Length of valid IV data. */
> > +    le32 iv_len;
> > +    /* Authentication tag length */
> > +    le32 tag_len;
> > +    /* length of additional auth data */
> > +    le32 aad_len;
> > +    /* length of source data */
> > +    le32 src_data_len;
> > +    /* length of dst data, this should be at least src_data_len + tag_len */
> > +    le32 dst_data_len;
> > +};
> > +
> > +struct virtio_crypto_aead_data_req_stateless {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_aead_para_stateless para;
> > +    /* The cipher key */
> > +    u8 key[key_len];
> > +    /* Initialization Vector data. */
> > +    u8 iv[iv_len];
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +    /* Additional authenticated data if exists  */
> > +    u8 aad[aad_len];
> > +
> > +    /* Device-writable part */
> > +    /* Pointer to output data */
> > +    u8 dst_data[dst_data_len];
> > +
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +\drivernormative{\paragraph}{AEAD Service Operation}{Device Types /
> Crypto Device / Device Operation / AEAD Service Operation}
> > +
> > +\begin{itemize*}
> > +\item If the driver uses the session mode, then the driver MUST set the
> \field{session_id} in struct virtio_crypto_op_header
> > +      to a valid value which assigned by the device when a session is
> created.
> > +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated,
> the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto
> requests. Otherwise, the driver MUST use the struct
> virtio_crypto_op_data_req.
> > +\item If the VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE feature bit is
> negotiated, 1) if the driver use the stateless mode, then the driver MUST set
> \field{flag} field in struct virtio_crypto_op_header
> > +      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in
> struct virtio_crypto_aead_para_statelession.sess_para, 2) if the driver still
> uses the session mode, then the driver MUST set \field{flag} field in struct
> virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
> > +\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header
> to VIRTIO_CRYPTO_AEAD_ENCRYPT or VIRTIO_CRYPTO_AEAD_DECRYPT.
> > +\end{itemize*}
> > +
> > +\devicenormative{\paragraph}{AEAD Service Operation}{Device Types /
> Crypto Device / Device Operation / AEAD Service Operation}
> > +
> > +\begin{itemize*}
> > +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated,
> the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto
> requests. Otherwise, the device MUST parse the struct
> virtio_crypto_op_data_req.
> > +\item If the VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE feature bit is
> negotiated, the device MUST parse the virtio_crypto_aead_data_req based on
> the \field{opcode} in general header.
> > +\item The device MUST copy the result of cryptographic operation to the
> dst_data[].
> > +\item The device MUST copy the authentication tag to the dst_data[] offset
> the cipher result.
> > +\item The device MUST set the \field{status} field in struct
> virtio_crypto_inhdr to one of the values of enum VIRITO_CRYPTO_STATUS.
> 
> VIRTIO typo
> 
Fixed.

Thanks,
-Gonglei

> > +\item When the \field{opcode} is VIRTIO_CRYPTO_AEAD_DECRYPT, the
> device MUST verify and return the verification result to the driver, and if the
> verification result is incorrect, VIRTIO_CRYPTO_BADMSG (bad message) MUST
> be returned to the driver.
> > +\end{itemize*}
> > \ No newline at end of file
> > --
> > 1.7.12.4
> >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
> > For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org
> >
Stefan Hajnoczi April 21, 2017, 1:07 p.m. UTC | #5
On Thu, Apr 13, 2017 at 05:11:13PM +0800, Gonglei wrote:
> +The request of dataq, mixing both session and stateless mode is as follows:

It sounds more natural when "request" is plural:

"Dataq requests for both session and stateless modes are as follows:"

> +
> +\begin{lstlisting}
> +struct virtio_crypto_op_data_req_mux {
> +    struct virtio_crypto_op_header header;
> +
> +    union {
> +        struct virtio_crypto_sym_data_req   sym_req;
> +        struct virtio_crypto_hash_data_req  hash_req;
> +        struct virtio_crypto_mac_data_req   mac_req;
> +        struct virtio_crypto_aead_data_req  aead_req;
> +        struct virtio_crypto_sym_data_req_stateless   sym_stateless_req;
> +        struct virtio_crypto_hash_data_req_stateless  hash_stateless_req;
> +        struct virtio_crypto_mac_data_req_stateless   mac_stateless_req;
> +        struct virtio_crypto_aead_data_req_stateless  aead_stateless_req;
> +    } u;
> +};
> +\end{lstlisting}
> +
> +The header is the general header and the union is of the algorithm-specific type,
> +which is set by the driver. All properties in the union are shown as follows.
> +
> +There is a unified input header structure for all crypto services.
> +
> +The structure is defined as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_inhdr {
> +    u8 status;
> +};
> +\end{lstlisting}
> +
> +\subsubsection{HASH Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / HASH Service Operation}
> +
> +The session mode request of HASH service:

Plural "request":

"Session mode HASH service requests are defined as follows:"

> +
> +\begin{lstlisting}
> +struct virtio_crypto_hash_para {
> +    /* length of source data */
> +    le32 src_data_len;
> +    /* hash result length */
> +    le32 hash_result_len;
> +};
> +
> +struct virtio_crypto_hash_data_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_hash_para para;
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +
> +    /* Device-writable part */
> +    /* Hash result data */
> +    u8 hash_result[hash_result_len];
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +Each data request uses virtio_crypto_hash_data_req structure to store information
> +used to run the HASH operations. 
> +
> +The information includes the hash parameters stored by \field{para}, output data and input data.

"stored in $container" vs "stored by $actor_or_service_or_action".  For
example:

"stored in register EAX" <-- container
"stored in /etc/passwd" <-- container
"stored by the worker thread" <-- actor
"stored by calling api_write()" <-- action
"stored by ext4" <-- service

Since \field{para} is a container it needs to be "stored in
\field{para}".

> +The output data here includes the source data and the input data includes the hash result data used to save the results of the HASH operations.
> +\field{inhdr} stores status of executing the HASH operations.

Missing article: "stores the status"

> +
> +The stateless mode request of HASH service is as follows:

Plural "requests":

"Stateless mode HASH service requests are as follows:"

(The same applies to more instances below.)

> +
> +\begin{lstlisting}
> +struct virtio_crypto_hash_para_statelesss {
> +    struct {
> +        /* See VIRTIO_CRYPTO_HASH_* above */
> +        le32 algo;
> +    } sess_para;
> +
> +    /* length of source data */
> +    le32 src_data_len;
> +    /* hash result length */
> +    le32 hash_result_len;
> +    le32 reserved;
> +};
> +struct virtio_crypto_hash_data_req_stateless {
> +    /* Device-readable part */
> +    struct virtio_crypto_hash_para_stateless para;
> +    /* Source data */
> +    u8 src_data[src_data_len];
> +
> +    /* Device-writable part */
> +    /* Hash result data */
> +    u8 hash_result[hash_result_len];
> +    struct virtio_crypto_inhdr inhdr;
> +};
> +\end{lstlisting}
> +
> +\drivernormative{\paragraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / HASH Service Operation}
> +
> +\begin{itemize*}
> +\item If the driver uses the session mode, then the driver MUST set the \field{session_id} in struct virtio_crypto_op_header
> +      to a valid value which assigned by the device when a session is created.

Please see my previous email for a change to "a valid value which
assigned by the device when a session is created".

> +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto requests. Otherwise, the driver MUST use the struct virtio_crypto_op_data_req.

The article is omitted when referring to a specific named object:
"use struct virtio_crypto_op_data_req_mux" and "use struct virtio_crypto_op_data_req"

> +\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is negotiated, 1) if the driver use the stateless mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header

"he/she/it uses" so it should be "if the driver uses the stateless
mode".

"set X field" is missing a definite article.  Either add "the" ("set the
X field") or drop "field" so that X isn't a member of a group ("set X"):
"set \field{flag} in struct virtio_crypto_op_header"

https://owl.english.purdue.edu/owl/resource/540/01/

> +      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in struct virtio_crypto_hash_para_statelession.sess_para, 2) if the driver still uses the session mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.

I don't understand the meaning of "still" here.  Maybe it was meant to
be "instead"?  It's simplest to drop it:
s/driver still uses/driver uses/

s/MUST set \field{flag} field/MUST set \field{flag}/

> +\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_HASH.
> +\end{itemize*}
> +
> +\devicenormative{\paragraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / HASH Service Operation}
> +
> +\begin{itemize*}
> +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto requests. Otherwise, the device MUST parse the struct virtio_crypto_op_data_req.
> +\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is negotiated, the device MUST parse \field{flag} field in struct virtio_crypto_op_header in order to decide which mode the driver uses.
> +\item The device MUST copy the results of HASH operations to the hash_result[] if HASH operations success.
> +\item The device MUST set \field{status} in struct virtio_crypto_inhdr to one of the values of enum VIRITO_CRYPTO_STATUS.
> +\end{itemize*}

More instances of the same grammar issues mentioned above.  This is a
good point to stop review for now and wait for the next revision that
fixes them throughout the document.
Gonglei (Arei) April 21, 2017, 1:39 p.m. UTC | #6
> -----Original Message-----
> From: Stefan Hajnoczi [mailto:stefanha@redhat.com]
> Sent: Friday, April 21, 2017 9:07 PM
>
> Subject: Re: [virtio-dev] [PATCH v17 1/2] virtio-crypto: Add virtio crypto device
> specification
> 
> On Thu, Apr 13, 2017 at 05:11:13PM +0800, Gonglei wrote:
> > +The request of dataq, mixing both session and stateless mode is as follows:
> 
> It sounds more natural when "request" is plural:
> 
> "Dataq requests for both session and stateless modes are as follows:"
> 
OK.

> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_op_data_req_mux {
> > +    struct virtio_crypto_op_header header;
> > +
> > +    union {
> > +        struct virtio_crypto_sym_data_req   sym_req;
> > +        struct virtio_crypto_hash_data_req  hash_req;
> > +        struct virtio_crypto_mac_data_req   mac_req;
> > +        struct virtio_crypto_aead_data_req  aead_req;
> > +        struct virtio_crypto_sym_data_req_stateless
> sym_stateless_req;
> > +        struct virtio_crypto_hash_data_req_stateless
> hash_stateless_req;
> > +        struct virtio_crypto_mac_data_req_stateless
> mac_stateless_req;
> > +        struct virtio_crypto_aead_data_req_stateless
> aead_stateless_req;
> > +    } u;
> > +};
> > +\end{lstlisting}
> > +
> > +The header is the general header and the union is of the algorithm-specific
> type,
> > +which is set by the driver. All properties in the union are shown as follows.
> > +
> > +There is a unified input header structure for all crypto services.
> > +
> > +The structure is defined as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_inhdr {
> > +    u8 status;
> > +};
> > +\end{lstlisting}
> > +
> > +\subsubsection{HASH Service Operation}\label{sec:Device Types / Crypto
> Device / Device Operation / HASH Service Operation}
> > +
> > +The session mode request of HASH service:
> 
> Plural "request":
> 
> "Session mode HASH service requests are defined as follows:"
> 
Fixed.

> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_hash_para {
> > +    /* length of source data */
> > +    le32 src_data_len;
> > +    /* hash result length */
> > +    le32 hash_result_len;
> > +};
> > +
> > +struct virtio_crypto_hash_data_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_hash_para para;
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +
> > +    /* Device-writable part */
> > +    /* Hash result data */
> > +    u8 hash_result[hash_result_len];
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +Each data request uses virtio_crypto_hash_data_req structure to store
> information
> > +used to run the HASH operations.
> > +
> > +The information includes the hash parameters stored by \field{para}, output
> data and input data.
> 
> "stored in $container" vs "stored by $actor_or_service_or_action".  For
> example:
> 
> "stored in register EAX" <-- container
> "stored in /etc/passwd" <-- container
> "stored by the worker thread" <-- actor
> "stored by calling api_write()" <-- action
> "stored by ext4" <-- service
> 
> Since \field{para} is a container it needs to be "stored in
> \field{para}".
> 
Great thanks :)
All fixed.

> > +The output data here includes the source data and the input data includes
> the hash result data used to save the results of the HASH operations.
> > +\field{inhdr} stores status of executing the HASH operations.
> 
> Missing article: "stores the status"
> 
All fixed.

> > +
> > +The stateless mode request of HASH service is as follows:
> 
> Plural "requests":
> 
> "Stateless mode HASH service requests are as follows:"
> 
> (The same applies to more instances below.)
> 
All fixed.

> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_hash_para_statelesss {
> > +    struct {
> > +        /* See VIRTIO_CRYPTO_HASH_* above */
> > +        le32 algo;
> > +    } sess_para;
> > +
> > +    /* length of source data */
> > +    le32 src_data_len;
> > +    /* hash result length */
> > +    le32 hash_result_len;
> > +    le32 reserved;
> > +};
> > +struct virtio_crypto_hash_data_req_stateless {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_hash_para_stateless para;
> > +    /* Source data */
> > +    u8 src_data[src_data_len];
> > +
> > +    /* Device-writable part */
> > +    /* Hash result data */
> > +    u8 hash_result[hash_result_len];
> > +    struct virtio_crypto_inhdr inhdr;
> > +};
> > +\end{lstlisting}
> > +
> > +\drivernormative{\paragraph}{HASH Service Operation}{Device Types /
> Crypto Device / Device Operation / HASH Service Operation}
> > +
> > +\begin{itemize*}
> > +\item If the driver uses the session mode, then the driver MUST set the
> \field{session_id} in struct virtio_crypto_op_header
> > +      to a valid value which assigned by the device when a session is
> created.
> 
> Please see my previous email for a change to "a valid value which
> assigned by the device when a session is created".
> 
Sure, all fixed.

> > +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated,
> the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto
> requests. Otherwise, the driver MUST use the struct
> virtio_crypto_op_data_req.
> 
> The article is omitted when referring to a specific named object:
> "use struct virtio_crypto_op_data_req_mux" and "use struct
> virtio_crypto_op_data_req"
> 
OK, all fixed.

> > +\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is
> negotiated, 1) if the driver use the stateless mode, then the driver MUST set
> \field{flag} field in struct virtio_crypto_op_header
> 
> "he/she/it uses" so it should be "if the driver uses the stateless
> mode".
> 
Yes, all fixed.

> "set X field" is missing a definite article.  Either add "the" ("set the
> X field") or drop "field" so that X isn't a member of a group ("set X"):
> "set \field{flag} in struct virtio_crypto_op_header"
> 
> https://owl.english.purdue.edu/owl/resource/540/01/
> 
OK, I get it. All fixed.

> > +      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in
> struct virtio_crypto_hash_para_statelession.sess_para, 2) if the driver still
> uses the session mode, then the driver MUST set \field{flag} field in struct
> virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
> 
> I don't understand the meaning of "still" here.  Maybe it was meant to
> be "instead"?  It's simplest to drop it:
> s/driver still uses/driver uses/
> 
OK. All fixed.

> s/MUST set \field{flag} field/MUST set \field{flag}/
> 
> > +\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header
> to VIRTIO_CRYPTO_HASH.
> > +\end{itemize*}
> > +
> > +\devicenormative{\paragraph}{HASH Service Operation}{Device Types /
> Crypto Device / Device Operation / HASH Service Operation}
> > +
> > +\begin{itemize*}
> > +\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated,
> the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto
> requests. Otherwise, the device MUST parse the struct
> virtio_crypto_op_data_req.
> > +\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is
> negotiated, the device MUST parse \field{flag} field in struct
> virtio_crypto_op_header in order to decide which mode the driver uses.
> > +\item The device MUST copy the results of HASH operations to the
> hash_result[] if HASH operations success.
> > +\item The device MUST set \field{status} in struct virtio_crypto_inhdr to one
> of the values of enum VIRITO_CRYPTO_STATUS.
> > +\end{itemize*}
> 
> More instances of the same grammar issues mentioned above.  This is a
> good point to stop review for now and wait for the next revision that
> fixes them throughout the document.

Thanks for your patience Stefan. I have finished the fixes as your suggestions
Throughout the document.

Thanks!
-Gonglei
diff mbox

Patch

diff --git a/acknowledgements.tex b/acknowledgements.tex
index 53942b0..6714544 100644
--- a/acknowledgements.tex
+++ b/acknowledgements.tex
@@ -44,4 +44,5 @@  Patrick Durusau,	Technical Advisory Board, OASIS	\newline
 Thomas Huth,	Red Hat	\newline
 Yan Vugenfirer, Red Hat / Daynix	\newline
 Kevin Lo,	MSI	\newline
+Halil Pasic, IBM  \newline
 \end{oasistitlesection}
diff --git a/content.tex b/content.tex
index 4b45678..ab75f78 100644
--- a/content.tex
+++ b/content.tex
@@ -5750,6 +5750,8 @@  descriptor for the \field{sense_len}, \field{residual},
 \field{status_qualifier}, \field{status}, \field{response} and
 \field{sense} fields.
 
+\input{virtio-crypto.tex}
+
 \chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits}
 
 Currently there are three device-independent feature bits defined:
diff --git a/virtio-crypto.tex b/virtio-crypto.tex
new file mode 100644
index 0000000..c73a1ef
--- /dev/null
+++ b/virtio-crypto.tex
@@ -0,0 +1,1305 @@ 
+\section{Crypto Device}\label{sec:Device Types / Crypto Device}
+
+The virtio crypto device is a virtual cryptography device as well as a kind of
+virtual hardware accelerator for virtual machines. The encryption and
+decryption requests are placed in any of the data queues and are ultimately handled by the
+backend crypto accelerators. The second kind of queue is the control queue used to create 
+or destroy sessions for symmetric algorithms and will control some advanced
+features in the future. The virtio crypto device provides the following crypto
+services: CIPHER, MAC, HASH, and AEAD.
+
+
+\subsection{Device ID}\label{sec:Device Types / Crypto Device / Device ID}
+
+20
+
+\subsection{Virtqueues}\label{sec:Device Types / Crypto Device / Virtqueues}
+
+\begin{description}
+\item[0] dataq1
+\item[\ldots]
+\item[N-1] dataqN
+\item[N] controlq
+\end{description}
+
+N is set by \field{max_dataqueues}.
+
+\subsection{Feature bits}\label{sec:Device Types / Crypto Device / Feature bits}
+
+VIRTIO_CRYPTO_F_STATELESS_MODE (0) stateless mode is available.
+VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE (1) stateless mode is available for CIPHER service.
+VIRTIO_CRYPTO_F_HASH_STATELESS_MODE (2) stateless mode is available for HASH service.
+VIRTIO_CRYPTO_F_MAC_STATELESS_MODE (3) stateless mode is available for MAC service.
+VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE (4) stateless mode is available for AEAD service.
+
+\subsubsection{Feature bit requirements}\label{sec:Device Types / Crypto Device / Feature bits}
+
+Some crypto feature bits require other crypto feature bits
+(see \ref{drivernormative:Basic Facilities of a Virtio Device / Feature Bits}):
+
+\begin{description}
+\item[VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
+\item[VIRTIO_CRYPTO_F_HASH_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
+\item[VIRTIO_CRYPTO_F_MAC_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
+\item[VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE] Requires VIRTIO_CRYPTO_F_STATELESS_MODE.
+\end{description}
+
+\subsection{Supported crypto services}\label{sec:Device Types / Crypto Device / Supported crypto services}
+
+The virtio crypto device provides the following crypto services: CIPHER, MAC, HASH, and AEAD.
+
+\begin{lstlisting}
+/* CIPHER service */
+#define VIRTIO_CRYPTO_SERVICE_CIPHER 0
+/* HASH service */
+#define VIRTIO_CRYPTO_SERVICE_HASH   1
+/* MAC (Message Authentication Codes) service */
+#define VIRTIO_CRYPTO_SERVICE_MAC    2
+/* AEAD (Authenticated Encryption with Associated Data) service */
+#define VIRTIO_CRYPTO_SERVICE_AEAD   3
+\end{lstlisting}
+
+The above constants are bit numbers, which used to tell the driver which crypto services
+are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
+
+\subsubsection{CIPHER services}\label{sec:Device Types / Crypto Device / Supported crypto services / CIPHER services}
+
+The following CIPHER algorithms are defined:
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_NO_CIPHER                 0
+#define VIRTIO_CRYPTO_CIPHER_ARC4               1
+#define VIRTIO_CRYPTO_CIPHER_AES_ECB            2
+#define VIRTIO_CRYPTO_CIPHER_AES_CBC            3
+#define VIRTIO_CRYPTO_CIPHER_AES_CTR            4
+#define VIRTIO_CRYPTO_CIPHER_DES_ECB            5
+#define VIRTIO_CRYPTO_CIPHER_DES_CBC            6
+#define VIRTIO_CRYPTO_CIPHER_3DES_ECB           7
+#define VIRTIO_CRYPTO_CIPHER_3DES_CBC           8
+#define VIRTIO_CRYPTO_CIPHER_3DES_CTR           9
+#define VIRTIO_CRYPTO_CIPHER_KASUMI_F8          10
+#define VIRTIO_CRYPTO_CIPHER_SNOW3G_UEA2        11
+#define VIRTIO_CRYPTO_CIPHER_AES_F8             12
+#define VIRTIO_CRYPTO_CIPHER_AES_XTS            13
+#define VIRTIO_CRYPTO_CIPHER_ZUC_EEA3           14
+\end{lstlisting}
+
+The above constants have two usages:
+\begin{enumerate}
+\item As bit numbers, which used to tell the driver which CIPHER algorithms
+are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
+\item As values, which used to tell the device which CIPHER algorithm
+a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
+\end{enumerate}
+
+\subsubsection{HASH services}\label{sec:Device Types / Crypto Device / Supported crypto services / HASH services}
+
+The following HASH algorithms are defined:
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_NO_HASH            0
+#define VIRTIO_CRYPTO_HASH_MD5           1
+#define VIRTIO_CRYPTO_HASH_SHA1          2
+#define VIRTIO_CRYPTO_HASH_SHA_224       3
+#define VIRTIO_CRYPTO_HASH_SHA_256       4
+#define VIRTIO_CRYPTO_HASH_SHA_384       5
+#define VIRTIO_CRYPTO_HASH_SHA_512       6
+#define VIRTIO_CRYPTO_HASH_SHA3_224      7
+#define VIRTIO_CRYPTO_HASH_SHA3_256      8
+#define VIRTIO_CRYPTO_HASH_SHA3_384      9
+#define VIRTIO_CRYPTO_HASH_SHA3_512      10
+#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE128      11
+#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE256      12
+\end{lstlisting}
+
+The above constants have two usages:
+\begin{enumerate}
+\item As bit numbers, which used to tell the driver which HASH algorithms
+are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
+\item As values, which used to tell the device which HASH algorithm
+a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
+\end{enumerate}
+
+\subsubsection{MAC services}\label{sec:Device Types / Crypto Device / Supported crypto services / MAC services}
+
+The following MAC algorithms are defined:
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_NO_MAC                       0
+#define VIRTIO_CRYPTO_MAC_HMAC_MD5                 1
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA1                2
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_224             3
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_256             4
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_384             5
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_512             6
+#define VIRTIO_CRYPTO_MAC_CMAC_3DES                25
+#define VIRTIO_CRYPTO_MAC_CMAC_AES                 26
+#define VIRTIO_CRYPTO_MAC_KASUMI_F9                27
+#define VIRTIO_CRYPTO_MAC_SNOW3G_UIA2              28
+#define VIRTIO_CRYPTO_MAC_GMAC_AES                 41
+#define VIRTIO_CRYPTO_MAC_GMAC_TWOFISH             42
+#define VIRTIO_CRYPTO_MAC_CBCMAC_AES               49
+#define VIRTIO_CRYPTO_MAC_CBCMAC_KASUMI_F9         50
+#define VIRTIO_CRYPTO_MAC_XCBC_AES                 53
+#define VIRTIO_CRYPTO_MAC_ZUC_EIA3                 54
+\end{lstlisting}
+
+The above constants have two usages:
+\begin{enumerate}
+\item As bit numbers, which used to tell the driver which MAC algorithms
+are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
+\item As values, which used to tell the device which MAC algorithm
+a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
+\end{enumerate}
+
+\subsubsection{AEAD services}\label{sec:Device Types / Crypto Device / Supported crypto services / AEAD services}
+
+The following AEAD algorithms are defined:
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_NO_AEAD     0
+#define VIRTIO_CRYPTO_AEAD_GCM    1
+#define VIRTIO_CRYPTO_AEAD_CCM    2
+#define VIRTIO_CRYPTO_AEAD_CHACHA20_POLY1305  3
+\end{lstlisting}
+
+The above constants have two usages:
+\begin{enumerate}
+\item As bit numbers, which used to tell the driver which AEAD algorithms
+are supported by the device, see \ref{sec:Device Types / Crypto Device / Device configuration layout}.
+\item As values, which used to tell the device what AEAD algorithm
+a crypto request require by the driver, see \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}.
+\end{enumerate}
+
+\subsection{Device configuration layout}\label{sec:Device Types / Crypto Device / Device configuration layout}
+
+\begin{lstlisting}
+struct virtio_crypto_config {
+    le32 status;
+    le32 max_dataqueues;
+    le32 crypto_services;
+    /* Detailed algorithms mask */
+    le32 cipher_algo_l;
+    le32 cipher_algo_h;
+    le32 hash_algo;
+    le32 mac_algo_l;
+    le32 mac_algo_h;
+    le32 aead_algo;
+    /* Maximum length of cipher key in bytes */
+    le32 max_cipher_key_len;
+    /* Maximum length of authenticated key in bytes */
+    le32 max_auth_key_len;
+    le32 reserved;
+    /* Maximum size of each crypto request's content in bytes */
+    le64 max_size;
+};
+\end{lstlisting}
+
+\begin{description}
+\item[\field{status}] is used to show whether the device is ready to work or not, it can be either zero or have one or more flags
+    Only one read-only bit (for the driver) is currently defined for the \field{status} field: VIRTIO_CRYPTO_S_HW_READY:
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_S_HW_READY  (1 << 0)
+\end{lstlisting}
+
+\item[\field{max_dataqueues}] is the maximum number of data virtqueues exposed by
+    the device. The driver MAY use only one data queue,
+    or it can use more to achieve better performance.
+
+\item[\field{crypto_services}] is a 32-bit mask which indicates the crypto services supported by
+    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services}.
+
+\item[\field{cipher_algo_l}] is the low 32-bit mask wihich indicates the CIPHER algorithms supported by
+    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / CIPHER services}.
+
+\item[\field{cipher_algo_h}] is the high 32-bit mask wihich indicates the CIPHER algorithms supported by
+    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / CIPHER services}.
+
+\item[\field{hash_algo}] is a 32-bit mask wihich indicates the HASH algorithms supported by
+    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / HASH services}.
+
+\item[\field{mac_algo_l}] is the low 32-bit mask wihich indicates the MAC algorithms supported by
+    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / MAC services}.
+
+\item[\field{mac_algo_h}] is the high 32-bit mask wihich indicates the MAC algorithms supported by
+    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / MAC services}.
+
+\item[\field{aead_algo}] is a 32-bit mask wihich indicates the AEAD algorithms supported by
+    the device, see \ref{sec:Device Types / Crypto Device / Supported crypto services  / AEAD services}.
+
+\item[\field{max_cipher_key_len}] is the maximum length of cipher key supported by the device.
+
+\item[\field{max_auth_key_len}] is the maximum length of authenticated key supported by the device.
+
+\item[\field{reserved}] is reserved for future use.
+
+\item[\field{max_size}] is the maximum size of each crypto request's content supported by the device
+\end{description}
+
+\begin{note}
+Unless explicitly stated otherwise all lengths and sizes are in bytes.
+\end{note}
+
+\devicenormative{\subsubsection}{Device configuration layout}{Device Types / Crypto Device / Device configuration layout}
+
+\begin{itemize*}
+\item The device MUST set \field{max_dataqueues} to between 1 and 65535 inclusive.
+\item The device MUST set \field{status} based on the status of the backend crypto accelerator. 
+\item The device MUST accept and handle requests after \field{status} is set to VIRTIO_CRYPTO_S_HW_READY.
+\item The device MUST set \field{crypto_services} based on the crypto services the device offers.
+\item The device MUST set detailed algorithms masks based on the \field{crypto_services} field.
+\item The device MUST set \field{max_size} to show the maximum size of crypto request the device supports.
+\item The device MUST set \field{max_cipher_key_len} to show the maximum length of cipher key if the device supports CIPHER service.
+\item The device MUST set \field{max_auth_key_len} to show the maximum length of authenticated key if the device supports MAC service.
+\end{itemize*}
+
+\drivernormative{\subsubsection}{Device configuration layout}{Device Types / Crypto Device / Device configuration layout}
+
+\begin{itemize*}
+\item The driver MUST read the ready \field{status} from the bottom bit of status to check whether the backend crypto accelerator
+      is ready or not, and the driver MUST reread it after the device reset. 
+\item The driver MUST NOT transmit any requests to the device if the ready \field{status} is not set.
+\item The driver MUST read \field{max_dataqueues} field to discover the number of data queues the device supports.
+\item The driver MUST read \field{crypto_services} field to discover which services the device is able to offer.
+\item The driver MUST read the detailed algorithms fields based on \field{crypto_services} field.
+\item The driver SHOULD read \field{max_size} to discover the maximum size of crypto request the device supports.
+\item The driver SHOULD read \field{max_cipher_key_len} to discover the maximum length of cipher key the device supports.
+\item The driver SHOULD read \field{max_auth_key_len} to discover the maximum length of authenticated key the device supports.
+\end{itemize*}
+
+\subsection{Device Initialization}\label{sec:Device Types / Crypto Device / Device Initialization}
+
+\drivernormative{\subsubsection}{Device Initialization}{Device Types / Crypto Device / Device Initialization}
+
+\begin{itemize*}
+\item The driver MUST identify and initialize all virtqueues.
+\item The driver MUST read the supported crypto services from bits of \field{crypto_services}. 
+\item The driver MUST read the supported algorithms based on \field{crypto_services} field.
+\end{itemize*}
+
+\subsection{Device Operation}\label{sec:Device Types / Crypto Device / Device Operation}
+
+Requests can be transmitted by placing them in both the controlq and dataq.
+Requests consist of a queue-type specific header specifying among
+others the operation, and an operation specific payload.
+Where the payload are composed of operation parameter + output data + input data in general.
+Operation parameters are algorithm-specific parameters, output data is the
+data that should be utilized in operations, and input data is equal to
+"operation result + result data".
+
+The device can support both session mode (See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}) and stateless mode.
+As VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is negotiated, the driver can use stateless mode for CIPHER service, otherwise it can only use session mode.
+
+The header for controlq is as follows:
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_OPCODE(service, op)   (((service) << 8) | (op))
+
+struct virtio_crypto_ctrl_header {
+#define VIRTIO_CRYPTO_CIPHER_CREATE_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x02)
+#define VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x03)
+#define VIRTIO_CRYPTO_HASH_CREATE_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x02)
+#define VIRTIO_CRYPTO_HASH_DESTROY_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x03)
+#define VIRTIO_CRYPTO_MAC_CREATE_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x02)
+#define VIRTIO_CRYPTO_MAC_DESTROY_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x03)
+#define VIRTIO_CRYPTO_AEAD_CREATE_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x02)
+#define VIRTIO_CRYPTO_AEAD_DESTROY_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x03)
+    le32 opcode;
+    /* algo should be service-specific algorithms */
+    le32 algo;
+    le32 flag;
+    /* data virtqueue id */
+    le32 queue_id;
+};
+\end{lstlisting}
+
+The header of dataq is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_op_header {
+#define VIRTIO_CRYPTO_CIPHER_ENCRYPT \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x00)
+#define VIRTIO_CRYPTO_CIPHER_DECRYPT \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x01)
+#define VIRTIO_CRYPTO_HASH \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x00)
+#define VIRTIO_CRYPTO_MAC \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x00)
+#define VIRTIO_CRYPTO_AEAD_ENCRYPT \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x00)
+#define VIRTIO_CRYPTO_AEAD_DECRYPT \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x01)
+    le32 opcode;
+    /* algo should be service-specific algorithms */
+    le32 algo;
+    /* session_id should be service-specific algorithms */
+    le64 session_id;VIRTIO_CRYPTO_F_STATELESS_MODE
+#define VIRTIO_CRYPTO_FLAG_STATE_MODE 1
+#define VIRTIO_CRYPTO_FLAG_STATELESS_MODE 2
+    /* control flag to control the request */
+    le32 flag;
+    le32 padding;
+};
+\end{lstlisting}
+
+The device can set the operation status as follows: VIRTIO_CRYPTO_OK: success;
+VIRTIO_CRYPTO_ERR: failure or device error; VIRTIO_CRYPTO_NOTSUPP: not supported;
+VIRTIO_CRYPTO_INVSESS: invalid session ID when executing crypto operations.
+
+\begin{lstlisting}
+enum VIRITO_CRYPTO_STATUS {
+    VIRTIO_CRYPTO_OK = 0,
+    VIRTIO_CRYPTO_ERR = 1,
+    VIRTIO_CRYPTO_BADMSG = 2,
+    VIRTIO_CRYPTO_NOTSUPP = 3,
+    VIRTIO_CRYPTO_INVSESS = 4,
+    VIRTIO_CRYPTO_MAX
+};
+\end{lstlisting}
+
+\subsubsection{Control Virtqueue}\label{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue}
+
+The driver uses the control virtqueue to send control commands to the
+device, such as session operations (See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}).
+
+The request of controlq is as below:
+
+\begin{lstlisting}
+struct virtio_crypto_op_ctrl_req {
+    struct virtio_crypto_ctrl_header header;
+
+    union {
+        struct virtio_crypto_sym_create_session_req   sym_create_session;
+        struct virtio_crypto_hash_create_session_req  hash_create_session;
+        struct virtio_crypto_mac_create_session_req   mac_create_session;
+        struct virtio_crypto_aead_create_session_req  aead_create_session;
+        struct virtio_crypto_destroy_session_req      destroy_session;
+    } u;
+};
+\end{lstlisting}
+
+struct virtio_crypto_op_ctrl_req is the only loading form of controlq requests.
+The header is the general header, and the union is of the algorithm-specific type,
+which is set by the driver. All the properties in the union are shown as follows.
+
+\paragraph{Session operation}\label{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}
+
+The symmetric algorithms involve the concept of sessions. A session is a
+handle which describes the cryptographic parameters to be applied to
+a number of buffers. The data within a session handle includes:
+
+\begin{enumerate}
+\item The operation (CIPHER, HASH/MAC or both, and if both, the order in
+      which the algorithms should be applied).
+\item The CIPHER set data, including the CIPHER algorithm and mode,
+      the key and its length, and the direction (encryption or decryption).
+\item The HASH/MAC set data, including the HASH algorithm or MAC algorithm,
+      and hash result length (to allow for truncation).
+\begin{itemize*}
+\item Authenticated mode can refer to MAC, which requires that the key and
+      its length are also specified.
+\item For nested mode, the inner and outer prefix data and length are specified,
+      as well as the outer HASH algorithm.
+\end{itemize*}
+\end{enumerate}
+
+The following structure stores the result of session creation set by the device:
+
+\begin{lstlisting}
+struct virtio_crypto_session_input {
+    /* Device-writable part */
+    le64 session_id;
+    le32 status;
+    le32 padding;
+};
+\end{lstlisting}
+
+A request to destroy a session includes the following information:
+
+\begin{lstlisting}
+struct virtio_crypto_destroy_session_req {
+    /* Device-readable part */
+    le64  session_id;
+    /* Device-writable part */
+    le32  status;
+    le32  padding;
+};
+\end{lstlisting}
+
+\subparagraph{Session operation: HASH session}\label{sec:Device Types / Crypto Device / Device
+Operation / Control Virtqueue / Session operation / Session operation: HASH session}
+
+The request of HASH session is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_hash_session_para {
+    /* See VIRTIO_CRYPTO_HASH_* above */
+    le32 algo;
+    /* hash result length */
+    le32 hash_result_len;
+};
+struct virtio_crypto_hash_create_session_req {
+    /* Device-readable part */
+    struct virtio_crypto_hash_session_para para;
+    /* Device-writable part */
+    struct virtio_crypto_session_input input;
+};
+\end{lstlisting}
+
+\subparagraph{Session operation: MAC session}\label{sec:Device Types / Crypto Device / Device
+Operation / Control Virtqueue / Session operation / Session operation: MAC session}
+
+The request of MAC session is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_mac_session_para {
+    /* See VIRTIO_CRYPTO_MAC_* above */
+    le32 algo;
+    /* hash result length */
+    le32 hash_result_len;
+    /* length of authenticated key */
+    le32 auth_key_len;
+    le32 padding;
+};
+
+struct virtio_crypto_mac_create_session_req {
+    /* Device-readable part */
+    struct virtio_crypto_mac_session_para para;
+    /* The authenticated key */
+    u8 auth_key[auth_key_len];
+
+    /* Device-writable part */
+    struct virtio_crypto_session_input input;
+};
+\end{lstlisting}
+
+\subparagraph{Session operation: Symmetric algorithms session}\label{sec:Device Types / Crypto Device / Device
+Operation / Control Virtqueue / Session operation / Session operation: Symmetric algorithms session}
+
+The request of symmetric session includes two parts, CIPHER algorithms and chain
+algorithms (chaining CIPHER and HASH/MAC). The request for CIPHER session is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_cipher_session_para {
+    /* See VIRTIO_CRYPTO_CIPHER* above */
+    le32 algo;
+    /* length of key */
+    le32 keylen;
+#define VIRTIO_CRYPTO_OP_ENCRYPT  1
+#define VIRTIO_CRYPTO_OP_DECRYPT  2
+    /* encryption or decryption */
+    le32 op;
+    le32 padding;
+};
+
+struct virtio_crypto_cipher_session_req {
+    /* Device-readable part */
+    struct virtio_crypto_cipher_session_para para;
+    /* The cipher key */
+    u8 cipher_key[keylen];
+
+    /* Device-writable part */
+    struct virtio_crypto_session_input input;
+};
+\end{lstlisting}
+
+The request for algorithm chaining is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_alg_chain_session_para {
+#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER  1
+#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH  2
+    le32 alg_chain_order;
+/* Plain hash */
+#define VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN    1
+/* Authenticated hash (mac) */
+#define VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH     2
+/* Nested hash */
+#define VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED   3
+    le32 hash_mode;
+    struct virtio_crypto_cipher_session_para cipher_param;
+    union {
+        struct virtio_crypto_hash_session_para hash_param;
+        struct virtio_crypto_mac_session_para mac_param;
+    } u;
+    /* length of the additional authenticated data (AAD) in bytes */
+    le32 aad_len;
+    le32 padding;
+};
+
+struct virtio_crypto_alg_chain_session_req {
+    /* Device-readable part */
+    struct virtio_crypto_alg_chain_session_para para;
+    /* The cipher key */
+    u8 cipher_key[keylen];
+    /* The authenticated key */
+    u8 auth_key[auth_key_len];
+
+    /* Device-writable part */
+    struct virtio_crypto_session_input input;
+};
+\end{lstlisting}
+
+The request for symmetric algorithm is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_sym_create_session_req {
+    union {
+        struct virtio_crypto_cipher_session_req cipher;
+        struct virtio_crypto_alg_chain_session_req chain;
+    } u;
+
+    /* Device-readable part */
+
+/* No operation */
+#define VIRTIO_CRYPTO_SYM_OP_NONE  0
+/* Cipher only operation on the data */
+#define VIRTIO_CRYPTO_SYM_OP_CIPHER  1
+/* Chain any cipher with any hash or mac operation. The order
+   depends on the value of alg_chain_order param */
+#define VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING  2
+    le32 op_type;
+    le32 padding;
+};
+\end{lstlisting}
+
+\subparagraph{Session operation: AEAD session}\label{sec:Device Types / Crypto Device / Device
+Operation / Control Virtqueue / Session operation / Session operation: AEAD session}
+
+The request for AEAD session is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_aead_session_para {
+    /* See VIRTIO_CRYPTO_AEAD_* above */
+    le32 algo;
+    /* length of key */
+    le32 key_len;
+    /* Authentication tag length */
+    le32 tag_len;
+    /* The length of the additional authenticated data (AAD) in bytes */
+    le32 aad_len;
+    /* encryption or decryption, See above VIRTIO_CRYPTO_OP_* */
+    le32 op;
+    le32 padding;
+};
+
+struct virtio_crypto_aead_create_session_req {
+    /* Device-readable part */
+    struct virtio_crypto_aead_session_para para;
+    u8 key[key_len];
+
+    /* Device-writeable part */
+    struct virtio_crypto_session_input input;
+};
+\end{lstlisting}
+
+\drivernormative{\subparagraph}{Session operation: create session}{Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation / Session operation: create session}
+
+\begin{itemize*}
+\item The driver MUST set the control general header and corresponding properties of the union in structure virtio_crypto_op_ctrl_req. See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue}.
+\item The driver MUST set \field{opcode} field based on service type: CIPHER, HASH, MAC, or AEAD.
+\item The driver MUST set \field{queue_id} field to show used dataq.
+\end{itemize*}
+
+\devicenormative{\subparagraph}{Session operation: create session}{Device Types / Crypto Device / Device
+Operation / Control Virtqueue / Session operation / Session operation: create session}
+
+\begin{itemize*}
+\item The device MUST set \field{session_id} field as a session identifier return to the driver when the device finishes processing session creation.
+\item The device MUST set \field{status} field to one of the values of enum VIRITO_CRYPTO_STATUS.
+\end{itemize*}
+
+\drivernormative{\subparagraph}{Session operation: destroy session}{Device Types / Crypto Device / Device
+Operation / Control Virtqueue / Session operation / Session operation: destroy session}
+
+\begin{itemize*}
+\item The driver MUST set \field{opcode} field based on service type: CIPHER, HASH, MAC, or AEAD.
+\item The driver MUST set the \field{session_id} to a valid value which assigned by the device when a session is created.
+\end{itemize*}
+
+\devicenormative{\subparagraph}{Session operation: destroy session}{Device Types / Crypto Device / Device
+Operation / Control Virtqueue / Session operation / Session operation: destroy session}
+
+\begin{itemize*}
+\item The device MUST set \field{status} field to one of the values of enum VIRITO_CRYPTO_STATUS.
+\end{itemize*}
+
+\subsubsection{Data Virtqueue}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue}
+
+The driver uses the data virtqueue to transmit the requests of crypto operation to the device,
+and completes the data plane operations (such as crypto operation).
+
+The session mode request of dataq is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_op_data_req {
+    struct virtio_crypto_op_header header;
+
+    union {
+        struct virtio_crypto_sym_data_req   sym_req;
+        struct virtio_crypto_hash_data_req  hash_req;
+        struct virtio_crypto_mac_data_req   mac_req;
+        struct virtio_crypto_aead_data_req  aead_req;
+    } u;
+};
+\end{lstlisting}
+
+The request of dataq, mixing both session and stateless mode is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_op_data_req_mux {
+    struct virtio_crypto_op_header header;
+
+    union {
+        struct virtio_crypto_sym_data_req   sym_req;
+        struct virtio_crypto_hash_data_req  hash_req;
+        struct virtio_crypto_mac_data_req   mac_req;
+        struct virtio_crypto_aead_data_req  aead_req;
+        struct virtio_crypto_sym_data_req_stateless   sym_stateless_req;
+        struct virtio_crypto_hash_data_req_stateless  hash_stateless_req;
+        struct virtio_crypto_mac_data_req_stateless   mac_stateless_req;
+        struct virtio_crypto_aead_data_req_stateless  aead_stateless_req;
+    } u;
+};
+\end{lstlisting}
+
+The header is the general header and the union is of the algorithm-specific type,
+which is set by the driver. All properties in the union are shown as follows.
+
+There is a unified input header structure for all crypto services.
+
+The structure is defined as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_inhdr {
+    u8 status;
+};
+\end{lstlisting}
+
+\subsubsection{HASH Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / HASH Service Operation}
+
+The session mode request of HASH service:
+
+\begin{lstlisting}
+struct virtio_crypto_hash_para {
+    /* length of source data */
+    le32 src_data_len;
+    /* hash result length */
+    le32 hash_result_len;
+};
+
+struct virtio_crypto_hash_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_hash_para para;
+    /* Source data */
+    u8 src_data[src_data_len];
+
+    /* Device-writable part */
+    /* Hash result data */
+    u8 hash_result[hash_result_len];
+    struct virtio_crypto_inhdr inhdr;
+};
+\end{lstlisting}
+
+Each data request uses virtio_crypto_hash_data_req structure to store information
+used to run the HASH operations. 
+
+The information includes the hash parameters stored by \field{para}, output data and input data.
+The output data here includes the source data and the input data includes the hash result data used to save the results of the HASH operations.
+\field{inhdr} stores status of executing the HASH operations.
+
+The stateless mode request of HASH service is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_hash_para_statelesss {
+    struct {
+        /* See VIRTIO_CRYPTO_HASH_* above */
+        le32 algo;
+    } sess_para;
+
+    /* length of source data */
+    le32 src_data_len;
+    /* hash result length */
+    le32 hash_result_len;
+    le32 reserved;
+};
+struct virtio_crypto_hash_data_req_stateless {
+    /* Device-readable part */
+    struct virtio_crypto_hash_para_stateless para;
+    /* Source data */
+    u8 src_data[src_data_len];
+
+    /* Device-writable part */
+    /* Hash result data */
+    u8 hash_result[hash_result_len];
+    struct virtio_crypto_inhdr inhdr;
+};
+\end{lstlisting}
+
+\drivernormative{\paragraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / HASH Service Operation}
+
+\begin{itemize*}
+\item If the driver uses the session mode, then the driver MUST set the \field{session_id} in struct virtio_crypto_op_header
+      to a valid value which assigned by the device when a session is created.
+\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto requests. Otherwise, the driver MUST use the struct virtio_crypto_op_data_req.
+\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is negotiated, 1) if the driver use the stateless mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header
+      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in struct virtio_crypto_hash_para_statelession.sess_para, 2) if the driver still uses the session mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
+\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_HASH.
+\end{itemize*}
+
+\devicenormative{\paragraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / HASH Service Operation}
+
+\begin{itemize*}
+\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto requests. Otherwise, the device MUST parse the struct virtio_crypto_op_data_req.
+\item If the VIRTIO_CRYPTO_F_HASH_STATELESS_MODE feature bit is negotiated, the device MUST parse \field{flag} field in struct virtio_crypto_op_header in order to decide which mode the driver uses.
+\item The device MUST copy the results of HASH operations to the hash_result[] if HASH operations success.
+\item The device MUST set \field{status} in struct virtio_crypto_inhdr to one of the values of enum VIRITO_CRYPTO_STATUS.
+\end{itemize*}
+
+\subsubsection{MAC Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / MAC Service Operation}
+
+The session mode request of MAC service is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_mac_para {
+    struct virtio_crypto_hash_para hash;
+};
+
+struct virtio_crypto_mac_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_mac_para para;
+    /* Source data */
+    u8 src_data[src_data_len];
+
+    /* Device-writable part */
+    /* Hash result data */
+    u8 hash_result[hash_result_len];
+    struct virtio_crypto_inhdr inhdr;
+};
+\end{lstlisting}
+
+Each data request uses virtio_crypto_mac_data_req structure to store information
+used to run the MAC operations. 
+
+The information includes the hash parameters stored by \field{para}, output data and input data.
+The output data here includes the source data and the input data includes the hash result data used to save the results of the MAC operations.
+\field{inhdr} stores status of executing the MAC operations.
+
+The stateless mode request of MAC service:
+
+\begin{lstlisting}
+struct virtio_crypto_mac_para_stateless {
+    struct {
+        /* See VIRTIO_CRYPTO_MAC_* above */
+        le32 algo;
+        /* length of authenticated key */
+        le32 auth_key_len;
+    } sess_para;
+
+    /* length of source data */
+    le32 src_data_len;
+    /* hash result length */
+    le32 hash_result_len;
+};
+
+struct virtio_crypto_mac_data_req_stateless {
+    /* Device-readable part */
+    struct virtio_crypto_mac_para_stateless para;
+    /* The authenticated key */
+    u8 auth_key[auth_key_len];
+    /* Source data */
+    u8 src_data[src_data_len];
+
+    /* Device-writable part */
+    /* Hash result data */
+    u8 hash_result[hash_result_len];
+    struct virtio_crypto_inhdr inhdr;
+};
+\end{lstlisting}
+
+\drivernormative{\paragraph}{MAC Service Operation}{Device Types / Crypto Device / Device Operation / MAC Service Operation}
+
+\begin{itemize*}
+\item If the driver uses the session mode, then the driver MUST set the \field{session_id} in struct virtio_crypto_op_header
+      to a valid value which assigned by the device when a session is created.
+\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto requests. Otherwise, the driver MUST use the struct virtio_crypto_op_data_req.
+\item If the VIRTIO_CRYPTO_F_MAC_STATELESS_MODE feature bit is negotiated, 1) if the driver use the stateless mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header
+      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in struct virtio_crypto_mac_para_statelession.sess_para, 2) if the driver still uses the session mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
+\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_MAC.
+\end{itemize*}
+
+\devicenormative{\paragraph}{MAC Service Operation}{Device Types / Crypto Device / Device Operation / MAC Service Operation}
+
+\begin{itemize*}
+\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto requests. Otherwise, the device MUST parse the struct virtio_crypto_op_data_req.
+\item If the VIRTIO_CRYPTO_F_MAC_STATELESS_MODE feature bit is negotiated, the device MUST parse \field{flag} field in struct virtio_crypto_op_header in order to decide which mode the driver uses.
+\item The device MUST copy the results of MAC operations to the hash_result[] if HASH operations success.
+\item The device MUST set \field{status} in struct virtio_crypto_inhdr to one of the values of enum VIRITO_CRYPTO_STATUS.
+\end{itemize*}
+
+\subsubsection{Symmetric algorithms Operation}\label{sec:Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation}
+
+The session mode request of plain CIPHER service is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_cipher_para {
+    /*
+     * Byte Length of valid IV/Counter data pointed to by the below iv data.
+     *
+     * For block ciphers in CBC or F8 mode, or for Kasumi in F8 mode, or for
+     *   SNOW3G in UEA2 mode, this is the length of the IV (which
+     *   must be the same as the block length of the cipher).
+     * For block ciphers in CTR mode, this is the length of the counter
+     *   (which must be the same as the block length of the cipher).
+     */
+    le32 iv_len;
+    /* length of source data */
+    le32 src_data_len;
+    /* length of destination data */
+    le32 dst_data_len;
+    le32 padding;
+};
+
+struct virtio_crypto_cipher_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_cipher_para para;
+    /*
+     * Initialization Vector or Counter data.
+     *
+     * For block ciphers in CBC or F8 mode, or for Kasumi in F8 mode, or for
+     *   SNOW3G in UEA2 mode, this is the Initialization Vector (IV)
+     *   value.
+     * For block ciphers in CTR mode, this is the counter.
+     * For AES-XTS, this is the 128bit tweak, i, from IEEE Std 1619-2007.
+     *
+     * The IV/Counter will be updated after every partial cryptographic
+     * operation.
+     */
+    u8 iv[iv_len];
+    /* Source data */
+    u8 src_data[src_data_len];
+
+    /* Device-writable part */
+    /* Destination data */
+    u8 dst_data[dst_data_len];
+    struct virtio_crypto_inhdr inhdr;
+};
+\end{lstlisting}
+
+The session mode request of algorithm chaining is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_alg_chain_data_para {
+    le32 iv_len;
+    /* Length of source data */
+    le32 src_data_len;
+    /* Length of destination data */
+    le32 dst_data_len;
+    /* Starting point for cipher processing in source data */
+    le32 cipher_start_src_offset;
+    /* Length of the source data that the cipher will be computed on */
+    le32 len_to_cipher;
+    /* Starting point for hash processing in source data */
+    le32 hash_start_src_offset;
+    /* Length of the source data that the hash will be computed on */
+    le32 len_to_hash;
+    /* Length of the additional auth data */
+    le32 aad_len;
+    /* Length of the hash result */
+    le32 hash_result_len;
+    le32 reserved;
+};
+
+struct virtio_crypto_alg_chain_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_alg_chain_data_para para;
+    /* Initialization Vector or Counter data */
+    u8 iv[iv_len];
+    /* Source data */
+    u8 src_data[src_data_len];
+    /* Additional authenticated data if exists  */
+    u8 aad[aad_len];
+
+    /* Device-writable part */
+    /* Destination data */
+    u8 dst_data[dst_data_len];
+    /* Hash result data */
+    u8 hash_result[hash_result_len];
+    struct virtio_crypto_inhdr inhdr;
+};
+\end{lstlisting}
+
+The session mode request of symmetric algorithm is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_sym_data_req {
+    union {
+        struct virtio_crypto_cipher_data_req cipher;
+        struct virtio_crypto_alg_chain_data_req chain;
+    } u;
+
+    /* Device-readable part */
+
+    /* See above VIRTIO_CRYPTO_SYM_OP_* */
+    le32 op_type;
+    le32 padding;
+};
+\end{lstlisting}
+
+Each data request uses virtio_crypto_sym_data_req structure to store information
+used to run the CIPHER operations. 
+
+The information includes the cipher parameters stored by \field{para}, output data and input data.
+In the first virtio_crypto_cipher_para structure, \field{iv_len} specifies the length of the initialization vector or counter,
+\field{src_data_len} specifies the length of the source data, and \field{dst_data_len} specifies the
+length of the destination data. 
+For plain CIPHER operations, the output data here includes the IV/Counter data and source data, and the input data includes the destination data used to save the results of the CIPHER operations. 
+
+For algorithms chain, the output data here includes the IV/Counter data, source data and additional authenticated data if exists.
+The input data includes both destination data and hash result data used to store the results of the HASH/MAC operations.
+\field{inhdr} stores status of executing the crypto operations.
+
+The stateless mode request of plain CIPHER service is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_cipher_para_stateless {
+    struct {
+        /* See VIRTIO_CRYPTO_CIPHER* above */
+        le32 algo;
+        /* length of key */
+        le32 keylen;
+
+        /* See VIRTIO_CRYPTO_OP_* above */
+        le32 op;
+    } sess_para;
+
+    /*
+     * Byte Length of valid IV/Counter data pointed to by the below iv data.
+     */
+    le32 iv_len;
+    /* length of source data */
+    le32 src_data_len;
+    /* length of destination data */
+    le32 dst_data_len;
+};
+
+struct virtio_crypto_cipher_data_req_stateless {
+    /* Device-readable part */
+    struct virtio_crypto_cipher_para_stateless para;
+    /* The cipher key */
+    u8 cipher_key[keylen];
+
+    /* Initialization Vector or Counter data. */
+    u8 iv[iv_len];
+    /* Source data */
+    u8 src_data[src_data_len];
+
+    /* Device-writable part */
+    /* Destination data */
+    u8 dst_data[dst_data_len];
+    struct virtio_crypto_inhdr inhdr;
+};
+\end{lstlisting}
+
+The stateless mode request of algorithm chaining is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_alg_chain_data_para_stateless {
+    struct {
+        /* See VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_* above */
+        le32 alg_chain_order;
+        /* length of the additional authenticated data in bytes */
+        le32 aad_len;
+
+        struct {
+            /* See VIRTIO_CRYPTO_CIPHER* above */
+            le32 algo;
+            /* length of key */
+            le32 keylen;
+            /* See VIRTIO_CRYPTO_OP_* above */
+            le32 op;
+        } cipher;
+
+        struct {
+            /* See VIRTIO_CRYPTO_HASH_* or VIRTIO_CRYPTO_MAC_* above */
+            le32 algo;
+            /* length of authenticated key */
+            le32 auth_key_len;
+            /* See VIRTIO_CRYPTO_SYM_HASH_MODE_* above */
+            le32 hash_mode;
+        } hash;
+    } sess_para;
+
+    le32 iv_len;
+    /* Length of source data */
+    le32 src_data_len;
+    /* Length of destination data */
+    le32 dst_data_len;
+    /* Starting point for cipher processing in source data */
+    le32 cipher_start_src_offset;
+    /* Length of the source data that the cipher will be computed on */
+    le32 len_to_cipher;
+    /* Starting point for hash processing in source data */
+    le32 hash_start_src_offset;
+    /* Length of the source data that the hash will be computed on */
+    le32 len_to_hash;
+    /* Length of the additional auth data */
+    le32 aad_len;
+    /* Length of the hash result */
+    le32 hash_result_len;
+    le32 reserved;
+};
+
+struct virtio_crypto_alg_chain_data_req_stateless {
+    /* Device-readable part */
+    struct virtio_crypto_alg_chain_data_para_stateless para;
+    /* The cipher key */
+    u8 cipher_key[keylen];
+    /* The auth key */
+    u8 auth_key[auth_key_len];
+    /* Initialization Vector or Counter data */
+    u8 iv[iv_len];
+    /* Source data */
+    u8 src_data[src_data_len];
+    /* Additional authenticated data if exists  */
+    u8 aad[aad_len];
+
+    /* Device-writable part */
+    /* Destination data */
+    u8 dst_data[dst_data_len];
+    /* Hash result data */
+    u8 hash_result[hash_result_len];
+    struct virtio_crypto_inhdr inhdr;
+};
+\end{lstlisting}
+
+The stateless mode request of symmetric algorithm is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_sym_data_req_stateless {
+    union {
+        struct virtio_crypto_cipher_data_req_stateless cipher;
+        struct virtio_crypto_alg_chain_data_req_stateless chain;
+    } u;
+
+    /* Device-readable part */
+
+    /* See above VIRTIO_CRYPTO_SYM_OP_* */
+    le32 op_type;
+    le32 padding;
+};
+\end{lstlisting}
+
+\drivernormative{\paragraph}{Symmetric algorithms Operation}{Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation}
+
+\begin{itemize*}
+\item If the driver uses the session mode, then the driver MUST set the \field{session_id} in struct virtio_crypto_op_header
+      to a valid value which assigned by the device when a session is created.
+\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto requests. Otherwise, the driver MUST use the struct virtio_crypto_op_data_req.
+\item If the VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is negotiated, 1) if the driver use the stateless mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header
+      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in struct virtio_crypto_cipher_para_statelession.sess_para or struct virtio_crypto_alg_chain_data_para_stateless.sess_para, 2) if the driver still uses the session mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
+\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_CIPHER_ENCRYPT or VIRTIO_CRYPTO_CIPHER_DECRYPT.
+\item The driver MUST specify the fields of struct virtio_crypto_cipher_data_req in struct virtio_crypto_sym_data_req if the request is based on VIRTIO_CRYPTO_SYM_OP_CIPHER.
+\item The driver MUST specify the fields of both struct virtio_crypto_cipher_data_req and struct virtio_crypto_mac_data_req in struct virtio_crypto_sym_data_req if the request
+      is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING type and in the VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode.
+\end{itemize*}
+
+\devicenormative{\paragraph}{Symmetric algorithms Operation}{Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation}
+
+\begin{itemize*}
+\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto requests. Otherwise, the device MUST parse the struct virtio_crypto_op_data_req.
+\item If the VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE feature bit is negotiated, the device MUST parse \field{flag} field in struct virtio_crypto_op_header in order to decide which mode the driver uses.
+\item The device MUST parse the virtio_crypto_sym_data_req based on the \field{opcode} in general header.
+\item The device SHOULD only parse fields of struct virtio_crypto_cipher_data_req in struct virtio_crypto_sym_data_req if the request is VIRTIO_CRYPTO_SYM_OP_CIPHER type.
+\item The device MUST parse fields of both struct virtio_crypto_cipher_data_req and struct virtio_crypto_mac_data_req in struct virtio_crypto_sym_data_req if the request
+      is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING operation type and in the VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode.
+\item The device MUST copy the result of cryptographic operation to the dst_data[] in both plain CIPHER mode and algorithms chain mode.
+\item The device MUST check the \field{para}.\field{add_len} is bigger than 0 before parse the additional authenticated data in plain algorithms chain mode.
+\item The device MUST copy the result of HASH/MAC operation to the hash_result[] is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING type.
+\item The device MUST set the \field{status} field in struct virtio_crypto_inhdr to one of the values of enum VIRITO_CRYPTO_STATUS.
+\end{itemize*}
+
+\paragraph{Steps of Operation}\label{sec:Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation / Steps of Operation}
+
+\subparagraph{Step1: Create session}\label{sec:Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation / Steps of Operation / Step1: Create session on session mode}
+
+\begin{enumerate}
+\item The driver specifies information in struct virtio_crypto_op_ctrl_req, including the algorithm name, key, keylen etc;
+\item The driver adds the request of session creation into the controlq's Vring Descriptor Table;
+\item The driver kicks the device;
+\item The device receives the request from controlq;
+\item The device parses information about the request, and determines the information concerning the backend crypto accelerator;
+\item The device packs information based on the APIs of the backend crypto accelerator;
+\item The device invokes the session creation APIs of the backend crypto accelerator to create a session;
+\item The device returns the session id to the driver.
+\end{enumerate}
+
+\subparagraph{Step2: Execute cryptographic operation}\label{sec:Device Types / Crypto Device / Device Operation / Symmetric algorithms Operation / Steps of Operation / Step2: Execute cryptographic operation}
+
+\begin{enumerate}
+\item The driver specifies information in struct virtio_crypto_op_data_req, including struct virtio_crypto_op_header and struct virtio_crypto_sym_data_req, see \ref{sec:Device Types / Crypto Device / Device
+      Operation / Symmetric algorithms Operation};
+\item The driver adds the request for cryptographic operation into the dataq's Vring Descriptor Table;
+\item The driver kicks the device (Or the device actively polls the dataq's Vring Descriptor Table);
+\item The device receives the request from dataq;
+\item The device parses information about the request, and determines the identification information for the backend crypto accelerator. For example, converting guest physical addresses to host physical addresses;
+\item The device packs identification information based on the API of the backend crypto accelerator;
+\item The device invokes the cryptographic APIs of the backend crypto accelerator;
+\item The backend crypto accelerator executes the cryptographic operation implicitly;
+\item The device receives the cryptographic results from the backend crypto accelerator (synchronous or asynchronous);
+\item The device sets the \field{status} in struct virtio_crypto_inhdr;
+\item The device updates and flushes the Used Ring to return the cryptographic results to the driver;
+\item The device notifies the driver (Or the driver actively polls the dataq's Used Ring);
+\item The driver saves the cryptographic results.
+\end{enumerate}
+
+\begin{note}
+\begin{itemize*}
+\item For better performance, the device should by preference use vhost scheme (user space or kernel space)
+      as the backend crypto accelerator in the real production environment.
+\end{itemize*}
+\end{note}
+
+\subsubsection{AEAD Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / AEAD Service Operation}
+
+The session mode request of symmetric algorithm is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_aead_para {
+    /*
+     * Byte Length of valid IV data.
+     *
+     * For GCM mode, this is either 12 (for 96-bit IVs) or 16, in which
+     *   case iv points to J0.
+     * For CCM mode, this is the length of the nonce, which can be in the
+     *   range 7 to 13 inclusive.
+     */
+    le32 iv_len;
+    /* length of additional auth data */
+    le32 aad_len;
+    /* length of source data */
+    le32 src_data_len;
+    /* length of dst data, this should be at least src_data_len + tag_len */
+    le32 dst_data_len;
+    /* Authentication tag length */
+    le32 tag_len;
+    le32 reserved;
+};
+
+struct virtio_crypto_aead_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_aead_para para;
+    /*
+     * Initialization Vector data.
+     *
+     * For GCM mode, this is either the IV (if the length is 96 bits) or J0
+     *   (for other sizes), where J0 is as defined by NIST SP800-38D.
+     *   Regardless of the IV length, a full 16 bytes needs to be allocated.
+     * For CCM mode, the first byte is reserved, and the nonce should be
+     *   written starting at &iv[1] (to allow space for the implementation
+     *   to write in the flags in the first byte).  Note that a full 16 bytes
+     *   should be allocated, even though the iv_len field will have
+     *   a value less than this.
+     *
+     * The IV will be updated after every partial cryptographic operation.
+     */
+    u8 iv[iv_len];
+    /* Source data */
+    u8 src_data[src_data_len];
+    /* Additional authenticated data if exists  */
+    u8 aad[aad_len];
+
+    /* Device-writable part */
+    /* Pointer to output data */
+    u8 dst_data[dst_data_len];
+
+    struct virtio_crypto_inhdr inhdr;
+};
+\end{lstlisting}
+
+Each data request uses virtio_crypto_aead_data_req structure to store information
+used to run the AEAD operations. 
+
+The information includes the hash parameters stored by \field{para}, output data and input data.
+In the first virtio_crypto_aead_para structure, \field{iv_len} specifies the length of the initialization vector. \field{tag_len} specifies the length of the authentication tag;
+\field{aad_len} specifies the length of additional authentication data, \field{src_data_len} specifies the
+length of the source data; \field{dst_data_len} specifies the length of the destination data, which is at least \field{src_data_len} + \field{tag_len}.
+
+The output data here includes the IV/Counter data, source data and additional authenticated data if exists.
+The input data includes both destination data used to save the results of the AEAD operations.
+\field{inhdr} stores status of executing the AEAD operations.
+
+The stateless mode request of AEAD service is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_aead_para_stateless {
+    struct {
+        /* See VIRTIO_CRYPTO_AEAD_* above */
+        le32 algo;
+        /* length of key */
+        le32 key_len;
+        /* encrypt or decrypt, See above VIRTIO_CRYPTO_OP_* */
+        le32 op;
+    } sess_para;
+
+    /* Byte Length of valid IV data. */
+    le32 iv_len;
+    /* Authentication tag length */
+    le32 tag_len;
+    /* length of additional auth data */
+    le32 aad_len;
+    /* length of source data */
+    le32 src_data_len;
+    /* length of dst data, this should be at least src_data_len + tag_len */
+    le32 dst_data_len;
+};
+
+struct virtio_crypto_aead_data_req_stateless {
+    /* Device-readable part */
+    struct virtio_crypto_aead_para_stateless para;
+    /* The cipher key */
+    u8 key[key_len];
+    /* Initialization Vector data. */
+    u8 iv[iv_len];
+    /* Source data */
+    u8 src_data[src_data_len];
+    /* Additional authenticated data if exists  */
+    u8 aad[aad_len];
+
+    /* Device-writable part */
+    /* Pointer to output data */
+    u8 dst_data[dst_data_len];
+
+    struct virtio_crypto_inhdr inhdr;
+};
+\end{lstlisting}
+
+\drivernormative{\paragraph}{AEAD Service Operation}{Device Types / Crypto Device / Device Operation / AEAD Service Operation}
+
+\begin{itemize*}
+\item If the driver uses the session mode, then the driver MUST set the \field{session_id} in struct virtio_crypto_op_header
+      to a valid value which assigned by the device when a session is created.
+\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the driver MUST use the struct virtio_crypto_op_data_req_mux to wrap crypto requests. Otherwise, the driver MUST use the struct virtio_crypto_op_data_req.
+\item If the VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE feature bit is negotiated, 1) if the driver use the stateless mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header
+      to VIRTIO_CRYPTO_FLAG_STATELESS_MODE and MUST set fields in struct virtio_crypto_aead_para_statelession.sess_para, 2) if the driver still uses the session mode, then the driver MUST set \field{flag} field in struct virtio_crypto_op_header to VIRTIO_CRYPTO_FLAG_STATE_MODE.
+\item The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_AEAD_ENCRYPT or VIRTIO_CRYPTO_AEAD_DECRYPT.
+\end{itemize*}
+
+\devicenormative{\paragraph}{AEAD Service Operation}{Device Types / Crypto Device / Device Operation / AEAD Service Operation}
+
+\begin{itemize*}
+\item If the VIRTIO_CRYPTO_F_STATELESS_MODE feature bit is negotiated, the device MUST parse the struct virtio_crypto_op_data_req_mux for crypto requests. Otherwise, the device MUST parse the struct virtio_crypto_op_data_req.
+\item If the VIRTIO_CRYPTO_F_AEAD_STATELESS_MODE feature bit is negotiated, the device MUST parse the virtio_crypto_aead_data_req based on the \field{opcode} in general header.
+\item The device MUST copy the result of cryptographic operation to the dst_data[].
+\item The device MUST copy the authentication tag to the dst_data[] offset the cipher result.
+\item The device MUST set the \field{status} field in struct virtio_crypto_inhdr to one of the values of enum VIRITO_CRYPTO_STATUS.
+\item When the \field{opcode} is VIRTIO_CRYPTO_AEAD_DECRYPT, the device MUST verify and return the verification result to the driver, and if the verification result is incorrect, VIRTIO_CRYPTO_BADMSG (bad message) MUST be returned to the driver.
+\end{itemize*}
\ No newline at end of file