xref: /openbmc/qemu/include/sysemu/cryptodev.h (revision 243975c0)
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 "qemu/throttle.h"
28 #include "qom/object.h"
29 #include "qapi/qapi-types-cryptodev.h"
30 
31 /**
32  * CryptoDevBackend:
33  *
34  * The CryptoDevBackend object is an interface
35  * for different cryptodev backends, which provides crypto
36  * operation wrapper.
37  *
38  */
39 
40 #define TYPE_CRYPTODEV_BACKEND "cryptodev-backend"
41 
42 OBJECT_DECLARE_TYPE(CryptoDevBackend, CryptoDevBackendClass,
43                     CRYPTODEV_BACKEND)
44 
45 
46 #define MAX_CRYPTO_QUEUE_NUM  64
47 
48 typedef struct CryptoDevBackendConf CryptoDevBackendConf;
49 typedef struct CryptoDevBackendPeers CryptoDevBackendPeers;
50 typedef struct CryptoDevBackendClient
51                      CryptoDevBackendClient;
52 
53 /**
54  * CryptoDevBackendSymSessionInfo:
55  *
56  * @cipher_alg: algorithm type of CIPHER
57  * @key_len: byte length of cipher key
58  * @hash_alg: algorithm type of HASH/MAC
59  * @hash_result_len: byte length of HASH operation result
60  * @auth_key_len: byte length of authenticated key
61  * @add_len: byte length of additional authenticated data
62  * @op_type: operation type (refer to virtio_crypto.h)
63  * @direction: encryption or direction for CIPHER
64  * @hash_mode: HASH mode for HASH operation (refer to virtio_crypto.h)
65  * @alg_chain_order: order of algorithm chaining (CIPHER then HASH,
66  *                   or HASH then CIPHER)
67  * @cipher_key: point to a key of CIPHER
68  * @auth_key: point to an authenticated key of MAC
69  *
70  */
71 typedef struct CryptoDevBackendSymSessionInfo {
72     /* corresponding with virtio crypto spec */
73     uint32_t cipher_alg;
74     uint32_t key_len;
75     uint32_t hash_alg;
76     uint32_t hash_result_len;
77     uint32_t auth_key_len;
78     uint32_t add_len;
79     uint8_t op_type;
80     uint8_t direction;
81     uint8_t hash_mode;
82     uint8_t alg_chain_order;
83     uint8_t *cipher_key;
84     uint8_t *auth_key;
85 } CryptoDevBackendSymSessionInfo;
86 
87 /**
88  * CryptoDevBackendAsymSessionInfo:
89  */
90 typedef struct CryptoDevBackendRsaPara {
91     uint32_t padding_algo;
92     uint32_t hash_algo;
93 } CryptoDevBackendRsaPara;
94 
95 typedef struct CryptoDevBackendAsymSessionInfo {
96     /* corresponding with virtio crypto spec */
97     uint32_t algo;
98     uint32_t keytype;
99     uint32_t keylen;
100     uint8_t *key;
101     union {
102         CryptoDevBackendRsaPara rsa;
103     } u;
104 } CryptoDevBackendAsymSessionInfo;
105 
106 typedef struct CryptoDevBackendSessionInfo {
107     uint32_t op_code;
108     union {
109         CryptoDevBackendSymSessionInfo sym_sess_info;
110         CryptoDevBackendAsymSessionInfo asym_sess_info;
111     } u;
112     uint64_t session_id;
113 } CryptoDevBackendSessionInfo;
114 
115 /**
116  * CryptoDevBackendSymOpInfo:
117  *
118  * @aad_len: byte length of additional authenticated data
119  * @iv_len: byte length of initialization vector or counter
120  * @src_len: byte length of source data
121  * @dst_len: byte length of destination data
122  * @digest_result_len: byte length of hash digest result
123  * @hash_start_src_offset: Starting point for hash processing, specified
124  *  as number of bytes from start of packet in source data, only used for
125  *  algorithm chain
126  * @cipher_start_src_offset: Starting point for cipher processing, specified
127  *  as number of bytes from start of packet in source data, only used for
128  *  algorithm chain
129  * @len_to_hash: byte length of source data on which the hash
130  *  operation will be computed, only used for algorithm chain
131  * @len_to_cipher: byte length of source data on which the cipher
132  *  operation will be computed, only used for algorithm chain
133  * @op_type: operation type (refer to virtio_crypto.h)
134  * @iv: point to the initialization vector or counter
135  * @src: point to the source data
136  * @dst: point to the destination data
137  * @aad_data: point to the additional authenticated data
138  * @digest_result: point to the digest result data
139  * @data[0]: point to the extensional memory by one memory allocation
140  *
141  */
142 typedef struct CryptoDevBackendSymOpInfo {
143     uint32_t aad_len;
144     uint32_t iv_len;
145     uint32_t src_len;
146     uint32_t dst_len;
147     uint32_t digest_result_len;
148     uint32_t hash_start_src_offset;
149     uint32_t cipher_start_src_offset;
150     uint32_t len_to_hash;
151     uint32_t len_to_cipher;
152     uint8_t op_type;
153     uint8_t *iv;
154     uint8_t *src;
155     uint8_t *dst;
156     uint8_t *aad_data;
157     uint8_t *digest_result;
158     uint8_t data[];
159 } CryptoDevBackendSymOpInfo;
160 
161 
162 /**
163  * CryptoDevBackendAsymOpInfo:
164  *
165  * @src_len: byte length of source data
166  * @dst_len: byte length of destination data
167  * @src: point to the source data
168  * @dst: point to the destination data
169  *
170  */
171 typedef struct CryptoDevBackendAsymOpInfo {
172     uint32_t src_len;
173     uint32_t dst_len;
174     uint8_t *src;
175     uint8_t *dst;
176 } CryptoDevBackendAsymOpInfo;
177 
178 typedef void (*CryptoDevCompletionFunc) (void *opaque, int ret);
179 
180 typedef struct CryptoDevBackendOpInfo {
181     QCryptodevBackendAlgType algtype;
182     uint32_t op_code;
183     uint32_t queue_index;
184     CryptoDevCompletionFunc cb;
185     void *opaque; /* argument for cb */
186     uint64_t session_id;
187     union {
188         CryptoDevBackendSymOpInfo *sym_op_info;
189         CryptoDevBackendAsymOpInfo *asym_op_info;
190     } u;
191     QTAILQ_ENTRY(CryptoDevBackendOpInfo) next;
192 } CryptoDevBackendOpInfo;
193 
194 struct CryptoDevBackendClass {
195     ObjectClass parent_class;
196 
197     void (*init)(CryptoDevBackend *backend, Error **errp);
198     void (*cleanup)(CryptoDevBackend *backend, Error **errp);
199 
200     int (*create_session)(CryptoDevBackend *backend,
201                           CryptoDevBackendSessionInfo *sess_info,
202                           uint32_t queue_index,
203                           CryptoDevCompletionFunc cb,
204                           void *opaque);
205 
206     int (*close_session)(CryptoDevBackend *backend,
207                          uint64_t session_id,
208                          uint32_t queue_index,
209                          CryptoDevCompletionFunc cb,
210                          void *opaque);
211 
212     int (*do_op)(CryptoDevBackend *backend,
213                  CryptoDevBackendOpInfo *op_info);
214 };
215 
216 struct CryptoDevBackendClient {
217     QCryptodevBackendType type;
218     char *info_str;
219     unsigned int queue_index;
220     int vring_enable;
221     QTAILQ_ENTRY(CryptoDevBackendClient) next;
222 };
223 
224 struct CryptoDevBackendPeers {
225     CryptoDevBackendClient *ccs[MAX_CRYPTO_QUEUE_NUM];
226     uint32_t queues;
227 };
228 
229 struct CryptoDevBackendConf {
230     CryptoDevBackendPeers peers;
231 
232     /* Supported service mask */
233     uint32_t crypto_services;
234 
235     /* Detailed algorithms mask */
236     uint32_t cipher_algo_l;
237     uint32_t cipher_algo_h;
238     uint32_t hash_algo;
239     uint32_t mac_algo_l;
240     uint32_t mac_algo_h;
241     uint32_t aead_algo;
242     uint32_t akcipher_algo;
243     /* Maximum length of cipher key */
244     uint32_t max_cipher_key_len;
245     /* Maximum length of authenticated key */
246     uint32_t max_auth_key_len;
247     /* Maximum size of each crypto request's content */
248     uint64_t max_size;
249 };
250 
251 typedef struct CryptodevBackendSymStat {
252     int64_t encrypt_ops;
253     int64_t decrypt_ops;
254     int64_t encrypt_bytes;
255     int64_t decrypt_bytes;
256 } CryptodevBackendSymStat;
257 
258 typedef struct CryptodevBackendAsymStat {
259     int64_t encrypt_ops;
260     int64_t decrypt_ops;
261     int64_t sign_ops;
262     int64_t verify_ops;
263     int64_t encrypt_bytes;
264     int64_t decrypt_bytes;
265     int64_t sign_bytes;
266     int64_t verify_bytes;
267 } CryptodevBackendAsymStat;
268 
269 struct CryptoDevBackend {
270     Object parent_obj;
271 
272     bool ready;
273     /* Tag the cryptodev backend is used by virtio-crypto or not */
274     bool is_used;
275     CryptoDevBackendConf conf;
276     CryptodevBackendSymStat *sym_stat;
277     CryptodevBackendAsymStat *asym_stat;
278 
279     ThrottleState ts;
280     ThrottleTimers tt;
281     ThrottleConfig tc;
282     QTAILQ_HEAD(, CryptoDevBackendOpInfo) opinfos;
283 };
284 
285 #define CryptodevSymStatInc(be, op, bytes) do { \
286    be->sym_stat->op##_bytes += (bytes); \
287    be->sym_stat->op##_ops += 1; \
288 } while (/*CONSTCOND*/0)
289 
290 #define CryptodevSymStatIncEncrypt(be, bytes) \
291             CryptodevSymStatInc(be, encrypt, bytes)
292 
293 #define CryptodevSymStatIncDecrypt(be, bytes) \
294             CryptodevSymStatInc(be, decrypt, bytes)
295 
296 #define CryptodevAsymStatInc(be, op, bytes) do { \
297     be->asym_stat->op##_bytes += (bytes); \
298     be->asym_stat->op##_ops += 1; \
299 } while (/*CONSTCOND*/0)
300 
301 #define CryptodevAsymStatIncEncrypt(be, bytes) \
302             CryptodevAsymStatInc(be, encrypt, bytes)
303 
304 #define CryptodevAsymStatIncDecrypt(be, bytes) \
305             CryptodevAsymStatInc(be, decrypt, bytes)
306 
307 #define CryptodevAsymStatIncSign(be, bytes) \
308             CryptodevAsymStatInc(be, sign, bytes)
309 
310 #define CryptodevAsymStatIncVerify(be, bytes) \
311             CryptodevAsymStatInc(be, verify, bytes)
312 
313 
314 /**
315  * cryptodev_backend_new_client:
316  *
317  * Creates a new cryptodev backend client object.
318  *
319  * The returned object must be released with
320  * cryptodev_backend_free_client() when no
321  * longer required
322  *
323  * Returns: a new cryptodev backend client object
324  */
325 CryptoDevBackendClient *cryptodev_backend_new_client(void);
326 
327 /**
328  * cryptodev_backend_free_client:
329  * @cc: the cryptodev backend client object
330  *
331  * Release the memory associated with @cc that
332  * was previously allocated by cryptodev_backend_new_client()
333  */
334 void cryptodev_backend_free_client(
335                   CryptoDevBackendClient *cc);
336 
337 /**
338  * cryptodev_backend_cleanup:
339  * @backend: the cryptodev backend object
340  * @errp: pointer to a NULL-initialized error object
341  *
342  * Clean the resouce associated with @backend that realizaed
343  * by the specific backend's init() callback
344  */
345 void cryptodev_backend_cleanup(
346            CryptoDevBackend *backend,
347            Error **errp);
348 
349 /**
350  * cryptodev_backend_create_session:
351  * @backend: the cryptodev backend object
352  * @sess_info: parameters needed by session creating
353  * @queue_index: queue index of cryptodev backend client
354  * @errp: pointer to a NULL-initialized error object
355  * @cb: callback when session create is compeleted
356  * @opaque: parameter passed to callback
357  *
358  * Create a session for symmetric/asymmetric algorithms
359  *
360  * Returns: 0 for success and cb will be called when creation is completed,
361  * negative value for error, and cb will not be called.
362  */
363 int cryptodev_backend_create_session(
364            CryptoDevBackend *backend,
365            CryptoDevBackendSessionInfo *sess_info,
366            uint32_t queue_index,
367            CryptoDevCompletionFunc cb,
368            void *opaque);
369 
370 /**
371  * cryptodev_backend_close_session:
372  * @backend: the cryptodev backend object
373  * @session_id: the session id
374  * @queue_index: queue index of cryptodev backend client
375  * @errp: pointer to a NULL-initialized error object
376  * @cb: callback when session create is compeleted
377  * @opaque: parameter passed to callback
378  *
379  * Close a session for which was previously
380  * created by cryptodev_backend_create_session()
381  *
382  * Returns: 0 for success and cb will be called when creation is completed,
383  * negative value for error, and cb will not be called.
384  */
385 int cryptodev_backend_close_session(
386            CryptoDevBackend *backend,
387            uint64_t session_id,
388            uint32_t queue_index,
389            CryptoDevCompletionFunc cb,
390            void *opaque);
391 
392 /**
393  * cryptodev_backend_crypto_operation:
394  * @backend: the cryptodev backend object
395  * @op_info: pointer to a CryptoDevBackendOpInfo object
396  *
397  * Do crypto operation, such as encryption, decryption, signature and
398  * verification
399  *
400  * Returns: 0 for success and cb will be called when creation is completed,
401  * negative value for error, and cb will not be called.
402  */
403 int cryptodev_backend_crypto_operation(
404                  CryptoDevBackend *backend,
405                  CryptoDevBackendOpInfo *op_info);
406 
407 /**
408  * cryptodev_backend_set_used:
409  * @backend: the cryptodev backend object
410  * @used: ture or false
411  *
412  * Set the cryptodev backend is used by virtio-crypto or not
413  */
414 void cryptodev_backend_set_used(CryptoDevBackend *backend, bool used);
415 
416 /**
417  * cryptodev_backend_is_used:
418  * @backend: the cryptodev backend object
419  *
420  * Return the status that the cryptodev backend is used
421  * by virtio-crypto or not
422  *
423  * Returns: true on used, or false on not used
424  */
425 bool cryptodev_backend_is_used(CryptoDevBackend *backend);
426 
427 /**
428  * cryptodev_backend_set_ready:
429  * @backend: the cryptodev backend object
430  * @ready: ture or false
431  *
432  * Set the cryptodev backend is ready or not, which is called
433  * by the children of the cryptodev banckend interface.
434  */
435 void cryptodev_backend_set_ready(CryptoDevBackend *backend, bool ready);
436 
437 /**
438  * cryptodev_backend_is_ready:
439  * @backend: the cryptodev backend object
440  *
441  * Return the status that the cryptodev backend is ready or not
442  *
443  * Returns: true on ready, or false on not ready
444  */
445 bool cryptodev_backend_is_ready(CryptoDevBackend *backend);
446 
447 #endif /* CRYPTODEV_H */
448