2022-06-03 19:15:11 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
2022-11-01 20:26:26 +00:00
|
|
|
* Copyright (C) 2018 Intel Corporation.
|
2018-03-07 23:44:06 +00:00
|
|
|
* All rights reserved.
|
2022-01-20 08:25:05 +00:00
|
|
|
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
|
|
|
|
* All rights reserved.
|
2018-03-07 23:44:06 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "vbdev_crypto.h"
|
|
|
|
|
2022-08-24 16:37:51 +00:00
|
|
|
#include "spdk/hexlify.h"
|
|
|
|
|
2022-08-31 15:26:12 +00:00
|
|
|
/* Reasonable bdev name length + cipher's name len */
|
|
|
|
#define MAX_KEY_NAME_LEN 128
|
|
|
|
|
2018-03-07 23:44:06 +00:00
|
|
|
/* Structure to hold the parameters for this RPC method. */
|
|
|
|
struct rpc_construct_crypto {
|
|
|
|
char *base_bdev_name;
|
2018-09-17 22:29:29 +00:00
|
|
|
char *name;
|
2018-03-07 23:44:06 +00:00
|
|
|
char *crypto_pmd;
|
2022-08-31 15:26:12 +00:00
|
|
|
struct spdk_accel_crypto_key_create_param param;
|
2018-03-07 23:44:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Free the allocated memory resource after the RPC handling. */
|
|
|
|
static void
|
|
|
|
free_rpc_construct_crypto(struct rpc_construct_crypto *r)
|
|
|
|
{
|
|
|
|
free(r->base_bdev_name);
|
2018-09-17 22:29:29 +00:00
|
|
|
free(r->name);
|
2018-03-07 23:44:06 +00:00
|
|
|
free(r->crypto_pmd);
|
2022-08-31 15:26:12 +00:00
|
|
|
free(r->param.cipher);
|
|
|
|
if (r->param.hex_key) {
|
|
|
|
memset(r->param.hex_key, 0, strnlen(r->param.hex_key, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH));
|
|
|
|
free(r->param.hex_key);
|
|
|
|
}
|
|
|
|
if (r->param.hex_key2) {
|
|
|
|
memset(r->param.hex_key2, 0, strnlen(r->param.hex_key2, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH));
|
|
|
|
free(r->param.hex_key2);
|
|
|
|
}
|
|
|
|
free(r->param.key_name);
|
2018-03-07 23:44:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Structure to decode the input parameters for this RPC method. */
|
|
|
|
static const struct spdk_json_object_decoder rpc_construct_crypto_decoders[] = {
|
|
|
|
{"base_bdev_name", offsetof(struct rpc_construct_crypto, base_bdev_name), spdk_json_decode_string},
|
2018-09-17 22:29:29 +00:00
|
|
|
{"name", offsetof(struct rpc_construct_crypto, name), spdk_json_decode_string},
|
2022-08-31 15:26:12 +00:00
|
|
|
{"crypto_pmd", offsetof(struct rpc_construct_crypto, crypto_pmd), spdk_json_decode_string, true},
|
|
|
|
{"key", offsetof(struct rpc_construct_crypto, param.hex_key), spdk_json_decode_string, true},
|
|
|
|
{"cipher", offsetof(struct rpc_construct_crypto, param.cipher), spdk_json_decode_string, true},
|
|
|
|
{"key2", offsetof(struct rpc_construct_crypto, param.hex_key2), spdk_json_decode_string, true},
|
|
|
|
{"key_name", offsetof(struct rpc_construct_crypto, param.key_name), spdk_json_decode_string, true},
|
2018-03-07 23:44:06 +00:00
|
|
|
};
|
|
|
|
|
2022-01-20 08:25:05 +00:00
|
|
|
static struct vbdev_crypto_opts *
|
2022-08-31 15:26:12 +00:00
|
|
|
create_crypto_opts(struct rpc_construct_crypto *rpc, struct spdk_accel_crypto_key *key,
|
|
|
|
bool key_owner)
|
2022-01-20 08:25:05 +00:00
|
|
|
{
|
2022-08-31 15:26:12 +00:00
|
|
|
struct vbdev_crypto_opts *opts = calloc(1, sizeof(*opts));
|
2022-01-20 08:25:05 +00:00
|
|
|
|
|
|
|
if (!opts) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
opts->bdev_name = strdup(rpc->base_bdev_name);
|
|
|
|
if (!opts->bdev_name) {
|
2022-08-31 15:26:12 +00:00
|
|
|
free_crypto_opts(opts);
|
|
|
|
return NULL;
|
2022-01-20 08:25:05 +00:00
|
|
|
}
|
|
|
|
opts->vbdev_name = strdup(rpc->name);
|
|
|
|
if (!opts->vbdev_name) {
|
2022-08-31 15:26:12 +00:00
|
|
|
free_crypto_opts(opts);
|
|
|
|
return NULL;
|
2022-01-20 08:25:05 +00:00
|
|
|
}
|
|
|
|
|
2022-08-31 15:26:12 +00:00
|
|
|
opts->key = key;
|
|
|
|
opts->key_owner = key_owner;
|
2022-01-20 08:25:05 +00:00
|
|
|
|
|
|
|
return opts;
|
|
|
|
}
|
|
|
|
|
2018-03-07 23:44:06 +00:00
|
|
|
/* Decode the parameters for this RPC method and properly construct the crypto
|
|
|
|
* device. Error status returned in the failed cases.
|
|
|
|
*/
|
|
|
|
static void
|
2020-05-10 07:09:08 +00:00
|
|
|
rpc_bdev_crypto_create(struct spdk_jsonrpc_request *request,
|
|
|
|
const struct spdk_json_val *params)
|
2018-03-07 23:44:06 +00:00
|
|
|
{
|
2022-08-31 15:26:12 +00:00
|
|
|
struct rpc_construct_crypto req = {};
|
|
|
|
struct vbdev_crypto_opts *crypto_opts = NULL;
|
2018-03-07 23:44:06 +00:00
|
|
|
struct spdk_json_write_ctx *w;
|
2022-08-31 15:26:12 +00:00
|
|
|
struct spdk_accel_crypto_key *key = NULL;
|
|
|
|
struct spdk_accel_crypto_key *created_key = NULL;
|
|
|
|
int rc = 0;
|
2018-03-07 23:44:06 +00:00
|
|
|
|
|
|
|
if (spdk_json_decode_object(params, rpc_construct_crypto_decoders,
|
|
|
|
SPDK_COUNTOF(rpc_construct_crypto_decoders),
|
|
|
|
&req)) {
|
2022-08-31 15:26:12 +00:00
|
|
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
|
2022-01-20 08:25:05 +00:00
|
|
|
"Failed to decode crypto disk create parameters.");
|
2019-07-09 11:45:22 +00:00
|
|
|
goto cleanup;
|
2018-03-07 23:44:06 +00:00
|
|
|
}
|
|
|
|
|
2022-08-31 15:26:12 +00:00
|
|
|
if (!req.name) {
|
|
|
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
|
|
"crypto_bdev name is missing");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req.param.key_name) {
|
|
|
|
/* New config version */
|
|
|
|
key = spdk_accel_crypto_key_get(req.param.key_name);
|
|
|
|
if (key) {
|
|
|
|
if (req.param.hex_key || req.param.cipher || req.crypto_pmd) {
|
|
|
|
SPDK_NOTICELOG("Key name specified, other parameters are ignored\n");
|
|
|
|
}
|
|
|
|
SPDK_NOTICELOG("Found key \"%s\"\n", req.param.key_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No key_name. Support legacy configuration */
|
|
|
|
if (!key) {
|
|
|
|
if (req.param.key_name) {
|
|
|
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
|
|
"Key was not found");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req.param.cipher == NULL) {
|
|
|
|
req.param.cipher = strdup(BDEV_CRYPTO_DEFAULT_CIPHER);
|
|
|
|
if (req.param.cipher == NULL) {
|
|
|
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
|
|
|
"Unable to allocate memory for req.cipher");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (req.crypto_pmd) {
|
|
|
|
SPDK_WARNLOG("\"crypto_pmd\" parameters is obsolete and ignored\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
req.param.key_name = calloc(1, MAX_KEY_NAME_LEN);
|
|
|
|
if (!req.param.key_name) {
|
|
|
|
/* The new API requires key name. Create it as pmd_name + cipher */
|
2020-01-31 22:19:09 +00:00
|
|
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
2022-08-31 15:26:12 +00:00
|
|
|
"Unable to allocate memory for key_name");
|
2020-01-31 22:19:09 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2022-08-31 15:26:12 +00:00
|
|
|
snprintf(req.param.key_name, MAX_KEY_NAME_LEN, "%s_%s", req.name, req.param.cipher);
|
|
|
|
|
|
|
|
/* Try to find a key with generated name, we may be loading from a json config where crypto_bdev had no key_name parameter */
|
|
|
|
key = spdk_accel_crypto_key_get(req.param.key_name);
|
|
|
|
if (key) {
|
|
|
|
SPDK_NOTICELOG("Found key \"%s\"\n", req.param.key_name);
|
|
|
|
} else {
|
|
|
|
rc = spdk_accel_crypto_key_create(&req.param);
|
|
|
|
if (!rc) {
|
|
|
|
key = spdk_accel_crypto_key_get(req.param.key_name);
|
|
|
|
created_key = key;
|
|
|
|
}
|
|
|
|
}
|
2020-01-31 22:19:09 +00:00
|
|
|
}
|
|
|
|
|
2022-08-31 15:26:12 +00:00
|
|
|
if (!key) {
|
|
|
|
/* We haven't found an existing key or were not able to create a new one */
|
|
|
|
SPDK_ERRLOG("No key was found\n");
|
|
|
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
|
|
|
"No key was found");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
crypto_opts = create_crypto_opts(&req, key, created_key != NULL);
|
|
|
|
if (!crypto_opts) {
|
|
|
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
|
|
|
"Memory allocation failed");
|
2020-01-31 22:19:09 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2022-01-20 08:25:05 +00:00
|
|
|
rc = create_crypto_disk(crypto_opts);
|
2019-07-09 11:45:22 +00:00
|
|
|
if (rc) {
|
|
|
|
spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
|
2022-01-20 08:25:05 +00:00
|
|
|
free_crypto_opts(crypto_opts);
|
2019-07-09 11:45:22 +00:00
|
|
|
goto cleanup;
|
2018-03-07 23:44:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
w = spdk_jsonrpc_begin_result(request);
|
2018-09-17 22:29:29 +00:00
|
|
|
spdk_json_write_string(w, req.name);
|
2018-03-07 23:44:06 +00:00
|
|
|
spdk_jsonrpc_end_result(request, w);
|
2022-08-31 15:26:12 +00:00
|
|
|
|
2019-07-09 11:45:22 +00:00
|
|
|
cleanup:
|
2022-08-31 15:26:12 +00:00
|
|
|
if (rc && created_key) {
|
|
|
|
spdk_accel_crypto_key_destroy(created_key);
|
|
|
|
}
|
2018-03-07 23:44:06 +00:00
|
|
|
free_rpc_construct_crypto(&req);
|
|
|
|
}
|
2020-05-10 07:09:08 +00:00
|
|
|
SPDK_RPC_REGISTER("bdev_crypto_create", rpc_bdev_crypto_create, SPDK_RPC_RUNTIME)
|
2018-03-07 23:44:06 +00:00
|
|
|
|
|
|
|
struct rpc_delete_crypto {
|
|
|
|
char *name;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
free_rpc_delete_crypto(struct rpc_delete_crypto *req)
|
|
|
|
{
|
|
|
|
free(req->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct spdk_json_object_decoder rpc_delete_crypto_decoders[] = {
|
|
|
|
{"name", offsetof(struct rpc_delete_crypto, name), spdk_json_decode_string},
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
2020-05-10 07:09:08 +00:00
|
|
|
rpc_bdev_crypto_delete_cb(void *cb_arg, int bdeverrno)
|
2018-03-07 23:44:06 +00:00
|
|
|
{
|
|
|
|
struct spdk_jsonrpc_request *request = cb_arg;
|
|
|
|
|
2022-03-29 12:02:58 +00:00
|
|
|
if (bdeverrno == 0) {
|
|
|
|
spdk_jsonrpc_send_bool_response(request, true);
|
|
|
|
} else {
|
|
|
|
spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
|
|
|
|
}
|
2018-03-07 23:44:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-05-10 07:09:08 +00:00
|
|
|
rpc_bdev_crypto_delete(struct spdk_jsonrpc_request *request,
|
|
|
|
const struct spdk_json_val *params)
|
2018-03-07 23:44:06 +00:00
|
|
|
{
|
|
|
|
struct rpc_delete_crypto req = {NULL};
|
|
|
|
|
|
|
|
if (spdk_json_decode_object(params, rpc_delete_crypto_decoders,
|
|
|
|
SPDK_COUNTOF(rpc_delete_crypto_decoders),
|
|
|
|
&req)) {
|
2020-01-31 20:45:23 +00:00
|
|
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
|
|
|
|
"Invalid parameters");
|
2019-07-09 11:45:22 +00:00
|
|
|
goto cleanup;
|
2018-03-07 23:44:06 +00:00
|
|
|
}
|
|
|
|
|
2022-03-29 05:55:53 +00:00
|
|
|
delete_crypto_disk(req.name, rpc_bdev_crypto_delete_cb, request);
|
2018-03-07 23:44:06 +00:00
|
|
|
|
|
|
|
free_rpc_delete_crypto(&req);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
2019-07-09 11:45:22 +00:00
|
|
|
cleanup:
|
2018-03-07 23:44:06 +00:00
|
|
|
free_rpc_delete_crypto(&req);
|
|
|
|
}
|
2020-05-10 07:09:08 +00:00
|
|
|
SPDK_RPC_REGISTER("bdev_crypto_delete", rpc_bdev_crypto_delete, SPDK_RPC_RUNTIME)
|