Skip to content

Commit

Permalink
kernel: lib: Add convert functions for hex strings and binary arrays
Browse files Browse the repository at this point in the history
Move duplicate hex2bin and add bin2hex function so that application can
use the functions and avoid code duplication.

Signed-off-by: Joakim Andersson <[email protected]>
  • Loading branch information
joerchan authored and carlescufi committed Jul 16, 2019
1 parent 743f3db commit 7a93e94
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 140 deletions.
51 changes: 51 additions & 0 deletions include/sys/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <zephyr/types.h>
#include <stdbool.h>
#include <stddef.h>

/* Helper to pass a int as a pointer or vice-versa. */
#define POINTER_TO_UINT(x) ((uintptr_t) (x))
Expand Down Expand Up @@ -122,6 +123,56 @@ static inline s64_t arithmetic_shift_right(s64_t value, u8_t shift)
return (value >> shift) | (sign_ext << (64 - shift));
}

/**
* @brief Convert a single character into a hexadecimal nibble.
*
* @param[in] c The character to convert
* @param x The address of storage for the converted number.
*
* @return Zero on success or (negative) error code otherwise.
*/
int char2hex(char c, u8_t *x);

/**
* @brief Convert a single hexadecimal nibble into a character.
*
* @param[in] c The number to convert
* @param x The address of storage for the converted character.
*
* @return Zero on success or (negative) error code otherwise.
*/
int hex2char(u8_t x, char *c);

/**
* @brief Convert a binary array into string representation.
*
* @param[in] buf The binary array to convert
* @param[in] buflen The length of the binary array to convert
* @param[out] hex Address of where to store the string representation.
* @param[in] hexlen Size of the storage area for string representation.
*
* @return The length of the converted string, or 0 if an error occurred.
*/
size_t bin2hex(const u8_t *buf, size_t buflen, char *hex, size_t hexlen);

/*
* Convert hex string to byte string
* Return number of bytes written to buf, or 0 on error
* @return The length of the converted array, or 0 if an error occurred.
*/

/**
* @brief Convert a hexadecimal string into a binary array.
*
* @param[in] hex The hexadecimal string to convert
* @param[in] hexlen The length of the hexadecimal string to convert.
* @param[out] buf Address of where to store the binary data
* @param[in] buflen Size of the storage area for binary data
*
* @return The length of the binary array , or 0 if an error occurred.
*/
size_t hex2bin(const char *hex, size_t hexlen, u8_t *buf, size_t buflen);

#endif /* !_ASMLANGUAGE */

