diff mbox

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

Message ID 1474364762-285736-2-git-send-email-arei.gonglei@huawei.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gonglei (Arei) Sept. 20, 2016, 9:46 a.m. UTC
The virtio crypto device is a virtual crypto device (ie. hardware
crypto accelerator card). The virtio crypto device can provide
five crypto services: CIPHER, MAC, HASH, AEAD, KDF, ASYM, PRIMITIVE.

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

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: Hanweidong <hanweidong@huawei.com>
CC: Mihai Claudiu Caraman <mike.caraman@nxp.com>
---
 content.tex       |   2 +
 virtio-crypto.tex | 942 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 944 insertions(+)
 create mode 100644 virtio-crypto.tex

Comments

Michael S. Tsirkin Sept. 20, 2016, 7:10 p.m. UTC | #1
On Tue, Sep 20, 2016 at 05:46:01PM +0800, Gonglei wrote:
> The virtio crypto device is a virtual crypto device (ie. hardware
> crypto accelerator card). The virtio crypto device can provide
> five crypto services: CIPHER, MAC, HASH, AEAD, KDF, ASYM, PRIMITIVE.

Only CIPHER, MAC, HASH, AEAD are documented at this point.
Let's drop others for now?


> 
> In this patch, CIPHER, MAC, HASH, AEAD services are introduced.
> 
> 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: Hanweidong <hanweidong@huawei.com>
> CC: Mihai Claudiu Caraman <mike.caraman@nxp.com>
> ---
>  content.tex       |   2 +
>  virtio-crypto.tex | 942 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 944 insertions(+)
>  create mode 100644 virtio-crypto.tex
> 
> 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..ac1fc0a
> --- /dev/null
> +++ b/virtio-crypto.tex
> @@ -0,0 +1,942 @@
> +\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 the data queue and are ultimately handled by the
> +real crypto accelerators.

I would like "real" to be renamed "backend".

> The second 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 seven crypto
> +services: CIPHER, MAC, HASH, AEAD, KDF, ASYM, and PRIMITIVE.
> +
> +
> +\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}
> +  None currently defined
> +
> +\subsection{Device configuration layout}\label{sec:Device Types / Crypto Device / Device configuration layout}
> +
> +The following driver-read-only configuration fields are defined:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_config {
> +    le32  status;
> +    le32  max_dataqueues;

Is this just num_queues - 1?
Why isn't the generic num_queues sufficient?


> +    le32  crypto_services;

Would it make sense to use feature bits for this instead?
Looks like that you need to add algo masks when
adding services, and tying config space fields
to features  is well supported by guests.

> +    /* detailed algorithms mask */
> +    le32 cipher_algo_l;
> +    le32 cipher_algo_h;
> +    le32 hash_algo;
> +    le32 mac_algo_l;
> +    le32 mac_algo_h;
> +    le32 asym_algo;
> +    le32 kdf_algo;
> +    le32 aead_algo;
> +    le32 primitive_algo;
> +};
> +\end{lstlisting}
> +
> +In the \field{status}, the value of the field is VIRTIO_CRYPTO_S_HW_READY or VIRTIO_CRYPTO_S_STARTED.
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_S_HW_READY  (1 << 0)
> +#define VIRTIO_CRYPTO_S_STARTED  (1 << 1)
> +\end{lstlisting}
> +
> +The following driver-read-only fields include \field{max_dataqueues}, which specifies the
> +maximum number of data virtqueues (dataq1\ldots dataqN), and \field{crypto_services},
> +which indicates the crypto service the virtio crypto supports.
> +
> +The following services are defined:
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_SERVICE_CIPHER (0) /* CIPHER service */
> +#define VIRTIO_CRYPTO_SERVICE_HASH   (1) /* HASH service */
> +#define VIRTIO_CRYPTO_SERVICE_MAC    (2) /* MAC (Message Authentication Codes) service */
> +#define VIRTIO_CRYPTO_SERVICE_AEAD   (3) /* AEAD (Authenticated Encryption with Associated Data) service */
> +\end{lstlisting}
> +
> +The last driver-read-only fields specify detailed algorithms masks 
> +the device offers for corresponding 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 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 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 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}
> +
> +\begin{note}
> +More algorithms will be defined in the future.
> +\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 hardware-backed implementation. 
> +      If the backend crypto accelerator is ready for work, then set the ready \field{status} to VIRTIO_CRYPTO_S_HW_READY.

Let's write it in terms that are testable. For example:
	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 offer.
