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