util: made hexlify and unhexlify functions public

hexlify and unhexlify utils from vbdev_crypto.h have been moved so that
they could be included and reused outside of vbdev_crypto module.

Signed-off-by: Blachut, Bartosz <bartosz.blachut@intel.com>
Change-Id: Ia074250176907f4803b84024239ecd4e9d8a5fc1
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14191
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: Jacek Kalwas <jacek.kalwas@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
This commit is contained in:
Blachut, Bartosz 2022-08-24 18:37:51 +02:00 committed by Tomasz Zawadzki
parent 1a24dc8fef
commit 503835ee63
8 changed files with 136 additions and 103 deletions

View File

@ -75,6 +75,10 @@ tell the driver to not read the CHANGED_NS_LIST log page in response to a NS_ATT
AEN. When called the application is required to read this log page instead to clear the AEN. When called the application is required to read this log page instead to clear the
AEN. AEN.
### util
Added new functions: `spdk_hexlify` and `spdk_unhexlify`.
## v22.05 ## v22.05
### sock ### sock

28
include/spdk/hexlify.h Normal file
View File

@ -0,0 +1,28 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) Intel Corporation.
* All rights reserved.
*/
#ifndef SPDK_HEXLIFY_H
#define SPDK_HEXLIFY_H
#include "spdk/stdinc.h"
/**
* Convert a binary array to hexlified string terminated by zero.
*
* \param bin A binary array pointer.
* \param len Length of the binary array.
* \return Pointer to hexlified version of @bin or NULL on failure.
*/
char *spdk_hexlify(const char *bin, size_t len);
/**
* Convert hexlified string to binary array of size strlen(hex) / 2.
*
* \param hex A hexlified string terminated by zero.
* \return Binary array pointer or NULL on failure.
*/
char *spdk_unhexlify(const char *hex);
#endif /* SPDK_HEXLIFY_H */

View File

@ -10,7 +10,7 @@ SO_VER := 5
SO_MINOR := 1 SO_MINOR := 1
C_SRCS = base64.c bit_array.c cpuset.c crc16.c crc32.c crc32c.c crc32_ieee.c \ C_SRCS = base64.c bit_array.c cpuset.c crc16.c crc32.c crc32c.c crc32_ieee.c \
dif.c fd.c file.c iov.c math.c pipe.c strerror_tls.c string.c uuid.c \ dif.c fd.c file.c hexlify.c iov.c math.c pipe.c strerror_tls.c string.c uuid.c \
fd_group.c zipf.c fd_group.c zipf.c
LIBNAME = util LIBNAME = util
LOCAL_SYS_LIBS = -luuid LOCAL_SYS_LIBS = -luuid

85
lib/util/hexlify.c Normal file
View File

@ -0,0 +1,85 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) Intel Corporation.
* All rights reserved.
*/
#include "spdk/hexlify.h"
#include "spdk/log.h"
static inline int
__c2v(char c)
{
if ((c >= '0') && (c <= '9')) {
return c - '0';
}
if ((c >= 'a') && (c <= 'f')) {
return c - 'a' + 10;
}
if ((c >= 'A') && (c <= 'F')) {
return c - 'A' + 10;
}
return -1;
}
static inline signed char
__v2c(int c)
{
const char hexchar[] = "0123456789abcdef";
if (c < 0 || c > 15) {
return -1;
}
return hexchar[c];
}
char *
spdk_hexlify(const char *bin, size_t len)
{
char *hex, *phex;
hex = malloc((len * 2) + 1);
if (hex == NULL) {
return NULL;
}
phex = hex;
for (size_t i = 0; i < len; i++) {
signed char c0 = __v2c((bin[i] >> 4) & 0x0f);
signed char c1 = __v2c((bin[i]) & 0x0f);
if (c0 < 0 || c1 < 0) {
assert(false);
free(hex);
return NULL;
}
*phex++ = c0;
*phex++ = c1;
}
*phex = '\0';
return hex;
}
char *
spdk_unhexlify(const char *hex)
{
char *res, *pres;
size_t len = strlen(hex);
if (len % 2 != 0) {
SPDK_ERRLOG("Invalid hex string len %d. It must be mod of 2.\n", (int)len);
return NULL;
}
res = malloc(len / 2);
if (res == NULL) {
return NULL;
}
pres = res;
for (size_t i = 0; i < len; i += 2) {
int v0 = __c2v(hex[i]);
int v1 = __c2v(hex[i + 1]);
if (v0 < 0 || v1 < 0) {
SPDK_ERRLOG("Invalid hex string \"%s\"\n", hex);
free(res);
return NULL;
}
*pres++ = (v0 << 4) + v1;
}
return res;
}

