File: mac.ha

package info (click to toggle)
hare 0.25.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,948 kB
  • sloc: asm: 1,264; makefile: 123; sh: 114; lisp: 101
file content (64 lines) | stat: -rw-r--r-- 2,041 bytes parent folder | download | duplicates (2)
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
// SPDX-License-Identifier: MPL-2.0
// (c) Hare authors <https://harelang.org>

use io;
// TODO: Use a vtable-based approach like io::stream

// The general purpose interface for a MAC function.
export type mac = struct {
	// A stream which only supports writes and never returns errors.
	stream: io::stream,

	// Writes the resulting MAC to 'buf'. Must only be called once, and must
	// be followed by calling [[finish]].
	sum: nullable *fn(mac: *mac, buf: []u8) void,

	// Finalizes the MAC function, securely discards all state and frees
	// all resources used by the MAC.
	finish: *fn(mac: *mac) void,

	// Size of the MAC in bytes.
	sz: size,

	// Internal block size of the MAC in bytes.
	bsz: size,
};

// Writes an input to the MAC function.
export fn write(m: *mac, buf: const []u8) size = io::write(m, buf) as size;

// Computes the final MAC and writes it to 'buf', which must be at least [[sz]]
// bytes. Generally, each MAC implementation provides a constant which is equal
// to the length, so you may not have to dynamically allocate this buffer.
//
// This function may only be called once for any given [[mac]] object; calling
// it more than once will cause a runtime assertion to fail.
//
// After calling [[sum]], you must call [[finish]] to securely erase sensitive
// information stored in the MAC function state.
export fn sum(m: *mac, buf: []u8) void = {
	assert(len(buf) >= m.sz,
		"mac::finish buffer does not meet minimum required size");

	match(m.sum) {
	case let f: *fn(mac: *mac, buf: []u8) void =>
		f(m, buf);
		m.sum = null;
	case null =>
		abort("MAC is already finished or sum has already been called");
	};
};

// Finalizes the MAC function, securely discarding any sensitive state, and
// freeing any associated resources.
export fn finish(m: *mac) void = {
	m.finish(m);
	m.sum = null;
};

// Returns the size of the MAC in bytes. This is consistent regardless
// of the MAC state.
export fn sz(m: *mac) size = m.sz;

// Returns the block size of the MAC in bytes.
export fn bsz(m: *mac) size = m.bsz;