> +\item The device MUST set detailed algorithms masks based on the \field{crypto_services} field.
> +\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 hardware-backed
> +      implementation is ready or not, and the driver MUST reread it after the device reset. 
> +\item The driver MUST NOT transmit any packets to the device if the ready \filed{status} is not set.
> +\item The driver MAY 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.
> +\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 the control virtqueue.
> +\item The driver MUST read the supported crypto services from bits of \field{crypto_servies}. 
> +\item The driver MUST read the supported algorithms based on \field{crypto_services} field.
> +\end{itemize*}
> +
> +\devicenormative{\subsubsection}{Device Initialization}{Device Types / Crypto Device / Device Initialization}
> +
> +\begin{itemize*}
> +\item The device MUST be configured with at least one accelerator which executes real crypto operations.
> +\item The device MUST write the \field{crypto_services} field based on the capacities of the backend accelerator.
> +\end{itemize*}
> +
> +\subsection{Device Operation}\label{sec:Device Types / Crypto Device / Device Operation}
> +
> +Packets can be transmitted by placing them in both the controlq and dataq.
> +Packets consist of a general header and a service-specific request.
> +Where 'general header' is for all crypto requests, and 'service specific requests'
> +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 buffer".
> +
> +The general 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;
> +    le32 algo;
> +    le32 flag;
> +    /* data virtqueue id */
> +    le32 queue_id;
> +};
> +\end{lstlisting}
> +
> +The general header of dataq:
> +
> +\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;
> +    /* control flag to control the request */
> +    le32 flag;
> +    le32 padding;
> +};
> +\end{lstlisting}
> +
> +The device can set the operation status as follows: VIRTIO_CRYPTO_OP_OK: success;
> +VIRTIO_CRYPTO_OP_ERR: failure or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not supported;
> +VIRTIO_CRYPTO_OP_INVSESS: invalid session ID when executing crypto operations.
> +
> +\begin{lstlisting}
> +#define VIRTIO_CRYPTO_OP_OK        0
> +#define VIRTIO_CRYPTO_OP_ERR       1
> +#define VIRTIO_CRYPTO_OP_BADMSG    2
> +#define VIRTIO_CRYPTO_OP_NOTSUPP   3
> +#define VIRTIO_CRYPTO_OP_INVSESS   4
> +\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 which handles the non-data plane operations, such as session
> +operations (See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}).
> +The packet of controlq:
> +
> +\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}
> +
> +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 the following:
> +
> +\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 (encrypt or decrypt).
> +\item The HASH/MAC set data, including the HASH algorithm or MAC algorithm,
> +      and digest 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 includs 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 packet 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 packet 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_session_output {
> +    le64 auth_key_addr; /* guest key physical address */
> +};
> +
> +struct virtio_crypto_mac_create_session_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_mac_session_para para;
> +    struct virtio_crypto_mac_session_output out;
> +    /* 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 packet 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
> +    /* encrypt or decrypt */
> +    le32 op;
> +    le32 padding;
> +};
> +
> +struct virtio_crypto_cipher_session_output {
> +    le64 key_addr; /* guest key physical address */
> +};
> +
> +struct virtio_crypto_cipher_session_req {
> +    struct virtio_crypto_cipher_session_para para;
> +    struct virtio_crypto_cipher_session_output out;
> +    struct virtio_crypto_session_input input;
> +};
> +\end{lstlisting}
> +
> +The packet 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_output {
> +    struct virtio_crypto_cipher_session_output cipher;
> +    struct virtio_crypto_mac_session_output mac;
> +};
> +
> +struct virtio_crypto_alg_chain_session_req {
> +    struct virtio_crypto_alg_chain_session_para para;
> +    struct virtio_crypto_alg_chain_session_output out;
> +    struct virtio_crypto_session_input input;
> +};
> +\end{lstlisting}
> +
> +The packet 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 packet for AEAD session is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_aead_session_para {
> +    /* See VIRTIO_CRYPTO_AEAD_* above*/

Space before * pls.

> +    le32 algo;
> +    /* length of key */
> +    le32 key_len;
> +    /* digest result length */
> +    le32 digest_result_len;
> +    /* The length of the additional authenticated data (AAD) in bytes */
> +    le32 aad_len;
> +    /* encrypt or decrypt, See above VIRTIO_CRYPTO_OP_* */
> +    le32 op;
> +    le32 padding;
> +};
> +
> +struct virtio_crypto_aead_session_output {
> +    le64 key_addr; /* guest key phycial address */
> +};
> +
> +struct virtio_crypto_aead_create_session_req {
> +    struct virtio_crypto_aead_session_para para;
> +    struct virtio_crypto_aead_session_output out;
> +    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}
> +
> +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}.
> +The driver MUST set \field{opcode} field based on service type: CIPHER, HASH, MAC, or AEAD.
> +The driver MUST set \field{queue_id} field to show used dataq.
> +
> +\devicenormative{\subparagraph}{Session operation: create session}{Device Types / Crypto Device / Device
> +Operation / Control Virtqueue / Session operation / Session operation: create session}
> +
> +The device MUST return a session identifier to the driver when the device finishes processing session creation.
> +The device MUST set session creation request ended by \field{status} and \field{session_id} fields.
> +
> +Both \field{status} and \field{session_id} are written by the device: VIRTIO_CRYPTO_OP_OK: success;
> +VIRTIO_CRYPTO_OP_ERR: creation failed or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not supported;
> +VIRTIO_CRYPTO_OP_INVSESS: invalid session ID when the crypto operation is implemented.
> +
> +\drivernormative{\subparagraph}{Session operation: destroy session}{Device Types / Crypto Device / Device
> +Operation / Control Virtqueue / Session operation / Session operation: destroy session}
> +
> +The driver MUST set \field{opcode} field based on service type: CIPHER, HASH, MAC, or AEAD.
> +The driver MUST set the \field{session_id} to a valid value which assigned by the device when a session is created.
> +
> +\devicenormative{\subparagraph}{Session operation: destroy session}{Device Types / Crypto Device / Device
> +Operation / Control Virtqueue / Session operation / Session operation: destroy session}
> +
> +\field{status} field is written by the device: either VIRTIO_CRYPTO_OP_OK for success, VIRTIO_CRYPTO_OP_ERR for failure or device error.
> +
> +\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 packet 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 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 idata structure for all symmetric algorithms, including CIPHER, HASH, MAC, and AEAD.
> +
> +The structure is defined as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_sym_input {
> +    /* destination data, it's useless for plain HASH and MAC */
> +    struct virtio_crypto_iovec dst_data;
> +    /* digest result guest address, it's useless for plain cipher algos */
> +    le64 digest_result_addr;
> +    /* digest result length which is the same with session para above */
> +    le32 digest_result_len;
> +
> +    le32 status;
> +};
> +\end{lstlisting}
> +
> +For scatter/gather chain support, a buffer can be represented by virtio_crypto_iovec structure.
> +
> +The structure is defined as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_iovec {
> +    /* Guest physical address */
> +    le64 addr;
> +    /* Length of guest physical address */
> +    le32 len;
> +
> +/* This marks a buffer as continuing via the next field */
> +#define VIRTIO_CRYPTO_IOVEC_F_NEXT 1
> +    /* The flags as indicated above VIRTIO_CRYPTO_IOVEC_F_*. */
> +    le32 flags;
> +    /* Pointer to next struct virtio_crypto_iovec if flags & NEXT */
> +    le64 next_iovec;
> +};
> +\end{lstlisting}
> +
> +\paragraph{HASH Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue / HASH Service Operation}
> +
> +\begin{lstlisting}
> +struct virtio_crypto_hash_input {
> +    struct virtio_crypto_sym_input input;
> +};
> +
> +struct virtio_crypto_hash_output {
> +    /* source data */
> +    struct virtio_crypto_iovec src_data;
> +    le32 padding;
> +};
> +
> +struct virtio_crypto_hash_data_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_hash_output odata;
> +    /* Device-writable part */
> +    struct virtio_crypto_hash_input idata;
> +};
> +\end{lstlisting}
> +
> +Each data request uses virtio_crypto_hash_data_req structure to store information
> +used to run the HASH operations. The request only occupies one entry
> +in the Vring Descriptor Table in the virtio crypto device's dataq, which improves
> +the throughput of data transmitted for the HASH service, so that the virtio crypto
> +device can be better accelerated.
> +
> +The information includes the source data guest physical address stored by \field{src_data}.\field{addr},
> +length of source data stored by \field{src_data}.\field{len}, and the digest result guest physical address
> +stored by \field{digest_result_addr} used to save the results of the HASH operations.
> +The address and length can determine the exclusive content in the guest memory.
> +
> +\begin{note}
> +The guest memory is always guaranteed to be allocated and physically-contiguous
> +pointed by \field{digest_result_addr} in struct virtio_crypto_hash_input and
> +\field{src_data}.\field{addr} in struct virtio_crypto_hash_output is of single buffer.
> +If the source data is a scatter/gather chain, then each entry of s/g chain is always guaranteed to be physically-contiguous.
> +\end{note}
> +
> +\drivernormative{\subparagraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / HASH Service Operation}
> +
> +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.
> +The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_HASH.
> +The driver MUST set the \field{queue_id} field to show used dataq in struct virtio_crypto_op_header.
> +The driver MUST specify all fields in struct virtio_crypto_hash_data_req, including \field{para}, \field{odata} and \field{idata} sub structures.
> +The driver MUST set \field{src_data}.\field{flag} to VIRTIO_CRYPTO_IOVEC_F_NEXT and set the \field{src_data}.\field{next_iovec} if the source data is of a s/g chain.
> +The driver MUST set \field{src_data}.\field{flag} to ~VIRTIO_CRYPTO_IOVEC_F_NEXT if it's a single buffer or the last entry of one s/g chain.
> +
> +\devicenormative{\subparagraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / HASH Service Operation}
> +
> +The device MUST copy the results of HASH operations to the guest memory recorded by \field{digest_result_addr} filed in struct virtio_crypto_hash_input.
> +The device MUST set \field{status} in strut virtio_crypto_hash_input: VIRTIO_CRYPTO_OP_OK: success; VIRTIO_CRYPTO_OP_ERR: creation failed or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not support.
> +
> +\paragraph{MAC Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue / MAC Service Operation}
> +
> +\begin{lstlisting}
> +struct virtio_crypto_mac_input {
> +    struct virtio_crypto_sym_input input;
> +};
> +
> +struct virtio_crypto_mac_output {
> +    struct virtio_crypto_hash_output hash_output;
> +};
> +
> +struct virtio_crypto_mac_data_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_mac_output odata;
> +    /* Device-writable part */
> +    struct virtio_crypto_mac_input idata;
> +};
> +\end{lstlisting}
> +
> +Each data request uses virtio_crypto_mac_data_req structure to store information
> +used to run the MAC operations. The request only occupies one entry
> +in the Vring Descriptor Table in the virtio crypto device's dataq, which improves
> +the throughput of data transmitted for the MAC service, so that the virtio crypto
> +device can get the better result of acceleration.
> +
> +The information includes the source data guest physical address stored by \field{hash_output}.\field{src_data}.\field{addr},
> +the length of source data stored by \field{hash_output}.\field{src_data}.\field{len}, and the digest result guest physical address
> +stored by \field{digest_result_addr} used to save the results of the MAC operations.
> +The address and length can determine the exclusive content in the guest memory.
> +
> +\begin{note}
> +The guest memory is always guaranteed to be allocated and physically-contiguous
> +pointed by \field{digest_result_addr} in struct virtio_crypto_sym_input and
> +\field{hash_output}.\field{src_data}.\field{addr} in struct virtio_crypto_mac_output is of single buffer.
> +If the source data is a scatter/gather chain, then each entry of s/g chain is always guaranteed to be physically-contiguous.
> +\end{note}
> +
> +\drivernormative{\subparagraph}{MAC Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / MAC Service Operation}
> +
> +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.
> +The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_MAC.
> +The driver MUST set the \field{queue_id} field to show used dataq in struct virtio_crypto_op_header.
> +The driver MUST specify all fields in struct virtio_crypto_hash_data_req, including \field{para}, \field{odata} and \field{idata} sub structures.
> +The driver MUST set \field{hash_output}.\field{src_data}.\field{flag} to VIRTIO_CRYPTO_IOVEC_F_NEXT and set the \field{hash_output}.\field{src_data}.\field{next_iovec} if the source data is of a s/g chain.
> +The driver MUST set \field{hash_output}.\field{src_data}.\field{flag} to ~VIRTIO_CRYPTO_IOVEC_F_NEXT if it's a single buffer or the last entry of one s/g chain.
> +
> +\devicenormative{\subparagraph}{MAC Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / MAC Service Operation}
> +
> +The device MUST copy the results of MAC operations to the guest memory recorded by \field{digest_result_addr} filed in struct virtio_crypto_mac_input.
> +The device MUST set \field{status} in strut virtio_crypto_mac_input: VIRTIO_CRYPTO_OP_OK: success; VIRTIO_CRYPTO_OP_ERR: creation failed or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not support.
> +
> +\paragraph{Symmetric algorithms Operation}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue / Symmetric algorithms Operation}
> +
> +The packet of plain CIPHER service is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_cipher_para {
> +    le32 iv_len;
> +    /* length of source data */
> +    le32 src_data_len;
> +    /* length of dst data */
> +    le32 dst_data_len;
> +    le32 padding;
> +};
> +
> +struct virtio_crypto_cipher_input {
> +    struct virtio_crypto_sym_input input;
> +};
> +
> +struct virtio_crypto_cipher_output {
> +    /* iv guest address */
> +    le64 iv_addr;
> +    /* source data */
> +    struct virtio_crypto_iovec src_data;
> +};
> +
> +struct virtio_crypto_cipher_data_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_cipher_para para;
> +    struct virtio_crypto_cipher_output odata;
> +    /* Device-writable part */
> +    struct virtio_crypto_cipher_input idata;
> +};
> +\end{lstlisting}
> +
> +The packet of algorithm chaining is as follows:
> +
> +\begin{lstlisting}
> +struct virtio_crypto_alg_chain_data_para {
> +    struct virtio_crypto_cipher_para cipher;
> +};
> +
> +struct virtio_crypto_alg_chain_data_output {
> +    /* Device-writable part */
> +    struct virtio_crypto_cipher_output cipher;
> +
> +    /* Device-readable part */
> +    /* additional auth data guest address */
> +    struct virtio_crypto_iovec add_data;
> +};
> +
> +struct virtio_crypto_alg_chain_data_input {
> +    struct virtio_crypto_sym_input input;
> +};
> +
> +struct virtio_crypto_alg_chain_data_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_alg_chain_data_para para;
> +    struct virtio_crypto_alg_chain_data_output odata;
> +    /* Device-writable part */
> +    struct virtio_crypto_alg_chain_data_input idata;
> +};
> +\end{lstlisting}
> +
> +The packet 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 the virtio_crypto_cipher_data_req structure to store information
> +used to run the CIPHER operations. The request only occupies one entry
> +in the Vring Descriptor Table in the virtio crypto device's dataq, which improves
> +the throughput of data transmitted for the CIPHER service, so that the virtio crypto
> +device can get the better result of acceleration.
> +
> +In the first virtio_crypto_cipher_para structure, \field{iv_len} specifies the length of the initialization vector,
> +\field{src_data_len} specifies the length of the source data, and \field{dst_data_len} specifies the
> +length of the destination data.
> +
> +In the following virtio_crypto_cipher_input structure, \field{dst_data_addr} specifies the destination
> +data guest physical address used to store the results of the CIPHER operations, and \field{status} specifies
> +the CIPHER operation status. See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation /
> +Session operation: create session / Device Requirements: Session operation: create session}. 
> +
> +In the virtio_crypto_cipher_output structure, \field{iv_addr} specifics the guest physical address of initialization vector,
> +\field{src_data}.\field{addr} specifics the source data guest physical address.
> +
> +The addresses and length can determine the exclusive content in the guest memory.
> +
> +\begin{note}
> +The guest memory is always guaranteed to be allocated and physically-contiguous
> +pointed by \field{dst_data}.\field{addr} in struct virtio_crypto_cipher_input, 
> +\field{iv_addr} and \field{src_data}.\field{addr} in struct virtio_crypto_cipher_output is of single buffer.
> +If the source data or destination data is a scatter/gather chain, then each entry of s/g chain is always guaranteed to be physically-contiguous.
> +\end{note}
> +
> +\drivernormative{\subparagraph}{Symmetric algorithms Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / Symmetric algorithms Operation}
> +
> +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.
> +The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_CIPHER_ENCRYPT or VIRTIO_CRYPTO_CIPHER_DECRYPT.
> +The driver MUST set the \field{queue_id} field to show used dataq in struct virtio_crypto_op_header.
> +The driver MUST specify the fields in struct virtio_crypto_sym_data_req, including \field{para}, \field{odata} and \field{idata} sub structures based on the operation type of session.
> +The driver MUST specify the fields of struct virtio_crypto_cipher_data_req in struct virtio_crypto_sym_data_req if the created session is based on VIRTIO_CRYPTO_SYM_OP_CIPHER.
> +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 created session
> +is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING type and in the VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode.
> +The driver MUST set \field{src_data}.\field{flag} to VIRTIO_CRYPTO_IOVEC_F_NEXT and set the \field{src_data}.\field{next_iovec} if the source data is of a s/g chain.
> +The driver MUST set \field{src_data}.\field{flag} to ~VIRTIO_CRYPTO_IOVEC_F_NEXT if it's a single buffer or the last entry of one s/g chain.
> +
> +\devicenormative{\subparagraph}{Symmetric algorithms Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / Symmetric algorithms Operation}
> +
> +The device MUST parse the virtio_crypto_sym_data_req based on the \field{op_code} in general header.
> +The device SHOULD only parse fields of struct virtio_crypto_cipher_data_req in struct virtio_crypto_sym_data_req if the created session is VIRTIO_CRYPTO_SYM_OP_CIPHER type.
> +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 created
> +session is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING operation type and in the VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode.
> +The device MUST copy the result of cryptographic operation to the guest memory recorded by \filed{dst_data}.\field{addr} filed in struct virtio_crypto_cipher_input in plain CIPHER mode.
> +The device MUST copy the result of HASH/MAC operation to the guest memory recorded by \filed{digest_result_addr} filed in struct virtio_crypto_alg_chain_data_input is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING type.
> +The device MUST set the \filed{status} field in strut virtio_crypto_cipher_input or virtio_crypto_alg_chain_data_input structure:
> +VIRTIO_CRYPTO_OP_OK: success; VIRTIO_CRYPTO_OP_ERR: creation failed or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not supported.
> +
> +\subparagraph{Steps of Operation}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue / Symmetric algorithms Operation / Steps of Operation}
> +
> +Step1: Create a session:
> +\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 packages 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}
> +
> +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 / Data Virtqueue / Symmetric algorithms Operation / Driver Requirements: 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, changing 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_cipher_input;
> +\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 result.
> +\end{enumerate}
> +
> +\begin{note}
> +\begin{itemize*}
> +\item The driver MAY support both synchronous and asynchronous cryptographic operation. Then the performance
> +      is poor in synchronous operation since frequent context switching and virtualization overhead.
> +      The driver should by preference use asynchronous cryptographic operation.
> +\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}
> +
> +\paragraph{AEAD Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue / AEAD Service Operation}
> +
> +\begin{lstlisting}
> +struct virtio_crypto_aead_para {
> +    le32 iv_len;
> +    /* length of additional auth data */
> +    le32 aad_len;
> +    /* length of source data */
> +    le32 src_data_len;
> +    /* length of dst data */
> +    le32 dst_data_len;
> +};
> +
> +struct virtio_crypto_aead_input {
> +    struct virtio_crypto_sym_input input;
> +};
> +
> +struct virtio_crypto_aead_output {
> +    le64 iv_addr; /* iv guest address */
> +    /* source data */
> +    struct virtio_crypto_iovec src_data;
> +    /* additional auth data guest address */
> +    struct virtio_crypto_iovec add_data;
> +};
> +
> +struct virtio_crypto_aead_data_req {
> +    /* Device-readable part */
> +    struct virtio_crypto_aead_para para;
> +    struct virtio_crypto_aead_output odata;
> +    /* Device-writable part */
> +    struct virtio_crypto_aead_input idata;
> +};
> +\end{lstlisting}
> +
> +Each data request uses virtio_crypto_aead_data_req structure to store information
> +used to implement the CIPHER operations. The request only occupies one entry
> +in the Vring Descriptor Table in the virtio crypto device's dataq, which improves
> +the throughput of data transmitted for the AEAD service, so that the virtio crypto
> +device can be better accelerated.
> +
> +In the first virtio_crypto_aead_para structure, \field{iv_len} specifies the length of the initialization vector;
> +\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.
> +
> +In the following virtio_crypto_aead_input structure, \field{dst_data}.\field{addr} specifies destination
> +data guest physical address used to store the results of the CIPHER operations; \field{digest_result_addr} specifies
> +the digest result guest physical address used to store the results of the HASH/MAC operations; \field{status} specifies
> +the status of AEAD operation. See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation /
> +Session operation: create session / Device Requirements: Session operation: create session}. 
> +
> +In the virtio_crypto_aead_output structure, \field{iv_addr} specifics the guest physical address of initialization vector,
> +\field{src_data}.\field{addr} specifics the source data guest physical address, \field{add_data}.\field{addr} specifics the guest physical address
> +of additional authentication data.
> +
> +The addresses and length can determine the exclusive content in the guest memory.
> +
> +\begin{note}
> +The guest memory MUST be guaranteed to be allocated and physically-contiguous
> +pointed by \field{dst_data}.\field{addr} and \field{digest_result_addr} in struct virtio_crypto_aead_input, 
> +\field{iv_addr}, \field{add_data}.\field{addr}  and \field{src_data}.\field{addr} in struct virtio_crypto_aead_output is of single buffer.
> +If the source data, destination data or additional anthentication data is a scatter/gather chain, then each entry of s/g chain is always guaranteed to be physically-contiguous.
> +\end{note}
> +
> +\drivernormative{\subparagraph}{AEAD Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / AEAD Service Operation}
> +
> +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.
> +The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_AEAD_ENCRYPT or VIRTIO_CRYPTO_AEAD_DECRYPT.
> +The driver MUST set the \field{queue_id} field to show used dataq in struct virtio_crypto_op_header.
> +The driver MUST specify the fields in struct virtio_crypto_aead_data_req, including \field{para}, \field{odata} and \field{idata} sub structures.
> +The driver MUST set \field{src_data}.\field{flag} to VIRTIO_CRYPTO_IOVEC_F_NEXT and set the \field{src_data}.\field{next_iovec} if the source data is of a s/g chain.
> +The driver MUST set \field{src_data}.\field{flag} to ~VIRTIO_CRYPTO_IOVEC_F_NEXT if it's a single buffer or the last entry of one s/g chain.
> +
> +\devicenormative{\subparagraph}{AEAD Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / AEAD Service Operation}
> +
> +The device MUST parse the virtio_crypto_aead_data_req based on the \field{op_code} in general header.
> +The device MUST copy the result of cryptographic operation to the guest memory recorded by \filed{dst_data}.\field{addr} filed in struct virtio_crypto_aead_input.
> +The device MUST copy the digest result to the guest memory recorded by \filed{digest_result_addr} filed in struct virtio_crypto_aead_input.
> +The device MUST set the \filed{status} field in strut virtio_crypto_aead_input: VIRTIO_CRYPTO_OP_OK: success; VIRTIO_CRYPTO_OP_ERR: creation failed or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not supported.
> +When the \field{op_code} 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_OP_BADMSG (bad message) MUST be returned to the driver.
> \ No newline at end of file
> -- 
> 1.7.12.4
>
Gonglei (Arei) Sept. 21, 2016, 2:31 a.m. UTC | #2
Hi Michael,


