add encrypting for save files
add libhydrogen for encrypting and decrypting #9
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
int
|
||||
hydro_init(void)
|
||||
{
|
||||
hydro_random_ensure_initialized();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
hydro_memzero(void *pnt, size_t len)
|
||||
{
|
||||
#ifdef HAVE_EXPLICIT_BZERO
|
||||
explicit_bzero(pnt, len);
|
||||
#else
|
||||
volatile unsigned char *volatile pnt_ = (volatile unsigned char *volatile) pnt;
|
||||
size_t i = (size_t) 0U;
|
||||
|
||||
while (i < len) {
|
||||
pnt_[i++] = 0U;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
hydro_increment(uint8_t *n, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
uint_fast16_t c = 1U;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
c += (uint_fast16_t) n[i];
|
||||
n[i] = (uint8_t) c;
|
||||
c >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
hydro_bin2hex(char *hex, size_t hex_maxlen, const uint8_t *bin, size_t bin_len)
|
||||
{
|
||||
size_t i = (size_t) 0U;
|
||||
unsigned int x;
|
||||
int b;
|
||||
int c;
|
||||
|
||||
if (bin_len >= SIZE_MAX / 2 || hex_maxlen <= bin_len * 2U) {
|
||||
abort();
|
||||
}
|
||||
while (i < bin_len) {
|
||||
c = bin[i] & 0xf;
|
||||
b = bin[i] >> 4;
|
||||
x = (unsigned char) (87U + c + (((c - 10U) >> 8) & ~38U)) << 8 |
|
||||
(unsigned char) (87U + b + (((b - 10U) >> 8) & ~38U));
|
||||
hex[i * 2U] = (char) x;
|
||||
x >>= 8;
|
||||
hex[i * 2U + 1U] = (char) x;
|
||||
i++;
|
||||
}
|
||||
hex[i * 2U] = 0U;
|
||||
|
||||
return hex;
|
||||
}
|
||||
|
||||
int
|
||||
hydro_hex2bin(uint8_t *bin, size_t bin_maxlen, const char *hex, size_t hex_len, const char *ignore,
|
||||
const char **hex_end_p)
|
||||
{
|
||||
size_t bin_pos = (size_t) 0U;
|
||||
size_t hex_pos = (size_t) 0U;
|
||||
int ret = 0;
|
||||
unsigned char c;
|
||||
unsigned char c_alpha0, c_alpha;
|
||||
unsigned char c_num0, c_num;
|
||||
uint8_t c_acc = 0U;
|
||||
uint8_t c_val;
|
||||
unsigned char state = 0U;
|
||||
|
||||
while (hex_pos < hex_len) {
|
||||
c = (unsigned char) hex[hex_pos];
|
||||
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 = (uint8_t) ((c_num0 & c_num) | (c_alpha0 & c_alpha));
|
||||
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--;
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
}
|
||||
if (ret != 0) {
|
||||
bin_pos = (size_t) 0U;
|
||||
}
|
||||
if (hex_end_p != NULL) {
|
||||
*hex_end_p = &hex[hex_pos];
|
||||
} else if (hex_pos != hex_len) {
|
||||
errno = EINVAL;
|
||||
ret = -1;
|
||||
}
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
return (int) bin_pos;
|
||||
}
|
||||
|
||||
bool
|
||||
hydro_equal(const void *b1_, const void *b2_, size_t len)
|
||||
{
|
||||
const volatile uint8_t *volatile b1 = (const volatile uint8_t *volatile) b1_;
|
||||
const uint8_t *b2 = (const uint8_t *) b2_;
|
||||
size_t i;
|
||||
uint8_t d = (uint8_t) 0U;
|
||||
|
||||
if (b1 == b2) {
|
||||
d = ~d;
|
||||
}
|
||||
for (i = 0U; i < len; i++) {
|
||||
d |= b1[i] ^ b2[i];
|
||||
}
|
||||
return (bool) (1 & ((d - 1) >> 8));
|
||||
}
|
||||
|
||||
int
|
||||
hydro_compare(const uint8_t *b1_, const uint8_t *b2_, size_t len)
|
||||
{
|
||||
const volatile uint8_t *volatile b1 = (const volatile uint8_t *volatile) b1_;
|
||||
const uint8_t *b2 = (const uint8_t *) b2_;
|
||||
uint8_t gt = 0U;
|
||||
uint8_t eq = 1U;
|
||||
size_t i;
|
||||
|
||||
i = len;
|
||||
while (i != 0U) {
|
||||
i--;
|
||||
gt |= ((b2[i] - b1[i]) >> 8) & eq;
|
||||
eq &= ((b2[i] ^ b1[i]) - 1) >> 8;
|
||||
}
|
||||
return (int) (gt + gt + eq) - 1;
|
||||
}
|
||||
|
||||
int
|
||||
hydro_pad(unsigned char *buf, size_t unpadded_buflen, size_t blocksize, size_t max_buflen)
|
||||
{
|
||||
unsigned char *tail;
|
||||
size_t i;
|
||||
size_t xpadlen;
|
||||
size_t xpadded_len;
|
||||
volatile unsigned char mask;
|
||||
unsigned char barrier_mask;
|
||||
|
||||
if (blocksize <= 0U || max_buflen > INT_MAX) {
|
||||
return -1;
|
||||
}
|
||||
xpadlen = blocksize - 1U;
|
||||
if ((blocksize & (blocksize - 1U)) == 0U) {
|
||||
xpadlen -= unpadded_buflen & (blocksize - 1U);
|
||||
} else {
|
||||
xpadlen -= unpadded_buflen % blocksize;
|
||||
}
|
||||
if ((size_t) SIZE_MAX - unpadded_buflen <= xpadlen) {
|
||||
return -1;
|
||||
}
|
||||
xpadded_len = unpadded_buflen + xpadlen;
|
||||
if (xpadded_len >= max_buflen) {
|
||||
return -1;
|
||||
}
|
||||
tail = &buf[xpadded_len];
|
||||
mask = 0U;
|
||||
for (i = 0; i < blocksize; i++) {
|
||||
barrier_mask = (unsigned char) (((i ^ xpadlen) - 1U) >> ((sizeof(size_t) - 1U) * CHAR_BIT));
|
||||
*(tail - i) = ((*(tail - i)) & mask) | (0x80 & barrier_mask);
|
||||
mask |= barrier_mask;
|
||||
}
|
||||
return (int) (xpadded_len + 1);
|
||||
}
|
||||
|
||||
int
|
||||
hydro_unpad(const unsigned char *buf, size_t padded_buflen, size_t blocksize)
|
||||
{
|
||||
const unsigned char *tail;
|
||||
unsigned char acc = 0U;
|
||||
unsigned char c;
|
||||
unsigned char valid = 0U;
|
||||
volatile size_t pad_len = 0U;
|
||||
size_t i;
|
||||
size_t is_barrier;
|
||||
|
||||
if (padded_buflen < blocksize || blocksize <= 0U) {
|
||||
return -1;
|
||||
}
|
||||
tail = &buf[padded_buflen - 1U];
|
||||
|
||||
for (i = 0U; i < blocksize; i++) {
|
||||
c = *(tail - i);
|
||||
is_barrier = (((acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U)) >> 8) & 1U;
|
||||
acc |= c;
|
||||
pad_len |= i & (1U + ~is_barrier);
|
||||
valid |= (unsigned char) is_barrier;
|
||||
}
|
||||
if (valid == 0) {
|
||||
return -1;
|
||||
}
|
||||
return (int) (padded_buflen - 1 - pad_len);
|
||||
}
|
||||
Reference in New Issue
Block a user