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