> -----Original Message-----
> From: virtio-dev@lists.oasis-open.org [mailto:virtio-dev@lists.oasis-open.org]
> On Behalf Of Michael S. Tsirkin
> Sent: Wednesday, September 21, 2016 3:11 AM
> Subject: [virtio-dev] Re: [PATCH v10 1/2] virtio-crypto: Add virtio crypto device
> specification
> 
> On Tue, Sep 20, 2016 at 05:46:01PM +0800, Gonglei wrote:
> > The virtio crypto device is a virtual crypto device (ie. hardware
> > crypto accelerator card). The virtio crypto device can provide
> > five crypto services: CIPHER, MAC, HASH, AEAD, KDF, ASYM, PRIMITIVE.
> 
> Only CIPHER, MAC, HASH, AEAD are documented at this point.
> Let's drop others for now?
> 
OK, let's drop them. And Xin will add asym services soon by himself.
> 
> >
> > In this patch, CIPHER, MAC, HASH, AEAD services are introduced.
> >
> > 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: Hanweidong <hanweidong@huawei.com>
> > CC: Mihai Claudiu Caraman <mike.caraman@nxp.com>
> > ---
> >  content.tex       |   2 +
> >  virtio-crypto.tex | 942
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 944 insertions(+)
> >  create mode 100644 virtio-crypto.tex
> >
> > 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..ac1fc0a
> > --- /dev/null
> > +++ b/virtio-crypto.tex
> > @@ -0,0 +1,942 @@
> > +\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 the data queue and are ultimately handled
> by the
> > +real crypto accelerators.
> 
> I would like "real" to be renamed "backend".
> 
Good, it makes sense.

