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