1 /* TPM disk interface */
2 #include <blkfront.h>
3 #include <unistd.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <inttypes.h>
7 #include <stdlib.h>
8 #include <stdbool.h>
9 #include <mini-os/byteorder.h>
10 #include <mini-os/lib.h>
11 #include <polarssl/aes.h>
12 #include <polarssl/sha1.h>
13
14 #include "tpm.h"
15 #include "tpm2.h"
16 #include "tcg.h"
17
18 #include "vtpmmgr.h"
19 #include "vtpm_disk.h"
20 #include "disk_tpm.h"
21
22 #include "log.h"
23 // Print out input/output of seal/unseal operations (includes keys)
24 #undef DEBUG_SEAL_OPS
25
26 #ifdef DEBUG_SEAL_OPS
27 #include "marshal.h"
28 #include "tpm2_marshal.h"
29 #endif
30
31 struct pcr_list {
32 TPM_DIGEST pcrs[24];
33 };
34
35 static struct pcr_list hwtpm;
36
37 /*Ignore PCR on TPM 2.0, read PCR values for TPM 1.x seal | unseal*/
TPM_read_pcrs(void)38 void TPM_read_pcrs(void)
39 {
40 int i;
41 for (i=0; i < 24; i++) {
42 if (hw_is_tpm2())
43 tpm2_pcr_read(i, (uint8_t *)&hwtpm.pcrs[i]);
44 else
45 TPM_PCR_Read(i, &hwtpm.pcrs[i]);
46 }
47 }
48
49 struct pcr_composite_3 {
50 be16_t sel_size;
51 uint8_t sel[3];
52 be32_t val_size;
53 uint8_t val[0];
54 } __attribute__((packed));
55
TPM_pcr_digest(struct hash160 * buf,le32_t selection)56 void TPM_pcr_digest(struct hash160 *buf, le32_t selection)
57 {
58 int i;
59 int count = 0;
60 uint32_t sel = le32_native(selection);
61 struct pcr_composite_3 *v;
62 for(i=0; i < 24; i++) {
63 if (sel & (1 << i))
64 count++;
65 }
66 v = alloca(sizeof(*v) + 20 * count);
67 v->sel_size = native_be16(3);
68 memcpy(v->sel, &selection, 3);
69 v->val_size = native_be32(20 * count);
70
71 count = 0;
72 for(i=0; i < 24; i++) {
73 if (sel & (1 << i)) {
74 memcpy(v->val + 20 * count, &hwtpm.pcrs[i], 20);
75 count++;
76 }
77 }
78
79 sha1((void*)v, sizeof(*v) + 20 * count, buf->bits);
80 }
81
82
TPM_disk_seal(struct disk_seal_entry * dst,const void * src,size_t size)83 int TPM_disk_seal(struct disk_seal_entry *dst, const void* src, size_t size)
84 {
85 uint32_t rc;
86 uint32_t infoSize;
87 TPM_PCR_INFO_LONG info;
88 TPM_STORED_DATA12 out;
89 TPM_AUTH_SESSION osap = TPM_AUTH_SESSION_INIT;
90 TPM_AUTHDATA sharedsecret;
91 TPM_AUTHDATA auth;
92
93 printk("Calling TPM_disk_seal\n");
94
95 rc = TPM_OSAP(TPM_ET_KEYHANDLE, TPM_SRK_KEYHANDLE, (void*)&vtpm_globals.srk_auth,
96 &sharedsecret, &osap);
97
98 if (rc) abort();
99
100 #ifdef DEBUG_SEAL_OPS
101 int i;
102 printk("to-seal:");
103 for(i=0; i < size; i++)
104 printk(" %02x", ((uint8_t*)src)[i]);
105 printk("\n");
106 #endif
107
108 memset(auth, 0, 20);
109 info.tag = TPM_TAG_PCR_INFO_LONG;
110 info.localityAtCreation = 1 << vtpm_globals.hw_locality;
111 info.localityAtRelease = 1 << vtpm_globals.hw_locality;
112 info.creationPCRSelection.sizeOfSelect = 3;
113 info.creationPCRSelection.pcrSelect = (void*)&dst->pcr_selection;
114 info.releasePCRSelection.sizeOfSelect = 3;
115 info.releasePCRSelection.pcrSelect = (void*)&dst->pcr_selection;
116 memcpy(&info.digestAtCreation, &dst->digest_at_seal, 20);
117 memcpy(&info.digestAtRelease, &dst->digest_release, 20);
118
119 infoSize = 2 + 1 + 1 + 2 + 3 + 2 + 3 + 20 + 20;
120 //infoSize = sizeof_TPM_PCR_INFO_LONG(&info);
121
122 rc = TPM_Seal(TPM_SRK_KEYHANDLE, infoSize, &info, size, src, &out,
123 (void*)&sharedsecret, (void*)&auth, &osap);
124
125 TPM_TerminateHandle(osap.AuthHandle);
126
127 #ifdef DEBUG_SEAL_OPS
128 printk("TPM_Seal rc=%d encDataSize=%d sealInfoSize=%d\n", rc, out.encDataSize, out.sealInfoLongSize);
129 #endif
130 if (!rc)
131 memcpy(dst->sealed_data, out.encData, 256);
132
133 #ifdef DEBUG_SEAL_OPS
134 uint8_t buf[512];
135 uint8_t *start = buf;
136 uint8_t *end = pack_TPM_STORED_DATA12(buf, &out);
137 printk("stored_data:");
138 while (start != end) {
139 printk(" %02x", *start);
140 start++;
141 }
142 printk("\n");
143 #endif
144
145 free_TPM_STORED_DATA12(&out);
146 return rc;
147 }
148
TPM2_disk_bind(struct disk_seal_entry * dst,void * src,unsigned int size)149 TPM_RC TPM2_disk_bind(struct disk_seal_entry *dst, void* src, unsigned int size)
150 {
151 TPM_RESULT status = TPM_SUCCESS;
152
153 TPMTRYRETURN(TPM2_Bind(vtpm_globals.sk_handle,
154 src,
155 size,
156 dst->sealed_data));
157
158 abort_egress:
159 egress:
160 return status;
161 }
162
TPM2_disk_unbind(void * dst,unsigned int * size,const struct disk_seal_entry * src)163 TPM_RC TPM2_disk_unbind(void *dst, unsigned int *size, const struct disk_seal_entry *src)
164 {
165 TPM_RESULT status = TPM_SUCCESS;
166 unsigned char buf[RSA_CIPHER_SIZE];
167
168 memcpy(buf, src->sealed_data, RSA_CIPHER_SIZE);
169 TPMTRYRETURN(TPM2_UnBind(vtpm_globals.sk_handle,
170 RSA_CIPHER_SIZE,
171 buf,
172 size,
173 dst));
174 abort_egress:
175 egress:
176 return status;
177 }
178
TPM_disk_unseal(void * dst,size_t size,const struct disk_seal_entry * src)179 int TPM_disk_unseal(void *dst, size_t size, const struct disk_seal_entry *src)
180 {
181 uint32_t rc;
182 TPM_STORED_DATA12 in;
183 TPM_AUTH_SESSION oiap = TPM_AUTH_SESSION_INIT;
184 TPM_AUTHDATA auth;
185 uint32_t outSize = 0;
186 uint8_t *out = NULL;
187
188 printk("Calling TPM_disk_unseal\n");
189
190 rc = TPM_OIAP(&oiap);
191 if (rc) abort();
192
193 memset(auth, 0, 20);
194
195 in.tag = TPM_TAG_STORED_DATA12;
196 in.et = 0;
197 //in.sealInfoLongSize = sizeof_TPM_PCR_INFO_LONG(&in.sealInfoLong);
198 in.sealInfoLongSize = 2 + 1 + 1 + 2 + 3 + 2 + 3 + 20 + 20;
199 in.sealInfoLong.tag = TPM_TAG_PCR_INFO_LONG;
200 in.sealInfoLong.localityAtCreation = 1 << vtpm_globals.hw_locality;
201 in.sealInfoLong.localityAtRelease = 1 << vtpm_globals.hw_locality;
202 in.sealInfoLong.creationPCRSelection.sizeOfSelect = 3;
203 in.sealInfoLong.creationPCRSelection.pcrSelect = (void*)&src->pcr_selection;
204 in.sealInfoLong.releasePCRSelection.sizeOfSelect = 3;
205 in.sealInfoLong.releasePCRSelection.pcrSelect = (void*)&src->pcr_selection;
206 memcpy(&in.sealInfoLong.digestAtCreation, &src->digest_at_seal, 20);
207 memcpy(&in.sealInfoLong.digestAtRelease, &src->digest_release, 20);
208 in.encDataSize = 256;
209 in.encData = (void*)src->sealed_data;
210
211 #ifdef DEBUG_SEAL_OPS
212 uint8_t buf[512];
213 uint8_t *start = buf;
214 uint8_t *end = pack_TPM_STORED_DATA12(buf, &in);
215 printk("stored_data:");
216 while (start != end) {
217 printk(" %02x", *start);
218 start++;
219 }
220 printk("\n");
221 #endif
222
223 rc = TPM_Unseal(TPM_SRK_KEYHANDLE, &in, &outSize, &out,
224 (void*)&vtpm_globals.srk_auth, (void*)&auth, &vtpm_globals.oiap, &oiap);
225
226 TPM_TerminateHandle(oiap.AuthHandle);
227
228 #ifdef DEBUG_SEAL_OPS
229 printk("TPM_Unseal rc=%d outSize=%d size=%d\n", rc, outSize, size);
230 #endif
231 if (!rc) {
232 memcpy(dst, out, size);
233 #ifdef DEBUG_SEAL_OPS
234 printk("unsealed:");
235 int i;
236 for(i=0; i < size; i++)
237 printk(" %02x", ((uint8_t*)dst)[i]);
238 printk("\n");
239 #endif
240 }
241
242 free(out);
243
244 return rc;
245 }
246
TPM_disk_nvalloc(be32_t * nvram_slot,struct tpm_authdata auth)247 int TPM_disk_nvalloc(be32_t *nvram_slot, struct tpm_authdata auth)
248 {
249 // TODO-3
250 nvram_slot->value = 0;
251 return 0;
252 }
253
TPM_disk_nvread(void * buf,size_t bufsiz,be32_t nvram_slot,struct tpm_authdata auth)254 int TPM_disk_nvread(void *buf, size_t bufsiz, be32_t nvram_slot, struct tpm_authdata auth)
255 {
256 // TODO-3
257 memset(buf, 0, bufsiz);
258 return 0;
259 }
260
TPM_disk_nvwrite(void * buf,size_t bufsiz,be32_t nvram_slot,struct tpm_authdata auth)261 int TPM_disk_nvwrite(void *buf, size_t bufsiz, be32_t nvram_slot, struct tpm_authdata auth)
262 {
263 // TODO-3
264 return 0;
265 }
266
TPM_disk_nvchange(be32_t nvram_slot,struct tpm_authdata old,struct tpm_authdata noo)267 int TPM_disk_nvchange(be32_t nvram_slot, struct tpm_authdata old, struct tpm_authdata noo)
268 {
269 // TODO-3
270 return 0;
271 }
272
TPM_disk_alloc_counter(be32_t * slot,struct tpm_authdata auth,be32_t * value)273 int TPM_disk_alloc_counter(be32_t *slot, struct tpm_authdata auth, be32_t *value)
274 {
275 // TODO-3
276 slot->value = 0;
277 value->value = 0;
278 return 0;
279 }
280
TPM_disk_check_counter(be32_t slot,struct tpm_authdata auth,be32_t value)281 int TPM_disk_check_counter(be32_t slot, struct tpm_authdata auth, be32_t value)
282 {
283 // TODO-3
284 return 0;
285 }
286
TPM_disk_incr_counter(be32_t slot,struct tpm_authdata auth)287 int TPM_disk_incr_counter(be32_t slot, struct tpm_authdata auth)
288 {
289 // TODO-3
290 return 0;
291 }
292
TPM_disk_change_counter(be32_t slot,struct tpm_authdata old,struct tpm_authdata noo)293 int TPM_disk_change_counter(be32_t slot, struct tpm_authdata old, struct tpm_authdata noo)
294 {
295 // TODO-3
296 return 0;
297 }
298