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