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 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 #define CRYPTODEV_BACKEND(obj) \ 41 OBJECT_CHECK(CryptoDevBackend, \ 42 (obj), TYPE_CRYPTODEV_BACKEND) 43 #define CRYPTODEV_BACKEND_GET_CLASS(obj) \ 44 OBJECT_GET_CLASS(CryptoDevBackendClass, \ 45 (obj), TYPE_CRYPTODEV_BACKEND) 46 #define CRYPTODEV_BACKEND_CLASS(klass) \ 47 OBJECT_CLASS_CHECK(CryptoDevBackendClass, \ 48 (klass), TYPE_CRYPTODEV_BACKEND) 49 50 51 #define MAX_CRYPTO_QUEUE_NUM 64 52 53 typedef struct CryptoDevBackendConf CryptoDevBackendConf; 54 typedef struct CryptoDevBackendPeers CryptoDevBackendPeers; 55 typedef struct CryptoDevBackendClient 56 CryptoDevBackendClient; 57 typedef struct CryptoDevBackend CryptoDevBackend; 58 59 enum CryptoDevBackendAlgType { 60 CRYPTODEV_BACKEND_ALG_SYM, 61 CRYPTODEV_BACKEND_ALG__MAX, 62 }; 63 64 /** 65 * CryptoDevBackendSymSessionInfo: 66 * 67 * @op_code: operation code (refer to virtio_crypto.h) 68 * @cipher_alg: algorithm type of CIPHER 69 * @key_len: byte length of cipher key 70 * @hash_alg: algorithm type of HASH/MAC 71 * @hash_result_len: byte length of HASH operation result 72 * @auth_key_len: byte length of authenticated key 73 * @add_len: byte length of additional authenticated data 74 * @op_type: operation type (refer to virtio_crypto.h) 75 * @direction: encryption or direction for CIPHER 76 * @hash_mode: HASH mode for HASH operation (refer to virtio_crypto.h) 77 * @alg_chain_order: order of algorithm chaining (CIPHER then HASH, 78 * or HASH then CIPHER) 79 * @cipher_key: point to a key of CIPHER 80 * @auth_key: point to an authenticated key of MAC 81 * 82 */ 83 typedef struct CryptoDevBackendSymSessionInfo { 84 /* corresponding with virtio crypto spec */ 85 uint32_t op_code; 86 uint32_t cipher_alg; 87 uint32_t key_len; 88 uint32_t hash_alg; 89 uint32_t hash_result_len; 90 uint32_t auth_key_len; 91 uint32_t add_len; 92 uint8_t op_type; 93 uint8_t direction; 94 uint8_t hash_mode; 95 uint8_t alg_chain_order; 96 uint8_t *cipher_key; 97 uint8_t *auth_key; 98 } CryptoDevBackendSymSessionInfo; 99 100 /** 101 * CryptoDevBackendSymOpInfo: 102 * 103 * @session_id: session index which was previously 104 * created by cryptodev_backend_sym_create_session() 105 * @aad_len: byte length of additional authenticated data 106 * @iv_len: byte length of initialization vector or counter 107 * @src_len: byte length of source data 108 * @dst_len: byte length of destination data 109 * @digest_result_len: byte length of hash digest result 110 * @hash_start_src_offset: Starting point for hash processing, specified 111 * as number of bytes from start of packet in source data, only used for 112 * algorithm chain 113 * @cipher_start_src_offset: Starting point for cipher processing, specified 114 * as number of bytes from start of packet in source data, only used for 115 * algorithm chain 116 * @len_to_hash: byte length of source data on which the hash 117 * operation will be computed, only used for algorithm chain 118 * @len_to_cipher: byte length of source data on which the cipher 119 * operation will be computed, only used for algorithm chain 120 * @op_type: operation type (refer to virtio_crypto.h) 121 * @iv: point to the initialization vector or counter 122 * @src: point to the source data 123 * @dst: point to the destination data 124 * @aad_data: point to the additional authenticated data 125 * @digest_result: point to the digest result data 126 * @data[0]: point to the extensional memory by one memory allocation 127 * 128 */ 129 typedef struct CryptoDevBackendSymOpInfo { 130 uint64_t session_id; 131 uint32_t aad_len; 132 uint32_t iv_len; 133 uint32_t src_len; 134 uint32_t dst_len; 135 uint32_t digest_result_len; 136 uint32_t hash_start_src_offset; 137 uint32_t cipher_start_src_offset; 138 uint32_t len_to_hash; 139 uint32_t len_to_cipher; 140 uint8_t op_type; 141 uint8_t *iv; 142 uint8_t *src; 143 uint8_t *dst; 144 uint8_t *aad_data; 145 uint8_t *digest_result; 146 uint8_t data[0]; 147 } CryptoDevBackendSymOpInfo; 148 149 typedef struct CryptoDevBackendClass { 150 ObjectClass parent_class; 151 152 void (*init)(CryptoDevBackend *backend, Error **errp); 153 void (*cleanup)(CryptoDevBackend *backend, Error **errp); 154 155 int64_t (*create_session)(CryptoDevBackend *backend, 156 CryptoDevBackendSymSessionInfo *sess_info, 157 uint32_t queue_index, Error **errp); 158 int (*close_session)(CryptoDevBackend *backend, 159 uint64_t session_id, 160 uint32_t queue_index, Error **errp); 161 int (*do_sym_op)(CryptoDevBackend *backend, 162 CryptoDevBackendSymOpInfo *op_info, 163 uint32_t queue_index, Error **errp); 164 } CryptoDevBackendClass; 165 166 typedef enum CryptoDevBackendOptionsType { 167 CRYPTODEV_BACKEND_TYPE_NONE = 0, 168 CRYPTODEV_BACKEND_TYPE_BUILTIN = 1, 169 CRYPTODEV_BACKEND_TYPE_VHOST_USER = 2, 170 CRYPTODEV_BACKEND_TYPE__MAX, 171 } CryptoDevBackendOptionsType; 172 173 struct CryptoDevBackendClient { 174 CryptoDevBackendOptionsType type; 175 char *model; 176 char *name; 177 char *info_str; 178 unsigned int queue_index; 179 int vring_enable; 180 QTAILQ_ENTRY(CryptoDevBackendClient) next; 181 }; 182 183 struct CryptoDevBackendPeers { 184 CryptoDevBackendClient *ccs[MAX_CRYPTO_QUEUE_NUM]; 185 uint32_t queues; 186 }; 187 188 struct CryptoDevBackendConf { 189 CryptoDevBackendPeers peers; 190 191 /* Supported service mask */ 192 uint32_t crypto_services; 193 194 /* Detailed algorithms mask */ 195 uint32_t cipher_algo_l; 196 uint32_t cipher_algo_h; 197 uint32_t hash_algo; 198 uint32_t mac_algo_l; 199 uint32_t mac_algo_h; 200 uint32_t aead_algo; 201 /* Maximum length of cipher key */ 202 uint32_t max_cipher_key_len; 203 /* Maximum length of authenticated key */ 204 uint32_t max_auth_key_len; 205 /* Maximum size of each crypto request's content */ 206 uint64_t max_size; 207 }; 208 209 struct CryptoDevBackend { 210 Object parent_obj; 211 212 bool ready; 213 /* Tag the cryptodev backend is used by virtio-crypto or not */ 214 bool is_used; 215 CryptoDevBackendConf conf; 216 }; 217 218 /** 219 * cryptodev_backend_new_client: 220 * @model: the cryptodev backend model 221 * @name: the cryptodev backend name, can be NULL 222 * 223 * Creates a new cryptodev backend client object 224 * with the @name in the model @model. 225 * 226 * The returned object must be released with 227 * cryptodev_backend_free_client() when no 228 * longer required 229 * 230 * Returns: a new cryptodev backend client object 231 */ 232 CryptoDevBackendClient * 233 cryptodev_backend_new_client(const char *model, 234 const char *name); 235 /** 236 * cryptodev_backend_free_client: 237 * @cc: the cryptodev backend client object 238 * 239 * Release the memory associated with @cc that 240 * was previously allocated by cryptodev_backend_new_client() 241 */ 242 void cryptodev_backend_free_client( 243 CryptoDevBackendClient *cc); 244 245 /** 246 * cryptodev_backend_cleanup: 247 * @backend: the cryptodev backend object 248 * @errp: pointer to a NULL-initialized error object 249 * 250 * Clean the resouce associated with @backend that realizaed 251 * by the specific backend's init() callback 252 */ 253 void cryptodev_backend_cleanup( 254 CryptoDevBackend *backend, 255 Error **errp); 256 257 /** 258 * cryptodev_backend_sym_create_session: 259 * @backend: the cryptodev backend object 260 * @sess_info: parameters needed by session creating 261 * @queue_index: queue index of cryptodev backend client 262 * @errp: pointer to a NULL-initialized error object 263 * 264 * Create a session for symmetric algorithms 265 * 266 * Returns: session id on success, or -1 on error 267 */ 268 int64_t cryptodev_backend_sym_create_session( 269 CryptoDevBackend *backend, 270 CryptoDevBackendSymSessionInfo *sess_info, 271 uint32_t queue_index, Error **errp); 272 273 /** 274 * cryptodev_backend_sym_close_session: 275 * @backend: the cryptodev backend object 276 * @session_id: the session id 277 * @queue_index: queue index of cryptodev backend client 278 * @errp: pointer to a NULL-initialized error object 279 * 280 * Close a session for symmetric algorithms which was previously 281 * created by cryptodev_backend_sym_create_session() 282 * 283 * Returns: 0 on success, or Negative on error 284 */ 285 int cryptodev_backend_sym_close_session( 286 CryptoDevBackend *backend, 287 uint64_t session_id, 288 uint32_t queue_index, Error **errp); 289 290 /** 291 * cryptodev_backend_crypto_operation: 292 * @backend: the cryptodev backend object 293 * @opaque: pointer to a VirtIOCryptoReq object 294 * @queue_index: queue index of cryptodev backend client 295 * @errp: pointer to a NULL-initialized error object 296 * 297 * Do crypto operation, such as encryption and 298 * decryption 299 * 300 * Returns: VIRTIO_CRYPTO_OK on success, 301 * or -VIRTIO_CRYPTO_* on error 302 */ 303 int cryptodev_backend_crypto_operation( 304 CryptoDevBackend *backend, 305 void *opaque, 306 uint32_t queue_index, Error **errp); 307 308 /** 309 * cryptodev_backend_set_used: 310 * @backend: the cryptodev backend object 311 * @used: ture or false 312 * 313 * Set the cryptodev backend is used by virtio-crypto or not 314 */ 315 void cryptodev_backend_set_used(CryptoDevBackend *backend, bool used); 316 317 /** 318 * cryptodev_backend_is_used: 319 * @backend: the cryptodev backend object 320 * 321 * Return the status that the cryptodev backend is used 322 * by virtio-crypto or not 323 * 324 * Returns: true on used, or false on not used 325 */ 326 bool cryptodev_backend_is_used(CryptoDevBackend *backend); 327 328 /** 329 * cryptodev_backend_set_ready: 330 * @backend: the cryptodev backend object 331 * @ready: ture or false 332 * 333 * Set the cryptodev backend is ready or not, which is called 334 * by the children of the cryptodev banckend interface. 335 */ 336 void cryptodev_backend_set_ready(CryptoDevBackend *backend, bool ready); 337 338 /** 339 * cryptodev_backend_is_ready: 340 * @backend: the cryptodev backend object 341 * 342 * Return the status that the cryptodev backend is ready or not 343 * 344 * Returns: true on ready, or false on not ready 345 */ 346 bool cryptodev_backend_is_ready(CryptoDevBackend *backend); 347 348 #endif /* CRYPTODEV_H */ 349