cryptodev: introduce cryptodev backend interface
cryptodev backend interface is used to realize the active work for virtual crypto device. This patch only add the framework, doesn't include specific operations. Signed-off-by: Gonglei <arei.gonglei@huawei.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
		
							parent
							
								
									2bd3c31a60
								
							
						
					
					
						commit
						d0ee7a135f
					
				| 
						 | 
				
			
			@ -9,3 +9,5 @@ common-obj-$(CONFIG_TPM) += tpm.o
 | 
			
		|||
 | 
			
		||||
common-obj-y += hostmem.o hostmem-ram.o
 | 
			
		||||
common-obj-$(CONFIG_LINUX) += hostmem-file.o
 | 
			
		||||
 | 
			
		||||
common-obj-y += cryptodev.o
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,176 @@
 | 
			
		|||
/*
 | 
			
		||||
 * QEMU Crypto Device Implementation
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors:
 | 
			
		||||
 *    Gonglei <arei.gonglei@huawei.com>
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "qemu/osdep.h"
 | 
			
		||||
#include "sysemu/cryptodev.h"
 | 
			
		||||
#include "hw/boards.h"
 | 
			
		||||
#include "qapi/error.h"
 | 
			
		||||
#include "qapi/visitor.h"
 | 
			
		||||
#include "qapi-types.h"
 | 
			
		||||
#include "qapi-visit.h"
 | 
			
		||||
#include "qemu/config-file.h"
 | 
			
		||||
#include "qom/object_interfaces.h"
 | 
			
		||||
 | 
			
		||||
static QTAILQ_HEAD(, CryptoDevBackendClient) crypto_clients;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CryptoDevBackendClient *
 | 
			
		||||
cryptodev_backend_new_client(const char *model,
 | 
			
		||||
                                    const char *name)
 | 
			
		||||
{
 | 
			
		||||
    CryptoDevBackendClient *cc;
 | 
			
		||||
 | 
			
		||||
    cc = g_malloc0(sizeof(CryptoDevBackendClient));
 | 
			
		||||
    cc->model = g_strdup(model);
 | 
			
		||||
    if (name) {
 | 
			
		||||
        cc->name = g_strdup(name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QTAILQ_INSERT_TAIL(&crypto_clients, cc, next);
 | 
			
		||||
 | 
			
		||||
    return cc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cryptodev_backend_free_client(
 | 
			
		||||
                  CryptoDevBackendClient *cc)
 | 
			
		||||
{
 | 
			
		||||
    QTAILQ_REMOVE(&crypto_clients, cc, next);
 | 
			
		||||
    g_free(cc->name);
 | 
			
		||||
    g_free(cc->model);
 | 
			
		||||
    g_free(cc->info_str);
 | 
			
		||||
    g_free(cc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cryptodev_backend_cleanup(
 | 
			
		||||
             CryptoDevBackend *backend,
 | 
			
		||||
             Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    CryptoDevBackendClass *bc =
 | 
			
		||||
                  CRYPTODEV_BACKEND_GET_CLASS(backend);
 | 
			
		||||
 | 
			
		||||
    if (bc->cleanup) {
 | 
			
		||||
        bc->cleanup(backend, errp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    backend->ready = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cryptodev_backend_get_queues(Object *obj, Visitor *v, const char *name,
 | 
			
		||||
                             void *opaque, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    CryptoDevBackend *backend = CRYPTODEV_BACKEND(obj);
 | 
			
		||||
    uint32_t value = backend->conf.peers.queues;
 | 
			
		||||
 | 
			
		||||
    visit_type_uint32(v, name, &value, errp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cryptodev_backend_set_queues(Object *obj, Visitor *v, const char *name,
 | 
			
		||||
                             void *opaque, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    CryptoDevBackend *backend = CRYPTODEV_BACKEND(obj);
 | 
			
		||||
    Error *local_err = NULL;
 | 
			
		||||
    uint32_t value;
 | 
			
		||||
 | 
			
		||||
    visit_type_uint32(v, name, &value, &local_err);
 | 
			
		||||
    if (local_err) {
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    if (!value) {
 | 
			
		||||
        error_setg(&local_err, "Property '%s.%s' doesn't take value '%"
 | 
			
		||||
                   PRIu32 "'", object_get_typename(obj), name, value);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    backend->conf.peers.queues = value;
 | 
			
		||||
out:
 | 
			
		||||
    error_propagate(errp, local_err);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cryptodev_backend_complete(UserCreatable *uc, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    CryptoDevBackend *backend = CRYPTODEV_BACKEND(uc);
 | 
			
		||||
    CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_GET_CLASS(uc);
 | 
			
		||||
    Error *local_err = NULL;
 | 
			
		||||
 | 
			
		||||
    if (bc->init) {
 | 
			
		||||
        bc->init(backend, &local_err);
 | 
			
		||||
        if (local_err) {
 | 
			
		||||
            goto out;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    backend->ready = true;
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    backend->ready = false;
 | 
			
		||||
    error_propagate(errp, local_err);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cryptodev_backend_instance_init(Object *obj)
 | 
			
		||||
{
 | 
			
		||||
    object_property_add(obj, "queues", "int",
 | 
			
		||||
                          cryptodev_backend_get_queues,
 | 
			
		||||
                          cryptodev_backend_set_queues,
 | 
			
		||||
                          NULL, NULL, NULL);
 | 
			
		||||
    /* Initialize devices' queues property to 1 */
 | 
			
		||||
    object_property_set_int(obj, 1, "queues", NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cryptodev_backend_finalize(Object *obj)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cryptodev_backend_class_init(ObjectClass *oc, void *data)
 | 
			
		||||
{
 | 
			
		||||
    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
 | 
			
		||||
 | 
			
		||||
    ucc->complete = cryptodev_backend_complete;
 | 
			
		||||
 | 
			
		||||
    QTAILQ_INIT(&crypto_clients);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo cryptodev_backend_info = {
 | 
			
		||||
    .name = TYPE_CRYPTODEV_BACKEND,
 | 
			
		||||
    .parent = TYPE_OBJECT,
 | 
			
		||||
    .instance_size = sizeof(CryptoDevBackend),
 | 
			
		||||
    .instance_init = cryptodev_backend_instance_init,
 | 
			
		||||
    .instance_finalize = cryptodev_backend_finalize,
 | 
			
		||||
    .class_size = sizeof(CryptoDevBackendClass),
 | 
			
		||||
    .class_init = cryptodev_backend_class_init,
 | 
			
		||||
    .interfaces = (InterfaceInfo[]) {
 | 
			
		||||
        { TYPE_USER_CREATABLE },
 | 
			
		||||
        { }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cryptodev_backend_register_types(void)
 | 
			
		||||
{
 | 
			
		||||
    type_register_static(&cryptodev_backend_info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type_init(cryptodev_backend_register_types);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,148 @@
 | 
			
		|||
/*
 | 
			
		||||
 * QEMU Crypto Device Implementation
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors:
 | 
			
		||||
 *    Gonglei <arei.gonglei@huawei.com>
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public
 | 
			
		||||
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#ifndef CRYPTODEV_H
 | 
			
		||||
#define CRYPTODEV_H
 | 
			
		||||
 | 
			
		||||
#include "qom/object.h"
 | 
			
		||||
#include "qemu-common.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * CryptoDevBackend:
 | 
			
		||||
 *
 | 
			
		||||
 * The CryptoDevBackend object is an interface
 | 
			
		||||
 * for different cryptodev backends, which provides crypto
 | 
			
		||||
 * operation wrapper.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define TYPE_CRYPTODEV_BACKEND "cryptodev-backend"
 | 
			
		||||
 | 
			
		||||
#define CRYPTODEV_BACKEND(obj) \
 | 
			
		||||
    OBJECT_CHECK(CryptoDevBackend, \
 | 
			
		||||
                 (obj), TYPE_CRYPTODEV_BACKEND)
 | 
			
		||||
#define CRYPTODEV_BACKEND_GET_CLASS(obj) \
 | 
			
		||||
    OBJECT_GET_CLASS(CryptoDevBackendClass, \
 | 
			
		||||
                 (obj), TYPE_CRYPTODEV_BACKEND)
 | 
			
		||||
#define CRYPTODEV_BACKEND_CLASS(klass) \
 | 
			
		||||
    OBJECT_CLASS_CHECK(CryptoDevBackendClass, \
 | 
			
		||||
                (klass), TYPE_CRYPTODEV_BACKEND)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define MAX_CRYPTO_QUEUE_NUM  64
 | 
			
		||||
 | 
			
		||||
typedef struct CryptoDevBackendConf CryptoDevBackendConf;
 | 
			
		||||
typedef struct CryptoDevBackendPeers CryptoDevBackendPeers;
 | 
			
		||||
typedef struct CryptoDevBackendClient
 | 
			
		||||
                     CryptoDevBackendClient;
 | 
			
		||||
typedef struct CryptoDevBackend CryptoDevBackend;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct CryptoDevBackendClass {
 | 
			
		||||
    ObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
    void (*init)(CryptoDevBackend *backend, Error **errp);
 | 
			
		||||
    void (*cleanup)(CryptoDevBackend *backend, Error **errp);
 | 
			
		||||
} CryptoDevBackendClass;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct CryptoDevBackendClient {
 | 
			
		||||
    char *model;
 | 
			
		||||
    char *name;
 | 
			
		||||
    char *info_str;
 | 
			
		||||
    unsigned int queue_index;
 | 
			
		||||
    QTAILQ_ENTRY(CryptoDevBackendClient) next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct CryptoDevBackendPeers {
 | 
			
		||||
    CryptoDevBackendClient *ccs[MAX_CRYPTO_QUEUE_NUM];
 | 
			
		||||
    uint32_t queues;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct CryptoDevBackendConf {
 | 
			
		||||
    CryptoDevBackendPeers peers;
 | 
			
		||||
 | 
			
		||||
    /* Supported service mask */
 | 
			
		||||
    uint32_t crypto_services;
 | 
			
		||||
 | 
			
		||||
    /* Detailed algorithms mask */
 | 
			
		||||
    uint32_t cipher_algo_l;
 | 
			
		||||
    uint32_t cipher_algo_h;
 | 
			
		||||
    uint32_t hash_algo;
 | 
			
		||||
    uint32_t mac_algo_l;
 | 
			
		||||
    uint32_t mac_algo_h;
 | 
			
		||||
    uint32_t aead_algo;
 | 
			
		||||
    /* Maximum length of cipher key */
 | 
			
		||||
    uint32_t max_cipher_key_len;
 | 
			
		||||
    /* Maximum length of authenticated key */
 | 
			
		||||
    uint32_t max_auth_key_len;
 | 
			
		||||
    /* Maximum size of each crypto request's content */
 | 
			
		||||
    uint64_t max_size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct CryptoDevBackend {
 | 
			
		||||
    Object parent_obj;
 | 
			
		||||
 | 
			
		||||
    bool ready;
 | 
			
		||||
    CryptoDevBackendConf conf;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cryptodev_backend_new_client:
 | 
			
		||||
 * @model: the cryptodev backend model
 | 
			
		||||
 * @name: the cryptodev backend name, can be NULL
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a new cryptodev backend client object
 | 
			
		||||
 * with the @name in the model @model.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned object must be released with
 | 
			
		||||
 * cryptodev_backend_free_client() when no
 | 
			
		||||
 * longer required
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a new cryptodev backend client object
 | 
			
		||||
 */
 | 
			
		||||
CryptoDevBackendClient *
 | 
			
		||||
cryptodev_backend_new_client(const char *model,
 | 
			
		||||
                                    const char *name);
 | 
			
		||||
/**
 | 
			
		||||
 * cryptodev_backend_free_client:
 | 
			
		||||
 * @cc: the cryptodev backend client object
 | 
			
		||||
 *
 | 
			
		||||
 * Release the memory associated with @cc that
 | 
			
		||||
 * was previously allocated by cryptodev_backend_new_client()
 | 
			
		||||
 */
 | 
			
		||||
void cryptodev_backend_free_client(
 | 
			
		||||
                  CryptoDevBackendClient *cc);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * cryptodev_backend_cleanup:
 | 
			
		||||
 * @backend: the cryptodev backend object
 | 
			
		||||
 * @errp: pointer to a NULL-initialized error object
 | 
			
		||||
 *
 | 
			
		||||
 * Clean the resouce associated with @backend that realizaed
 | 
			
		||||
 * by the specific backend's init() callback
 | 
			
		||||
 */
 | 
			
		||||
void cryptodev_backend_cleanup(
 | 
			
		||||
           CryptoDevBackend *backend,
 | 
			
		||||
           Error **errp);
 | 
			
		||||
 | 
			
		||||
#endif /* CRYPTODEV_H */
 | 
			
		||||
		Loading…
	
		Reference in New Issue