xref: /openbmc/qemu/include/sysemu/cryptodev.h (revision 0e76929d)
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 } CryptoDevBackendSessionInfo;
117 
118 /**
119  * CryptoDevBackendSymOpInfo:
120  *
121  * @aad_len: byte length of additional authenticated data
122  * @iv_len: byte length of initialization vector or counter
123  * @src_len: byte length of source data
124  * @dst_len: byte length of destination data
125  * @digest_result_len: byte length of hash digest result
126  * @hash_start_src_offset: Starting point for hash processing, specified
127  *  as number of bytes from start of packet in source data, only used for
128  *  algorithm chain
129  * @cipher_start_src_offset: Starting point for cipher processing, specified
130  *  as number of bytes from start of packet in source data, only used for
131  *  algorithm chain
132  * @len_to_hash: byte length of source data on which the hash
133  *  operation will be computed, only used for algorithm chain
134  * @len_to_cipher: byte length of source data on which the cipher
135  *  operation will be computed, only used for algorithm chain
136  * @op_type: operation type (refer to virtio_crypto.h)
137  * @iv: point to the initialization vector or counter
138  * @src: point to the source data
139  * @dst: point to the destination data
140  * @aad_data: point to the additional authenticated data
141  * @digest_result: point to the digest result data
142  * @data[0]: point to the extensional memory by one memory allocation
143  *
144  */
145 typedef struct CryptoDevBackendSymOpInfo {
146     uint32_t aad_len;
147     uint32_t iv_len;
148     uint32_t src_len;
149     uint32_t dst_len;
150     uint32_t digest_result_len;
151     uint32_t hash_start_src_offset;
152     uint32_t cipher_start_src_offset;
153     uint32_t len_to_hash;
154     uint32_t len_to_cipher;
155     uint8_t op_type;
156     uint8_t *iv;
157     uint8_t *src;
158     uint8_t *dst;
159     uint8_t *aad_data;
160     uint8_t *digest_result;
161     uint8_t data[];
162 } CryptoDevBackendSymOpInfo;
163 
164 
165 /**
166  * CryptoDevBackendAsymOpInfo:
167  *
168  * @src_len: byte length of source data
169  * @dst_len: byte length of destination data
170  * @src: point to the source data
171  * @dst: point to the destination data
172  *
173  */
174 typedef struct CryptoDevBackendAsymOpInfo {
175     uint32_t src_len;
176     uint32_t dst_len;
177     uint8_t *src;
178     uint8_t *dst;
179 } CryptoDevBackendAsymOpInfo;
180 
181 typedef struct CryptoDevBackendOpInfo {
182     enum CryptoDevBackendAlgType algtype;
183     uint32_t op_code;
184     uint64_t session_id;
185     union {
186         CryptoDevBackendSymOpInfo *sym_op_info;
187         CryptoDevBackendAsymOpInfo *asym_op_info;
188     } u;
189 } CryptoDevBackendOpInfo;
190 
191 struct CryptoDevBackendClass {
192     ObjectClass parent_class;
193 
194     void (*init)(CryptoDevBackend *backend, Error **errp);
195     void (*cleanup)(CryptoDevBackend *backend, Error **errp);
196 
197     int64_t (*create_session)(CryptoDevBackend *backend,
198                        CryptoDevBackendSessionInfo *sess_info,
199                        uint32_t queue_index, Error **errp);
200     int (*close_session)(CryptoDevBackend *backend,
201                            uint64_t session_id,
202                            uint32_t queue_index, Error **errp);
203     int (*do_op)(CryptoDevBackend *backend,
204                      CryptoDevBackendOpInfo *op_info,
205                      uint32_t queue_index, Error **errp);
206 };
207 
208 typedef enum CryptoDevBackendOptionsType {
209     CRYPTODEV_BACKEND_TYPE_NONE = 0,
210     CRYPTODEV_BACKEND_TYPE_BUILTIN = 1,
211     CRYPTODEV_BACKEND_TYPE_VHOST_USER = 2,
212     CRYPTODEV_BACKEND_TYPE__MAX,
213 } CryptoDevBackendOptionsType;
214 
215 struct CryptoDevBackendClient {
216     CryptoDevBackendOptionsType type;
217     char *model;
218     char *name;
219     char *info_str;
220     unsigned int queue_index;
221     int vring_enable;
222     QTAILQ_ENTRY(CryptoDevBackendClient) next;
223 };
224 
225 struct CryptoDevBackendPeers {
226     CryptoDevBackendClient *ccs[MAX_CRYPTO_QUEUE_NUM];
227     uint32_t queues;
228 };
229 
230 struct CryptoDevBackendConf {
231     CryptoDevBackendPeers peers;
232 
233     /* Supported service mask */
234     uint32_t crypto_services;
235 
236     /* Detailed algorithms mask */
237     uint32_t cipher_algo_l;
238     uint32_t cipher_algo_h;
239     uint32_t hash_algo;
240     uint32_t mac_algo_l;
241     uint32_t mac_algo_h;
242     uint32_t aead_algo;
243     uint32_t akcipher_algo;
244     /* Maximum length of cipher key */
245     uint32_t max_cipher_key_len;
246     /* Maximum length of authenticated key */
247     uint32_t max_auth_key_len;
248     /* Maximum size of each crypto request's content */
249     uint64_t max_size;
250 };
251 
252 struct CryptoDevBackend {
253     Object parent_obj;
254 
255     bool ready;
256     /* Tag the cryptodev backend is used by virtio-crypto or not */
257     bool is_used;
258     CryptoDevBackendConf conf;
259 };
260 
261 /**
262  * cryptodev_backend_new_client:
263  * @model: the cryptodev backend model
264  * @name: the cryptodev backend name, can be NULL
265  *
266  * Creates a new cryptodev backend client object
267  * with the @name in the model @model.
268  *
269  * The returned object must be released with
270  * cryptodev_backend_free_client() when no
271  * longer required
272  *
273  * Returns: a new cryptodev backend client object
274  */
275 CryptoDevBackendClient *
276 cryptodev_backend_new_client(const char *model,
277                                     const char *name);
278 /**
279  * cryptodev_backend_free_client:
280  * @cc: the cryptodev backend client object
281  *
282  * Release the memory associated with @cc that
283  * was previously allocated by cryptodev_backend_new_client()
284  */
285 void cryptodev_backend_free_client(
286                   CryptoDevBackendClient *cc);
287 
288 /**
289  * cryptodev_backend_cleanup:
290  * @backend: the cryptodev backend object
291  * @errp: pointer to a NULL-initialized error object
292  *
293  * Clean the resouce associated with @backend that realizaed
294  * by the specific backend's init() callback
295  */
296 void cryptodev_backend_cleanup(
297            CryptoDevBackend *backend,
298            Error **errp);
299 
300 /**
301  * cryptodev_backend_create_session:
302  * @backend: the cryptodev backend object
303  * @sess_info: parameters needed by session creating
304  * @queue_index: queue index of cryptodev backend client
305  * @errp: pointer to a NULL-initialized error object
306  *
307  * Create a session for symmetric/symmetric algorithms
308  *
309  * Returns: session id on success, or -1 on error
310  */
311 int64_t cryptodev_backend_create_session(
312            CryptoDevBackend *backend,
313            CryptoDevBackendSessionInfo *sess_info,
314            uint32_t queue_index, Error **errp);
315 
316 /**
317  * cryptodev_backend_close_session:
318  * @backend: the cryptodev backend object
319  * @session_id: the session id
320  * @queue_index: queue index of cryptodev backend client
321  * @errp: pointer to a NULL-initialized error object
322  *
323  * Close a session for which was previously
324  * created by cryptodev_backend_create_session()
325  *
326  * Returns: 0 on success, or Negative on error
327  */
328 int cryptodev_backend_close_session(
329            CryptoDevBackend *backend,
330            uint64_t session_id,
331            uint32_t queue_index, Error **errp);
332 
333 /**
334  * cryptodev_backend_crypto_operation:
335  * @backend: the cryptodev backend object
336  * @opaque: pointer to a VirtIOCryptoReq object
337  * @queue_index: queue index of cryptodev backend client
338  * @errp: pointer to a NULL-initialized error object
339  *
340  * Do crypto operation, such as encryption and
341  * decryption
342  *
343  * Returns: VIRTIO_CRYPTO_OK on success,
344  *         or -VIRTIO_CRYPTO_* on error
345  */
346 int cryptodev_backend_crypto_operation(
347                  CryptoDevBackend *backend,
348                  void *opaque,
349                  uint32_t queue_index, Error **errp);
350 
351 /**
352  * cryptodev_backend_set_used:
353  * @backend: the cryptodev backend object
354  * @used: ture or false
355  *
356  * Set the cryptodev backend is used by virtio-crypto or not
357  */
358 void cryptodev_backend_set_used(CryptoDevBackend *backend, bool used);
359 
360 /**
361  * cryptodev_backend_is_used:
362  * @backend: the cryptodev backend object
363  *
364  * Return the status that the cryptodev backend is used
365  * by virtio-crypto or not
366  *
367  * Returns: true on used, or false on not used
368  */
369 bool cryptodev_backend_is_used(CryptoDevBackend *backend);
370 
371 /**
372  * cryptodev_backend_set_ready:
373  * @backend: the cryptodev backend object
374  * @ready: ture or false
375  *
376  * Set the cryptodev backend is ready or not, which is called
377  * by the children of the cryptodev banckend interface.
378  */
379 void cryptodev_backend_set_ready(CryptoDevBackend *backend, bool ready);
380 
381 /**
382  * cryptodev_backend_is_ready:
383  * @backend: the cryptodev backend object
384  *
385  * Return the status that the cryptodev backend is ready or not
386  *
387  * Returns: true on ready, or false on not ready
388  */
389 bool cryptodev_backend_is_ready(CryptoDevBackend *backend);
390 
391 #endif /* CRYPTODEV_H */
392