aboutsummaryrefslogtreecommitdiffstats
path: root/libhashsum_init_blake384_hasher.c
blob: a5075934d45b5bc220c3649bc23fd1df0d1d5365 (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
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* See LICENSE file for copyright and license details. */
#include "common.h"
#ifdef SUPPORT_BLAKE384


LIBHASHSUM_1_NONNULL_
static size_t
process(struct libhashsum_hasher *this, const void *data, size_t bytes)
{
	return libblake_blake384_update(&this->state.blake384.s, data, bytes);
}


LIBHASHSUM_1_NONNULL_
static int
finalise_const(struct libhashsum_hasher *this, const void *data, size_t bytes, unsigned extra_bits)
{
	const uint8_t *m = data;
	size_t r;

	if (extra_bits > 7U) {
		errno = EINVAL;
		return -1;
	}

	r = libblake_blake384_update(&this->state.blake384.s, data, bytes);
	m = &m[r];
	bytes -= r;

	if (!this->hash_output)
		this->hash_output = this->state.blake384.buf;

	memcpy(this->state.blake384.buf, m, bytes + (size_t)(extra_bits > 0U));
	if (extra_bits)
		this->state.blake384.buf[bytes] = libhashsum_reverse_byte__(this->state.blake384.buf[bytes]);
	libblake_blake384_digest(&this->state.blake384.s, this->state.blake384.buf, bytes,
	                         extra_bits, NULL, this->hash_output);
	memset(&this->state.blake384.s, 0, sizeof(this->state.blake384.s));
	return 0;
}


LIBHASHSUM_1_NONNULL_
static int
finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size)
{
	uint8_t *m = data;
	size_t r;

	if (extra_bits > 7U) {
		errno = EINVAL;
		return -1;
	}

	r = libblake_blake384_update(&this->state.blake384.s, data, bytes);
	m = &m[r];
	bytes -= r;
	size -= r;

	if (!this->hash_output)
		this->hash_output = this->state.blake384.buf;

	if (size < libblake_blake384_digest_get_required_input_size(bytes, extra_bits, NULL)) {
		memcpy(this->state.blake384.buf, m, bytes + (size_t)(extra_bits > 0U));
		m = this->state.blake384.buf;
	}
	if (extra_bits)
		m[bytes] = libhashsum_reverse_byte__(m[bytes]);
	libblake_blake384_digest(&this->state.blake384.s, m, bytes, extra_bits, NULL, this->hash_output);
	memset(&this->state.blake384.s, 0, sizeof(this->state.blake384.s));
	return 0;
}


static const char *
mkalgostr(char *buf, const char *name, const uint8_t *salt)
{
	char *p;
	size_t i;
	if (!salt)
		return name;
	for (i = 0; i < 32U; i++)
		if (salt[i])
			goto nonzero;
	return name;
nonzero:
	p = stpcpy(stpcpy(buf, name), "[salt=");
	for (i = 0; i < 32U; i++) {
		*p++ = "0123456789abcdef"[(salt[i] >> 4) & 15];
		*p++ = "0123456789abcdef"[(salt[i] >> 0) & 15];
	}
	*p++ = ']';
	*p++ = '\0';
	return buf;
}


int
libhashsum_init_blake384_hasher(struct libhashsum_hasher *this, const void *salt)
{
	libblake_init();
	this->algorithm = LIBHASHSUM_BLAKE384;
	this->algorithm_string = mkalgostr(this->state.blake384.algostr, "BLAKE384", salt);
	this->input_block_size = 128U;
	this->hash_size = LIBHASHSUM_BLAKE384_HASH_SIZE;
	this->hash_output = NULL;
	this->supports_non_whole_bytes = 1;
	this->standard_partial_byte_input_encoding = LIBHASHSUM_MOST_SIGNIFICANT;
	this->standard_partial_byte_output_encoding = LIBHASHSUM_UNSUPPORTED;
	this->hash_excess_bits = 0;
	this->process = &process;
	this->finalise_const = &finalise_const;
	this->finalise = &finalise;
	this->stretch = NULL;
	this->destroy = NULL;
	libblake_blake384_init2(&this->state.blake384.s, salt);
	return 0;
}


#else
int
libhashsum_init_blake384_hasher(struct libhashsum_hasher *this, const void *salt)
{
	(void) this;
	(void) salt;
	errno = ENOSYS;
	return -1;
}
#endif