1 /*
2  * Copyright (c) 2019 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stddef.h>
8 #include <zephyr/types.h>
9 #include <errno.h>
10 #include <sys/util.h>
11 
char2hex(char c,uint8_t * x)12 int char2hex(char c, uint8_t *x)
13 {
14 	if (c >= '0' && c <= '9') {
15 		*x = c - '0';
16 	} else if (c >= 'a' && c <= 'f') {
17 		*x = c - 'a' + 10;
18 	} else if (c >= 'A' && c <= 'F') {
19 		*x = c - 'A' + 10;
20 	} else {
21 		return -EINVAL;
22 	}
23 
24 	return 0;
25 }
26 
hex2char(uint8_t x,char * c)27 int hex2char(uint8_t x, char *c)
28 {
29 	if (x <= 9) {
30 		*c = x + '0';
31 	} else  if (x <= 15) {
32 		*c = x - 10 + 'a';
33 	} else {
34 		return -EINVAL;
35 	}
36 
37 	return 0;
38 }
39 
bin2hex(const uint8_t * buf,size_t buflen,char * hex,size_t hexlen)40 size_t bin2hex(const uint8_t *buf, size_t buflen, char *hex, size_t hexlen)
41 {
42 	if ((hexlen + 1) < buflen * 2) {
43 		return 0;
44 	}
45 
46 	for (size_t i = 0; i < buflen; i++) {
47 		if (hex2char(buf[i] >> 4, &hex[2 * i]) < 0) {
48 			return 0;
49 		}
50 		if (hex2char(buf[i] & 0xf, &hex[2 * i + 1]) < 0) {
51 			return 0;
52 		}
53 	}
54 
55 	hex[2 * buflen] = '\0';
56 	return 2 * buflen;
57 }
58 
hex2bin(const char * hex,size_t hexlen,uint8_t * buf,size_t buflen)59 size_t hex2bin(const char *hex, size_t hexlen, uint8_t *buf, size_t buflen)
60 {
61 	uint8_t dec;
62 
63 	if (buflen < hexlen / 2 + hexlen % 2) {
64 		return 0;
65 	}
66 
67 	/* if hexlen is uneven, insert leading zero nibble */
68 	if (hexlen % 2) {
69 		if (char2hex(hex[0], &dec) < 0) {
70 			return 0;
71 		}
72 		buf[0] = dec;
73 		hex++;
74 		buf++;
75 	}
76 
77 	/* regular hex conversion */
78 	for (size_t i = 0; i < hexlen / 2; i++) {
79 		if (char2hex(hex[2 * i], &dec) < 0) {
80 			return 0;
81 		}
82 		buf[i] = dec << 4;
83 
84 		if (char2hex(hex[2 * i + 1], &dec) < 0) {
85 			return 0;
86 		}
87 		buf[i] += dec;
88 	}
89 
90 	return hexlen / 2 + hexlen % 2;
91 }
92