xref: /openbmc/qemu/include/sysemu/cryptodev.h (revision 7a5951f6)
1 /*
2  * QEMU Crypto Device Implementation
3  *
4  * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
5  *
6  * Authors:
7  *    Gonglei <arei.gonglei@huawei.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23 #ifndef CRYPTODEV_H
24 #define CRYPTODEV_H
25 
26 #include "qemu/queue.h"
27 #include "qom/object.h"
28 
29 /**
30  * CryptoDevBackend:
31  *
32  * The CryptoDevBackend object is an interface
33  * for different cryptodev backends, which provides crypto
34  * operation wrapper.
35  *
36  */
37 
38 #define TYPE_CRYPTODEV_BACKEND "cryptodev-backend"
39 
40 OBJECT_DECLARE_TYPE(CryptoDevBackend, CryptoDevBackendClass,
41                     CRYPTODEV_BACKEND)
42 
43 
44 #define MAX_CRYPTO_QUEUE_NUM  64
45 
46 typedef struct CryptoDevBackendConf CryptoDevBackendConf;
47 typedef struct CryptoDevBackendPeers CryptoDevBackendPeers;
48 typedef struct CryptoDevBackendClient
49                      CryptoDevBackendClient;
50 
51 enum CryptoDevBackendAlgType {
52     CRYPTODEV_BACKEND_ALG_SYM,
53     CRYPTODEV_BACKEND_ALG_ASYM,
54     CRYPTODEV_BACKEND_ALG__MAX,
55 };
56 
57 /**
58  * CryptoDevBackendSymSessionInfo:
59  *
60  * @cipher_alg: algorithm type of CIPHER
61  * @key_len: byte length of cipher key
62  * @hash_alg: algorithm type of HASH/MAC
63  * @hash_result_len: byte length of HASH operation result
64  * @auth_key_len: byte length of authenticated key
65  * @add_len: byte length of additional authenticated data
66  * @op_type: operation type (refer to virtio_crypto.h)
67  * @direction: encryption or direction for CIPHER
68  * @hash_mode: HASH mode for HASH operation (refer to virtio_crypto.h)
69  * @alg_chain_order: order of algorithm chaining (CIPHER then HASH,
70  *                   or HASH then CIPHER)
71  * @cipher_key: point to a key of CIPHER
72  * @auth_key: point to an authenticated key of MAC
73  *
74  */
75 typedef struct CryptoDevBackendSymSessionInfo {
76     /* corresponding with virtio crypto spec */
77     uint32_t cipher_alg;
78     uint32_t key_len;
79     uint32_t hash_alg;
80     uint32_t hash_result_len;
81     uint32_t auth_key_len;
82     uint32_t add_len;
83     uint8_t op_type;
84     uint8_t direction;
85     uint8_t hash_mode;
86     uint8_t alg_chain_order;
87     uint8_t *cipher_key;
88     uint8_t *auth_key;
89 } CryptoDevBackendSymSessionInfo;
90 
91 /**
92  * CryptoDevBackendAsymSessionInfo:
93  */
94 typedef struct CryptoDevBackendRsaPara {
95     uint32_t padding_algo;
96     uint32_t hash_algo;
97 } CryptoDevBackendRsaPara;
98 
99 typedef struct CryptoDevBackendAsymSessionInfo {
100     /* corresponding with virtio crypto spec */
101     uint32_t algo;
102     uint32_t keytype;
103     uint32_t keylen;
104     uint8_t *key;
105     union {
106         CryptoDevBackendRsaPara rsa;
107     } u;
108 } CryptoDevBackendAsymSessionInfo;
109 
110 typedef struct CryptoDevBackendSessionInfo {
111     uint32_t op_code;
112     union {
113         CryptoDevBackendSymSessionInfo sym_sess_info;
114         CryptoDevBackendAsymSessionInfo asym_sess_info;
115     } u;
116     uint64_t session_id;
117 } CryptoDevBackendSessionInfo;
118 
119 /**
120  * CryptoDevBackendSymOpInfo:
121  *
122  * @aad_len: byte length of additional authenticated data
123  * @iv_len: byte length of initialization vector or counter
124  * @src_len: byte length of source data
125  * @dst_len: byte length of destination data
126  * @digest_result_len: byte length of hash digest result
127  * @hash_start_src_offset: Starting point for hash processing, specified
128  *  as number of bytes from start of packet in source data, only used for
129  *  algorithm chain
130  * @cipher_start_src_offset: Starting point for cipher processing, specified
131  *  as number of bytes from start of packet in source data, only used for
132  *  algorithm chain
133  * @len_to_hash: byte length of source data on which the hash
134  *  operation will be computed, only used for algorithm chain
135  * @len_to_cipher: byte length of source data on which the cipher
136  *  operation will be computed, only used for algorithm chain
137  * @op_type: operation type (refer to virtio_crypto.h)
138  * @iv: point to the initialization vector or counter
139  * @src: point to the source data
140  * @dst: point to the destination data
141  * @aad_data: point to the additional authenticated data
142  * @digest_result: point to the digest result data
143  * @data[0]: point to the extensional memory by one memory allocation
144  *
145  */
146 typedef struct CryptoDevBackendSymOpInfo {
147     uint32_t aad_len;
148     uint32_t iv_len;
149     uint32_t src_len;
150     uint32_t dst_len;
151     uint32_t digest_result_len;
152     uint32_t hash_start_src_offset;
153     uint32_t cipher_start_src_offset;
154     uint32_t len_to_hash;
155     uint32_t len_to_cipher;
156     uint8_t op_type;
157     uint8_t *iv;
158     uint8_t *src;
159     uint8_t *dst;
160     uint8_t *aad_data;
161     uint8_t *digest_result;
162     uint8_t data[];
163 } CryptoDevBackendSymOpInfo;
164 
165 
166 /**
167  * CryptoDevBackendAsymOpInfo:
168  *
169  * @src_len: byte length of source data
170  * @dst_len: byte length of destination data
171  * @src: point to the source data
172  * @dst: point to the destination data
173  *
174  */
175 typedef struct CryptoDevBackendAsymOpInfo {
176     uint32_t src_len;
177     uint32_t dst_len;
178     uint8_t *src;
179     uint8_t *dst;
180 } CryptoDevBackendAsymOpInfo;
181 
182 typedef struct CryptoDevBackendOpInfo {
183     enum CryptoDevBackendAlgType algtype;
184     uint32_t op_code;
185     uint64_t session_id;
186     union {
187         CryptoDevBackendSymOpInfo *sym_op_info;
188         CryptoDevBackendAsymOpInfo *asym_op_info;
189     } u;
190 } CryptoDevBackendOpInfo;
191 
192 typedef void (*CryptoDevCompletionFunc) (void *opaque, int ret);
193 struct CryptoDevBackendClass {
194     ObjectClass parent_class;
195 
196     void (*init)(CryptoDevBackend *backend, Error **errp);
197     void (*cleanup)(CryptoDevBackend *backend, Error **errp);
198 
199     int (*create_session)(CryptoDevBackend *backend,
200                           CryptoDevBackendSessionInfo *sess_info,
201                           uint32_t queue_index,
202                           CryptoDevCompletionFunc cb,
203                           void *opaque);
204 
205     int (*close_session)(CryptoDevBackend *backend,
206                          uint64_t session_id,
207                          uint32_t queue_index,
208                          CryptoDevCompletionFunc cb,
209                          void *opaque);
210 
211     int (*do_op)(CryptoDevBackend *backend,
212                  CryptoDevBackendOpInfo *op_info,
213                  uint32_t queue_index,
214                  CryptoDevCompletionFunc cb,
215                  void *opaque);
216 };
217 
218 typedef enum CryptoDevBackendOptionsType {
219     CRYPTODEV_BACKEND_TYPE_NONE = 0,
220     CRYPTODEV_BACKEND_TYPE_BUILTIN = 1,
221     CRYPTODEV_BACKEND_TYPE_VHOST_USER = 2,
222     CRYPTODEV_BACKEND_TYPE_LKCF = 3,
223     CRYPTODEV_BACKEND_TYPE__MAX,
224 } CryptoDevBackendOptionsType;
225 
226 struct CryptoDevBackendClient {
227     CryptoDevBackendOptionsType type;
228     char *model;
229     char *name;
230     char *info_str;
231     unsigned int queue_index;
232     int vring_enable;
233     QTAILQ_ENTRY(CryptoDevBackendClient) next;
234 };
235 
236 struct CryptoDevBackendPeers {
237     CryptoDevBackendClient *ccs[MAX_CRYPTO_QUEUE_NUM];
238     uint32_t queues;
239 };
240 
241 struct CryptoDevBackendConf {
242     CryptoDevBackendPeers peers;
243 
244     /* Supported service mask */
245     uint32_t crypto_services;
246 
247     /* Detailed algorithms mask */
248     uint32_t cipher_algo_l;
249     uint32_t cipher_algo_h;
250     uint32_t hash_algo;
251     uint32_t mac_algo_l;
252     uint32_t mac_algo_h;
253     uint32_t aead_algo;
254     uint32_t akcipher_algo;
255     /* Maximum length of cipher key */
256     uint32_t max_cipher_key_len;
257     /* Maximum length of authenticated key */
258     uint32_t max_auth_key_len;
259     /* Maximum size of each crypto request's content */
260     uint64_t max_size;
261 };
262 
263 struct CryptoDevBackend {
264     Object parent_obj;
265 
266     bool ready;
267     /* Tag the cryptodev backend is used by virtio-crypto or not */
268     bool is_used;
269     CryptoDevBackendConf conf;
270 };
271 
272 /**
273  * cryptodev_backend_new_client:
274  * @model: the cryptodev backend model
275  * @name: the cryptodev backend name, can be NULL
276  *
277  * Creates a new cryptodev backend client object
278  * with the @name in the model @model.
279  *
280  * The returned object must be released with
281  * cryptodev_backend_free_client() when no
282  * longer required
283  *
284  * Returns: a new cryptodev backend client object
285  */
286 CryptoDevBackendClient *
287 cryptodev_backend_new_client(const char *model,
288                                     const char *name);
289 /**
290  * cryptodev_backend_free_client:
291  * @cc: the cryptodev backend client object
292  *
293  * Release the memory associated with @cc that
294  * was previously allocated by cryptodev_backend_new_client()
295  */
296 void cryptodev_backend_free_client(
297                   CryptoDevBackendClient *cc);
298 
299 /**
300  * cryptodev_backend_cleanup:
301  * @backend: the cryptodev backend object
302  * @errp: pointer to a NULL-initialized error object
303  *
304  * Clean the resouce associated with @backend that realizaed
305  * by the specific backend's init() callback
306  */
307 void cryptodev_backend_cleanup(
308            CryptoDevBackend *backend,
309            Error **errp);
310 
311 /**
312  * cryptodev_backend_create_session:
313  * @backend: the cryptodev backend object
314  * @sess_info: parameters needed by session creating
315  * @queue_index: queue index of cryptodev backend client
316  * @errp: pointer to a NULL-initialized error object
317  * @cb: callback when session create is compeleted
318  * @opaque: parameter passed to callback
319  *
320  * Create a session for symmetric/asymmetric algorithms
321  *
322  * Returns: 0 for success and cb will be called when creation is completed,
323  * negative value for error, and cb will not be called.
324  */
325 int cryptodev_backend_create_session(
326            CryptoDevBackend *backend,
327            CryptoDevBackendSessionInfo *sess_info,
328            uint32_t queue_index,
329            CryptoDevCompletionFunc cb,
330            void *opaque);
331 
332 /**
333  * cryptodev_backend_close_session:
334  * @backend: the cryptodev backend object
335  * @session_id: the session id
336  * @queue_index: queue index of cryptodev backend client
337  * @errp: pointer to a NULL-initialized error object
338  * @cb: callback when session create is compeleted
339  * @opaque: parameter passed to callback
340  *
341  * Close a session for which was previously
342  * created by cryptodev_backend_create_session()
343  *
344  * Returns: 0 for success and cb will be called when creation is completed,
345  * negative value for error, and cb will not be called.
346  */
347 int cryptodev_backend_close_session(
348            CryptoDevBackend *backend,
349            uint64_t session_id,
350            uint32_t queue_index,
351            CryptoDevCompletionFunc cb,
352            void *opaque);
353 
354 /**
355  * cryptodev_backend_crypto_operation:
356  * @backend: the cryptodev backend object
357  * @opaque1: pointer to a VirtIOCryptoReq object
358  * @queue_index: queue index of cryptodev backend client
359  * @errp: pointer to a NULL-initialized error object
360  * @cb: callbacks when operation is completed
361  * @opaque2: parameter passed to cb
362  *
363  * Do crypto operation, such as encryption and
364  * decryption
365  *
366  * Returns: 0 for success and cb will be called when creation is completed,
367  * negative value for error, and cb will not be called.
368  */
369 int cryptodev_backend_crypto_operation(
370                  CryptoDevBackend *backend,
371                  void *opaque1,
372                  uint32_t queue_index,
373                  CryptoDevCompletionFunc cb,
374                  void *opaque2);
375 
376 /**
377  * cryptodev_backend_set_used:
378  * @backend: the cryptodev backend object
379  * @used: ture or false
380  *
381  * Set the cryptodev backend is used by virtio-crypto or not
382  */
383 void cryptodev_backend_set_used(CryptoDevBackend *backend, bool used);
384 
385 /**
386  * cryptodev_backend_is_used:
387  * @backend: the cryptodev backend object
388  *
389  * Return the status that the cryptodev backend is used
390  * by virtio-crypto or not
391  *
392  * Returns: true on used, or false on not used
393  */
394 bool cryptodev_backend_is_used(CryptoDevBackend *backend);
395 
396 /**
397  * cryptodev_backend_set_ready:
398  * @backend: the cryptodev backend object
399  * @ready: ture or false
400  *
401  * Set the cryptodev backend is ready or not, which is called
402  * by the children of the cryptodev banckend interface.
403  */
404 void cryptodev_backend_set_ready(CryptoDevBackend *backend, bool ready);
405 
406 /**
407  * cryptodev_backend_is_ready:
408  * @backend: the cryptodev backend object
409  *
410  * Return the status that the cryptodev backend is ready or not
411  *
412  * Returns: true on ready, or false on not ready
413  */
414 bool cryptodev_backend_is_ready(CryptoDevBackend *backend);
415 
416 #endif /* CRYPTODEV_H */
417