1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  *
5  * Secure storage APIs
6  */
7 
8 #include "2sysincludes.h"
9 #include "2common.h"
10 #include "2crc8.h"
11 #include "2misc.h"
12 #include "2secdata.h"
13 
vb2_secdata_check_crc(const struct vb2_context * ctx)14 int vb2_secdata_check_crc(const struct vb2_context *ctx)
15 {
16 	const struct vb2_secdata *sec =
17 		(const struct vb2_secdata *)ctx->secdata;
18 
19 	/* Verify CRC */
20 	if (sec->crc8 != vb2_crc8(sec, offsetof(struct vb2_secdata, crc8)))
21 		return VB2_ERROR_SECDATA_CRC;
22 
23 	return VB2_SUCCESS;
24 }
25 
vb2_secdata_create(struct vb2_context * ctx)26 int vb2_secdata_create(struct vb2_context *ctx)
27 {
28 	struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;
29 
30 	/* Clear the entire struct */
31 	memset(sec, 0, sizeof(*sec));
32 
33 	/* Set to current version */
34 	sec->struct_version = VB2_SECDATA_VERSION;
35 
36 	/* Calculate initial CRC */
37 	sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata, crc8));
38 	ctx->flags |= VB2_CONTEXT_SECDATA_CHANGED;
39 	return VB2_SUCCESS;
40 }
41 
vb2_secdata_init(struct vb2_context * ctx)42 int vb2_secdata_init(struct vb2_context *ctx)
43 {
44 	struct vb2_shared_data *sd = vb2_get_sd(ctx);
45 	int rv;
46 
47 	rv = vb2_secdata_check_crc(ctx);
48 	if (rv)
49 		return rv;
50 
51 	/* Set status flag */
52 	sd->status |= VB2_SD_STATUS_SECDATA_INIT;
53 	// TODO: unit test for that
54 
55 	/* Read this now to make sure crossystem has it even in rec mode. */
56 	rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS,
57 			     &sd->fw_version_secdata);
58 	if (rv)
59 		return rv;
60 
61 	return VB2_SUCCESS;
62 }
63 
vb2_secdata_get(struct vb2_context * ctx,enum vb2_secdata_param param,uint32_t * dest)64 int vb2_secdata_get(struct vb2_context *ctx,
65 		    enum vb2_secdata_param param,
66 		    uint32_t *dest)
67 {
68 	struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;
69 
70 	if (!(vb2_get_sd(ctx)->status & VB2_SD_STATUS_SECDATA_INIT))
71 		return VB2_ERROR_SECDATA_GET_UNINITIALIZED;
72 
73 	switch(param) {
74 	case VB2_SECDATA_FLAGS:
75 		*dest = sec->flags;
76 		return VB2_SUCCESS;
77 
78 	case VB2_SECDATA_VERSIONS:
79 		*dest = sec->fw_versions;
80 		return VB2_SUCCESS;
81 
82 	default:
83 		return VB2_ERROR_SECDATA_GET_PARAM;
84 	}
85 }
86 
vb2_secdata_set(struct vb2_context * ctx,enum vb2_secdata_param param,uint32_t value)87 int vb2_secdata_set(struct vb2_context *ctx,
88 		    enum vb2_secdata_param param,
89 		    uint32_t value)
90 {
91 	struct vb2_secdata *sec = (struct vb2_secdata *)ctx->secdata;
92 	uint32_t now;
93 
94 	if (!(vb2_get_sd(ctx)->status & VB2_SD_STATUS_SECDATA_INIT))
95 		return VB2_ERROR_SECDATA_SET_UNINITIALIZED;
96 
97 	/* If not changing the value, don't regenerate the CRC. */
98 	if (vb2_secdata_get(ctx, param, &now) == VB2_SUCCESS && now == value)
99 		return VB2_SUCCESS;
100 
101 	switch(param) {
102 	case VB2_SECDATA_FLAGS:
103 		/* Make sure flags is in valid range */
104 		if (value > 0xff)
105 			return VB2_ERROR_SECDATA_SET_FLAGS;
106 
107 		sec->flags = value;
108 		break;
109 
110 	case VB2_SECDATA_VERSIONS:
111 		sec->fw_versions = value;
112 		break;
113 
114 	default:
115 		return VB2_ERROR_SECDATA_SET_PARAM;
116 	}
117 
118 	/* Regenerate CRC */
119 	sec->crc8 = vb2_crc8(sec, offsetof(struct vb2_secdata, crc8));
120 	ctx->flags |= VB2_CONTEXT_SECDATA_CHANGED;
121 	return VB2_SUCCESS;
122 }
123