View File

@ -92,6 +92,10 @@
# public functions in file.h # public functions in file.h
spdk_posix_file_load; spdk_posix_file_load;
# public functions in hexlify.h
spdk_hexlify;
spdk_unhexlify;
# public functions in pipe.h # public functions in pipe.h
spdk_pipe_create; spdk_pipe_create;
spdk_pipe_destroy; spdk_pipe_destroy;

View File

@ -13,6 +13,7 @@
#include "spdk/thread.h" #include "spdk/thread.h"
#include "spdk/bdev_module.h" #include "spdk/bdev_module.h"
#include "spdk/log.h" #include "spdk/log.h"
#include "spdk/hexlify.h"
#include <rte_config.h> #include <rte_config.h>
#include <rte_bus_vdev.h> #include <rte_bus_vdev.h>
@ -1443,14 +1444,14 @@ vbdev_crypto_dump_info_json(void *ctx, struct spdk_json_write_ctx *w)
char *hexkey = NULL, *hexkey2 = NULL; char *hexkey = NULL, *hexkey2 = NULL;
int rc = 0; int rc = 0;
hexkey = hexlify(crypto_bdev->opts->key, hexkey = spdk_hexlify(crypto_bdev->opts->key,
crypto_bdev->opts->key_size); crypto_bdev->opts->key_size);
if (!hexkey) { if (!hexkey) {
return -ENOMEM; return -ENOMEM;
} }
if (crypto_bdev->opts->key2) { if (crypto_bdev->opts->key2) {
hexkey2 = hexlify(crypto_bdev->opts->key2, hexkey2 = spdk_hexlify(crypto_bdev->opts->key2,
crypto_bdev->opts->key2_size); crypto_bdev->opts->key2_size);
if (!hexkey2) { if (!hexkey2) {
rc = -ENOMEM; rc = -ENOMEM;
@ -1489,14 +1490,14 @@ vbdev_crypto_config_json(struct spdk_json_write_ctx *w)
TAILQ_FOREACH(crypto_bdev, &g_vbdev_crypto, link) { TAILQ_FOREACH(crypto_bdev, &g_vbdev_crypto, link) {
char *hexkey = NULL, *hexkey2 = NULL; char *hexkey = NULL, *hexkey2 = NULL;
hexkey = hexlify(crypto_bdev->opts->key, hexkey = spdk_hexlify(crypto_bdev->opts->key,
crypto_bdev->opts->key_size); crypto_bdev->opts->key_size);
if (!hexkey) { if (!hexkey) {
return -ENOMEM; return -ENOMEM;
} }
if (crypto_bdev->opts->key2) { if (crypto_bdev->opts->key2) {
hexkey2 = hexlify(crypto_bdev->opts->key2, hexkey2 = spdk_hexlify(crypto_bdev->opts->key2,
crypto_bdev->opts->key2_size); crypto_bdev->opts->key2_size);
if (!hexkey2) { if (!hexkey2) {
memset(hexkey, 0, strlen(hexkey)); memset(hexkey, 0, strlen(hexkey));

View File

@ -78,95 +78,4 @@ void delete_crypto_disk(const char *bdev_name, spdk_delete_crypto_complete cb_fn
*/ */
void free_crypto_opts(struct vbdev_crypto_opts *opts); void free_crypto_opts(struct vbdev_crypto_opts *opts);
static inline int
__c2v(char c)
{
if ((c >= '0') && (c <= '9')) {
return c - '0';
}
if ((c >= 'a') && (c <= 'f')) {
return c - 'a' + 10;
}
if ((c >= 'A') && (c <= 'F')) {
return c - 'A' + 10;
}
return -1;
}
static inline signed char
__v2c(int c)
{
const char hexchar[] = "0123456789abcdef";
if (c < 0 || c > 15) {
return -1;
}
return hexchar[c];
}
/**
* Convert a binary array to hexlified string terminated by zero.
*
* \param bin A binary array pointer.
* \param len Length of the binary array.
* \return Pointer to hexlified version of @bin or NULL on failure.
*/
static inline char *
hexlify(const char *bin, size_t len)
{
char *hex, *phex;
hex = malloc((len * 2) + 1);
if (hex == NULL) {
return NULL;
}
phex = hex;
for (size_t i = 0; i < len; i++) {
signed char c0 = __v2c((bin[i] >> 4) & 0x0f);
signed char c1 = __v2c((bin[i]) & 0x0f);
if (c0 < 0 || c1 < 0) {
assert(false);
free(hex);
return NULL;
}
*phex++ = c0;
*phex++ = c1;
}
*phex = '\0';
return hex;
}
/**
* Convert hexlified string to binary array of size strlen(hex) / 2.
*
* \param hex A hexlified string terminated by zero.
* \return Binary array pointer or NULL on failure.
*/
static inline char *
unhexlify(const char *hex)
{
char *res, *pres;
size_t len = strlen(hex);
if (len % 2 != 0) {
SPDK_ERRLOG("Invalid hex string len %d. It must be mod of 2.\n", (int)len);
return NULL;
}
res = malloc(len / 2);
if (res == NULL) {
return NULL;
}
pres = res;
for (size_t i = 0; i < len; i += 2) {
int v0 = __c2v(hex[i]);
int v1 = __c2v(hex[i + 1]);
if (v0 < 0 || v1 < 0) {
SPDK_ERRLOG("Invalid hex string \"%s\"\n", hex);
free(res);
return NULL;
}
*pres++ = (v0 << 4) + v1;
}
return res;
}
#endif /* SPDK_VBDEV_CRYPTO_H */ #endif /* SPDK_VBDEV_CRYPTO_H */

View File

@ -7,6 +7,8 @@
#include "vbdev_crypto.h" #include "vbdev_crypto.h"
#include "spdk/hexlify.h"
/* Structure to hold the parameters for this RPC method. */ /* Structure to hold the parameters for this RPC method. */
struct rpc_construct_crypto { struct rpc_construct_crypto {
char *base_bdev_name; char *base_bdev_name;
@ -110,7 +112,7 @@ create_crypto_opts(struct rpc_construct_crypto *rpc,
if (strcmp(opts->drv_name, MLX5) == 0) { if (strcmp(opts->drv_name, MLX5) == 0) {
/* Only AES-XTS supported. */ /* Only AES-XTS supported. */
/* We cannot use strlen() after unhexlify() because of possible \0 chars /* We cannot use strlen() after spdk_unhexlify() because of possible \0 chars
* used in the key. Hexlified version of key is twice as longer. */ * used in the key. Hexlified version of key is twice as longer. */
key_size = strnlen(rpc->key, (AES_XTS_512_BLOCK_KEY_LENGTH * 2) + 1); key_size = strnlen(rpc->key, (AES_XTS_512_BLOCK_KEY_LENGTH * 2) + 1);
if (key_size != AES_XTS_256_BLOCK_KEY_LENGTH * 2 && if (key_size != AES_XTS_256_BLOCK_KEY_LENGTH * 2 &&
@ -144,7 +146,7 @@ create_crypto_opts(struct rpc_construct_crypto *rpc,
} }
} }
} }
opts->key = unhexlify(rpc->key); opts->key = spdk_unhexlify(rpc->key);
if (!opts->key) { if (!opts->key) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Failed to unhexlify key."); "Failed to unhexlify key.");
@ -163,7 +165,7 @@ create_crypto_opts(struct rpc_construct_crypto *rpc,
key2_size, AES_XTS_TWEAK_KEY_LENGTH * 2); key2_size, AES_XTS_TWEAK_KEY_LENGTH * 2);
goto error_invalid_key2; goto error_invalid_key2;
} }
opts->key2 = unhexlify(rpc->key2); opts->key2 = spdk_unhexlify(rpc->key2);
if (!opts->key2) { if (!opts->key2) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS, spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Failed to unhexlify key2."); "Failed to unhexlify key2.");