/* KB, MB, GB */
Expand Down
1 change: 1 addition & 0 deletions lib/os/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ zephyr_sources(
crc8_sw.c
crc7_sw.c
fdtable.c
hex.c
mempool.c
rb.c
thread_entry.c
Expand Down
91 changes: 91 additions & 0 deletions lib/os/hex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stddef.h>
#include <zephyr/types.h>
#include <errno.h>
#include <sys/util.h>

int char2hex(char c, u8_t *x)
{
if (c >= '0' && c <= '9') {
*x = c - '0';
} else if (c >= 'a' && c <= 'f') {
*x = c - 'a' + 10;
} else if (c >= 'A' && c <= 'F') {
*x = c - 'A' + 10;
} else {
return -EINVAL;
}

return 0;
}

int hex2char(u8_t x, char *c)
{
if (x <= 9) {
*c = x + '0';
} else if (x >= 10 && x <= 15) {
*c = x - 10 + 'a';
} else {
return -EINVAL;
}

return 0;
}

size_t bin2hex(const u8_t *buf, size_t buflen, char *hex, size_t hexlen)
{
if ((hexlen + 1) < buflen * 2) {
return 0;
}

for (size_t i = 0; i < buflen; i++) {
if (hex2char(buf[i] >> 4, &hex[2 * i]) < 0) {
return 0;
}
if (hex2char(buf[i] & 0xf, &hex[2 * i + 1]) < 0) {
return 0;
}
}

hex[2 * buflen] = '\0';
return 2 * buflen;
}

size_t hex2bin(const char *hex, size_t hexlen, u8_t *buf, size_t buflen)
{
u8_t dec;

if (buflen < hexlen / 2 + hexlen % 2) {
return 0;
}

/* if hexlen is uneven, insert leading zero nibble */
if (hexlen % 2) {
if (char2hex(hex[0], &dec) < 0) {
return 0;
}
buf[0] = dec;
hex++;
buf++;
}

/* regular hex conversion */
for (size_t i = 0; i < hexlen / 2; i++) {
if (char2hex(hex[2 * i], &dec) < 0) {
return 0;
}
buf[i] = dec << 4;

if (char2hex(hex[2 * i + 1], &dec) < 0) {
return 0;
}
buf[i] += dec;
}

return hexlen / 2 + hexlen % 2;
}
50 changes: 12 additions & 38 deletions subsys/bluetooth/mesh/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <ctype.h>
#include <zephyr.h>
#include <sys/printk.h>
#include <sys/util.h>

#include <shell/shell.h>
#include <settings/settings.h>
Expand Down Expand Up @@ -205,37 +206,6 @@ static const struct bt_mesh_comp comp = {
.elem_count = ARRAY_SIZE(elements),
};

static u8_t hex2val(char c)
{
if (c >= '0' && c <= '9') {
return c - '0';
} else if (c >= 'a' && c <= 'f') {
return c - 'a' + 10;
} else if (c >= 'A' && c <= 'F') {
return c - 'A' + 10;
} else {
return 0;
}
}

static size_t hex2bin(const char *hex, u8_t *bin, size_t bin_len)
{
size_t len = 0;

while (*hex && len < bin_len) {
bin[len] = hex2val(*hex++) << 4;

if (!*hex) {
len++;
break;
}

bin[len++] |= hex2val(*hex++);
}

return len;
}

static void prov_complete(u16_t net_idx, u16_t addr)
{
shell_print(ctx_shell, "Local node provisioned, net_idx 0x%04x address "
Expand Down Expand Up @@ -395,7 +365,8 @@ static int cmd_static_oob(const struct shell *shell, size_t argc, char *argv[])
prov.static_val = NULL;
prov.static_val_len = 0U;
} else {
prov.static_val_len = hex2bin(argv[1], static_val, 16);
prov.static_val_len = hex2bin(argv[1], strlen(argv[1]),
static_val, 16);
if (prov.static_val_len) {
prov.static_val = static_val;
} else {
Expand All @@ -422,7 +393,7 @@ static int cmd_uuid(const struct shell *shell, size_t argc, char *argv[])
return -EINVAL;
}

len = hex2bin(argv[1], uuid, sizeof(uuid));
len = hex2bin(argv[1], strlen(argv[1]), uuid, sizeof(uuid));
if (len < 1) {
return -EINVAL;
}
Expand Down Expand Up @@ -727,7 +698,8 @@ static int cmd_net_send(const struct shell *shell, size_t argc, char *argv[])
return 0;
}

len = hex2bin(argv[1], msg.data, net_buf_simple_tailroom(&msg) - 4);
len = hex2bin(argv[1], strlen(argv[1]),
msg.data, net_buf_simple_tailroom(&msg) - 4);
net_buf_simple_add(&msg, len);

err = bt_mesh_trans_send(&tx, &msg, NULL, NULL);
Expand Down Expand Up @@ -940,7 +912,8 @@ static int cmd_net_key_add(const struct shell *shell, size_t argc, char *argv[])
if (argc > 2) {
size_t len;

len = hex2bin(argv[3], key_val, sizeof(key_val));
len = hex2bin(argv[3], strlen(argv[3]),
key_val, sizeof(key_val));
(void)memset(key_val, 0, sizeof(key_val) - len);
} else {
memcpy(key_val, default_key, sizeof(key_val));
Expand Down Expand Up @@ -981,7 +954,8 @@ static int cmd_app_key_add(const struct shell *shell, size_t argc, char *argv[])
if (argc > 3) {
size_t len;

len = hex2bin(argv[3], key_val, sizeof(key_val));
len = hex2bin(argv[3], strlen(argv[3]),
key_val, sizeof(key_val));
(void)memset(key_val, 0, sizeof(key_val) - len);
} else {
memcpy(key_val, default_key, sizeof(key_val));
Expand Down Expand Up @@ -1141,7 +1115,7 @@ static int cmd_mod_sub_add_va(const struct shell *shell, size_t argc,

elem_addr = strtoul(argv[1], NULL, 0);

len = hex2bin(argv[2], label, sizeof(label));
len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
(void)memset(label + len, 0, sizeof(label) - len);

mod_id = strtoul(argv[3], NULL, 0);
Expand Down Expand Up @@ -1189,7 +1163,7 @@ static int cmd_mod_sub_del_va(const struct shell *shell, size_t argc,

elem_addr = strtoul(argv[1], NULL, 0);

len = hex2bin(argv[2], label, sizeof(label));
len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
(void)memset(label + len, 0, sizeof(label) - len);

mod_id = strtoul(argv[3], NULL, 0);
Expand Down
16 changes: 1 addition & 15 deletions subsys/bluetooth/shell/bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <string.h>
#include <sys/printk.h>
#include <sys/byteorder.h>
#include <sys/util.h>
#include <zephyr.h>

#include <settings/settings.h>
Expand Down Expand Up @@ -229,21 +230,6 @@ static struct bt_conn_cb conn_callbacks = {
};
#endif /* CONFIG_BT_CONN */

static int char2hex(const char *c, u8_t *x)
{
if (*c >= '0' && *c <= '9') {
*x = *c - '0';
} else if (*c >= 'a' && *c <= 'f') {
*x = *c - 'a' + 10;
} else if (*c >= 'A' && *c <= 'F') {
*x = *c - 'A' + 10;
} else {
return -EINVAL;
}

return 0;
}

static int hexstr2array(const char *str, u8_t *array, u8_t size)
{
int i, j;
Expand Down
15 changes: 0 additions & 15 deletions subsys/net/l2/bluetooth/bluetooth_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,6 @@ LOG_MODULE_REGISTER(net_bt_shell, CONFIG_NET_L2_BT_LOG_LEVEL);
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>

static int char2hex(const char *c, u8_t *x)
{
if (*c >= '0' && *c <= '9') {
*x = *c - '0';
} else if (*c >= 'a' && *c <= 'f') {
*x = *c - 'a' + 10;
} else if (*c >= 'A' && *c <= 'F') {
*x = *c - 'A' + 10;
} else {
return -EINVAL;
}

return 0;
}

static int str2bt_addr_le(const char *str, const char *type, bt_addr_le_t *addr)
{
int i, j;
Expand Down
10 changes: 0 additions & 10 deletions subsys/testsuite/include/test_ecc_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,6 @@
#include <tinycrypt/ecc.h>
#include <test_utils.h>

int hex2int(char hex);


/*
* Convert hex string to byte string
* Return number of bytes written to buf, or 0 on error
*/
int hex2bin(uint8_t *buf, const size_t buflen, const char *hex,
const size_t hexlen);

/*
* Convert hex string to zero-padded nanoECC scalar
*/
Expand Down
5 changes: 3 additions & 2 deletions tests/crypto/tinycrypt/src/ecc_dsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include <tinycrypt/sha256.h>
#include <test_utils.h>
#include <test_ecc_utils.h>
#include <sys/util.h>

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -109,7 +110,7 @@ int sign_vectors(TCSha256State_t hash, char **d_vec, char **k_vec,
string2scalar(exp_r, NUM_ECC_WORDS, r_vec[i]);
string2scalar(exp_s, NUM_ECC_WORDS, s_vec[i]);

msglen = hex2bin(msg, BUF_SIZE, msg_vec[i], strlen(msg_vec[i]));
msglen = hex2bin(msg_vec[i], strlen(msg_vec[i]), msg, BUF_SIZE);

/**TESTPOINT: Check if msg imported*/
zassert_true(msglen, "failed to import message!");
Expand Down Expand Up @@ -366,7 +367,7 @@ int vrfy_vectors(TCSha256State_t hash, char **msg_vec, char **qx_vec, char **qy_
exp_rc = res_vec[i];

/* validate ECDSA: hash message, verify r+s */
msglen = hex2bin(msg, BUF_SIZE, msg_vec[i], strlen(msg_vec[i]));
msglen = hex2bin(msg_vec[i], strlen(msg_vec[i]), msg, BUF_SIZE);

/**TESTPOINT: Check if msg imported*/
zassert_true(msglen, "failed to import message!");
Expand Down
Loading

0 comments on commit 7a93e94

Please sign in to comment.