aboutsummaryrefslogtreecommitdiffstats
path: root/libblake_decode_hex.c
blob: afdc31c33f0bc31705b4a15d81f8ede657a7a075 (plain) (blame)
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
/* See LICENSE file for copyright and license details. */
#include "common.h"

size_t
libblake_decode_hex(const char *data, size_t n, void *out_, int *validp)
{
	unsigned char *out = out_, value;
	size_t i, j = 0;
	int odd = 0;

	*validp = 1;

	if (!out) {
		for (i = 0; i < n && data[i]; i++) {
			if (isxdigit(data[i])) {
				j += (size_t)odd;
				odd ^= 1;
			} else if (isgraph(data[i])) {
				*validp = 0;
			}
		}
		*validp &= !odd;
		return j;
	}

	for (i = 0; i < n && data[i]; i++) {
		if (isxdigit(data[i])) {
			value = (unsigned char)((data[i] & 15) + (data[i] > '9' ? 9 : 0));
			if (!odd) {
				out[j] = (unsigned char)(value << 4);
				odd = 1;
			} else {
				out[j++] |= value;
				odd = 0;
			}
		} else if (isgraph(data[i])) {
			*validp = 0;
		}
	}

	*validp &= !odd;
	return j;
}