> > The second 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 seven crypto
> > +services: CIPHER, MAC, HASH, AEAD, KDF, ASYM, and PRIMITIVE.
> > +
> > +
> > +\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}
> > +  None currently defined
> > +
> > +\subsection{Device configuration layout}\label{sec:Device Types / Crypto
> Device / Device configuration layout}
> > +
> > +The following driver-read-only configuration fields are defined:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_config {
> > +    le32  status;
> > +    le32  max_dataqueues;
> 
> Is this just num_queues - 1?

Yes.

> Why isn't the generic num_queues sufficient?
> 
Actually I referred to the virtio net device definition. This field specifies the
maximum number of data virtqueues, not including control virtqueue.

> 
> > +    le32  crypto_services;
> 
> Would it make sense to use feature bits for this instead?
> Looks like that you need to add algo masks when
> adding services, and tying config space fields
> to features  is well supported by guests.
> 
Actually I did that in a previous version. but Cornelia gave me a convincing
viewpoint to drop the feature bit:

"I'm wondering whether you'll really want a feature bit for each algorithm. Bits
0-23 are device specific, so there's still some more to go; but could this also go
into the configuration space instead? It's not like the driver will want to negotiate
which algorithms it wants to use, but rather it will want to check what the
device may offer."

And I think it makes sense. The driver could be tell if the service is supported or
not by the device by reading the configuration field.

> > +    /* detailed algorithms mask */
> > +    le32 cipher_algo_l;
> > +    le32 cipher_algo_h;
> > +    le32 hash_algo;
> > +    le32 mac_algo_l;
> > +    le32 mac_algo_h;
> > +    le32 asym_algo;
> > +    le32 kdf_algo;
> > +    le32 aead_algo;
> > +    le32 primitive_algo;
> > +};
> > +\end{lstlisting}
> > +
> > +In the \field{status}, the value of the field is VIRTIO_CRYPTO_S_HW_READY
> or VIRTIO_CRYPTO_S_STARTED.
> > +
> > +\begin{lstlisting}
> > +#define VIRTIO_CRYPTO_S_HW_READY  (1 << 0)
> > +#define VIRTIO_CRYPTO_S_STARTED  (1 << 1)
> > +\end{lstlisting}
> > +
> > +The following driver-read-only fields include \field{max_dataqueues}, which
> specifies the
> > +maximum number of data virtqueues (dataq1\ldots dataqN), and
> \field{crypto_services},
> > +which indicates the crypto service the virtio crypto supports.
> > +
> > +The following services are defined:
> > +
> > +\begin{lstlisting}
> > +#define VIRTIO_CRYPTO_SERVICE_CIPHER (0) /* CIPHER service */
> > +#define VIRTIO_CRYPTO_SERVICE_HASH   (1) /* HASH service */
> > +#define VIRTIO_CRYPTO_SERVICE_MAC    (2) /* MAC (Message
> Authentication Codes) service */
> > +#define VIRTIO_CRYPTO_SERVICE_AEAD   (3) /* AEAD (Authenticated
> Encryption with Associated Data) service */
> > +\end{lstlisting}
> > +
> > +The last driver-read-only fields specify detailed algorithms masks
> > +the device offers for corresponding 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 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 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 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}
> > +
> > +\begin{note}
> > +More algorithms will be defined in the future.
> > +\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
> hardware-backed implementation.
> > +      If the backend crypto accelerator is ready for work, then set the
> ready \field{status} to VIRTIO_CRYPTO_S_HW_READY.
> 
> Let's write it in terms that are testable. For example:
> 	Device MUST accept and handle requests after
> 	\field{status} is set to VIRTIO_CRYPTO_S_HW_READY.
> 
OK, will do.

