From 219db714cf47542baff29955913e6c89a6f2cb4b Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 15 Apr 2014 00:39:14 -0700 Subject: [PATCH] Add sodium_hex2bin() --- src/libsodium/include/sodium/utils.h | 8 +++- src/libsodium/sodium/utils.c | 57 +++++++++++++++++++++++++++- test/default/sodium_utils.c | 8 ++++ test/default/sodium_utils.exp | 1 + 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/libsodium/include/sodium/utils.h b/src/libsodium/include/sodium/utils.h index f9f3875a..e962d71d 100644 --- a/src/libsodium/include/sodium/utils.h +++ b/src/libsodium/include/sodium/utils.h @@ -26,9 +26,15 @@ SODIUM_EXPORT int sodium_memcmp(const void * const b1_, const void * const b2_, size_t size); SODIUM_EXPORT -char *sodium_bin2hex(char * const hex, const size_t hex_len, +char *sodium_bin2hex(char * const hex, const size_t hex_maxlen, const unsigned char * const bin, const size_t bin_len); +SODIUM_EXPORT +int sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen, + const char * const hex, const size_t hex_len, + const char * const ignore, size_t * const bin_len, + const char ** const hex_end); + #ifdef __cplusplus } #endif diff --git a/src/libsodium/sodium/utils.c b/src/libsodium/sodium/utils.c index a6afd93d..27a0a9f8 100644 --- a/src/libsodium/sodium/utils.c +++ b/src/libsodium/sodium/utils.c @@ -2,6 +2,7 @@ #ifndef __STDC_WANT_LIB_EXT1__ # define __STDC_WANT_LIB_EXT1__ 1 #endif +#include #include #include #include @@ -77,7 +78,7 @@ _sodium_alignedcalloc(unsigned char ** const unaligned_p, const size_t len) } char * -sodium_bin2hex(char * const hex, const size_t hex_len, +sodium_bin2hex(char * const hex, const size_t hex_maxlen, const unsigned char * const bin, const size_t bin_len) { static const char hexdigits[16] = { @@ -87,7 +88,7 @@ sodium_bin2hex(char * const hex, const size_t hex_len, size_t i = (size_t) 0U; size_t j = (size_t) 0U; - if (bin_len >= SIZE_MAX / 2 || hex_len < bin_len * 2U) { + if (bin_len >= SIZE_MAX / 2 || hex_maxlen < bin_len * 2U) { abort(); } while (i < bin_len) { @@ -99,3 +100,55 @@ sodium_bin2hex(char * const hex, const size_t hex_len, return hex; } + +int +sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen, + const char * const hex, const size_t hex_len, + const char * const ignore, size_t * const bin_len, + const char ** const hex_end) +{ + size_t bin_pos = (size_t) 0U; + size_t hex_pos = (size_t) 0U; + int ret = 0; + unsigned char c; + unsigned char c_acc = 0U; + unsigned char c_num; + unsigned char c_val; + unsigned char state = 0U; + + while (hex_pos < hex_len) { + c = (unsigned char) hex[hex_pos]; + if ((c_num = c ^ 48U) < 10U) { + c_val = c_num; + } else if ((c_num = (c & ~32U)) > 64 && c_num < 71U) { + c_val = c_num - 55U; + } else if (ignore != NULL && strchr(ignore, c) != NULL && state == 0U) { + hex_pos++; + continue; + } else { + break; + } + if (bin_pos >= bin_maxlen) { + ret = -1; + errno = ERANGE; + break; + } + if (state == 0U) { + c_acc = c_val * 16U; + } else { + bin[bin_pos++] = c_acc | c_val; + } + state = ~state; + hex_pos++; + } + if (state != 0U) { + hex_pos--; + } + if (hex_end != NULL) { + *hex_end = &hex[hex_pos]; + } + if (bin_len != NULL) { + *bin_len = bin_pos; + } + return ret; +} diff --git a/test/default/sodium_utils.c b/test/default/sodium_utils.c index 177dbf23..f309cfe6 100644 --- a/test/default/sodium_utils.c +++ b/test/default/sodium_utils.c @@ -9,6 +9,9 @@ int main(void) unsigned char buf1[1000]; unsigned char buf2[1000]; char buf3[33]; + unsigned char buf4[4]; + const char *hex; + size_t bin_len; randombytes(buf1, sizeof buf1); memcpy(buf2, buf1, sizeof buf2); @@ -23,5 +26,10 @@ int main(void) printf("%s\n", sodium_bin2hex(buf3, 33U, (const unsigned char *) "0123456789ABCDEF", 16U)); + hex = "Cafe : 6942"; + sodium_hex2bin(buf4, sizeof buf4, hex, strlen(hex), ": ", &bin_len, NULL); + printf("%zu:%02x%02x%02x%02x\n", bin_len, + buf4[0], buf4[1], buf4[2], buf4[3]); + return 0; } diff --git a/test/default/sodium_utils.exp b/test/default/sodium_utils.exp index 713a1d9b..2be34ae3 100644 --- a/test/default/sodium_utils.exp +++ b/test/default/sodium_utils.exp @@ -4,3 +4,4 @@ 0 0 30313233343536373839414243444546 +4:cafe6942