Branch data Line data Source code
1 : : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2 : : /* Copyright 2020 IBM Corp. */
3 : : #include <skiboot.h>
4 : : #include "secboot_tpm.h"
5 : :
6 : : /* Offset into the SECBOOT PNOR partition to write "TPMNV" data */
7 : : static size_t fakenv_offset = sizeof(struct secboot);
8 : :
9 : : struct fake_tpmnv {
10 : : struct {
11 : : struct secboot_header header;
12 : : char vars[2048]; // Hardcode the size to 2048 for now
13 : : } vars;
14 : : struct tpmnv_control control;
15 : : int defined[2];
16 : : } __attribute__((packed));
17 : :
18 : : static struct fake_tpmnv fakenv;
19 : : static int tpm_ready;
20 : :
21 : :
22 : 9 : static inline void *nv_index_address(int index)
23 : : {
24 : 9 : switch (index) {
25 : 3 : case SECBOOT_TPMNV_VARS_INDEX:
26 : 3 : return &fakenv.vars;
27 : 6 : case SECBOOT_TPMNV_CONTROL_INDEX:
28 : 6 : return &fakenv.control;
29 : 0 : default:
30 : 0 : return 0;
31 : : }
32 : : }
33 : :
34 : :
35 : 12 : static int tpm_init(void)
36 : : {
37 : : int rc;
38 : :
39 : 12 : if (tpm_ready)
40 : 11 : return 0;
41 : :
42 : 1 : rc = flash_secboot_read(&fakenv, fakenv_offset, sizeof(struct fake_tpmnv));
43 : 1 : if (rc)
44 : 0 : return rc;
45 : :
46 : 1 : tpm_ready = 1;
47 : :
48 : 1 : return 0;
49 : : }
50 : :
51 : 0 : static int fakenv_read(TPMI_RH_NV_INDEX nvIndex, void *buf,
52 : : size_t bufsize, uint16_t off)
53 : : {
54 : 0 : if (tpm_init())
55 : 0 : return OPAL_INTERNAL_ERROR;
56 : :
57 : 0 : memcpy(buf, nv_index_address(nvIndex) + off, bufsize);
58 : :
59 : 0 : return 0;
60 : : }
61 : :
62 : 9 : static int fakenv_write(TPMI_RH_NV_INDEX nvIndex, void *buf,
63 : : size_t bufsize, uint16_t off)
64 : : {
65 : 9 : if (tpm_init())
66 : 0 : return OPAL_INTERNAL_ERROR;
67 : :
68 : 9 : memcpy(nv_index_address(nvIndex) + off, buf, bufsize);
69 : :
70 : : /* Just write the whole NV struct for now */
71 : 9 : return flash_secboot_write(fakenv_offset, &fakenv, sizeof(struct fake_tpmnv));
72 : : }
73 : :
74 : 2 : static int fakenv_definespace(TPMI_RH_NV_INDEX nvIndex, uint16_t dataSize)
75 : : {
76 : 2 : if (tpm_init())
77 : 0 : return OPAL_INTERNAL_ERROR;
78 : :
79 : : (void) dataSize;
80 : :
81 : 2 : switch (nvIndex) {
82 : 1 : case SECBOOT_TPMNV_VARS_INDEX:
83 : 1 : fakenv.defined[0] = 1;
84 : 1 : return 0;
85 : 1 : case SECBOOT_TPMNV_CONTROL_INDEX:
86 : 1 : fakenv.defined[1] = 1;
87 : 1 : return 0;
88 : : }
89 : :
90 : 0 : return OPAL_INTERNAL_ERROR;
91 : : }
92 : :
93 : 0 : static int fakenv_writelock(TPMI_RH_NV_INDEX nvIndex)
94 : : {
95 : 0 : if (tpm_init())
96 : 0 : return OPAL_INTERNAL_ERROR;
97 : :
98 : : (void) nvIndex;
99 : :
100 : 0 : return 0;
101 : : }
102 : :
103 : 1 : static int fakenv_get_defined_indices(TPMI_RH_NV_INDEX **indices, size_t *count)
104 : : {
105 : 1 : if (tpm_init())
106 : 0 : return OPAL_INTERNAL_ERROR;
107 : :
108 : 1 : *indices = zalloc(sizeof(fakenv.defined));
109 : 1 : if (*indices == NULL)
110 : 0 : return OPAL_NO_MEM;
111 : :
112 : 1 : *count = 0;
113 : :
114 : 1 : if (fakenv.defined[0]) {
115 : 0 : *indices[0] = SECBOOT_TPMNV_VARS_INDEX;
116 : 0 : (*count)++;
117 : : }
118 : 1 : if (fakenv.defined[1]) {
119 : 0 : *indices[1] = SECBOOT_TPMNV_CONTROL_INDEX;
120 : 0 : (*count)++;
121 : : }
122 : :
123 : 1 : return 0;
124 : : }
125 : :
126 : 0 : static int fakenv_undefinespace(TPMI_RH_NV_INDEX index)
127 : : {
128 : 0 : if (tpm_init())
129 : 0 : return OPAL_INTERNAL_ERROR;
130 : :
131 : 0 : switch (index) {
132 : 0 : case SECBOOT_TPMNV_VARS_INDEX:
133 : 0 : fakenv.defined[0] = 0;
134 : 0 : memset(&fakenv.vars, 0, sizeof(fakenv.vars));
135 : 0 : return 0;
136 : 0 : case SECBOOT_TPMNV_CONTROL_INDEX:
137 : 0 : fakenv.defined[1] = 0;
138 : 0 : memset(&fakenv.control, 0, sizeof(fakenv.control));
139 : 0 : return 0;
140 : : }
141 : :
142 : 0 : return -1;
143 : : }
144 : :
145 : 0 : static int fakenv_readpublic(TPMI_RH_NV_INDEX index, TPMS_NV_PUBLIC *nv_public,
146 : : TPM2B_NAME *nv_name)
147 : : {
148 : 0 : if (tpm_init())
149 : 0 : return OPAL_INTERNAL_ERROR;
150 : :
151 : : (void) nv_public;
152 : :
153 : 0 : switch (index) {
154 : 0 : case SECBOOT_TPMNV_VARS_INDEX:
155 : 0 : memcpy(&nv_name->t.name, tpmnv_vars_name, sizeof(tpmnv_vars_name));
156 : 0 : break;
157 : 0 : case SECBOOT_TPMNV_CONTROL_INDEX:
158 : 0 : memcpy(&nv_name->t.name, tpmnv_control_name, sizeof(tpmnv_control_name));
159 : 0 : break;
160 : 0 : default:
161 : 0 : return OPAL_INTERNAL_ERROR;
162 : : }
163 : :
164 : 0 : return 0;
165 : : }
166 : :
167 : : struct tpmnv_ops_s tpmnv_ops = {
168 : : .read = fakenv_read,
169 : : .write = fakenv_write,
170 : : .writelock = fakenv_writelock,
171 : : .definespace = fakenv_definespace,
172 : : .getindices = fakenv_get_defined_indices,
173 : : .undefinespace = fakenv_undefinespace,
174 : : .readpublic = fakenv_readpublic,
175 : : };
|