| OLD | NEW |
| 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
| 3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
| 4 */ | 4 */ |
| 5 | 5 |
| 6 /* This program generates partially filled TPM datagrams and other compile-time | 6 /* This program generates partially filled TPM datagrams and other compile-time |
| 7 * constants (e.g. structure sizes and offsets). Compile this file---and ONLY | 7 * constants (e.g. structure sizes and offsets). Compile this file---and ONLY |
| 8 * this file---with -fpack-struct. We take advantage of the fact that the | 8 * this file---with -fpack-struct. We take advantage of the fact that the |
| 9 * (packed) TPM structures layout (mostly) match the TPM request and response | 9 * (packed) TPM structures layout (mostly) match the TPM request and response |
| 10 * datagram layout. When they don't completely match, some fixing is necessary | 10 * datagram layout. When they don't completely match, some fixing is necessary |
| 11 * (see PCR_SELECTION_FIX below). | 11 * (see PCR_SELECTION_FIX below). |
| 12 */ | 12 */ |
| 13 | 13 |
| 14 #include <assert.h> |
| 14 #include <stddef.h> | 15 #include <stddef.h> |
| 15 #include <stdio.h> | 16 #include <stdio.h> |
| 16 #include <stdlib.h> | 17 #include <stdlib.h> |
| 17 #include <tss/tcs.h> | 18 #include <tss/tcs.h> |
| 18 | 19 |
| 19 #include "tlcl.h" | 20 #include "tlcl.h" |
| 20 #include "tlcl_internal.h" | 21 #include "tlcl_internal.h" |
| 21 #include "tpmextras.h" | 22 #include "tpmextras.h" |
| 22 #include "utility.h" | |
| 23 | 23 |
| 24 /* See struct Command below. This structure represent a field in a TPM | 24 /* See struct Command below. This structure represent a field in a TPM |
| 25 * command. [name] is the field name. [visible] is 1 if the field is | 25 * command. [name] is the field name. [visible] is 1 if the field is |
| 26 * modified by the run-time. Non-visible fields are initialized at build time | 26 * modified by the run-time. Non-visible fields are initialized at build time |
| 27 * and remain constant. [size] is the field size in bytes. [value] is the | 27 * and remain constant. [size] is the field size in bytes. [value] is the |
| 28 * fixed value of non-visible fields. | 28 * fixed value of non-visible fields. |
| 29 */ | 29 */ |
| 30 typedef struct Field { | 30 typedef struct Field { |
| 31 const char* name; | 31 const char* name; |
| 32 int visible; | 32 int visible; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 47 int size; | 47 int size; |
| 48 int max_size; | 48 int max_size; |
| 49 Field* fields; | 49 Field* fields; |
| 50 struct Command* next; | 50 struct Command* next; |
| 51 } Command; | 51 } Command; |
| 52 | 52 |
| 53 /* Adds a field to a command, and makes its offset visible. The fields must be | 53 /* Adds a field to a command, and makes its offset visible. The fields must be |
| 54 * added at increasing offsets. | 54 * added at increasing offsets. |
| 55 */ | 55 */ |
| 56 static void AddVisibleField(Command* cmd, const char* name, int offset) { | 56 static void AddVisibleField(Command* cmd, const char* name, int offset) { |
| 57 Field* fld = (Field*) Malloc(sizeof(Field)); | 57 Field* fld = (Field*) malloc(sizeof(Field)); |
| 58 if (cmd->fields != NULL) { | 58 if (cmd->fields != NULL) { |
| 59 Field* fn = cmd->fields; | |
| 60 assert(offset > fn->offset); | 59 assert(offset > fn->offset); |
| 61 } | 60 } |
| 62 fld->next = cmd->fields; | 61 fld->next = cmd->fields; |
| 63 cmd->fields = fld; | 62 cmd->fields = fld; |
| 64 fld->name = name; | 63 fld->name = name; |
| 65 fld->visible = 1; | 64 fld->visible = 1; |
| 66 fld->offset = offset; | 65 fld->offset = offset; |
| 67 } | 66 } |
| 68 | 67 |
| 69 /* Adds a constant field with its value. The fields must be added at | 68 /* Adds a constant field with its value. The fields must be added at |
| 70 * increasing offsets. | 69 * increasing offsets. |
| 71 */ | 70 */ |
| 72 static void AddInitializedField(Command* cmd, int offset, | 71 static void AddInitializedField(Command* cmd, int offset, |
| 73 int size, uint32_t value) { | 72 int size, uint32_t value) { |
| 74 Field* fld = (Field*) Malloc(sizeof(Field)); | 73 Field* fld = (Field*) malloc(sizeof(Field)); |
| 75 fld->next = cmd->fields; | 74 fld->next = cmd->fields; |
| 76 cmd->fields = fld; | 75 cmd->fields = fld; |
| 77 fld->name = NULL; | 76 fld->name = NULL; |
| 78 fld->visible = 0; | 77 fld->visible = 0; |
| 79 fld->size = size; | 78 fld->size = size; |
| 80 fld->offset = offset; | 79 fld->offset = offset; |
| 81 fld->value = value; | 80 fld->value = value; |
| 82 } | 81 } |
| 83 | 82 |
| 84 /* Create a structure representing a TPM command datagram. | 83 /* Create a structure representing a TPM command datagram. |
| 85 */ | 84 */ |
| 86 Command* newCommand(TPM_COMMAND_CODE code, int size) { | 85 Command* newCommand(TPM_COMMAND_CODE code, int size) { |
| 87 Command* cmd = (Command*) Malloc(sizeof(Command)); | 86 Command* cmd = (Command*) malloc(sizeof(Command)); |
| 88 cmd->size = size; | 87 cmd->size = size; |
| 89 AddInitializedField(cmd, 0, sizeof(TPM_TAG), TPM_TAG_RQU_COMMAND); | 88 AddInitializedField(cmd, 0, sizeof(TPM_TAG), TPM_TAG_RQU_COMMAND); |
| 90 AddInitializedField(cmd, sizeof(TPM_TAG), sizeof(uint32_t), size); | 89 AddInitializedField(cmd, sizeof(TPM_TAG), sizeof(uint32_t), size); |
| 91 AddInitializedField(cmd, sizeof(TPM_TAG) + sizeof(uint32_t), | 90 AddInitializedField(cmd, sizeof(TPM_TAG) + sizeof(uint32_t), |
| 92 sizeof(TPM_COMMAND_CODE), code); | 91 sizeof(TPM_COMMAND_CODE), code); |
| 93 return cmd; | 92 return cmd; |
| 94 } | 93 } |
| 95 | 94 |
| 96 /* The TPM_PCR_SELECTION structure in /usr/include/tss/tpm.h contains a pointer | 95 /* The TPM_PCR_SELECTION structure in /usr/include/tss/tpm.h contains a pointer |
| 97 * instead of an array[3] of bytes, so we need to adjust sizes and offsets | 96 * instead of an array[3] of bytes, so we need to adjust sizes and offsets |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 | 298 |
| 300 /* Output the fields of a structure. | 299 /* Output the fields of a structure. |
| 301 */ | 300 */ |
| 302 void OutputFields(Field* fld) { | 301 void OutputFields(Field* fld) { |
| 303 /* | 302 /* |
| 304 * Field order is reversed. | 303 * Field order is reversed. |
| 305 */ | 304 */ |
| 306 if (fld != NULL) { | 305 if (fld != NULL) { |
| 307 OutputFields(fld->next); | 306 OutputFields(fld->next); |
| 308 if (fld->visible) { | 307 if (fld->visible) { |
| 309 printf(" uint8_t* %s;\n", fld->name); | 308 printf(" uint16_t %s;\n", fld->name); |
| 310 } | 309 } |
| 311 } | 310 } |
| 312 } | 311 } |
| 313 | 312 |
| 314 /* Outputs a structure initializer. | 313 /* Outputs a structure initializer. |
| 315 */ | 314 */ |
| 316 int OutputBytes_(Command* cmd, Field* fld) { | 315 int OutputBytes_(Command* cmd, Field* fld) { |
| 317 int cursor = 0; | 316 int cursor = 0; |
| 318 int i; | 317 int i; |
| 319 /* | 318 /* |
| (...skipping 23 matching lines...) Expand all Loading... |
| 343 cursor += 2; | 342 cursor += 2; |
| 344 break; | 343 break; |
| 345 case 4: | 344 case 4: |
| 346 printf("0x%x, 0x%x, 0x%x, 0x%x, ", fld->value >> 24, | 345 printf("0x%x, 0x%x, 0x%x, 0x%x, ", fld->value >> 24, |
| 347 (fld->value >> 16) & 0xff, | 346 (fld->value >> 16) & 0xff, |
| 348 (fld->value >> 8) & 0xff, | 347 (fld->value >> 8) & 0xff, |
| 349 fld->value & 0xff); | 348 fld->value & 0xff); |
| 350 cursor += 4; | 349 cursor += 4; |
| 351 break; | 350 break; |
| 352 default: | 351 default: |
| 353 error("invalid field size %d\n", fld->size); | 352 fprintf(stderr, "invalid field size %d\n", fld->size); |
| 353 exit(1); |
| 354 break; | 354 break; |
| 355 } | 355 } |
| 356 } | 356 } |
| 357 return cursor; | 357 return cursor; |
| 358 } | 358 } |
| 359 | 359 |
| 360 /* Helper to output a structure initializer. | 360 /* Helper to output a structure initializer. |
| 361 */ | 361 */ |
| 362 void OutputBytes(Command* cmd) { | 362 void OutputBytes(Command* cmd) { |
| 363 (void) OutputBytes_(cmd, cmd->fields); | 363 (void) OutputBytes_(cmd, cmd->fields); |
| 364 } | 364 } |
| 365 | 365 |
| 366 void OutputFieldPointers(Command* cmd, Field* fld) { | 366 void OutputFieldPointers(Command* cmd, Field* fld) { |
| 367 if (fld == NULL) { | 367 if (fld == NULL) { |
| 368 return; | 368 return; |
| 369 } else { | 369 } else { |
| 370 OutputFieldPointers(cmd, fld->next); | 370 OutputFieldPointers(cmd, fld->next); |
| 371 if (fld->visible) { | 371 if (fld->visible) { |
| 372 printf("%s.buffer + %d, ", cmd->name, fld->offset); | 372 printf("%d, ", fld->offset); |
| 373 } | 373 } |
| 374 } | 374 } |
| 375 } | 375 } |
| 376 | 376 |
| 377 /* Outputs the structure initializers for all commands. | 377 /* Outputs the structure initializers for all commands. |
| 378 */ | 378 */ |
| 379 void OutputCommands(Command* cmd) { | 379 void OutputCommands(Command* cmd) { |
| 380 if (cmd == NULL) { | 380 if (cmd == NULL) { |
| 381 return; | 381 return; |
| 382 } else { | 382 } else { |
| 383 printf("struct {\n uint8_t buffer[%d];\n", | 383 printf("struct s_%s{\n uint8_t buffer[%d];\n", |
| 384 cmd->size == 0 ? cmd->max_size : cmd->size); | 384 cmd->name, cmd->size == 0 ? cmd->max_size : cmd->size); |
| 385 OutputFields(cmd->fields); | 385 OutputFields(cmd->fields); |
| 386 printf("} %s = {{", cmd->name); | 386 printf("} %s = {{", cmd->name); |
| 387 OutputBytes(cmd); | 387 OutputBytes(cmd); |
| 388 printf("},\n"); | 388 printf("},\n"); |
| 389 OutputFieldPointers(cmd, cmd->fields); | 389 OutputFieldPointers(cmd, cmd->fields); |
| 390 printf("};\n\n"); | 390 printf("};\n\n"); |
| 391 } | 391 } |
| 392 OutputCommands(cmd->next); | 392 OutputCommands(cmd->next); |
| 393 } | 393 } |
| 394 | 394 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 407 BuildPhysicalEnableCommand, | 407 BuildPhysicalEnableCommand, |
| 408 BuildPhysicalSetDeactivatedCommand, | 408 BuildPhysicalSetDeactivatedCommand, |
| 409 BuildGetFlagsCommand, | 409 BuildGetFlagsCommand, |
| 410 BuildGetPermissionsCommand, | 410 BuildGetPermissionsCommand, |
| 411 BuildExtendCommand, | 411 BuildExtendCommand, |
| 412 }; | 412 }; |
| 413 | 413 |
| 414 static void FreeFields(Field* fld) { | 414 static void FreeFields(Field* fld) { |
| 415 if (fld != NULL) { | 415 if (fld != NULL) { |
| 416 Field* next_field = fld->next; | 416 Field* next_field = fld->next; |
| 417 Free(fld); | 417 free(fld); |
| 418 FreeFields(next_field); | 418 FreeFields(next_field); |
| 419 } | 419 } |
| 420 } | 420 } |
| 421 | 421 |
| 422 static void FreeCommands(Command* cmd) { | 422 static void FreeCommands(Command* cmd) { |
| 423 if (cmd != NULL) { | 423 if (cmd != NULL) { |
| 424 Command* next_command = cmd->next; | 424 Command* next_command = cmd->next; |
| 425 Free(cmd); | 425 free(cmd); |
| 426 FreeFields(cmd->fields); | 426 FreeFields(cmd->fields); |
| 427 FreeCommands(next_command); | 427 FreeCommands(next_command); |
| 428 } | 428 } |
| 429 } | 429 } |
| 430 | 430 |
| 431 int main(void) { | 431 int main(void) { |
| 432 Command* commands = NULL; | 432 Command* commands = NULL; |
| 433 int i; | 433 int i; |
| 434 for (i = 0; i < sizeof(builders) / sizeof(builders[0]); i++) { | 434 for (i = 0; i < sizeof(builders) / sizeof(builders[0]); i++) { |
| 435 Command* cmd = builders[i](); | 435 Command* cmd = builders[i](); |
| 436 cmd->next = commands; | 436 cmd->next = commands; |
| 437 commands = cmd; | 437 commands = cmd; |
| 438 } | 438 } |
| 439 | 439 |
| 440 printf("/* This file is automatically generated */\n\n"); | 440 printf("/* This file is automatically generated */\n\n"); |
| 441 OutputCommands(commands); | 441 OutputCommands(commands); |
| 442 printf("const int kWriteInfoLength = %d;\n", (int) sizeof(TPM_WRITE_INFO)); | 442 printf("const int kWriteInfoLength = %d;\n", (int) sizeof(TPM_WRITE_INFO)); |
| 443 printf("const int kNvDataPublicPermissionsOffset = %d;\n", | 443 printf("const int kNvDataPublicPermissionsOffset = %d;\n", |
| 444 (int) (offsetof(TPM_NV_DATA_PUBLIC, permission) + | 444 (int) (offsetof(TPM_NV_DATA_PUBLIC, permission) + |
| 445 2 * PCR_SELECTION_FIX + | 445 2 * PCR_SELECTION_FIX + |
| 446 offsetof(TPM_NV_ATTRIBUTES, attributes))); | 446 offsetof(TPM_NV_ATTRIBUTES, attributes))); |
| 447 | 447 |
| 448 FreeCommands(commands); | 448 FreeCommands(commands); |
| 449 return 0; | 449 return 0; |
| 450 } | 450 } |
| OLD | NEW |