> 
> 
> > +\item The device MUST set \field{crypto_services} based on the crypto
> services the device offer.
> > +\item The device MUST set detailed algorithms masks based on the
> \field{crypto_services} field.
> > +\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 hardware-backed
> > +      implementation is ready or not, and the driver MUST reread it after
> the device reset.
> > +\item The driver MUST NOT transmit any packets to the device if the ready
> \filed{status} is not set.
> > +\item The driver MAY 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.
> > +\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 the control virtqueue.
> > +\item The driver MUST read the supported crypto services from bits of
> \field{crypto_servies}.
> > +\item The driver MUST read the supported algorithms based on
> \field{crypto_services} field.
> > +\end{itemize*}
> > +
> > +\devicenormative{\subsubsection}{Device Initialization}{Device Types /
> Crypto Device / Device Initialization}
> > +
> > +\begin{itemize*}
> > +\item The device MUST be configured with at least one accelerator which
> executes real crypto operations.
> > +\item The device MUST write the \field{crypto_services} field based on the
> capacities of the backend accelerator.
> > +\end{itemize*}
> > +
> > +\subsection{Device Operation}\label{sec:Device Types / Crypto Device /
> Device Operation}
> > +
> > +Packets can be transmitted by placing them in both the controlq and dataq.
> > +Packets consist of a general header and a service-specific request.
> > +Where 'general header' is for all crypto requests, and 'service specific
> requests'
> > +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 buffer".
> > +
> > +The general 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;
> > +    le32 algo;
> > +    le32 flag;
> > +    /* data virtqueue id */
> > +    le32 queue_id;
> > +};
> > +\end{lstlisting}
> > +
> > +The general header of dataq:
> > +
> > +\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;
> > +    /* control flag to control the request */
> > +    le32 flag;
> > +    le32 padding;
> > +};
> > +\end{lstlisting}
> > +
> > +The device can set the operation status as follows: VIRTIO_CRYPTO_OP_OK:
> success;
> > +VIRTIO_CRYPTO_OP_ERR: failure or device error;
> VIRTIO_CRYPTO_OP_NOTSUPP: not supported;
> > +VIRTIO_CRYPTO_OP_INVSESS: invalid session ID when executing crypto
> operations.
> > +
> > +\begin{lstlisting}
> > +#define VIRTIO_CRYPTO_OP_OK        0
> > +#define VIRTIO_CRYPTO_OP_ERR       1
> > +#define VIRTIO_CRYPTO_OP_BADMSG    2
> > +#define VIRTIO_CRYPTO_OP_NOTSUPP   3
> > +#define VIRTIO_CRYPTO_OP_INVSESS   4
> > +\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 which handles the non-data plane operations, such as session
> > +operations (See \ref{sec:Device Types / Crypto Device / Device Operation /
> Control Virtqueue / Session operation}).
> > +The packet of controlq:
> > +
> > +\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}
> > +
> > +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 the following:
> > +
> > +\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 (encrypt or decrypt).
> > +\item The HASH/MAC set data, including the HASH algorithm or MAC
> algorithm,
> > +      and digest 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 includs 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 packet 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 packet 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_session_output {
> > +    le64 auth_key_addr; /* guest key physical address */
> > +};
> > +
> > +struct virtio_crypto_mac_create_session_req {
> > +    /* Device-readable part */
> > +    struct virtio_crypto_mac_session_para para;
> > +    struct virtio_crypto_mac_session_output out;
> > +    /* 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 packet 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
> > +    /* encrypt or decrypt */
> > +    le32 op;
> > +    le32 padding;
> > +};
> > +
> > +struct virtio_crypto_cipher_session_output {
> > +    le64 key_addr; /* guest key physical address */
> > +};
> > +
> > +struct virtio_crypto_cipher_session_req {
> > +    struct virtio_crypto_cipher_session_para para;
> > +    struct virtio_crypto_cipher_session_output out;
> > +    struct virtio_crypto_session_input input;
> > +};
> > +\end{lstlisting}
> > +
> > +The packet 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_output {
> > +    struct virtio_crypto_cipher_session_output cipher;
> > +    struct virtio_crypto_mac_session_output mac;
> > +};
> > +
> > +struct virtio_crypto_alg_chain_session_req {
> > +    struct virtio_crypto_alg_chain_session_para para;
> > +    struct virtio_crypto_alg_chain_session_output out;
> > +    struct virtio_crypto_session_input input;
> > +};
> > +\end{lstlisting}
> > +
> > +The packet 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 packet for AEAD session is as follows:
> > +
> > +\begin{lstlisting}
> > +struct virtio_crypto_aead_session_para {
> > +    /* See VIRTIO_CRYPTO_AEAD_* above*/
> 
> Space before * pls.
> 
Sharp-sighted as an eagle, thanks ;)

Regards,
-Gonglei
diff mbox

