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 QCryptodevBackendAlgoType 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 resource 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: true 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: true 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