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.
### util
Added new functions: `spdk_hexlify` and `spdk_unhexlify`.
## v22.05
### 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
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
LIBNAME = util
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
spdk_posix_file_load;
# public functions in hexlify.h
spdk_hexlify;
spdk_unhexlify;
# public functions in pipe.h
spdk_pipe_create;
spdk_pipe_destroy;

View File

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

View File

@ -7,6 +7,8 @@
#include "vbdev_crypto.h"
#include "spdk/hexlify.h"
/* Structure to hold the parameters for this RPC method. */
struct rpc_construct_crypto {
char *base_bdev_name;
@ -110,7 +112,7 @@ create_crypto_opts(struct rpc_construct_crypto *rpc,
if (strcmp(opts->drv_name, MLX5) == 0) {
/* 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. */
key_size = strnlen(rpc->key, (AES_XTS_512_BLOCK_KEY_LENGTH * 2) + 1);
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) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Failed to unhexlify key.");
@ -163,7 +165,7 @@ create_crypto_opts(struct rpc_construct_crypto *rpc,
key2_size, AES_XTS_TWEAK_KEY_LENGTH * 2);
goto error_invalid_key2;
}
opts->key2 = unhexlify(rpc->key2);
opts->key2 = spdk_unhexlify(rpc->key2);
if (!opts->key2) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"Failed to unhexlify key2.");