aboutsummaryrefslogtreecommitdiffstats
path: root/ext/util/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/util/util.c')
-rw-r--r--ext/util/util.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/ext/util/util.c b/ext/util/util.c
new file mode 100644
index 0000000..42fe8ac
--- /dev/null
+++ b/ext/util/util.c
@@ -0,0 +1,93 @@
+#include <ctype.h>
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/random.h>
+
+#include "util.h"
+
+int bin2hex(char *hex, size_t hexsize, const uint8_t *bin, size_t binlen)
+{
+ static const char hex_chars[] = "0123456789ABCDEF";
+
+ if (hex == NULL || bin == NULL || hexsize == 0)
+ return -1;
+
+ if (hexsize < (binlen * 2 + 1))
+ return -2;
+
+ for (size_t i = 0; i < binlen; ++i) {
+ hex[2 * i + 0] = hex_chars[(bin[i] >> 4) & 0xF];
+ hex[2 * i + 1] = hex_chars[(bin[i] >> 0) & 0xF];
+ }
+
+ hex[binlen * 2] = '\0';
+ return 0;
+}
+
+int hex2bin(uint8_t *bin, size_t binsize, const char *hex, size_t hexlen)
+{
+ size_t ibin = 0;
+
+ const int hi_reset = -1;
+ int hi = hi_reset;
+
+ for (size_t ihex = 0; ihex < hexlen; ihex++) {
+ char c = hex[ihex];
+
+ if (isspace((unsigned char) c))
+ continue;
+
+ /* invalid character */
+ if (!isxdigit((unsigned char) c))
+ return -1;
+
+ /* hex char encountered after bin is full */
+ if (ibin >= binsize)
+ return -2;
+
+ uint8_t val = (uint8_t) (isdigit(c) ? c - '0' : (tolower(c) - 'a' + 10));
+
+ if (hi < 0) {
+ /* process hi nibble */
+ hi = val;
+ } else {
+ /* process lo nibble, complete byte, reset hi nibble */
+ bin[ibin++] = (hi << 4) | val;
+ hi = hi_reset;
+ }
+ }
+
+ /* odd number of hex chars */
+ if (hi != hi_reset)
+ return -3;
+
+ return (int) ibin;
+}
+
+void randombytes(uint8_t *buf, uint64_t n)
+{
+ while (n > 0) {
+ ssize_t nbread;
+
+ do {
+ nbread = getrandom(buf, n, 0);
+ } while (nbread == -1 && errno == EINTR);
+
+ if (nbread < 0)
+ exit(1);
+
+ buf += nbread;
+ n -= nbread;
+ }
+}
+
+void memzero(void *ptr, size_t num)
+{
+ volatile unsigned char *volatile ptr_ = (volatile unsigned char *volatile) ptr;
+ size_t i = (size_t) 0U;
+
+ while (i < num)
+ ptr_[i++] = 0U;
+}