kernel: lib: Add convert functions for hex strings and binary arrays

Move duplicate hex2bin and add bin2hex function so that application can
use the functions and avoid code duplication.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2019-05-28 13:20:35 +02:00 committed by Carles Cufí
parent 743f3dbae0
commit 7a93e948a9
9 changed files with 161 additions and 140 deletions

View file

@ -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))
@ -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 */

View file

@ -8,6 +8,7 @@ zephyr_sources(
crc8_sw.c
crc7_sw.c
fdtable.c
hex.c
mempool.c
rb.c
thread_entry.c

91
lib/os/hex.c Normal file
View file

@ -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;
}

View file

@ -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>
@ -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 "
@ -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 {
@ -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;
}
@ -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);
@ -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));
@ -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));
@ -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);
@ -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);

View file

@ -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>
@ -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;

View file

@ -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;

View file

@ -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
*/

View file

@ -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>
@ -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!");
@ -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!");

View file

@ -58,71 +58,13 @@
#include <test_ecc_utils.h>
#include <tinycrypt/constants.h>
#include <sys/util.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int hex2int(char hex)
{
uint8_t dec;
if ('0' <= hex && hex <= '9') {
dec = hex - '0';
} else if ('a' <= hex && hex <= 'f') {
dec = hex - 'a' + 10;
} else if ('A' <= hex && hex <= 'F') {
dec = hex - 'A' + 10;
} else {
return -1;
}
return dec;
}
/*
* 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)
{
int dec;
if (buflen < hexlen / 2 + hexlen % 2) {
return false;
}
/* if hexlen is uneven, insert leading zero nibble */
if (hexlen % 2) {
dec = hex2int(hex[0]);
if (dec == -1) {
return false;
}
buf[0] = dec;
buf++;
hex++;
}
/* regular hex conversion */
for (size_t i = 0; i < hexlen / 2; i++) {
dec = hex2int(hex[2 * i]);
if (dec == -1) {
return false;
}
buf[i] = dec << 4;
dec = hex2int(hex[2 * i + 1]);
if (dec == -1) {
return false;
}
buf[i] += dec;
}
return hexlen / 2 + hexlen % 2;
}
/*
* Convert hex string to zero-padded nanoECC scalar
*/
@ -144,7 +86,7 @@ void string2scalar(unsigned int *scalar, unsigned int num_word32, char *str)
(void)memset(tmp, 0, padding / 2);
if (false == hex2bin(tmp + padding / 2, num_bytes, str, hexlen)) {
if (hex2bin(str, hexlen, tmp + padding / 2, num_bytes) == 0) {
k_panic();
}
uECC_vli_bytesToNative(scalar, tmp, num_bytes);