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