1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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;
}
|