LCOV - code coverage report
Current view: top level - module/bdev/crypto - vbdev_crypto_rpc.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 0 124 0.0 %
Date: 2024-12-15 19:29:58 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright (C) 2018 Intel Corporation.
       3             :  *   All rights reserved.
       4             :  *   Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
       5             :  *   All rights reserved.
       6             :  */
       7             : 
       8             : #include "vbdev_crypto.h"
       9             : 
      10             : #include "spdk/hexlify.h"
      11             : 
      12             : /* Reasonable bdev name length + cipher's name len */
      13             : #define MAX_KEY_NAME_LEN 128
      14             : 
      15             : /* Structure to hold the parameters for this RPC method. */
      16             : struct rpc_construct_crypto {
      17             :         char *base_bdev_name;
      18             :         char *name;
      19             :         char *crypto_pmd;
      20             :         struct spdk_accel_crypto_key_create_param param;
      21             : };
      22             : 
      23             : /* Free the allocated memory resource after the RPC handling. */
      24             : static void
      25           0 : free_rpc_construct_crypto(struct rpc_construct_crypto *r)
      26             : {
      27           0 :         free(r->base_bdev_name);
      28           0 :         free(r->name);
      29           0 :         free(r->crypto_pmd);
      30           0 :         free(r->param.cipher);
      31           0 :         if (r->param.hex_key) {
      32           0 :                 memset(r->param.hex_key, 0, strnlen(r->param.hex_key, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH));
      33           0 :                 free(r->param.hex_key);
      34           0 :         }
      35           0 :         if (r->param.hex_key2) {
      36           0 :                 memset(r->param.hex_key2, 0, strnlen(r->param.hex_key2, SPDK_ACCEL_CRYPTO_KEY_MAX_HEX_LENGTH));
      37           0 :                 free(r->param.hex_key2);
      38           0 :         }
      39           0 :         free(r->param.key_name);
      40           0 : }
      41             : 
      42             : /* Structure to decode the input parameters for this RPC method. */
      43             : static const struct spdk_json_object_decoder rpc_construct_crypto_decoders[] = {
      44             :         {"base_bdev_name", offsetof(struct rpc_construct_crypto, base_bdev_name), spdk_json_decode_string},
      45             :         {"name", offsetof(struct rpc_construct_crypto, name), spdk_json_decode_string},
      46             :         {"crypto_pmd", offsetof(struct rpc_construct_crypto, crypto_pmd), spdk_json_decode_string, true},
      47             :         {"key", offsetof(struct rpc_construct_crypto, param.hex_key), spdk_json_decode_string, true},
      48             :         {"cipher", offsetof(struct rpc_construct_crypto, param.cipher), spdk_json_decode_string, true},
      49             :         {"key2", offsetof(struct rpc_construct_crypto, param.hex_key2), spdk_json_decode_string, true},
      50             :         {"key_name", offsetof(struct rpc_construct_crypto, param.key_name), spdk_json_decode_string, true},
      51             : };
      52             : 
      53             : static struct vbdev_crypto_opts *
      54           0 : create_crypto_opts(struct rpc_construct_crypto *rpc, struct spdk_accel_crypto_key *key,
      55             :                    bool key_owner)
      56             : {
      57           0 :         struct vbdev_crypto_opts *opts = calloc(1, sizeof(*opts));
      58             : 
      59           0 :         if (!opts) {
      60           0 :                 return NULL;
      61             :         }
      62             : 
      63           0 :         opts->bdev_name = strdup(rpc->base_bdev_name);
      64           0 :         if (!opts->bdev_name) {
      65           0 :                 free_crypto_opts(opts);
      66           0 :                 return NULL;
      67             :         }
      68           0 :         opts->vbdev_name = strdup(rpc->name);
      69           0 :         if (!opts->vbdev_name) {
      70           0 :                 free_crypto_opts(opts);
      71           0 :                 return NULL;
      72             :         }
      73             : 
      74           0 :         opts->key = key;
      75           0 :         opts->key_owner = key_owner;
      76             : 
      77           0 :         return opts;
      78           0 : }
      79             : 
      80             : /* Decode the parameters for this RPC method and properly construct the crypto
      81             :  * device. Error status returned in the failed cases.
      82             :  */
      83             : static void
      84           0 : rpc_bdev_crypto_create(struct spdk_jsonrpc_request *request,
      85             :                        const struct spdk_json_val *params)
      86             : {
      87           0 :         struct rpc_construct_crypto req = {};
      88           0 :         struct vbdev_crypto_opts *crypto_opts = NULL;
      89           0 :         struct spdk_json_write_ctx *w;
      90           0 :         struct spdk_accel_crypto_key *key = NULL;
      91           0 :         struct spdk_accel_crypto_key *created_key = NULL;
      92           0 :         int rc = 0;
      93             : 
      94           0 :         if (spdk_json_decode_object(params, rpc_construct_crypto_decoders,
      95             :                                     SPDK_COUNTOF(rpc_construct_crypto_decoders),
      96             :                                     &req)) {
      97           0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_PARSE_ERROR,
      98             :                                                  "Failed to decode crypto disk create parameters.");
      99           0 :                 goto cleanup;
     100             :         }
     101             : 
     102           0 :         if (!req.name) {
     103           0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     104             :                                                  "crypto_bdev name is missing");
     105           0 :                 goto cleanup;
     106             :         }
     107             : 
     108           0 :         if (req.param.key_name) {
     109             :                 /* New config version */
     110           0 :                 key = spdk_accel_crypto_key_get(req.param.key_name);
     111           0 :                 if (key) {
     112           0 :                         if (req.param.hex_key || req.param.cipher || req.crypto_pmd) {
     113           0 :                                 SPDK_NOTICELOG("Key name specified, other parameters are ignored\n");
     114           0 :                         }
     115           0 :                         SPDK_NOTICELOG("Found key \"%s\"\n", req.param.key_name);
     116           0 :                 }
     117           0 :         }
     118             : 
     119             :         /* No key_name. Support legacy configuration */
     120           0 :         if (!key) {
     121           0 :                 if (req.param.key_name) {
     122           0 :                         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     123             :                                                          "Key was not found");
     124           0 :                         goto cleanup;
     125             :                 }
     126             : 
     127           0 :                 if (req.param.cipher == NULL) {
     128           0 :                         req.param.cipher = strdup(BDEV_CRYPTO_DEFAULT_CIPHER);
     129           0 :                         if (req.param.cipher == NULL) {
     130           0 :                                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     131             :                                                                  "Unable to allocate memory for req.cipher");
     132           0 :                                 goto cleanup;
     133             :                         }
     134           0 :                 }
     135           0 :                 if (req.crypto_pmd) {
     136           0 :                         SPDK_WARNLOG("\"crypto_pmd\" parameters is obsolete and ignored\n");
     137           0 :                 }
     138             : 
     139           0 :                 req.param.key_name = calloc(1, MAX_KEY_NAME_LEN);
     140           0 :                 if (!req.param.key_name) {
     141             :                         /* The new API requires key name. Create it as pmd_name + cipher */
     142           0 :                         spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     143             :                                                          "Unable to allocate memory for key_name");
     144           0 :                         goto cleanup;
     145             :                 }
     146           0 :                 snprintf(req.param.key_name, MAX_KEY_NAME_LEN, "%s_%s", req.name, req.param.cipher);
     147             : 
     148             :                 /* Try to find a key with generated name, we may be loading from a json config where crypto_bdev had no key_name parameter */
     149           0 :                 key = spdk_accel_crypto_key_get(req.param.key_name);
     150           0 :                 if (key) {
     151           0 :                         SPDK_NOTICELOG("Found key \"%s\"\n", req.param.key_name);
     152           0 :                 } else {
     153           0 :                         rc = spdk_accel_crypto_key_create(&req.param);
     154           0 :                         if (!rc) {
     155           0 :                                 key = spdk_accel_crypto_key_get(req.param.key_name);
     156           0 :                                 created_key = key;
     157           0 :                         }
     158             :                 }
     159           0 :         }
     160             : 
     161           0 :         if (!key) {
     162             :                 /* We haven't found an existing key or were not able to create a new one */
     163           0 :                 SPDK_ERRLOG("No key was found\n");
     164           0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     165             :                                                  "No key was found");
     166           0 :                 goto cleanup;
     167             :         }
     168             : 
     169           0 :         crypto_opts = create_crypto_opts(&req, key, created_key != NULL);
     170           0 :         if (!crypto_opts) {
     171           0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
     172             :                                                  "Memory allocation failed");
     173           0 :                 goto cleanup;
     174             :         }
     175             : 
     176           0 :         rc = create_crypto_disk(crypto_opts);
     177           0 :         if (rc) {
     178           0 :                 spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
     179           0 :                 free_crypto_opts(crypto_opts);
     180           0 :                 goto cleanup;
     181             :         }
     182             : 
     183           0 :         w = spdk_jsonrpc_begin_result(request);
     184           0 :         spdk_json_write_string(w, req.name);
     185           0 :         spdk_jsonrpc_end_result(request, w);
     186             : 
     187             : cleanup:
     188           0 :         if (rc && created_key) {
     189           0 :                 spdk_accel_crypto_key_destroy(created_key);
     190           0 :         }
     191           0 :         free_rpc_construct_crypto(&req);
     192           0 : }
     193           0 : SPDK_RPC_REGISTER("bdev_crypto_create", rpc_bdev_crypto_create, SPDK_RPC_RUNTIME)
     194             : 
     195             : struct rpc_delete_crypto {
     196             :         char *name;
     197             : };
     198             : 
     199             : static void
     200           0 : free_rpc_delete_crypto(struct rpc_delete_crypto *req)
     201             : {
     202           0 :         free(req->name);
     203           0 : }
     204             : 
     205             : static const struct spdk_json_object_decoder rpc_delete_crypto_decoders[] = {
     206             :         {"name", offsetof(struct rpc_delete_crypto, name), spdk_json_decode_string},
     207             : };
     208             : 
     209             : static void
     210           0 : rpc_bdev_crypto_delete_cb(void *cb_arg, int bdeverrno)
     211             : {
     212           0 :         struct spdk_jsonrpc_request *request = cb_arg;
     213             : 
     214           0 :         if (bdeverrno == 0) {
     215           0 :                 spdk_jsonrpc_send_bool_response(request, true);
     216           0 :         } else {
     217           0 :                 spdk_jsonrpc_send_error_response(request, bdeverrno, spdk_strerror(-bdeverrno));
     218             :         }
     219           0 : }
     220             : 
     221             : static void
     222           0 : rpc_bdev_crypto_delete(struct spdk_jsonrpc_request *request,
     223             :                        const struct spdk_json_val *params)
     224             : {
     225           0 :         struct rpc_delete_crypto req = {NULL};
     226             : 
     227           0 :         if (spdk_json_decode_object(params, rpc_delete_crypto_decoders,
     228             :                                     SPDK_COUNTOF(rpc_delete_crypto_decoders),
     229             :                                     &req)) {
     230           0 :                 spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
     231             :                                                  "Invalid parameters");
     232           0 :                 goto cleanup;
     233             :         }
     234             : 
     235           0 :         delete_crypto_disk(req.name, rpc_bdev_crypto_delete_cb, request);
     236             : 
     237           0 :         free_rpc_delete_crypto(&req);
     238             : 
     239           0 :         return;
     240             : 
     241             : cleanup:
     242           0 :         free_rpc_delete_crypto(&req);
     243           0 : }
     244           0 : SPDK_RPC_REGISTER("bdev_crypto_delete", rpc_bdev_crypto_delete, SPDK_RPC_RUNTIME)

Generated by: LCOV version 1.15