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