summaryrefslogtreecommitdiffstats
path: root/src/keystore-blob.c
blob: e3bffb3bc853647e53becc0c110bbd41af2c12b5 (plain)
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
/*
 * Copyright (C) 2015 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de>
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License version 2 as published by the
 * Free Software Foundation.
 */

#include <common.h>
#include <crypto/keystore.h>
#include <base64.h>
#include <barebox-state.h>
#include <state.h>

static const char keystore_state_name[] = "/blobs";
static const char blob_gen_payload[] = "/sys/bus/platform/devices/blob_gen/payload";
static const char blob_gen_modifier[] = "/sys/bus/platform/devices/blob_gen/modifier";
static const char blob_gen_blob[] = "/sys/bus/platform/devices/blob_gen/blob";

static struct state *state;

int keystore_get_secret(const char *name, const unsigned char **key, int *key_len)
{
	FILE *fp;
	char *blob, *modifier, *payload;
	u8 *blob_bin, *payload_bin;
	ssize_t len;
	int fd, ret;

	if (!state) {
		struct state *tmp;

		tmp = state_get(keystore_state_name, true);
		if (IS_ERR(tmp))
			return  PTR_ERR(tmp);
		state = tmp;
	}

	/* modifier */
	fp = fopen(blob_gen_modifier, "w");
	if (!fp)
		return -errno;

	ret = fprintf(fp, "user:%s", name);
	if (ret < 0) {
		fclose(fp);
		return ret;
	}

	ret = fclose(fp);
	if (ret == EOF)
		return -errno;


	/* blob */
	blob = state_get_var(state, name);
	if (!blob)
		return -ENOENT;

	len = strlen(blob) + 1;
	blob_bin = xzalloc(len);
	len = decode_base64(blob_bin, len, blob);
	free(blob);

	fd = open(blob_gen_blob, O_WRONLY);
	if (fd < 0) {
		free(blob_bin);
		return -errno;
	}

	ret = write(fd, blob_bin, len);
	free(blob_bin);
	if (ret != len) {
		return -errno;
	}

	ret = close(fd);
	if (ret)
		return -errno;


	/* payload */
	fd = open(blob_gen_payload, O_RDONLY);
	if (fd < 0) {
		free(blob_bin);
		return -errno;
	}

	payload = xzalloc(len);
	len = read(fd, payload, len);
	close(fd);
	if (len <= 0) {
		free(payload);
		return -errno;
	}

	payload_bin = xzalloc(len);
	len = decode_base64(payload_bin, len, payload);
	free(payload);

	*key = payload_bin;
	*key_len = len;

	return 0;
}