Skip to content

Commit

Permalink
cryptodev: introduce cryptodev backend interface
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>
  • Loading branch information
gongleiarei authored and mstsirkin committed Oct 30, 2016
1 parent 2bd3c31 commit d0ee7a1
Show file tree
Hide file tree
Showing 3 changed files with 326 additions and 0 deletions.
2 changes: 2 additions & 0 deletions backends/Makefile.objs
Original file line number Diff line number Diff line change
Expand Up @@ -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
176 changes: 176 additions & 0 deletions backends/cryptodev.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
* QEMU Crypto Device Implementation
*
* Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
*
* Authors:
* Gonglei <[email protected]>
*
* 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);
148 changes: 148 additions & 0 deletions include/sysemu/cryptodev.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* QEMU Crypto Device Implementation
*
* Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
*
* Authors:
* Gonglei <[email protected]>
*
* 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 */

0 comments on commit d0ee7a1

Please sign in to comment.