Patch

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..ac1fc0a
--- /dev/null
+++ b/virtio-crypto.tex
@@ -0,0 +1,942 @@ 
+\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 the data queue and are ultimately handled by the
+real crypto accelerators. The second 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 seven crypto
+services: CIPHER, MAC, HASH, AEAD, KDF, ASYM, and PRIMITIVE.
+
+
+\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}
+  None currently defined
+
+\subsection{Device configuration layout}\label{sec:Device Types / Crypto Device / Device configuration layout}
+
+The following driver-read-only configuration fields are defined:
+
+\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 asym_algo;
+    le32 kdf_algo;
+    le32 aead_algo;
+    le32 primitive_algo;
+};
+\end{lstlisting}
+
+In the \field{status}, the value of the field is VIRTIO_CRYPTO_S_HW_READY or VIRTIO_CRYPTO_S_STARTED.
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_S_HW_READY  (1 << 0)
+#define VIRTIO_CRYPTO_S_STARTED  (1 << 1)
+\end{lstlisting}
+
+The following driver-read-only fields include \field{max_dataqueues}, which specifies the
+maximum number of data virtqueues (dataq1\ldots dataqN), and \field{crypto_services},
+which indicates the crypto service the virtio crypto supports.
+
+The following services are defined:
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_SERVICE_CIPHER (0) /* CIPHER service */
+#define VIRTIO_CRYPTO_SERVICE_HASH   (1) /* HASH service */
+#define VIRTIO_CRYPTO_SERVICE_MAC    (2) /* MAC (Message Authentication Codes) service */
+#define VIRTIO_CRYPTO_SERVICE_AEAD   (3) /* AEAD (Authenticated Encryption with Associated Data) service */
+\end{lstlisting}
+
+The last driver-read-only fields specify detailed algorithms masks 
+the device offers for corresponding 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 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 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 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}
+
+\begin{note}
+More algorithms will be defined in the future.
+\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 hardware-backed implementation. 
+      If the backend crypto accelerator is ready for work, then set the ready \field{status} to VIRTIO_CRYPTO_S_HW_READY.
+\item The device MUST set \field{crypto_services} based on the crypto services the device offer.
+\item The device MUST set detailed algorithms masks based on the \field{crypto_services} field.
+\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 hardware-backed
+      implementation is ready or not, and the driver MUST reread it after the device reset. 
+\item The driver MUST NOT transmit any packets to the device if the ready \filed{status} is not set.
+\item The driver MAY 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.
+\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 the control virtqueue.
+\item The driver MUST read the supported crypto services from bits of \field{crypto_servies}. 
+\item The driver MUST read the supported algorithms based on \field{crypto_services} field.
+\end{itemize*}
+
+\devicenormative{\subsubsection}{Device Initialization}{Device Types / Crypto Device / Device Initialization}
+
+\begin{itemize*}
+\item The device MUST be configured with at least one accelerator which executes real crypto operations.
+\item The device MUST write the \field{crypto_services} field based on the capacities of the backend accelerator.
+\end{itemize*}
+
+\subsection{Device Operation}\label{sec:Device Types / Crypto Device / Device Operation}
+
+Packets can be transmitted by placing them in both the controlq and dataq.
+Packets consist of a general header and a service-specific request.
+Where 'general header' is for all crypto requests, and 'service specific requests'
+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 buffer".
+
+The general 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;
+    le32 algo;
+    le32 flag;
+    /* data virtqueue id */
+    le32 queue_id;
+};
+\end{lstlisting}
+
+The general header of dataq:
+
+\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;
+    /* control flag to control the request */
+    le32 flag;
+    le32 padding;
+};
+\end{lstlisting}
+
+The device can set the operation status as follows: VIRTIO_CRYPTO_OP_OK: success;
+VIRTIO_CRYPTO_OP_ERR: failure or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not supported;
+VIRTIO_CRYPTO_OP_INVSESS: invalid session ID when executing crypto operations.
+
+\begin{lstlisting}
+#define VIRTIO_CRYPTO_OP_OK        0
+#define VIRTIO_CRYPTO_OP_ERR       1
+#define VIRTIO_CRYPTO_OP_BADMSG    2
+#define VIRTIO_CRYPTO_OP_NOTSUPP   3
+#define VIRTIO_CRYPTO_OP_INVSESS   4
+\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 which handles the non-data plane operations, such as session
+operations (See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation}).
+The packet of controlq:
+
+\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}
+
+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 the following:
+
+\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 (encrypt or decrypt).
+\item The HASH/MAC set data, including the HASH algorithm or MAC algorithm,
+      and digest 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 includs 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 packet 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 packet 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_session_output {
+    le64 auth_key_addr; /* guest key physical address */
+};
+
+struct virtio_crypto_mac_create_session_req {
+    /* Device-readable part */
+    struct virtio_crypto_mac_session_para para;
+    struct virtio_crypto_mac_session_output out;
+    /* 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 packet 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
+    /* encrypt or decrypt */
+    le32 op;
+    le32 padding;
+};
+
+struct virtio_crypto_cipher_session_output {
+    le64 key_addr; /* guest key physical address */
+};
+
+struct virtio_crypto_cipher_session_req {
+    struct virtio_crypto_cipher_session_para para;
+    struct virtio_crypto_cipher_session_output out;
+    struct virtio_crypto_session_input input;
+};
+\end{lstlisting}
+
+The packet 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_output {
+    struct virtio_crypto_cipher_session_output cipher;
+    struct virtio_crypto_mac_session_output mac;
+};
+
+struct virtio_crypto_alg_chain_session_req {
+    struct virtio_crypto_alg_chain_session_para para;
+    struct virtio_crypto_alg_chain_session_output out;
+    struct virtio_crypto_session_input input;
+};
+\end{lstlisting}
+
+The packet 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 packet 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;
+    /* digest result length */
+    le32 digest_result_len;
+    /* The length of the additional authenticated data (AAD) in bytes */
+    le32 aad_len;
+    /* encrypt or decrypt, See above VIRTIO_CRYPTO_OP_* */
+    le32 op;
+    le32 padding;
+};
+
+struct virtio_crypto_aead_session_output {
+    le64 key_addr; /* guest key phycial address */
+};
+
+struct virtio_crypto_aead_create_session_req {
+    struct virtio_crypto_aead_session_para para;
+    struct virtio_crypto_aead_session_output out;
+    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}
+
+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}.
+The driver MUST set \field{opcode} field based on service type: CIPHER, HASH, MAC, or AEAD.
+The driver MUST set \field{queue_id} field to show used dataq.
+
+\devicenormative{\subparagraph}{Session operation: create session}{Device Types / Crypto Device / Device
+Operation / Control Virtqueue / Session operation / Session operation: create session}
+
+The device MUST return a session identifier to the driver when the device finishes processing session creation.
+The device MUST set session creation request ended by \field{status} and \field{session_id} fields.
+
+Both \field{status} and \field{session_id} are written by the device: VIRTIO_CRYPTO_OP_OK: success;
+VIRTIO_CRYPTO_OP_ERR: creation failed or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not supported;
+VIRTIO_CRYPTO_OP_INVSESS: invalid session ID when the crypto operation is implemented.
+
+\drivernormative{\subparagraph}{Session operation: destroy session}{Device Types / Crypto Device / Device
+Operation / Control Virtqueue / Session operation / Session operation: destroy session}
+
+The driver MUST set \field{opcode} field based on service type: CIPHER, HASH, MAC, or AEAD.
+The driver MUST set the \field{session_id} to a valid value which assigned by the device when a session is created.
+
+\devicenormative{\subparagraph}{Session operation: destroy session}{Device Types / Crypto Device / Device
+Operation / Control Virtqueue / Session operation / Session operation: destroy session}
+
+\field{status} field is written by the device: either VIRTIO_CRYPTO_OP_OK for success, VIRTIO_CRYPTO_OP_ERR for failure or device error.
+
+\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 packet 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 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 idata structure for all symmetric algorithms, including CIPHER, HASH, MAC, and AEAD.
+
+The structure is defined as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_sym_input {
+    /* destination data, it's useless for plain HASH and MAC */
+    struct virtio_crypto_iovec dst_data;
+    /* digest result guest address, it's useless for plain cipher algos */
+    le64 digest_result_addr;
+    /* digest result length which is the same with session para above */
+    le32 digest_result_len;
+
+    le32 status;
+};
+\end{lstlisting}
+
+For scatter/gather chain support, a buffer can be represented by virtio_crypto_iovec structure.
+
+The structure is defined as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_iovec {
+    /* Guest physical address */
+    le64 addr;
+    /* Length of guest physical address */
+    le32 len;
+
+/* This marks a buffer as continuing via the next field */
+#define VIRTIO_CRYPTO_IOVEC_F_NEXT 1
+    /* The flags as indicated above VIRTIO_CRYPTO_IOVEC_F_*. */
+    le32 flags;
+    /* Pointer to next struct virtio_crypto_iovec if flags & NEXT */
+    le64 next_iovec;
+};
+\end{lstlisting}
+
+\paragraph{HASH Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue / HASH Service Operation}
+
+\begin{lstlisting}
+struct virtio_crypto_hash_input {
+    struct virtio_crypto_sym_input input;
+};
+
+struct virtio_crypto_hash_output {
+    /* source data */
+    struct virtio_crypto_iovec src_data;
+    le32 padding;
+};
+
+struct virtio_crypto_hash_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_hash_output odata;
+    /* Device-writable part */
+    struct virtio_crypto_hash_input idata;
+};
+\end{lstlisting}
+
+Each data request uses virtio_crypto_hash_data_req structure to store information
+used to run the HASH operations. The request only occupies one entry
+in the Vring Descriptor Table in the virtio crypto device's dataq, which improves
+the throughput of data transmitted for the HASH service, so that the virtio crypto
+device can be better accelerated.
+
+The information includes the source data guest physical address stored by \field{src_data}.\field{addr},
+length of source data stored by \field{src_data}.\field{len}, and the digest result guest physical address
+stored by \field{digest_result_addr} used to save the results of the HASH operations.
+The address and length can determine the exclusive content in the guest memory.
+
+\begin{note}
+The guest memory is always guaranteed to be allocated and physically-contiguous
+pointed by \field{digest_result_addr} in struct virtio_crypto_hash_input and
+\field{src_data}.\field{addr} in struct virtio_crypto_hash_output is of single buffer.
+If the source data is a scatter/gather chain, then each entry of s/g chain is always guaranteed to be physically-contiguous.
+\end{note}
+
+\drivernormative{\subparagraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / HASH Service Operation}
+
+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.
+The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_HASH.
+The driver MUST set the \field{queue_id} field to show used dataq in struct virtio_crypto_op_header.
+The driver MUST specify all fields in struct virtio_crypto_hash_data_req, including \field{para}, \field{odata} and \field{idata} sub structures.
+The driver MUST set \field{src_data}.\field{flag} to VIRTIO_CRYPTO_IOVEC_F_NEXT and set the \field{src_data}.\field{next_iovec} if the source data is of a s/g chain.
+The driver MUST set \field{src_data}.\field{flag} to ~VIRTIO_CRYPTO_IOVEC_F_NEXT if it's a single buffer or the last entry of one s/g chain.
+
+\devicenormative{\subparagraph}{HASH Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / HASH Service Operation}
+
+The device MUST copy the results of HASH operations to the guest memory recorded by \field{digest_result_addr} filed in struct virtio_crypto_hash_input.
+The device MUST set \field{status} in strut virtio_crypto_hash_input: VIRTIO_CRYPTO_OP_OK: success; VIRTIO_CRYPTO_OP_ERR: creation failed or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not support.
+
+\paragraph{MAC Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue / MAC Service Operation}
+
+\begin{lstlisting}
+struct virtio_crypto_mac_input {
+    struct virtio_crypto_sym_input input;
+};
+
+struct virtio_crypto_mac_output {
+    struct virtio_crypto_hash_output hash_output;
+};
+
+struct virtio_crypto_mac_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_mac_output odata;
+    /* Device-writable part */
+    struct virtio_crypto_mac_input idata;
+};
+\end{lstlisting}
+
+Each data request uses virtio_crypto_mac_data_req structure to store information
+used to run the MAC operations. The request only occupies one entry
+in the Vring Descriptor Table in the virtio crypto device's dataq, which improves
+the throughput of data transmitted for the MAC service, so that the virtio crypto
+device can get the better result of acceleration.
+
+The information includes the source data guest physical address stored by \field{hash_output}.\field{src_data}.\field{addr},
+the length of source data stored by \field{hash_output}.\field{src_data}.\field{len}, and the digest result guest physical address
+stored by \field{digest_result_addr} used to save the results of the MAC operations.
+The address and length can determine the exclusive content in the guest memory.
+
+\begin{note}
+The guest memory is always guaranteed to be allocated and physically-contiguous
+pointed by \field{digest_result_addr} in struct virtio_crypto_sym_input and
+\field{hash_output}.\field{src_data}.\field{addr} in struct virtio_crypto_mac_output is of single buffer.
+If the source data is a scatter/gather chain, then each entry of s/g chain is always guaranteed to be physically-contiguous.
+\end{note}
+
+\drivernormative{\subparagraph}{MAC Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / MAC Service Operation}
+
+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.
+The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_MAC.
+The driver MUST set the \field{queue_id} field to show used dataq in struct virtio_crypto_op_header.
+The driver MUST specify all fields in struct virtio_crypto_hash_data_req, including \field{para}, \field{odata} and \field{idata} sub structures.
+The driver MUST set \field{hash_output}.\field{src_data}.\field{flag} to VIRTIO_CRYPTO_IOVEC_F_NEXT and set the \field{hash_output}.\field{src_data}.\field{next_iovec} if the source data is of a s/g chain.
+The driver MUST set \field{hash_output}.\field{src_data}.\field{flag} to ~VIRTIO_CRYPTO_IOVEC_F_NEXT if it's a single buffer or the last entry of one s/g chain.
+
+\devicenormative{\subparagraph}{MAC Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / MAC Service Operation}
+
+The device MUST copy the results of MAC operations to the guest memory recorded by \field{digest_result_addr} filed in struct virtio_crypto_mac_input.
+The device MUST set \field{status} in strut virtio_crypto_mac_input: VIRTIO_CRYPTO_OP_OK: success; VIRTIO_CRYPTO_OP_ERR: creation failed or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not support.
+
+\paragraph{Symmetric algorithms Operation}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue / Symmetric algorithms Operation}
+
+The packet of plain CIPHER service is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_cipher_para {
+    le32 iv_len;
+    /* length of source data */
+    le32 src_data_len;
+    /* length of dst data */
+    le32 dst_data_len;
+    le32 padding;
+};
+
+struct virtio_crypto_cipher_input {
+    struct virtio_crypto_sym_input input;
+};
+
+struct virtio_crypto_cipher_output {
+    /* iv guest address */
+    le64 iv_addr;
+    /* source data */
+    struct virtio_crypto_iovec src_data;
+};
+
+struct virtio_crypto_cipher_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_cipher_para para;
+    struct virtio_crypto_cipher_output odata;
+    /* Device-writable part */
+    struct virtio_crypto_cipher_input idata;
+};
+\end{lstlisting}
+
+The packet of algorithm chaining is as follows:
+
+\begin{lstlisting}
+struct virtio_crypto_alg_chain_data_para {
+    struct virtio_crypto_cipher_para cipher;
+};
+
+struct virtio_crypto_alg_chain_data_output {
+    /* Device-writable part */
+    struct virtio_crypto_cipher_output cipher;
+
+    /* Device-readable part */
+    /* additional auth data guest address */
+    struct virtio_crypto_iovec add_data;
+};
+
+struct virtio_crypto_alg_chain_data_input {
+    struct virtio_crypto_sym_input input;
+};
+
+struct virtio_crypto_alg_chain_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_alg_chain_data_para para;
+    struct virtio_crypto_alg_chain_data_output odata;
+    /* Device-writable part */
+    struct virtio_crypto_alg_chain_data_input idata;
+};
+\end{lstlisting}
+
+The packet 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 the virtio_crypto_cipher_data_req structure to store information
+used to run the CIPHER operations. The request only occupies one entry
+in the Vring Descriptor Table in the virtio crypto device's dataq, which improves
+the throughput of data transmitted for the CIPHER service, so that the virtio crypto
+device can get the better result of acceleration.
+
+In the first virtio_crypto_cipher_para structure, \field{iv_len} specifies the length of the initialization vector,
+\field{src_data_len} specifies the length of the source data, and \field{dst_data_len} specifies the
+length of the destination data.
+
+In the following virtio_crypto_cipher_input structure, \field{dst_data_addr} specifies the destination
+data guest physical address used to store the results of the CIPHER operations, and \field{status} specifies
+the CIPHER operation status. See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation /
+Session operation: create session / Device Requirements: Session operation: create session}. 
+
+In the virtio_crypto_cipher_output structure, \field{iv_addr} specifics the guest physical address of initialization vector,
+\field{src_data}.\field{addr} specifics the source data guest physical address.
+
+The addresses and length can determine the exclusive content in the guest memory.
+
+\begin{note}
+The guest memory is always guaranteed to be allocated and physically-contiguous
+pointed by \field{dst_data}.\field{addr} in struct virtio_crypto_cipher_input, 
+\field{iv_addr} and \field{src_data}.\field{addr} in struct virtio_crypto_cipher_output is of single buffer.
+If the source data or destination data is a scatter/gather chain, then each entry of s/g chain is always guaranteed to be physically-contiguous.
+\end{note}
+
+\drivernormative{\subparagraph}{Symmetric algorithms Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / Symmetric algorithms Operation}
+
+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.
+The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_CIPHER_ENCRYPT or VIRTIO_CRYPTO_CIPHER_DECRYPT.
+The driver MUST set the \field{queue_id} field to show used dataq in struct virtio_crypto_op_header.
+The driver MUST specify the fields in struct virtio_crypto_sym_data_req, including \field{para}, \field{odata} and \field{idata} sub structures based on the operation type of session.
+The driver MUST specify the fields of struct virtio_crypto_cipher_data_req in struct virtio_crypto_sym_data_req if the created session is based on VIRTIO_CRYPTO_SYM_OP_CIPHER.
+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 created session
+is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING type and in the VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode.
+The driver MUST set \field{src_data}.\field{flag} to VIRTIO_CRYPTO_IOVEC_F_NEXT and set the \field{src_data}.\field{next_iovec} if the source data is of a s/g chain.
+The driver MUST set \field{src_data}.\field{flag} to ~VIRTIO_CRYPTO_IOVEC_F_NEXT if it's a single buffer or the last entry of one s/g chain.
+
+\devicenormative{\subparagraph}{Symmetric algorithms Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / Symmetric algorithms Operation}
+
+The device MUST parse the virtio_crypto_sym_data_req based on the \field{op_code} in general header.
+The device SHOULD only parse fields of struct virtio_crypto_cipher_data_req in struct virtio_crypto_sym_data_req if the created session is VIRTIO_CRYPTO_SYM_OP_CIPHER type.
+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 created
+session is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING operation type and in the VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode.
+The device MUST copy the result of cryptographic operation to the guest memory recorded by \filed{dst_data}.\field{addr} filed in struct virtio_crypto_cipher_input in plain CIPHER mode.
+The device MUST copy the result of HASH/MAC operation to the guest memory recorded by \filed{digest_result_addr} filed in struct virtio_crypto_alg_chain_data_input is of the VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING type.
+The device MUST set the \filed{status} field in strut virtio_crypto_cipher_input or virtio_crypto_alg_chain_data_input structure:
+VIRTIO_CRYPTO_OP_OK: success; VIRTIO_CRYPTO_OP_ERR: creation failed or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not supported.
+
+\subparagraph{Steps of Operation}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue / Symmetric algorithms Operation / Steps of Operation}
+
+Step1: Create a session:
+\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 packages 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}
+
+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 / Data Virtqueue / Symmetric algorithms Operation / Driver Requirements: 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, changing 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_cipher_input;
+\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 result.
+\end{enumerate}
+
+\begin{note}
+\begin{itemize*}
+\item The driver MAY support both synchronous and asynchronous cryptographic operation. Then the performance
+      is poor in synchronous operation since frequent context switching and virtualization overhead.
+      The driver should by preference use asynchronous cryptographic operation.
+\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}
+
+\paragraph{AEAD Service Operation}\label{sec:Device Types / Crypto Device / Device Operation / Data Virtqueue / AEAD Service Operation}
+
+\begin{lstlisting}
+struct virtio_crypto_aead_para {
+    le32 iv_len;
+    /* length of additional auth data */
+    le32 aad_len;
+    /* length of source data */
+    le32 src_data_len;
+    /* length of dst data */
+    le32 dst_data_len;
+};
+
+struct virtio_crypto_aead_input {
+    struct virtio_crypto_sym_input input;
+};
+
+struct virtio_crypto_aead_output {
+    le64 iv_addr; /* iv guest address */
+    /* source data */
+    struct virtio_crypto_iovec src_data;
+    /* additional auth data guest address */
+    struct virtio_crypto_iovec add_data;
+};
+
+struct virtio_crypto_aead_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_aead_para para;
+    struct virtio_crypto_aead_output odata;
+    /* Device-writable part */
+    struct virtio_crypto_aead_input idata;
+};
+\end{lstlisting}
+
+Each data request uses virtio_crypto_aead_data_req structure to store information
+used to implement the CIPHER operations. The request only occupies one entry
+in the Vring Descriptor Table in the virtio crypto device's dataq, which improves
+the throughput of data transmitted for the AEAD service, so that the virtio crypto
+device can be better accelerated.
+
+In the first virtio_crypto_aead_para structure, \field{iv_len} specifies the length of the initialization vector;
+\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.
+
+In the following virtio_crypto_aead_input structure, \field{dst_data}.\field{addr} specifies destination
+data guest physical address used to store the results of the CIPHER operations; \field{digest_result_addr} specifies
+the digest result guest physical address used to store the results of the HASH/MAC operations; \field{status} specifies
+the status of AEAD operation. See \ref{sec:Device Types / Crypto Device / Device Operation / Control Virtqueue / Session operation /
+Session operation: create session / Device Requirements: Session operation: create session}. 
+
+In the virtio_crypto_aead_output structure, \field{iv_addr} specifics the guest physical address of initialization vector,
+\field{src_data}.\field{addr} specifics the source data guest physical address, \field{add_data}.\field{addr} specifics the guest physical address
+of additional authentication data.
+
+The addresses and length can determine the exclusive content in the guest memory.
+
+\begin{note}
+The guest memory MUST be guaranteed to be allocated and physically-contiguous
+pointed by \field{dst_data}.\field{addr} and \field{digest_result_addr} in struct virtio_crypto_aead_input, 
+\field{iv_addr}, \field{add_data}.\field{addr}  and \field{src_data}.\field{addr} in struct virtio_crypto_aead_output is of single buffer.
+If the source data, destination data or additional anthentication data is a scatter/gather chain, then each entry of s/g chain is always guaranteed to be physically-contiguous.
+\end{note}
+
+\drivernormative{\subparagraph}{AEAD Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / AEAD Service Operation}
+
+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.
+The driver MUST set \field{opcode} in struct virtio_crypto_op_header to VIRTIO_CRYPTO_AEAD_ENCRYPT or VIRTIO_CRYPTO_AEAD_DECRYPT.
+The driver MUST set the \field{queue_id} field to show used dataq in struct virtio_crypto_op_header.
+The driver MUST specify the fields in struct virtio_crypto_aead_data_req, including \field{para}, \field{odata} and \field{idata} sub structures.
+The driver MUST set \field{src_data}.\field{flag} to VIRTIO_CRYPTO_IOVEC_F_NEXT and set the \field{src_data}.\field{next_iovec} if the source data is of a s/g chain.
+The driver MUST set \field{src_data}.\field{flag} to ~VIRTIO_CRYPTO_IOVEC_F_NEXT if it's a single buffer or the last entry of one s/g chain.
+
+\devicenormative{\subparagraph}{AEAD Service Operation}{Device Types / Crypto Device / Device Operation / Data Virtqueue / AEAD Service Operation}
+
+The device MUST parse the virtio_crypto_aead_data_req based on the \field{op_code} in general header.
+The device MUST copy the result of cryptographic operation to the guest memory recorded by \filed{dst_data}.\field{addr} filed in struct virtio_crypto_aead_input.
+The device MUST copy the digest result to the guest memory recorded by \filed{digest_result_addr} filed in struct virtio_crypto_aead_input.
+The device MUST set the \filed{status} field in strut virtio_crypto_aead_input: VIRTIO_CRYPTO_OP_OK: success; VIRTIO_CRYPTO_OP_ERR: creation failed or device error; VIRTIO_CRYPTO_OP_NOTSUPP: not supported.
+When the \field{op_code} 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_OP_BADMSG (bad message) MUST be returned to the driver.
\ No newline at end of file