diff --git a/src/libsodium/sodium/utils.c b/src/libsodium/sodium/utils.c index dd59dbca..9c844c6e 100644 --- a/src/libsodium/sodium/utils.c +++ b/src/libsodium/sodium/utils.c @@ -131,22 +131,25 @@ sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen, int ret = 0; unsigned char c; unsigned char c_acc = 0U; - unsigned char c_num; + unsigned char c_alpha0, c_alpha; + unsigned char c_num0, 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 { + c_num = c ^ 48U; + c_num0 = (c_num - 10U) >> 8; + c_alpha = (c & ~32U) - 55U; + c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8; + if ((c_num0 | c_alpha0) == 0U) { + if (ignore != NULL && state == 0U && strchr(ignore, c) != NULL) { + hex_pos++; + continue; + } break; } + c_val = (c_num0 & c_num) | (c_alpha0 & c_alpha); if (bin_pos >= bin_maxlen) { ret = -1; errno = ERANGE;