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