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:
parent
743f3dbae0
commit
7a93e948a9
|
@ -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 */
|
||||
|
|
|
@ -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
91
lib/os/hex.c
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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!");
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue