aboutsummaryrefslogtreecommitdiffstats
path: root/crypt.c
blob: ca3626d22c84339336f7f06f46bf55ccb92c9589 (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
/* See LICENSE file for copyright and license details. */
#include "crypt.h"
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libar2simplified.h>
#include <libar2.h>

extern char *argv0;


char *
key2root_crypt(char *msg, size_t msglen, const char *paramstr, int autoerase)
{
	struct libar2_argon2_parameters *params = NULL;
	char *end, *ret = NULL, *hash = NULL;
	size_t size;
	struct libar2_context ctx;

	libar2simplified_init_context(&ctx);
	ctx.autoerase_message = (unsigned char)autoerase;

	if (!paramstr)
		paramstr = libar2simplified_recommendation(0);

	params = libar2simplified_decode_r(paramstr, NULL, &end, NULL, NULL);
	if (!params) {
		fprintf(stderr, "%s: libar2simplified_decode_r %s: %s\n", argv0, paramstr, strerror(errno));
		return NULL;
	}
	if (*end) {
		fprintf(stderr, "%s: libar2simplified_decode_r %s: excess data at end parameter string: %s\n", argv0, paramstr, end);
		goto out;
	}

	size = libar2_hash_buf_size(params);
	if (!size)
		abort();
	if (!size || !(hash = malloc(size))) {
		fprintf(stderr, "%s: malloc %zu: %s\n", argv0, size, strerror(errno));
		goto out;
	}

	if (libar2_hash(hash, msg, msglen, params, &ctx)) {
		if (autoerase)
			libar2_erase(msg, msglen);
		fprintf(stderr, "%s: libar2simplified_hash %s: %s\n", argv0, paramstr, strerror(errno));
		goto out;
	}

	ret = libar2simplified_encode(params, hash);

out:
	if (params) {
		libar2_erase(params->salt, params->saltlen);
		free(params);
	}
	free(hash);
	return ret;
}