1 /* Copyright 2016 The ChromiumOS Authors
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #include "2common.h"
7 #include "2sysincludes.h"
8 #include "tpm2_marshaling.h"
9
10 static uint16_t tpm_tag; /* Depends on the command type. */
11 static int ph_disabled; /* Platform hierarchy disabled. */
12
write_be16(void * dest,uint16_t val)13 static void write_be16(void *dest, uint16_t val)
14 {
15 uint8_t *byte_dest = dest;
16
17 byte_dest[0] = val >> 8;
18 byte_dest[1] = val;
19 }
20
write_be32(void * dest,uint32_t val)21 static void write_be32(void *dest, uint32_t val)
22 {
23 uint8_t *byte_dest = dest;
24
25 byte_dest[0] = val >> 24;
26 byte_dest[1] = val >> 16;
27 byte_dest[2] = val >> 8;
28 byte_dest[3] = val;
29 }
30
read_be16(const void * src)31 static uint16_t read_be16(const void *src)
32 {
33 const uint8_t *s = src;
34 return (((uint16_t)s[0]) << 8) | (((uint16_t)s[1]) << 0);
35 }
36
read_be32(const void * src)37 static inline uint32_t read_be32(const void *src)
38 {
39 const uint8_t *s = src;
40
41 return (((uint32_t)s[0]) << 24) | (((uint32_t)s[1]) << 16) |
42 (((uint32_t)s[2]) << 8) | (((uint32_t)s[3]) << 0);
43 }
44
45 /*
46 * Each unmarshaling function receives a pointer to the buffer pointer and a
47 * pointer to the size of data still in the buffer. The function extracts data
48 * from the buffer and adjusts both buffer pointer and remaining data size.
49 *
50 * Should there be not enough data in the buffer to unmarshal the required
51 * object, the remaining data size is set to -1 to indicate the error. The
52 * remaining data size is expected to be set to zero once the last data item
53 * has been extracted from the buffer.
54 */
55
unmarshal_u8(void ** buffer,int * buffer_space)56 static uint8_t unmarshal_u8(void **buffer, int *buffer_space)
57 {
58 uint8_t value;
59
60 if (*buffer_space < sizeof(value)) {
61 *buffer_space = -1; /* Indicate a failure. */
62 return 0;
63 }
64
65 value = *(uint8_t *)(*buffer);
66 *buffer = (void *) ((uintptr_t) (*buffer) + sizeof(value));
67 *buffer_space -= sizeof(value);
68
69 return value;
70 }
71
unmarshal_u16(void ** buffer,int * buffer_space)72 static uint16_t unmarshal_u16(void **buffer, int *buffer_space)
73 {
74 uint16_t value;
75
76 if (*buffer_space < sizeof(value)) {
77 *buffer_space = -1; /* Indicate a failure. */
78 return 0;
79 }
80
81 value = read_be16(*buffer);
82 *buffer = (void *) ((uintptr_t) (*buffer) + sizeof(value));
83 *buffer_space -= sizeof(value);
84
85 return value;
86 }
87
unmarshal_u32(void ** buffer,int * buffer_space)88 static uint32_t unmarshal_u32(void **buffer, int *buffer_space)
89 {
90 uint32_t value;
91
92 if (*buffer_space < sizeof(value)) {
93 *buffer_space = -1; /* Indicate a failure. */
94 return 0;
95 }
96
97 value = read_be32(*buffer);
98 *buffer = (void *) ((uintptr_t) (*buffer) + sizeof(value));
99 *buffer_space -= sizeof(value);
100
101 return value;
102 }
103
104 #define unmarshal_TPM_HANDLE(a, b) unmarshal_u32(a, b)
105 #define unmarshal_ALG_ID(a, b) unmarshal_u16(a, b)
106
unmarshal_TPM2B(void ** buffer,int * size,TPM2B * tpm2b)107 static void unmarshal_TPM2B(void **buffer, int *size, TPM2B *tpm2b)
108 {
109 tpm2b->size = unmarshal_u16(buffer, size);
110 if (tpm2b->size > *size) {
111 VB2_DEBUG("size mismatch: expected %d, remaining %d\n", tpm2b->size, *size);
112 tpm2b->buffer = NULL;
113 tpm2b->size = 0;
114 *buffer = NULL;
115 *size = -1;
116 return;
117 }
118
119 tpm2b->buffer = *buffer;
120
121 *buffer = ((uint8_t *)(*buffer)) + tpm2b->size;
122 *size -= tpm2b->size;
123 }
124
unmarshal_authorization_section(void ** buffer,int * size,const char * cmd_name)125 static void unmarshal_authorization_section(void **buffer, int *size,
126 const char *cmd_name)
127 {
128 /*
129 * Let's ignore the authorisation section. It should be 5 bytes total,
130 * just confirm that this is the case and report any discrepancy.
131 */
132 if (*size != 5)
133 VB2_DEBUG("unexpected authorisation section size %d for %s\n",
134 *size, cmd_name);
135
136 *buffer = ((uint8_t *)(*buffer)) + *size;
137 *size = 0;
138 }
139
unmarshal_nv_read(void ** buffer,int * size,struct nv_read_response * nvr)140 static void unmarshal_nv_read(void **buffer, int *size,
141 struct nv_read_response *nvr)
142 {
143 /* Total size of the parameter field. */
144 nvr->params_size = unmarshal_u32(buffer, size);
145 unmarshal_TPM2B(buffer, size, &nvr->buffer);
146
147 if (nvr->params_size != (nvr->buffer.size + sizeof(nvr->buffer.size))) {
148 VB2_DEBUG("parameter/buffer %d/%d size mismatch", nvr->params_size,
149 nvr->buffer.size);
150 return;
151 }
152
153 if (*size < 0)
154 return;
155
156 unmarshal_authorization_section(buffer, size, "NV_Read");
157 }
158
unmarshal_read_public(void ** buffer,int * size,struct read_public_response * rpr)159 static void unmarshal_read_public(void **buffer, int *size,
160 struct read_public_response *rpr)
161 {
162 unmarshal_TPM2B(buffer, size, &rpr->buffer);
163
164 if (*size < 0)
165 return;
166
167 /* Drain the name & authorization sections. */
168 *buffer = ((uint8_t *)(*buffer)) + *size;
169 *size = 0;
170 }
171
unmarshal_TPMS_NV_PUBLIC(void ** buffer,int * size,TPMS_NV_PUBLIC * pub)172 static void unmarshal_TPMS_NV_PUBLIC(void **buffer,
173 int *size,
174 TPMS_NV_PUBLIC *pub)
175 {
176 int tpm2b_size = unmarshal_u16(buffer, size);
177 if (tpm2b_size > *size) {
178 VB2_DEBUG("size mismatch: expected %d, remaining %d\n",
179 tpm2b_size, *size);
180 *size = -1;
181 return;
182 }
183 *size -= tpm2b_size;
184
185 pub->nvIndex = unmarshal_TPM_HANDLE(buffer, &tpm2b_size);
186 pub->nameAlg = unmarshal_ALG_ID(buffer, &tpm2b_size);
187 pub->attributes = unmarshal_u32(buffer, &tpm2b_size);
188 unmarshal_TPM2B(buffer, &tpm2b_size, &pub->authPolicy);
189 pub->dataSize = unmarshal_u16(buffer, &tpm2b_size);
190
191 if (tpm2b_size != 0) {
192 VB2_DEBUG("TPMS_NV_PUBLIC size doesn't match size field\n");
193 *size = -1;
194 return;
195 }
196 }
197
unmarshal_nv_read_public(void ** buffer,int * size,struct nv_read_public_response * nv_pub)198 static void unmarshal_nv_read_public(void **buffer, int *size,
199 struct nv_read_public_response *nv_pub)
200 {
201 unmarshal_TPMS_NV_PUBLIC(buffer, size, &nv_pub->nvPublic);
202 unmarshal_TPM2B(buffer, size, &nv_pub->nvName);
203
204 if (*size > 0) {
205 VB2_DEBUG("extra %d bytes after nvName\n", *size);
206 *size = -1;
207 return;
208 }
209 }
210
unmarshal_TPML_TAGGED_TPM_PROPERTY(void ** buffer,int * size,TPML_TAGGED_TPM_PROPERTY * prop)211 static void unmarshal_TPML_TAGGED_TPM_PROPERTY(void **buffer, int *size,
212 TPML_TAGGED_TPM_PROPERTY *prop)
213 {
214 prop->count = unmarshal_u32(buffer, size);
215
216 if (prop->count != 1) {
217 *size = -1;
218 VB2_DEBUG("Request to unmarshal unsupported "
219 "number of properties: %u\n",
220 prop->count);
221 return;
222 }
223
224 prop->tpm_property[0].property = unmarshal_u32(buffer, size);
225 prop->tpm_property[0].value = unmarshal_u32(buffer, size);
226 }
227
unmarshal_TPMS_CAPABILITY_DATA(void ** buffer,int * size,TPMS_CAPABILITY_DATA * cap_data)228 static void unmarshal_TPMS_CAPABILITY_DATA(void **buffer, int *size,
229 TPMS_CAPABILITY_DATA *cap_data)
230 {
231 cap_data->capability = unmarshal_u32(buffer, size);
232
233 switch (cap_data->capability) {
234
235 case TPM_CAP_TPM_PROPERTIES:
236 unmarshal_TPML_TAGGED_TPM_PROPERTY(buffer, size,
237 &cap_data->data.
238 tpm_properties);
239 break;
240
241 default:
242 *size = -1;
243 VB2_DEBUG("Request to unmarshal unsupported capability %#x\n",
244 cap_data->capability);
245 }
246 }
247
unmarshal_get_capability(void ** buffer,int * size,struct get_capability_response * cap)248 static void unmarshal_get_capability(void **buffer, int *size,
249 struct get_capability_response *cap)
250 {
251 /* Total size of the parameter field. */
252 cap->more_data = unmarshal_u8(buffer, size);
253 unmarshal_TPMS_CAPABILITY_DATA(buffer, size, &cap->capability_data);
254 }
255
unmarshal_get_random(void ** buffer,int * size,struct get_random_response * random)256 static void unmarshal_get_random(void **buffer, int *size,
257 struct get_random_response *random)
258 {
259 unmarshal_TPM2B(buffer, size, &random->random_bytes);
260 }
261
unmarshal_create_primary(void ** buffer,int * size,struct create_primary_response * resp)262 static void unmarshal_create_primary(void **buffer, int *size,
263 struct create_primary_response *resp)
264 {
265 resp->object_handle = unmarshal_TPM_HANDLE(buffer, size);
266
267 /* Drain the remaining sections. */
268 *buffer = ((uint8_t *)(*buffer)) + *size;
269 *size = 0;
270 }
271
272 /*
273 * Each marshaling function receives a pointer to the buffer to marshal into,
274 * a pointer to the data item to be marshaled, and a pointer to the remaining
275 * room in the buffer.
276 */
277
278 /*
279 * Marshaling an arbitrary blob requires its size in addition to common
280 * parameter set.
281 */
marshal_blob(void ** buffer,void * blob,size_t blob_size,int * buffer_space)282 static void marshal_blob(void **buffer, void *blob,
283 size_t blob_size, int *buffer_space)
284 {
285 if (*buffer_space < blob_size) {
286 *buffer_space = -1;
287 return;
288 }
289
290 memcpy(*buffer, blob, blob_size);
291 *buffer_space -= blob_size;
292 *buffer = (void *)((uintptr_t)(*buffer) + blob_size);
293 }
294
marshal_u8(void ** buffer,uint8_t value,int * buffer_space)295 static void marshal_u8(void **buffer, uint8_t value, int *buffer_space)
296 {
297 uint8_t *bp = *buffer;
298
299 if (*buffer_space < sizeof(value)) {
300 *buffer_space = -1;
301 return;
302 }
303
304 *bp++ = value;
305 *buffer = bp;
306 *buffer_space -= sizeof(value);
307 }
308
marshal_u16(void ** buffer,uint16_t value,int * buffer_space)309 static void marshal_u16(void **buffer, uint16_t value, int *buffer_space)
310 {
311 if (*buffer_space < sizeof(value)) {
312 *buffer_space = -1;
313 return;
314 }
315 write_be16(*buffer, value);
316 *buffer = (void *)((uintptr_t)(*buffer) + sizeof(value));
317 *buffer_space -= sizeof(value);
318 }
319
marshal_u32(void ** buffer,uint32_t value,int * buffer_space)320 static void marshal_u32(void **buffer, uint32_t value, int *buffer_space)
321 {
322 if (*buffer_space < sizeof(value)) {
323 *buffer_space = -1;
324 return;
325 }
326
327 write_be32(*buffer, value);
328 *buffer = (void *)((uintptr_t)(*buffer) + sizeof(value));
329 *buffer_space -= sizeof(value);
330 }
331
332 #define marshal_TPM_HANDLE(a, b, c) marshal_u32(a, b, c)
333 #define marshal_TPM_SU(a, b, c) marshal_u16(a, b, c)
334 #define marshal_ALG_ID(a, b, c) marshal_u16(a, b, c)
335 #define marshal_TPMI_ALG_HASH(a, b, c) marshal_u16(a, b, c)
336
337 /*
338 * For TPM2B* structures the size field (16 or 32 bits) goes before the data.
339 * When marshaling, we first reserve the space for the size field, then
340 * marshal the data, then fill the reserved size field with the actual size
341 * of the marshaled data.
342 */
343 typedef struct {
344 int size;
345 void *location;
346 } tpm2_marshal_size_field;
347
marshal_reserve_size_field(void ** buffer,tpm2_marshal_size_field * field,int field_size,int * buffer_space)348 static void marshal_reserve_size_field(void **buffer,
349 tpm2_marshal_size_field *field,
350 int field_size,
351 int *buffer_space)
352 {
353 if (field_size != sizeof(uint32_t) && field_size != sizeof(uint16_t)) {
354 VB2_DEBUG("Unsupported size field size: %d\n", field_size);
355 *buffer_space = -1;
356 return;
357 }
358 if (*buffer_space < field_size) {
359 *buffer_space = -1;
360 return;
361 }
362 field->size = field_size;
363 field->location = *buffer;
364 *buffer_space -= field_size;
365 *buffer = (void *)(((uintptr_t) *buffer) + field_size);
366 }
367
marshal_fill_size_field(void ** buffer,tpm2_marshal_size_field * field,int include_size_field,int * buffer_space)368 static void marshal_fill_size_field(void **buffer,
369 tpm2_marshal_size_field *field,
370 int include_size_field,
371 int *buffer_space)
372 {
373 uintptr_t size = (uintptr_t) *buffer - (uintptr_t) field->location;
374
375 if (*buffer_space < 0)
376 return; /* The structure did not fit. */
377
378 if (!include_size_field)
379 size -= field->size;
380 if (field->size == sizeof(uint32_t))
381 marshal_u32(&field->location, size, &field->size);
382 else /* if (field->size == sizeof(uint16_t)) */
383 marshal_u16(&field->location, size, &field->size);
384 }
385
marshal_session_header(void ** buffer,struct tpm2_session_header * session_header,int * buffer_space)386 static void marshal_session_header(void **buffer,
387 struct tpm2_session_header *session_header,
388 int *buffer_space)
389 {
390 tpm2_marshal_size_field size_field;
391
392 /* Skip room for the session header size. */
393 marshal_reserve_size_field(buffer, &size_field,
394 sizeof(uint32_t), buffer_space);
395
396 marshal_u32(buffer, session_header->session_handle, buffer_space);
397 marshal_u16(buffer, session_header->nonce_size, buffer_space);
398 marshal_blob(buffer, session_header->nonce,
399 session_header->nonce_size, buffer_space);
400 marshal_u8(buffer, session_header->session_attrs, buffer_space);
401 marshal_u16(buffer, session_header->auth_size, buffer_space);
402 marshal_blob(buffer, session_header->auth,
403 session_header->auth_size, buffer_space);
404
405 /* Paste in the session size. */
406 marshal_fill_size_field(buffer, &size_field, 0, buffer_space);
407 }
408
marshal_TPM2B(void ** buffer,TPM2B * data,int * buffer_space)409 static void marshal_TPM2B(void **buffer,
410 TPM2B *data,
411 int *buffer_space)
412 {
413 size_t total_size = data->size + sizeof(data->size);
414
415 if (total_size > *buffer_space) {
416 *buffer_space = -1;
417 return;
418 }
419 marshal_u16(buffer, data->size, buffer_space);
420 memcpy(*buffer, data->buffer, data->size);
421 *buffer = ((uint8_t *)(*buffer)) + data->size;
422 *buffer_space -= data->size;
423 }
424
marshal_TPMS_NV_PUBLIC(void ** buffer,TPMS_NV_PUBLIC * data,int * buffer_space)425 static void marshal_TPMS_NV_PUBLIC(void **buffer,
426 TPMS_NV_PUBLIC *data,
427 int *buffer_space)
428 {
429 tpm2_marshal_size_field size_field;
430
431 /* Skip room for the size. */
432 marshal_reserve_size_field(buffer, &size_field,
433 sizeof(uint16_t), buffer_space);
434
435 marshal_TPM_HANDLE(buffer, data->nvIndex, buffer_space);
436 marshal_ALG_ID(buffer, data->nameAlg, buffer_space);
437 marshal_u32(buffer, data->attributes, buffer_space);
438 marshal_TPM2B(buffer, &data->authPolicy, buffer_space);
439 marshal_u16(buffer, data->dataSize, buffer_space);
440
441 /* Paste in the structure size. */
442 marshal_fill_size_field(buffer, &size_field, 0, buffer_space);
443 }
444
marshal_nv_define_space(void ** buffer,struct tpm2_nv_define_space_cmd * command_body,int * buffer_space)445 static void marshal_nv_define_space(void **buffer,
446 struct tpm2_nv_define_space_cmd
447 *command_body,
448 int *buffer_space)
449 {
450 struct tpm2_session_header session_header;
451
452 /* Use platform authorization if PLATFORMCREATE is set, and owner
453 * authorization otherwise (per TPM2 Spec. Part 2. Section 31.3.1).
454 * Owner authorization with empty password will work only until
455 * ownership is taken. Platform authorization will work only until
456 * platform hierarchy is disabled (i.e. in firmware or in recovery
457 * mode).
458 */
459 if (command_body->publicInfo.attributes & TPMA_NV_PLATFORMCREATE)
460 marshal_TPM_HANDLE(buffer, TPM_RH_PLATFORM, buffer_space);
461 else
462 marshal_TPM_HANDLE(buffer, TPM_RH_OWNER, buffer_space);
463
464 memset(&session_header, 0, sizeof(session_header));
465 session_header.session_handle = TPM_RS_PW;
466 marshal_session_header(buffer, &session_header, buffer_space);
467 tpm_tag = TPM_ST_SESSIONS;
468
469 marshal_TPM2B(buffer, &command_body->auth, buffer_space);
470 marshal_TPMS_NV_PUBLIC(buffer, &command_body->publicInfo, buffer_space);
471 }
472
marshal_nv_undefine_space(void ** buffer,struct tpm2_nv_undefine_space_cmd * command_body,int * buffer_space)473 static void marshal_nv_undefine_space(void **buffer,
474 struct tpm2_nv_undefine_space_cmd
475 *command_body,
476 int *buffer_space)
477 {
478 struct tpm2_session_header session_header;
479
480 /* Use platform authorization if PLATFORMCREATE is set, and owner
481 * authorization otherwise (per TPM2 Spec. Part 2. Section 31.3.1).
482 * Owner authorization with empty password will work only until
483 * ownership is taken. Platform authorization will work only until
484 * platform hierarchy is disabled (i.e. in firmware or in recovery
485 * mode).
486 */
487 if (command_body->use_platform_auth)
488 marshal_TPM_HANDLE(buffer, TPM_RH_PLATFORM, buffer_space);
489 else
490 marshal_TPM_HANDLE(buffer, TPM_RH_OWNER, buffer_space);
491 marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
492
493 memset(&session_header, 0, sizeof(session_header));
494 session_header.session_handle = TPM_RS_PW;
495 marshal_session_header(buffer, &session_header, buffer_space);
496 tpm_tag = TPM_ST_SESSIONS;
497 }
498
499 /* Determine which authorization should be used when writing or write-locking
500 * an NV index.
501 *
502 * Use a simplified approach:
503 * 1) Use platform auth for indexes defined by TPM and Platform, as
504 * specified in "Registry of reserved TPM 2.0 handles and localities".
505 * That will only work for indexes with PPWRITE, and until the platform
506 * hierarchy is disabled.
507 * 2) Use empty password auth for other indexes.
508 * That will only work for indexes with AUTHWRITE and empty auth value.
509 *
510 * A more honest approach would require the caller to specify the
511 * authorization, or would check the NV index attributes.
512 * But that's not needed now, as all indexes defined by firmware are
513 * in the TPM range and have PPWRITE. The indexes defined by the
514 * OS are in the Owner range and have either OWNERWRITE or AUTHWRITE,
515 * but we don't ever use Tlcl to write to OWNERWRITE indexes.
516 */
get_nv_index_write_auth(TPMI_RH_NV_INDEX nvIndex)517 static TPM_HANDLE get_nv_index_write_auth(TPMI_RH_NV_INDEX nvIndex)
518 {
519 return nvIndex >= TPMI_RH_NV_INDEX_OWNER_START ?
520 nvIndex :
521 TPM_RH_PLATFORM;
522 }
523
marshal_nv_write(void ** buffer,struct tpm2_nv_write_cmd * command_body,int * buffer_space)524 static void marshal_nv_write(void **buffer,
525 struct tpm2_nv_write_cmd *command_body,
526 int *buffer_space)
527 {
528 struct tpm2_session_header session_header;
529
530 marshal_TPM_HANDLE(buffer,
531 get_nv_index_write_auth(command_body->nvIndex),
532 buffer_space);
533 marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
534 memset(&session_header, 0, sizeof(session_header));
535 session_header.session_handle = TPM_RS_PW;
536 marshal_session_header(buffer, &session_header, buffer_space);
537 tpm_tag = TPM_ST_SESSIONS;
538
539 marshal_TPM2B(buffer, &command_body->data, buffer_space);
540 marshal_u16(buffer, command_body->offset, buffer_space);
541 }
542
marshal_nv_read(void ** buffer,struct tpm2_nv_read_cmd * command_body,int * buffer_space)543 static void marshal_nv_read(void **buffer,
544 struct tpm2_nv_read_cmd *command_body,
545 int *buffer_space)
546 {
547 struct tpm2_session_header session_header;
548
549 /* Use empty password auth if platform hierarchy is disabled */
550 if (ph_disabled)
551 marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
552 else
553 marshal_TPM_HANDLE(buffer, TPM_RH_PLATFORM, buffer_space);
554 marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
555 memset(&session_header, 0, sizeof(session_header));
556 session_header.session_handle = TPM_RS_PW;
557 marshal_session_header(buffer, &session_header, buffer_space);
558 tpm_tag = TPM_ST_SESSIONS;
559 marshal_u16(buffer, command_body->size, buffer_space);
560 marshal_u16(buffer, command_body->offset, buffer_space);
561 }
562
marshal_nv_read_lock(void ** buffer,struct tpm2_nv_read_lock_cmd * command_body,int * buffer_space)563 static void marshal_nv_read_lock(void **buffer,
564 struct tpm2_nv_read_lock_cmd *command_body,
565 int *buffer_space)
566 {
567 struct tpm2_session_header session_header;
568
569 tpm_tag = TPM_ST_SESSIONS;
570 marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
571 marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
572 memset(&session_header, 0, sizeof(session_header));
573 session_header.session_handle = TPM_RS_PW;
574 marshal_session_header(buffer, &session_header, buffer_space);
575 }
576
marshal_nv_write_lock(void ** buffer,struct tpm2_nv_write_lock_cmd * command_body,int * buffer_space)577 static void marshal_nv_write_lock(void **buffer,
578 struct tpm2_nv_write_lock_cmd *command_body,
579 int *buffer_space)
580 {
581 struct tpm2_session_header session_header;
582
583 tpm_tag = TPM_ST_SESSIONS;
584 marshal_TPM_HANDLE(buffer,
585 get_nv_index_write_auth(command_body->nvIndex),
586 buffer_space);
587 marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
588 memset(&session_header, 0, sizeof(session_header));
589 session_header.session_handle = TPM_RS_PW;
590 marshal_session_header(buffer, &session_header, buffer_space);
591 }
592
marshal_nv_read_public(void ** buffer,struct tpm2_nv_read_public_cmd * command_body,int * buffer_space)593 static void marshal_nv_read_public(void **buffer,
594 struct tpm2_nv_read_public_cmd *command_body,
595 int *buffer_space)
596 {
597 tpm_tag = TPM_ST_NO_SESSIONS;
598
599 marshal_TPM_HANDLE(buffer, command_body->nvIndex, buffer_space);
600 }
601
marshal_hierarchy_control(void ** buffer,struct tpm2_hierarchy_control_cmd * command_body,int * buffer_space)602 static void marshal_hierarchy_control(void **buffer,
603 struct tpm2_hierarchy_control_cmd
604 *command_body,
605 int *buffer_space)
606 {
607 struct tpm2_session_header session_header;
608
609 tpm_tag = TPM_ST_SESSIONS;
610 marshal_TPM_HANDLE(buffer, TPM_RH_PLATFORM, buffer_space);
611 memset(&session_header, 0, sizeof(session_header));
612 session_header.session_handle = TPM_RS_PW;
613 marshal_session_header(buffer, &session_header, buffer_space);
614
615 marshal_TPM_HANDLE(buffer, command_body->enable, buffer_space);
616 marshal_u8(buffer, command_body->state, buffer_space);
617 }
618
marshal_read_public(void ** buffer,struct tpm2_read_public_cmd * command_body,int * buffer_space)619 static void marshal_read_public(void **buffer,
620 struct tpm2_read_public_cmd *command_body,
621 int *buffer_space)
622 {
623 marshal_u32(buffer, command_body->object_handle, buffer_space);
624 }
625
marshal_get_capability(void ** buffer,struct tpm2_get_capability_cmd * command_body,int * buffer_space)626 static void marshal_get_capability(void **buffer,
627 struct tpm2_get_capability_cmd
628 *command_body,
629 int *buffer_space)
630 {
631 tpm_tag = TPM_ST_NO_SESSIONS;
632
633 marshal_u32(buffer, command_body->capability, buffer_space);
634 marshal_u32(buffer, command_body->property, buffer_space);
635 marshal_u32(buffer, command_body->property_count, buffer_space);
636 }
637
marshal_get_random(void ** buffer,struct tpm2_get_random_cmd * command_body,int * buffer_space)638 static void marshal_get_random(void **buffer, struct tpm2_get_random_cmd
639 *command_body,
640 int *buffer_space)
641 {
642 tpm_tag = TPM_ST_NO_SESSIONS;
643
644 marshal_u16(buffer, command_body->bytes_requested, buffer_space);
645 }
646
marshal_clear(void ** buffer,void * command_body,int * buffer_space)647 static void marshal_clear(void **buffer,
648 void *command_body,
649 int *buffer_space)
650 {
651 struct tpm2_session_header session_header;
652
653 tpm_tag = TPM_ST_SESSIONS;
654 marshal_TPM_HANDLE(buffer, TPM_RH_PLATFORM, buffer_space);
655 memset(&session_header, 0, sizeof(session_header));
656 session_header.session_handle = TPM_RS_PW;
657 marshal_session_header(buffer, &session_header, buffer_space);
658 }
659
marshal_self_test(void ** buffer,struct tpm2_self_test_cmd * command_body,int * buffer_space)660 static void marshal_self_test(void **buffer,
661 struct tpm2_self_test_cmd *command_body,
662 int *buffer_space)
663 {
664 tpm_tag = TPM_ST_NO_SESSIONS;
665
666 marshal_u8(buffer, command_body->full_test, buffer_space);
667 }
668
marshal_startup(void ** buffer,struct tpm2_startup_cmd * command_body,int * buffer_space)669 static void marshal_startup(void **buffer,
670 struct tpm2_startup_cmd *command_body,
671 int *buffer_space)
672 {
673 tpm_tag = TPM_ST_NO_SESSIONS;
674
675 marshal_TPM_SU(buffer, command_body->startup_type, buffer_space);
676 }
677
marshal_shutdown(void ** buffer,struct tpm2_shutdown_cmd * command_body,int * buffer_space)678 static void marshal_shutdown(void **buffer,
679 struct tpm2_shutdown_cmd *command_body,
680 int *buffer_space)
681 {
682 tpm_tag = TPM_ST_NO_SESSIONS;
683
684 marshal_TPM_SU(buffer, command_body->shutdown_type, buffer_space);
685 }
686
marshal_evict_control(void ** buffer,struct tpm2_evict_control_cmd * command_body,int * buffer_space)687 static void marshal_evict_control(void **buffer,
688 struct tpm2_evict_control_cmd *command_body,
689 int *buffer_space)
690 {
691 struct tpm2_session_header session_header;
692
693 marshal_TPM_HANDLE(buffer, command_body->auth, buffer_space);
694 marshal_TPM_HANDLE(buffer, command_body->object_handle, buffer_space);
695
696 memset(&session_header, 0, sizeof(session_header));
697 session_header.session_handle = TPM_RS_PW;
698 marshal_session_header(buffer, &session_header, buffer_space);
699 tpm_tag = TPM_ST_SESSIONS;
700
701 marshal_TPM_HANDLE(buffer, command_body->persistent_handle,
702 buffer_space);
703 }
704
marshal_create_primary(void ** buffer,struct tpm2_create_primary_cmd * command_body,int * buffer_space)705 static void marshal_create_primary(void **buffer,
706 struct tpm2_create_primary_cmd *command_body,
707 int *buffer_space)
708 {
709 struct tpm2_session_header session_header;
710
711 marshal_TPM_HANDLE(buffer, command_body->primary_handle, buffer_space);
712
713 memset(&session_header, 0, sizeof(session_header));
714 session_header.session_handle = TPM_RS_PW;
715 marshal_session_header(buffer, &session_header, buffer_space);
716 tpm_tag = TPM_ST_SESSIONS;
717
718 marshal_TPM2B(buffer, &command_body->in_sensitive, buffer_space);
719 marshal_TPM2B(buffer, &command_body->in_public, buffer_space);
720 // Empty outsideInfo.
721 marshal_u16(buffer, 0, buffer_space);
722 // Empty creationPCR.
723 marshal_u32(buffer, 0, buffer_space);
724 }
725
marshal_TPMT_HA(void ** buffer,TPMT_HA * data,int * buffer_space)726 static void marshal_TPMT_HA(void **buffer,
727 TPMT_HA *data,
728 int *buffer_space)
729 {
730 if (data->hashAlg != TPM_ALG_SHA256)
731 {
732 VB2_DEBUG("Unsupported TPMT_HA hash algorithm: %#x\n",
733 data->hashAlg);
734 *buffer_space = -1;
735 return;
736 }
737 marshal_TPMI_ALG_HASH(buffer, data->hashAlg, buffer_space);
738 /* We only support SHA256 now. */
739 marshal_blob(buffer, data->digest.sha256,
740 SHA256_DIGEST_SIZE, buffer_space);
741 }
742
marshal_TPML_DIGEST_VALUES(void ** buffer,TPML_DIGEST_VALUES * data,int * buffer_space)743 static void marshal_TPML_DIGEST_VALUES(void **buffer,
744 TPML_DIGEST_VALUES *data,
745 int *buffer_space)
746 {
747 int i;
748
749 marshal_u32(buffer, data->count, buffer_space);
750 for (i = 0; i < data->count; i++)
751 marshal_TPMT_HA(buffer, &data->digests[i], buffer_space);
752 }
753
marshal_pcr_extend(void ** buffer,struct tpm2_pcr_extend_cmd * command_body,int * buffer_space)754 static void marshal_pcr_extend(void **buffer,
755 struct tpm2_pcr_extend_cmd *command_body,
756 int *buffer_space)
757 {
758 struct tpm2_session_header session_header;
759
760 tpm_tag = TPM_ST_SESSIONS;
761 marshal_TPM_HANDLE(buffer, command_body->pcrHandle, buffer_space);
762 memset(&session_header, 0, sizeof(session_header));
763 session_header.session_handle = TPM_RS_PW;
764 marshal_session_header(buffer, &session_header, buffer_space);
765 marshal_TPML_DIGEST_VALUES(buffer, &command_body->digests, buffer_space);
766 }
767
tpm_marshal_command(TPM_CC command,void * tpm_command_body,void * buffer,int buffer_size)768 int tpm_marshal_command(TPM_CC command, void *tpm_command_body,
769 void *buffer, int buffer_size)
770 {
771 void *cmd_body = (uint8_t *)buffer + sizeof(struct tpm_header);
772 int max_body_size = buffer_size - sizeof(struct tpm_header);
773 int body_size = max_body_size;
774
775 /* Will be modified when marshaling some commands. */
776 tpm_tag = TPM_ST_NO_SESSIONS;
777
778 switch (command) {
779
780 case TPM2_NV_DefineSpace:
781 marshal_nv_define_space(&cmd_body, tpm_command_body, &body_size);
782 break;
783
784 case TPM2_NV_UndefineSpace:
785 marshal_nv_undefine_space(&cmd_body, tpm_command_body, &body_size);
786 break;
787
788 case TPM2_NV_Read:
789 marshal_nv_read(&cmd_body, tpm_command_body, &body_size);
790 break;
791
792 case TPM2_NV_Write:
793 marshal_nv_write(&cmd_body, tpm_command_body, &body_size);
794 break;
795
796 case TPM2_NV_ReadLock:
797 marshal_nv_read_lock(&cmd_body, tpm_command_body, &body_size);
798 break;
799
800 case TPM2_NV_WriteLock:
801 marshal_nv_write_lock(&cmd_body, tpm_command_body, &body_size);
802 break;
803
804 case TPM2_NV_ReadPublic:
805 marshal_nv_read_public(&cmd_body, tpm_command_body, &body_size);
806 break;
807
808 case TPM2_Hierarchy_Control:
809 marshal_hierarchy_control(&cmd_body,
810 tpm_command_body, &body_size);
811 break;
812
813 case TPM2_GetCapability:
814 marshal_get_capability(&cmd_body, tpm_command_body, &body_size);
815 break;
816
817 case TPM2_GetRandom:
818 marshal_get_random(&cmd_body, tpm_command_body, &body_size);
819 break;
820
821 case TPM2_Clear:
822 marshal_clear(&cmd_body, tpm_command_body, &body_size);
823 break;
824
825 case TPM2_SelfTest:
826 marshal_self_test(&cmd_body, tpm_command_body, &body_size);
827 break;
828
829 case TPM2_Startup:
830 marshal_startup(&cmd_body, tpm_command_body, &body_size);
831 break;
832
833 case TPM2_Shutdown:
834 marshal_shutdown(&cmd_body, tpm_command_body, &body_size);
835 break;
836
837 case TPM2_PCR_Extend:
838 marshal_pcr_extend(&cmd_body, tpm_command_body, &body_size);
839 break;
840
841 case TPM2_ReadPublic:
842 marshal_read_public(&cmd_body, tpm_command_body, &body_size);
843 break;
844
845 case TPM2_EvictControl:
846 marshal_evict_control(&cmd_body, tpm_command_body, &body_size);
847 break;
848
849 case TPM2_CreatePrimary:
850 marshal_create_primary(&cmd_body, tpm_command_body, &body_size);
851 break;
852
853 default:
854 body_size = -1;
855 VB2_DEBUG("Request to marshal unsupported command %#x\n",
856 command);
857 }
858
859 if (body_size > 0) {
860
861 /* See how much room was taken by marshaling. */
862 body_size = max_body_size - body_size;
863
864 body_size += sizeof(struct tpm_header);
865
866 marshal_u16(&buffer, tpm_tag, &max_body_size);
867 marshal_u32(&buffer, body_size, &max_body_size);
868 marshal_u32(&buffer, command, &max_body_size);
869 }
870
871 return body_size;
872 }
873
tpm_unmarshal_response(TPM_CC command,void * response_body,int cr_size,struct tpm2_response * response)874 int tpm_unmarshal_response(TPM_CC command,
875 void *response_body,
876 int cr_size,
877 struct tpm2_response *response)
878 {
879 if (cr_size < sizeof(struct tpm_header))
880 return -1;
881
882 response->hdr.tpm_tag = unmarshal_u16(&response_body, &cr_size);
883 response->hdr.tpm_size = unmarshal_u32(&response_body, &cr_size);
884 response->hdr.tpm_code = unmarshal_u32(&response_body, &cr_size);
885
886 if (!cr_size) {
887 if (response->hdr.tpm_size != sizeof(response->hdr))
888 VB2_DEBUG("size mismatch in response to command %#x\n",
889 command);
890 return 0;
891 }
892
893 switch (command) {
894 case TPM2_NV_Read:
895 unmarshal_nv_read(&response_body, &cr_size,
896 &response->nvr);
897 break;
898
899 case TPM2_NV_ReadPublic:
900 unmarshal_nv_read_public(&response_body, &cr_size,
901 &response->nv_read_public);
902 break;
903
904 case TPM2_GetCapability:
905 unmarshal_get_capability(&response_body, &cr_size,
906 &response->cap);
907 break;
908
909 case TPM2_GetRandom:
910 unmarshal_get_random(&response_body, &cr_size,
911 &response->random);
912 break;
913
914 case TPM2_ReadPublic:
915 unmarshal_read_public(&response_body, &cr_size,
916 &response->read_pub);
917 break;
918
919 case TPM2_CreatePrimary:
920 unmarshal_create_primary(&response_body, &cr_size,
921 &response->create_primary);
922 break;
923
924 case TPM2_Hierarchy_Control:
925 case TPM2_NV_Write:
926 case TPM2_NV_WriteLock:
927 case TPM2_NV_ReadLock:
928 case TPM2_Clear:
929 case TPM2_SelfTest:
930 case TPM2_Startup:
931 case TPM2_Shutdown:
932 case TPM2_NV_DefineSpace:
933 case TPM2_NV_UndefineSpace:
934 case TPM2_PCR_Extend:
935 case TPM2_EvictControl:
936 /* Session data included in response can be safely ignored. */
937 cr_size = 0;
938 break;
939
940 default:
941 {
942 int i;
943
944 VB2_DEBUG("Request to unmarshal unexpected command %#x,"
945 " code %#x",
946 command,
947 response->hdr.tpm_code);
948
949 for (i = 0; i < cr_size; i++) {
950 if (!(i % 16))
951 VB2_DEBUG_RAW("\n");
952 VB2_DEBUG_RAW("%2.2x ",
953 ((uint8_t *)response_body)[i]);
954 }
955 }
956 VB2_DEBUG("\n");
957 return -1;
958 }
959
960 if (cr_size) {
961 VB2_DEBUG("got %d bytes back in response to %#x,"
962 " failed to parse (%d)\n",
963 response->hdr.tpm_size,
964 command, cr_size);
965 return -1;
966 }
967
968 /* The entire message have been parsed. */
969 return 0;
970 }
971
tpm_get_packet_size(const uint8_t * packet)972 uint32_t tpm_get_packet_size(const uint8_t *packet)
973 {
974 /* 0: tag (16 bit)
975 * 2: size (32 bit)
976 */
977 return read_be32(packet + 2);
978 }
979
tpm_get_packet_response_code(const uint8_t * packet)980 uint32_t tpm_get_packet_response_code(const uint8_t *packet)
981 {
982 /* 0: tag (16 bit)
983 * 2: size (32 bit)
984 * 6: resp code (32 bit)
985 */
986 return read_be32(packet + 6);
987 }
988
tpm_set_ph_disabled(int flag)989 void tpm_set_ph_disabled(int flag)
990 {
991 ph_disabled = flag;
992 }
993
tpm_is_ph_disabled(void)994 int tpm_is_ph_disabled(void)
995 {
996 return ph_disabled;
997 }
998