On Wed, Jul 27, 2016 at 06:08:23PM +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. > > In this patch, CIPHER, MAC, HASH, AEAD services are introduced. > > CC: Michael S. Tsirkin <m...@redhat.com> > CC: Cornelia Huck <cornelia.h...@de.ibm.com> > CC: Stefan Hajnoczi <stefa...@redhat.com> > CC: Lingli Deng <denglin...@chinamobile.com> > CC: Jani Kokkonen <jani.kokko...@huawei.com> > CC: Ola Liljedahl <ola.liljed...@arm.com> > CC: Varun Sethi <varun.se...@freescale.com> > CC: Zeng Xin <xin.z...@intel.com> > CC: Keating Brian <brian.a.keat...@intel.com> > CC: Ma Liang J <liang.j...@intel.com> > CC: Griffin John <john.grif...@intel.com> > CC: Hanweidong <hanweid...@huawei.com> > Signed-off-by: Gonglei <arei.gong...@huawei.com> > --- > This is the specification (version 5) about a new virtio crypto device. > This version is a big reconstruction based on Xin's comments, > thanks a lot. > > If you have any comments, please let me know, thanks :) > > Changes from v4: > - introduce crypto services into virtio crypto device. The services > currently defined are CIPHER, MAC, HASH, AEAD, KDF, ASYM, PRIMITIVE. > - define a unified crypto request format that is consisted of > general header + service specific request, Where 'general header' is for > all > crypto request, 'service specific request' is composed of > operation parameter + input data + output data in generally. > operation parameter is algorithm-specific parameters, > input data is the data should be operated , > output data is the "operation result + result buffer". > - redefine the algorithms and structure based on above crypto services. > - rearrange the title and subtitle > - Only support CIPHER, MAC, HASH and AEAD crypto services, and Xin will > focus KDF, ASYM and PRIMITIVE services. > - Some other corresponding fixes. > - Make a formal patch using tex type. > > Changes from v3: > - Don't use enum is the spec but macros in specific structures. [Michael & > Stefan] > - Add two complete structures for session creation and closing, so that > the spec is clear on how to lay out the request. [Stefan] > - Definite the crypto operation request with assigned structure, in this way, > each data request only occupies *one entry* of the Vring descriptor table, > which *improves* the *throughput* of data transferring. > > Changes from v2: > - Reserve virtio device ID 20 for crypto device. [Cornelia] > - Drop all feature bits, those capabilities are offered by the device all > the time. [Stefan & Cornelia] > - Add a new section 1.4.2 for driver requirements. [Stefan] > - Use definite type definition instead of enum type in some structure. > [Stefan] > - Add virtio_crypto_cipher_alg definition. [Stefan] > - Add a "Device requirements" section as using MUST. [Stefan] > - Some grammar nits fixes and typo fixes. [Stefan & Cornelia] > - Add one VIRTIO_CRYPTO_S_STARTED status for the driver as the flag of > virtio-crypto device started and can work now. > > Great thanks for Stefan and Cornelia! > > Changes from v1: > - Drop the feature bit definition for each algorithm, and using config space > instead [Cornelia] > - Add multiqueue support and add corresponding feature bit > - Update Encryption process and header definition > - Add session operation process and add corresponding header description > - Other better description in order to fit for virtio spec [Michael] > - Some other trivial fixes.
OK I will let people who understand crypto comment on this. Down the road before we release this we'll need to link confirmance clauses from confirmance section. Can be a patch on top, no big deal. > --- > content.tex | 2 + > virtio-crypto.tex | 792 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 794 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: Generally we keep it all in a single file. But ok, let's experiment with this split layout and see whether it makes things easier or harder. We can always squash it later. > diff --git a/virtio-crypto.tex b/virtio-crypto.tex > new file mode 100644 > index 0000000..0918f36 > --- /dev/null > +++ b/virtio-crypto.tex > @@ -0,0 +1,792 @@ > +\section{Crypto Device}\label{sec:Device Types / Crypto Device} > + > +The virtio crypto device is a virtual crypto device (ie. hardware > +crypto accelerator card). The encryption and decryption requests of > +are placed in the data queue, and handled by the real hardware crypto > +accelerators finally. The second queue is the control queue, which > +is used to create or destroy session for symmetric algorithms, and > +to control some advanced features in the future. The virtio crypto > +device can provide seven crypto services: CIPHER, MAC, HASH, AEAD, > +KDF, ASYM, 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} (\field{max_dataqueues} >= 1). > + > +\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} > + > +Thirteen driver-read-only configuration fields are currently defined. > + > +\begin{lstlisting} > +struct virtio_crypto_config { > + le32 version; > + le16 status; > + le16 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} > + > +The first driver-read-only field, \field{version} specifies the virtio > crypto??s > +version, which is reserved for back-compatibility in future.It??s currently > +defined for the version field: > + > +\begin{lstlisting} > +#define VIRTIO_CRYPTO_VERSION_1 (1) > +\end{lstlisting} > + We have feature bits so I think this should not be necessary. > +One read-only bit (for the device) is currently defined for the > \field{status} > +field: VIRTIO_CRYPTO_S_HW_READY. One read-only bit (for the driver) > +is currently defined for the status field: VIRTIO_CRYPTO_S_STARTED. what does for the device/for the driver mean here? > + > +\begin{lstlisting} > +#define VIRTIO_CRYPTO_S_HW_READY (1 << 0) so this is a way to tell guest "I am not ready yet, do not use"? > +#define VIRTIO_CRYPTO_S_STARTED (1 << 1) does not look like anyone uses bit 1. > +\end{lstlisting} What does each of these mean? > + > +The following driver-read-only field, \field{max_dataqueuess} specifies the > +maximum number of data virtqueues (dataq1\ldots dataqN). The crypto_services > +shows the crypto services the virtio crypto supports. The service currently > +defined are: > + > +\begin{lstlisting} > +#define VIRTIO_CRYPTO_NO_SERVICE (0) /* cipher services */ > +#define VIRTIO_CRYPTO_SERVICE_CIPHER (1) /* cipher services */ > +#define VIRTIO_CRYPTO_SERVICE_HASH (2) /* hash service */ > +#define VIRTIO_CRYPTO_SERVICE_MAC (3) /* MAC (Message Authentication > Codes) service */ > +#define VIRTIO_CRYPTO_SERVICE_AEAD (4) /* AEAD(Authenticated Encryption > with Associated Data) service */ > +\end{lstlisting} > + > +The last driver-read-only fields specify detailed algorithms mask which > +the device offered for corresponding service. The below CIPHER algorithms > +are defined currently: > + > +\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 below HASH algorithms are defined currently: > + > +\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 below MAC algorithms are defined currently: > + > +\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_CMAC_KASUMI_F9 27 > +#define VIRTIO_CRYPTO_MAC_CMAC_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 > +\end{lstlisting} > + > +The below AEAD algorithms are defined currently: > + > +\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} > + > +\subsubsection{Device Requirements: Device configuration > layout}\label{sec:Device Types / Crypto Device / Device configuration layout > / Device Requirements: Device configuration layout} > + > +\begin{itemize*} > +\item The device MUST set \field{version} in version filed. > +\item The device MUST set \field{max_dataqueues} to between 1 and 65535 > inclusive. > +\item The device SHOULD set \field{status} according to the status of the > hardware-backed implementation. does it always go not ready->ready and never back? > +\item The device MUST set \field{crypto_services} according to the crypto > services which the device offered. > +\item The device MUST set detailed algorithms mask according to > crypto_services field. > +\end{itemize*} > + > +\subsubsection{Driver Requirements: Device configuration > layout}\label{sec:Device Types / Crypto Device / Device configuration layout > / Driver Requirements: Device configuration layout} > + > +\begin{itemize*} > +\item The driver MUST read the ready \field{status} from the bottom bit of > status why not use a name instead of "bottom bit of"? > to > + check whether the hardware-backed implementation is ready or not. and if not ready then what is legal to do and what isn't? better say what it must not do until device is ready. > +\item The driver MAY read \field{max_dataqueues} field to discover how many > 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 detail algorithms field according to > crypto_services field. > +\end{itemize*} > + > +\subsection{Device Initialization}{Device Types / Crypto Device / Device > Initialization} > + > +The driver SHOULD perform a typical initialization routine like so: > + > +\begin{enumerate} > +\item Identify and initialize data virtqueue, up to \field{max_dataqueues}. > +\item Identify the control virtqueue. > +\item Identify the ready \field{status} of hardware-backend comes from the > bottom bit of status. > +\item Read the supported crypto services from bits of \field{crypto_servies}. > +\item Read the supported algorithms according to \field{crypto_services} > field. > +\end{enumerate} > + > +\subsection{Device Operation}\label{sec:Device Types / Crypto Device / > Device Operation} > + > +Packets can be transmitted by placing them in both the controlq and dataq. > +The packet are consisted of general header and services specific request, > +Where 'general header' is for all crypto request, 'service specific request' > +is composed of operation parameter + input data + output data in generally. > +Operation parameters are algorithm-specific parameters, input data is the > +data should be operated , output data is the "operation result + result > buffer". > +The general header of controlq: > + > +\begin{lstlisting} > +#define VIRTIO_CRYPTO_OPCODE(service, op) ((service << 8) | (op)) > + > +struct virtio_crypto_ctrl_header{ > +#define VIRTIO_CRYPTO_CIPHER_CREATE_SESSION > VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x02) > +#define VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION > VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x03) > +#define VIRTIO_CRYPTO_HASH_CREATE_SESSION > VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x02) > +#define VIRTIO_CRYPTO_HASH_DESTROY_SESSION > VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x03) > +#define VIRTIO_CRYPTO_MAC_CREATE_SESSION > VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x02) > +#define VIRTIO_CRYPTO_MAC_DESTROY_SESSION > VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x03) > +#define VIRTIO_CRYPTO_AEAD_CREATE_SESSION > VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x02) > +#define VIRTIO_CRYPTO_AEAD_DESTROY_SESSION > VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x03) > + le32 opcode; > + /* algo should be service-specific algorithms */ > + le32 algo; > + /* control flag to control the request */ > + u8 flag; > + /* data virtqeueu id */ > + le16 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; > + /* control flag to control the request */ > + u8 flag; > + /* data virtqeueu id */ > + le16 queue_id; > + /* session_id should be service-specific algorithms */ > + le64 session_id; > +}; > +\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 finish the non-data plane operations, such as session > +operations (see \ref{sec:Device Types / Crypto Device / Device Operation / > 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 sym_destroy_session; > + } u; does this means it is always the max size? or can any size be used as long as the struct fits in there? If second, then better split it I think. > +}; > +\end{lstlisting} > + > +The header is the general header, the union is algorithm-specific type, > +which is set by the driver. All the properties in the union will be shown as > follow. > + > +\subsubsection{Session operation}\label{sec:Device Types / Crypto Device / > Device Operation / Session operation} > + > +The symmetric algorithms have 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 setup data, including the cipher algorithm and mode, > + the key and its length, and the direction (encrypt or decrypt). > +\item Use VIRTIO_Crypto_CMD_RESOURCE_FLUSH why mixed case? > to flush the updated resource > + to the display. display? > +\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} > + > +\paragraph{Session operation: HASH session}\label{sec:Device Types / Crypto > Device / Device Operation / Session operation / Session operation: HASH > session} > + > +The packet of HASH session is: > + > +\begin{lstlisting} > +struct virtio_crypto_sym_session_input { > + u8 status; > + le64 session_id; > +}; > + > +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 { > + struct virtio_crypto_hash_session_para parameter; > + /* > + * in header guest physical address, See struct > virtio_crypto_sym_session_input > + * above > + */ > + le64 inhdr_addr; > +}; > +\end{lstlisting} > + > +\paragraph{Session operation: MAC session}\label{sec:Device Types / Crypto > Device / Device > +Operation / Session operation / Session operation: MAC session} > + > +The packet of MAC session is: > + > +\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; > +}; > +struct virtio_crypto_mac_create_session_req { > + struct virtio_crypto_mac_session_para parameter; > + /* > + * in header guest physical address, See struct > virtio_crypto_sym_session_input > + * above > + */ > + le64 inhdr_addr; > +}; > +\end{lstlisting} > + > +\paragraph{Session operation: Symmetric algorithms session}\label{sec:Device > Types / Crypto Device / Device > +Operation / Session operation / Session operation: Symmetric algorithms > session} > + > +The symmetric session include both ciphers (CIPHER service) and chain > +algorithms (chain cipher and hash/mac). The packet of symmetric session is: > + > +\begin{lstlisting} > +struct virtio_crypto_cipher_session_para { > +/* See VIRTIO_CRYPTO_CIPHER* above */ > + le32 algo; > + /* length of key */ > + le32 keylen; > + /* encrypt or decrypt */ > + u8 op; > +}; > +struct virtio_crypto_sym_create_session_req { > +/* 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 > + u8 op_type; > + > + union { > + struct virtio_crypto_cipher_session_para cipher_param; > + struct virtio_crypto_alg_chain_param { > +#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER 1 > +#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH 2 > + u8 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 > + u8 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; > + } chain; > + } sym; > + > + /* > + * in header guest physical address, See struct > virtio_crypto_sym_session_input > + * above > + */ > + le64 inhdr_addr; > +}; > +\end{lstlisting} > + > +\paragraph{Session operation: AEAD session}\label{sec:Device Types / Crypto > Device / Device > +Operation / Session operation / Session operation: AEAD session} > + > +The packet of AEAD session is: > + > +\begin{lstlisting} > +struct virtio_crypto_aead_session_para { > + /* See VIRTIO_CRYPTO_AEAD_* above*/ > + u8 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 */ > + u8 op; > +}; > +struct virtio_crypto_aead_create_session_req { > + struct virtio_crypto_aead_session_para parameter; > + /* > + * in header guest physical address, See struct > virtio_crypto_sym_session_input > + * above > + */ > + le64 inhdr_addr; > +}; > +\end{lstlisting} > + > +\paragraph{Session operation: create session}\label{sec:Device Types / > Crypto Device / Device > +Operation / Session operation / Session operation: create session} > + > +A request of creating a session including the following information: > + > +\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 sym_destroy_session; > + } u; > +}; > +\end{lstlisting} > + > +\subparagraph{Driver Requirements: Session operation: create > session}\label{sec:Device Types / Crypto Device / Device > +Operation / Session operation / Session operation: create session / Driver > Requirements: Session operation: create session} > + > +The driver MUST set the control general header and corresponding property > +of union in structure virtio_crypto_op_ctrl_req. See \ref{sec:Device Types / > Crypto Device / Device Operation}. > +Take the example of MAC service, the driver MUST set > VIRTIO_CRYPTO_MAC_CREATE_SESSION > +for \field{opcode} field in struct virtio_crypto_op_ctrl_req, and set the > \field{queue_id} > +to show dataq used. > + > +\subparagraph{Device Requirements: Session operation: create > session}\label{sec:Device Types / Crypto Device / Device > +Operation / Session operation / Session operation: create session / Device > Requirements: Session operation: create session} > + > +The device MUST return a session identifier to the driver when the device > +finishes the processing of session creation. The session creation request > +MUST end by a GPA of tailer: \field{inhdr_addr} field in struct > virtio_crypto_*_create_session_req > +of each crypto service. The \field{inhdr_addr} field point to the below > structure: > + > +\begin{lstlisting} > +struct virtio_crypto_sym_session_input { > + u8 status; > + le64 session_id; > +}; > +\end{lstlisting} > + > +Both status and session_id are written by the device: either > VIRTIO_CRYPTO_OP_OK for success, > +VIRTIO_CRYPTO_OP_ERR for creation failed or device error, > VIRTIO_CRYPTO_OP_NOTSUPP for not support. What is not supported? > + > +\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 > +\end{lstlisting} > + > +\paragraph{Session operation: destroy session}\label{sec:Device Types / > Crypto Device / Device > +Operation / Session operation / Session operation: destroy session} > + > +A request which destroy a session including the following information: > + > +\begin{lstlisting} > +struct virtio_crypto_destroy_session_req { > + le64 session_id; /* OUT parameter */ > + u8 status; /* IN parameter */ > +}; > +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 sym_destroy_session; > + } u; > +}; > +\end{lstlisting} > + > +\subparagraph{Driver Requirements: Session operation: destroy > session}\label{sec:Device Types / Crypto Device / Device > +Operation / Session operation / Session operation: destroy session / Driver > Requirements: Session operation: destroy session} > + > +The driver MUST set the control general header and corresponding property > +of union in struct virtio_crypto_op_ctrl_req. See \ref{sec:Device Types / > Crypto Device / Device Operation}. > +Take the example of MAC service, the driver MUST set > VIRTIO_CRYPTO_MAC_DESTROY_SESSION > +for \field{opcode} field in struct virtio_crypto_op_ctrl_req, and set the > \field{queue_id} shows dataq used. > +The driver MUST set the \field{session_id} which MUST be a valid value which > assigned by the > +device when a session was created. > + > +\subparagraph{Device Requirements: Session operation: destroy > session}\label{sec:Device Types / Crypto Device / Device > +Operation / Session operation / Session operation: destroy session / Device > Requirements: Session operation: destroy session} > + > +Status is written by the device: either VIRTIO_CRYPTO_OP_OK for success, > VIRTIO_CRYPTO_OP_ERR for failure or device error. > + > +\subsubsection{Crypto operation}\label{sec:Device Types / Crypto Device / > Device Operation / Crypto operation} > + > +The driver uses the dataq to finish the data plane operations (such as > crypto operation). > +The packet of dataq: > + > +\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, the union is algorithm-specific type, > +which are set by the driver. All the properties in the union will be shown > as follow. > + > +\paragraph{Crypto operation: HASH operation}\label{sec:Device Types / Crypto > Device / Device > +Operation / Crypto operation / Crypto operation: HASH operation} > + > +\begin{lstlisting} > +struct virtio_crypto_sym_crypt_op_inhdr { > + u8 status; > +}; > + > +struct virtio_crypto_hash_para { > + /* length of source data */ > + le32 src_data_len; > +}; > + > +struct virtio_crypto_hash_input { > + le64 digest_result_addr; /* digest result guest physical address */ > + /* > + * in header guest physical address, See struct > virtio_crypto_sym_crypt_op_inhdr > + * above > + */ > + le64 inhdr_addr; > +}; > + > +struct virtio_crypto_hash_output { > + le64 src_data_addr; /* source data guest physical address */ > +}; > + > +struct virtio_crypto_hash_data_req { > + struct virtio_crypto_hash_para parameter; > + struct virtio_crypto_hash_input idata; > + struct virtio_crypto_hash_output odata; > +}; > +\end{lstlisting} > + > +Both input and output parameters store the guest physical address (GPA) only > so > +that each data operation request only occupies one entry of the Vring > descriptor > +table, which improves the throughput of data transferring for HASH crypto > service. > +The struct virtio_crypto_hash_para store the corresponding parameters, such > as > +\field{src_data_len}. The length and GPA can determine the specific content > in > +the guest memory. > + > +\subparagraph{Driver Requirements: Crypto operation: HASH > operation}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: HASH operation / Driver > Requirements: Crypto operation: HASH operation} > + > +The driver MUST set the \field{opcode}, \field{session_id} in struct > virtio_crypto_op_header. > +The \field{opcode} is set to VIRTIO_CRYPTO_HASH, \field{session_id} MUST be > a valid value > +which assigned by the device when a session was created. > +The driver SHOULD set the \field{queue_id} field to show dataq used in > struct virtio_crypto_op_header. > +The driver MUST fill out all fields in struct virtio_crypto_hash_data_req, > including \field{parameter}, > +\field{idata} and \field{odata} sub structures. > + > +Note: \field{inhdr_addr} is a GPA pointed the struct > virtio_crypto_sym_crypt_op_inhdr > +which allocated by the driver. > + > +\subparagraph{Device Requirements: Crypto operation: HASH > operation}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: HASH operation / Device > Requirements: Crypto operation: HASH operation} > + > +The device MUST copy the result of hash operation recorded by > \field{digest_result_addr} > +filed in struct virtio_crypto_hash_input. > +The device MUST set the status recorded by \field{inhdr_addr field} in strut > virtio_crypto_hash_input > +which point struct virtio_crypto_sym_crypt_op_inhdr: either > VIRTIO_CRYPTO_OP_OK for success, > +VIRTIO_CRYPTO_OP_ERR for creation failed or device error, > VIRTIO_CRYPTO_OP_NOTSUPP for not support. > + > +\paragraph{Crypto operation: MAC operation}\label{sec:Device Types / Crypto > Device / Device > +Operation / Crypto operation / Crypto operation: MAC operation} > + > +\begin{lstlisting} > +struct virtio_crypto_mac_para { > + struct virtio_crypto_hash_para hash_para; > +}; > + > +struct virtio_crypto_mac_input { > + struct virtio_crypto_hash_input hash_input; > +}; > + > +struct virtio_crypto_mac_output { > + struct virtio_crypto_hash_output hash_output; > +}; > + > +struct virtio_crypto_mac_data_req { > + struct virtio_crypto_mac_para parameter; > + struct virtio_crypto_mac_input idata; > + struct virtio_crypto_mac_output odata; > +}; > +\end{lstlisting} > + > +Both input and output parameters store the guest physical address (GPA) only > so > +that each data operation request only occupies one entry of the Vring > descriptor > +table, which improves the throughput of data transferring for MAC crypto > service. > +The struct virtio_crypto_mac_para store the corresponding parameters, such as > +\field{src_data_len}. The length and GPA can determine the specific content > in the guest memory. > + > +\subparagraph{Driver Requirements: Crypto operation: MAC > operation}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: MAC operation / Driver > Requirements: Crypto operation: MAC operation} > + > +Refer to the hash operation. > +The driver MUST set the \field{opcode} field to VIRTIO_CRYPTO_MAC. > + > +\subparagraph{Device Requirements: Crypto operation: MAC > operation}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: MAC operation / Device > Requirements: Crypto operation: MAC operation} > + > +Refer to the hash operation. > + > +\paragraph{Crypto operation: Symmetric algorithms > operation}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: Symmetric algorithms > operation} > + > +\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; > +}; > +struct virtio_crypto_cipher_input { > + le64 dst_data_addr; /* destination data guest physical address */ > + /* > + * in header guest physical address, See struct > virtio_crypto_sym_crypt_op_inhdr > + * above > + */ > + le64 inhdr_addr; > +}; > + > +struct virtio_crypto_cipher_output { > + le64 iv_addr; /* iv guest physical address */ > + le64 src_data_addr; /* source data guest physical address */ > +}; > +struct virtio_crypto_cipher_data_req { > + struct virtio_crypto_cipher_para parameter; > + struct virtio_crypto_cipher_input idata; > + struct virtio_crypto_cipher_output odata; > +}; > +struct virtio_crypto_sym_data_req { > + struct virtio_crypto_cipher_data_req cipher_req; > + union { > + struct virtio_crypto_hash_data_req hash_req; > + struct virtio_crypto_mac_data_req mac_req; > + } u; > +}; > +\end{lstlisting} > + > +Both input and output parameters store the guest physical address (GPA) only > so that > +each data operation request only occupies one entry of the Vring descriptor > table, > +which improves the throughput of data transferring for symmetric algorithms. > +The struct virtio_crypto_cipher_para store the corresponding parameters, > +such as \field{src_data_len}. The length and GPA can determine the specific > content in the guest memory. > + > +\subparagraph{Driver Requirements: Crypto operation: Symmetric algorithms > encryption}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: Symmetric algorithms > operation / Driver Requirements: Crypto operation: Symmetric algorithms > encryption} > + > +Refer to the hash operation. > +The driver MUST set the opcode field to VIRTIO_CRYPTO_CIPHER_ENCRYPT. > +The driver MUST fill out the fields in struct virtio_crypto_sym_data_req > according to > +the operation type of the session. For example, if the created session is > based > +on VIRTIO_CRYPTO_SYM_OP_CIPHER, that means the driver just SHOULD fill out > fields > +of struct virtio_crypto_cipher_data_req in struct virtio_crypto_sym_data_req. > +If the created session is VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING type and > +VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode, that means the driver SHOULD fill out > +fields of both struct virtio_crypto_cipher_data_req and struct > +virtio_crypto_mac_data_req mac_req in struct virtio_crypto_sym_data_req. > + > +\subparagraph{Device Requirements: Crypto operation: Symmetric algorithms > encryption}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: Symmetric algorithms > operation / Device Requirements: Crypto operation: Symmetric algorithms > encryption} > + > +The device MUST parse the virtio_crypto_sym_data_req according to the > session_id in general header. > +For example, The device SHOULD only parsed 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 driver SHOULD parse fields of both struct virtio_crypto_cipher_data_req > and struct > +virtio_crypto_mac_data_req mac_req in struct virtio_crypto_sym_data_req if > the created > +session is VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING operation type and > VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH mode. > + > +The device MUST copy the result of encryption operation recorded by > \filed{dst_data_addr} filed in struct virtio_crypto_cipher_input in plain > cipher mode. > +The device MUST copy the result of hash operation recorded by > \filed{digest_result_addr} filed in struct virtio_crypto_hash_input in chain > hash/mac mode. > +The device MUST set the status recorded by \filed{inhdr_addr} field in strut > virtio_crypto_cipher_input which point > +struct virtio_crypto_sym_crypt_op_inhdr: either VIRTIO_CRYPTO_OP_OK for > success, VIRTIO_CRYPTO_OP_ERR for creation > +failed or device error, VIRTIO_CRYPTO_OP_NOTSUPP for not support. > + > +\subparagraph{Device Requirements: Crypto operation: Steps of > encryption}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: Symmetric algorithms > operation / Device Requirements: Crypto operation: Steps of encryption} > + > +Step1: Create a session: > +\begin{enumerate} > +\item The driver fills out the context message, including algorithm name, > key, keylen etc; > +\item The driver sends a context message to the backend device by controlq; > +\item The device creates a session using the message transmitted by controlq; > +\item Return the session id to the driver. > +\end{enumerate} > + > +Step2: Execute the detail encryption operation: > +\begin{enumerate} > +\item The driver fills out the encrypt requests; > +\item Put the requests into dataq and kick the virtqueue; > +\item The device executes the encryption operation according the requests?? > arguments; > +\item The device returns the encryption result to the driver by dataq; > +\item The driver callback handle the result and over. > +\end{enumerate} > + > +Note: the driver MAY support both synchronous and asynchronous encryption. > Then the performance > +is poor in synchronous operation because frequent context switching and > virtualization overhead. > +The driver SHOULD by preference use asynchronous encryption. > + > +\paragraph{Crypto operation: AEAD operation}\label{sec:Device Types / Crypto > Device / Device > +Operation / Crypto operation / Crypto operation: AEAD 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 { > + le64 dst_data_addr; /* destination data guest physical address */ > + le64 digest_result_addr; /* digest result guest physical address */ > + /* > + * in header guest physical address, See struct > virtio_crypto_sym_crypt_op_inhdr > + * above > + */ > + le64 inhdr_addr; > +}; > + > +struct virtio_crypto_aead_output { > + le64 iv_addr; /* iv guest physical address */ > + le64 src_data_addr; /* source data guest physical address */ > + le64 add_data_addr; /* additional auth data guest physical address */ > +}; > +struct virtio_crypto_aead_data_req { > + struct virtio_crypto_aead_para parameter; > + struct virtio_crypto_aead_input idata; > + struct virtio_crypto_aead_output odata; > +}; > +\end{lstlisting} > + > +Both input and output parameters store the guest physical address (GPA) only > so that > +each data operation request only occupies one entry of the Vring descriptor > table, > +which improves the throughput of data transferring for AEAD crypto service. > The > +struct virtio_crypto_aead_para store the corresponding parameters, such as > \field{src_data_len}. > +The length and GPA can determine the specific content in the guest memory. > + > +\subparagraph{Driver Requirements: Crypto operation: AEAD > encryption}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: AEAD operation / Driver > Requirements: Crypto operation: AEAD encryption} > + > +Refer to the symmetric algorithms encryption operation. > +The driver MUST set the \field{opcode} field to VIRTIO_CRYPTO_AEAD_ENCRYPT. > + > +\subparagraph{Device Requirements: Crypto operation: AEAD > encryption}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: AEAD operation / Device > Requirements: Crypto operation: AEAD encryption} > + > +Refer to the symmetric algorithms encryption operation. > + > +\subparagraph{Driver Requirements: Crypto operation: AEAD > decryption}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: AEAD operation / Driver > Requirements: Crypto operation: AEAD decryption} > + > +Refer to the symmetric algorithms encryption operation. > +The driver MUST set the \field{opcode} field to VIRTIO_CRYPTO_AEAD_DECRYPT. > + > +\subparagraph{Device Requirements: Crypto operation: AEAD > decryption}\label{sec:Device Types / Crypto Device / Device > +Operation / Crypto operation / Crypto operation: AEAD operation / Device > Requirements: Crypto operation: AEAD decryption} > + > +The device MUST verify and return the verify result to the driver. > +If the verify result is not correct, VIRTIO_CRYPTO_OP_BADMSG (bad message) > +MUST be returned the driver. > -- > 1.7.12.4 > >