"Das U-Boot" Source Tree
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'efi-2024-10-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi into next

Pull request efi-2024-10-rc1

Documentation:
Update requirements.txt to use current Python module versions
Add a page describing debugging U-Boot with GDB
FIT: describe data-size as a conditionally mandatory property
Correct link to FIT specification in SPL code.
Correct kaslrseed command long text description

UEFI:
Add unit test checking that don't have kaslr-seed when measuring boot
Deduplicate code for measured boot.

Other:
Print size information in fwu command

Tom Rini 2f960339 48641bfa

+1386 -1079
+4
boot/Kconfig
··· 734 734 config MEASURED_BOOT 735 735 bool "Measure boot images and configuration when booting without EFI" 736 736 depends on HASH && TPM_V2 737 + select SHA1 738 + select SHA256 739 + select SHA384 740 + select SHA512 737 741 help 738 742 This option enables measurement of the boot process when booting 739 743 without UEFI . Measurement involves creating cryptographic hashes
+1
boot/bootm.c
··· 24 24 #include <asm/io.h> 25 25 #include <linux/sizes.h> 26 26 #include <tpm-v2.h> 27 + #include <tpm_tcg2.h> 27 28 #if defined(CONFIG_CMD_USB) 28 29 #include <usb.h> 29 30 #endif
+1
cmd/fwu_mdata.c
··· 22 22 printf("\tFWU Metadata\n"); 23 23 printf("crc32: %#x\n", data->crc32); 24 24 printf("version: %#x\n", data->version); 25 + printf("size: %#x\n", data->metadata_size); 25 26 printf("active_index: %#x\n", data->active_index); 26 27 printf("previous_active_index: %#x\n", data->previous_active_index); 27 28
+1 -1
cmd/kaslrseed.c
··· 33 33 } 34 34 35 35 U_BOOT_LONGHELP(kaslrseed, 36 - "[n]\n" 36 + "\n" 37 37 " - append random bytes to chosen kaslr-seed node\n"); 38 38 39 39 U_BOOT_CMD(
+1 -1
common/spl/spl_fit.c
··· 587 587 static void warn_deprecated(const char *msg) 588 588 { 589 589 printf("DEPRECATED: %s\n", msg); 590 - printf("\tSee doc/uImage.FIT/source_file_format.txt\n"); 590 + printf("\tSee https://fitspec.osfw.foundation/\n"); 591 591 } 592 592 593 593 static int spl_fit_upload_fpga(struct spl_fit_info *ctx, int node,
+171
doc/develop/gdb.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0+ 2 + .. Copyright (c) 2024 Alexander Dahl 3 + 4 + Debugging U-Boot with GDB 5 + ========================= 6 + 7 + Using a JTAG adapter it is possible to debug a running U-Boot with GDB. 8 + A common way is to connect a debug adapter to the JTAG connector of your 9 + board, run a GDB server, connect GDB to the GDB server, and use GDB as usual. 10 + 11 + Similarly QEMU can provide a GDB server. 12 + 13 + Preparing build 14 + --------------- 15 + 16 + Building U-Boot with with reduced optimization (-Og) and without link time 17 + optimization is recommended for easier debugging:: 18 + 19 + CONFIG_CC_OPTIMIZE_FOR_DEBUG=y 20 + CONFIG_LTO=n 21 + 22 + Otherwise build, install, and run U-Boot as usual. 23 + 24 + Using OpenOCD as GDB server 25 + --------------------------- 26 + 27 + `OpenOCD <https://openocd.org/>`_ is an open source tool supporting hardware 28 + debug probes, and providing a GDB server. It is readily available in major Linux 29 + distributions or you can build it from source. 30 + 31 + Here is example of starting OpenOCD on Debian using a J-Link adapter and a 32 + board with an AT91 SAMA5D2 SoC: 33 + 34 + .. code-block:: console 35 + 36 + $ openocd -f interface/jlink.cfg -f target/at91sama5d2.cfg -c 'adapter speed 4000' 37 + Open On-Chip Debugger 0.12.0 38 + Licensed under GNU GPL v2 39 + For bug reports, read 40 + http://openocd.org/doc/doxygen/bugs.html 41 + Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'. 42 + adapter speed: 4000 kHz 43 + 44 + Info : Listening on port 6666 for tcl connections 45 + Info : Listening on port 4444 for telnet connections 46 + Info : J-Link V10 compiled Jan 30 2023 11:28:07 47 + Info : Hardware version: 10.10 48 + Info : VTarget = 3.244 V 49 + Info : clock speed 4000 kHz 50 + Info : JTAG tap: at91sama5d2.cpu tap/device found: 0x5ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x5) 51 + Info : at91sama5d2.cpu_a5.0: hardware has 3 breakpoints, 2 watchpoints 52 + Info : at91sama5d2.cpu_a5.0: MPIDR level2 0, cluster 0, core 0, mono core, no SMT 53 + Info : starting gdb server for at91sama5d2.cpu_a5.0 on 3333 54 + Info : Listening on port 3333 for gdb connections 55 + 56 + Notice that OpenOCD is listening on port 3333 for GDB connections. 57 + 58 + Using QEMU as GDB server 59 + ------------------------ 60 + 61 + When running U-Boot on QEMU you can used the '-gdb' parameter to provide a 62 + GDB server: 63 + 64 + qemu-system-riscv64 -M virt -nographic -gdb tcp::3333 -kernel u-boot 65 + 66 + Running a GDB session 67 + ---------------------- 68 + 69 + You need a GDB suited for your target. This can be the GDB coming with your 70 + toolchain or *gdb-multiarch* available in your Linux distribution. 71 + 72 + .. prompt:: bash $ 73 + 74 + gdb-multiarch u-boot 75 + 76 + In the above command-line *u-boot* is the U-boot binary in your build 77 + directory. You may need to adjust the path when calling GDB. 78 + 79 + Connect to the GDB server like this: 80 + 81 + .. code-block:: console 82 + 83 + (gdb) target extended-remote :3333 84 + Remote debugging using :3333 85 + 0x27fa9ac6 in ?? () 86 + (gdb) 87 + 88 + This is fine for debugging before U-Boot relocates itself. 89 + 90 + For debugging U-Boot after relocation you need to indicate the relocation 91 + address to GDB. You can retrieve the relocation address from the U-Boot shell 92 + with the command *bdinfo*: 93 + 94 + .. code-block:: console 95 + 96 + U-Boot> bdinfo 97 + boot_params = 0x20000100 98 + DRAM bank = 0x00000000 99 + -> start = 0x20000000 100 + -> size = 0x08000000 101 + flashstart = 0x00000000 102 + flashsize = 0x00000000 103 + flashoffset = 0x00000000 104 + baudrate = 115200 bps 105 + relocaddr = 0x27f7a000 106 + reloc off = 0x0607a000 107 + Build = 32-bit 108 + current eth = ethernet@f8008000 109 + ethaddr = 00:50:c2:31:58:d4 110 + IP addr = <NULL> 111 + fdt_blob = 0x27b36060 112 + new_fdt = 0x27b36060 113 + fdt_size = 0x00003e40 114 + lmb_dump_all: 115 + memory.cnt = 0x1 / max = 0x10 116 + memory[0] [0x20000000-0x27ffffff], 0x08000000 bytes flags: 0 117 + reserved.cnt = 0x1 / max = 0x10 118 + reserved[0] [0x27b31d00-0x27ffffff], 0x004ce300 bytes flags: 0 119 + devicetree = separate 120 + arch_number = 0x00000000 121 + TLB addr = 0x27ff0000 122 + irq_sp = 0x27b36050 123 + sp start = 0x27b36040 124 + Early malloc usage: cd8 / 2000 125 + 126 + Look out for the line starting with *relocaddr* which has the address 127 + you need, ``0x27f7a000`` in this case. 128 + 129 + On most architectures (not sandbox, x86, Xtensa) the global data pointer is 130 + stored in a fixed register: 131 + 132 + ============ ======== 133 + Architecture Register 134 + ============ ======== 135 + arc r25 136 + arm r9 137 + arm64 x18 138 + m68k d7 139 + microblaze r31 140 + mips k0 141 + nios2 gp 142 + powerpc r2 143 + riscv gp 144 + sh r13 145 + ============ ======== 146 + 147 + On these architecture the relocation address cat be determined by 148 + dereferencing the global data pointer stored in register, *r9* in the example: 149 + 150 + .. code-block:: console 151 + 152 + (gdb) p/x (*(struct global_data*)$r9)->relocaddr 153 + $1 = 0x27f7a000 154 + 155 + In the GDB shell discard the previously loaded symbol file and add it once 156 + again with the relocation address like this: 157 + 158 + .. code-block:: console 159 + 160 + (gdb) symbol-file 161 + Discard symbol table from `/home/adahl/build/u-boot/v2024.04.x/u-boot'? (y or n) y 162 + No symbol file now. 163 + (gdb) add-symbol-file u-boot 0x27f7a000 164 + add symbol table from file "u-boot" at 165 + .text_addr = 0x27f7a000 166 + (y or n) y 167 + Reading symbols from u-boot... 168 + (gdb) 169 + 170 + You can now use GDB as usual, setting breakpoints, printing backtraces, 171 + inspecting variables, stepping through the code, etc.
+1
doc/develop/index.rst
··· 60 60 :maxdepth: 1 61 61 62 62 crash_dumps 63 + gdb 63 64 trace 64 65 65 66 Packaging
+8 -8
doc/sphinx/requirements.txt
··· 1 1 alabaster==0.7.16 2 - Babel==2.14.0 3 - certifi==2023.11.17 2 + Babel==2.15.0 3 + certifi==2024.6.2 4 4 charset-normalizer==3.3.2 5 5 docutils==0.20.1 6 6 idna==3.7 7 7 imagesize==1.4.1 8 8 Jinja2==3.1.4 9 - MarkupSafe==2.1.3 10 - packaging==23.2 11 - Pygments==2.17.2 12 - requests==2.32.2 9 + MarkupSafe==2.1.5 10 + packaging==24.1 11 + Pygments==2.18.0 12 + requests==2.32.3 13 13 six==1.16.0 14 14 snowballstemmer==2.2.0 15 - Sphinx==7.2.6 15 + Sphinx==7.3.7 16 16 sphinx-prompt==1.8.0 17 17 sphinx-rtd-theme==2.0.0 18 18 sphinxcontrib-applehelp==1.0.8 ··· 22 22 sphinxcontrib-jsmath==1.0.1 23 23 sphinxcontrib-qthelp==1.0.7 24 24 sphinxcontrib-serializinghtml==1.1.10 25 - urllib3==2.1.0 25 + urllib3==2.2.1
+3 -3
doc/usage/fit/source_file_format.rst
··· 254 254 zstd zstd compressed 255 255 ==================== ================== 256 256 257 - data-size 258 - size of the data in bytes 259 - 260 257 261 258 Conditionally mandatory property 262 259 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ··· 275 272 Machine address at which the data is to be found. This is a fixed address 276 273 not relative to the loading of the FIT. This is mandatory if external data 277 274 used with a fixed address. 275 + 276 + data-size 277 + Size of the data in bytes. This is mandatory if external data is used. 278 278 279 279 os 280 280 OS name, mandatory for types "kernel". Valid OS names are:
+1 -8
include/efi_tcg2.h
··· 18 18 19 19 #include <efi_api.h> 20 20 #include <tpm-v2.h> 21 + #include <tpm_tcg2.h> 21 22 22 23 /* TPMV2 only */ 23 24 #define TCG2_EVENT_LOG_FORMAT_TCG_2 0x00000002 ··· 25 26 #define PE_COFF_IMAGE 0x0000000000000010 26 27 27 28 #define EFI_TCG2_MAX_PCR_INDEX 23 28 - 29 - /* Algorithm Registry */ 30 - #define EFI_TCG2_BOOT_HASH_ALG_SHA1 0x00000001 31 - #define EFI_TCG2_BOOT_HASH_ALG_SHA256 0x00000002 32 - #define EFI_TCG2_BOOT_HASH_ALG_SHA384 0x00000004 33 - #define EFI_TCG2_BOOT_HASH_ALG_SHA512 0x00000008 34 - #define EFI_TCG2_BOOT_HASH_ALG_SM3_256 0x00000010 35 - 36 29 #define EFI_TCG2_FINAL_EVENTS_TABLE_VERSION 1 37 30 38 31 #define TPM2_EVENT_LOG_SIZE CONFIG_EFI_TCG2_PROTOCOL_EVENTLOG_SIZE
+50 -338
include/tpm-v2.h
··· 55 55 #define TPM2_PT_MAX_COMMAND_SIZE (u32)(TPM2_PT_FIXED + 30) 56 56 #define TPM2_PT_MAX_RESPONSE_SIZE (u32)(TPM2_PT_FIXED + 31) 57 57 58 - /* 59 - * event types, cf. 60 - * "TCG Server Management Domain Firmware Profile Specification", 61 - * rev 1.00, 2020-05-01 62 - */ 63 - #define EV_POST_CODE ((u32)0x00000001) 64 - #define EV_NO_ACTION ((u32)0x00000003) 65 - #define EV_SEPARATOR ((u32)0x00000004) 66 - #define EV_ACTION ((u32)0x00000005) 67 - #define EV_TAG ((u32)0x00000006) 68 - #define EV_S_CRTM_CONTENTS ((u32)0x00000007) 69 - #define EV_S_CRTM_VERSION ((u32)0x00000008) 70 - #define EV_CPU_MICROCODE ((u32)0x00000009) 71 - #define EV_PLATFORM_CONFIG_FLAGS ((u32)0x0000000A) 72 - #define EV_TABLE_OF_DEVICES ((u32)0x0000000B) 73 - #define EV_COMPACT_HASH ((u32)0x0000000C) 74 - 75 - /* 76 - * event types, cf. 77 - * "TCG PC Client Platform Firmware Profile Specification", Family "2.0" 78 - * Level 00 Version 1.05 Revision 23, May 7, 2021 79 - */ 80 - #define EV_EFI_EVENT_BASE ((u32)0x80000000) 81 - #define EV_EFI_VARIABLE_DRIVER_CONFIG ((u32)0x80000001) 82 - #define EV_EFI_VARIABLE_BOOT ((u32)0x80000002) 83 - #define EV_EFI_BOOT_SERVICES_APPLICATION ((u32)0x80000003) 84 - #define EV_EFI_BOOT_SERVICES_DRIVER ((u32)0x80000004) 85 - #define EV_EFI_RUNTIME_SERVICES_DRIVER ((u32)0x80000005) 86 - #define EV_EFI_GPT_EVENT ((u32)0x80000006) 87 - #define EV_EFI_ACTION ((u32)0x80000007) 88 - #define EV_EFI_PLATFORM_FIRMWARE_BLOB ((u32)0x80000008) 89 - #define EV_EFI_HANDOFF_TABLES ((u32)0x80000009) 90 - #define EV_EFI_PLATFORM_FIRMWARE_BLOB2 ((u32)0x8000000A) 91 - #define EV_EFI_HANDOFF_TABLES2 ((u32)0x8000000B) 92 - #define EV_EFI_VARIABLE_BOOT2 ((u32)0x8000000C) 93 - #define EV_EFI_HCRTM_EVENT ((u32)0x80000010) 94 - #define EV_EFI_VARIABLE_AUTHORITY ((u32)0x800000E0) 95 - #define EV_EFI_SPDM_FIRMWARE_BLOB ((u32)0x800000E1) 96 - #define EV_EFI_SPDM_FIRMWARE_CONFIG ((u32)0x800000E2) 97 - 98 - #define EFI_CALLING_EFI_APPLICATION \ 99 - "Calling EFI Application from Boot Option" 100 - #define EFI_RETURNING_FROM_EFI_APPLICATION \ 101 - "Returning from EFI Application from Boot Option" 102 - #define EFI_EXIT_BOOT_SERVICES_INVOCATION \ 103 - "Exit Boot Services Invocation" 104 - #define EFI_EXIT_BOOT_SERVICES_FAILED \ 105 - "Exit Boot Services Returned with Failure" 106 - #define EFI_EXIT_BOOT_SERVICES_SUCCEEDED \ 107 - "Exit Boot Services Returned with Success" 108 - #define EFI_DTB_EVENT_STRING \ 109 - "DTB DATA" 110 - 111 58 /* TPMS_TAGGED_PROPERTY Structure */ 112 59 struct tpms_tagged_property { 113 60 u32 property; ··· 150 97 } __packed; 151 98 152 99 /** 153 - * SHA1 Event Log Entry Format 154 - * 155 - * @pcr_index: PCRIndex event extended to 156 - * @event_type: Type of event (see EFI specs) 157 - * @digest: Value extended into PCR index 158 - * @event_size: Size of event 159 - * @event: Event data 160 - */ 161 - struct tcg_pcr_event { 162 - u32 pcr_index; 163 - u32 event_type; 164 - u8 digest[TPM2_SHA1_DIGEST_SIZE]; 165 - u32 event_size; 166 - u8 event[]; 167 - } __packed; 168 - 169 - /** 170 100 * Definition of TPMU_HA Union 171 101 */ 172 102 union tpmu_ha { ··· 200 130 } __packed; 201 131 202 132 /** 203 - * Crypto Agile Log Entry Format 204 - * 205 - * @pcr_index: PCRIndex event extended to 206 - * @event_type: Type of event 207 - * @digests: List of digestsextended to PCR index 208 - * @event_size: Size of the event data 209 - * @event: Event data 210 - */ 211 - struct tcg_pcr_event2 { 212 - u32 pcr_index; 213 - u32 event_type; 214 - struct tpml_digest_values digests; 215 - u32 event_size; 216 - u8 event[]; 217 - } __packed; 218 - 219 - /** 220 - * struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information 221 - * 222 - * @algorithm_id: algorithm defined in enum tpm2_algorithms 223 - * @digest_size: size of the algorithm 224 - */ 225 - struct tcg_efi_spec_id_event_algorithm_size { 226 - u16 algorithm_id; 227 - u16 digest_size; 228 - } __packed; 229 - 230 - #define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03" 231 - #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2 232 - #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0 233 - #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2 234 - 235 - /** 236 - * struct TCG_EfiSpecIDEventStruct - content of the event log header 237 - * 238 - * @signature: signature, set to Spec ID Event03 239 - * @platform_class: class defined in TCG ACPI Specification 240 - * Client Common Header. 241 - * @spec_version_minor: minor version 242 - * @spec_version_major: major version 243 - * @spec_version_errata: major version 244 - * @uintn_size: size of the efi_uintn_t fields used in various 245 - * data structures used in this specification. 246 - * 0x01 indicates u32 and 0x02 indicates u64 247 - * @number_of_algorithms: hashing algorithms used in this event log 248 - * @digest_sizes: array of number_of_algorithms pairs 249 - * 1st member defines the algorithm id 250 - * 2nd member defines the algorithm size 251 - */ 252 - struct tcg_efi_spec_id_event { 253 - u8 signature[16]; 254 - u32 platform_class; 255 - u8 spec_version_minor; 256 - u8 spec_version_major; 257 - u8 spec_errata; 258 - u8 uintn_size; 259 - u32 number_of_algorithms; 260 - struct tcg_efi_spec_id_event_algorithm_size digest_sizes[]; 261 - } __packed; 262 - 263 - /** 264 133 * TPM2 Structure Tags for command/response buffers. 265 134 * 266 135 * @TPM2_ST_NO_SESSIONS: the command does not need an authentication. ··· 409 278 #define TCG2_BOOT_HASH_ALG_SM3_256 0x00000010 410 279 411 280 static const struct digest_info hash_algo_list[] = { 281 + #if IS_ENABLED(CONFIG_SHA1) 412 282 { 413 283 "sha1", 414 284 TPM2_ALG_SHA1, 415 285 TCG2_BOOT_HASH_ALG_SHA1, 416 286 TPM2_SHA1_DIGEST_SIZE, 417 287 }, 288 + #endif 289 + #if IS_ENABLED(CONFIG_SHA256) 418 290 { 419 291 "sha256", 420 292 TPM2_ALG_SHA256, 421 293 TCG2_BOOT_HASH_ALG_SHA256, 422 294 TPM2_SHA256_DIGEST_SIZE, 423 295 }, 296 + #endif 297 + #if IS_ENABLED(CONFIG_SHA384) 424 298 { 425 299 "sha384", 426 300 TPM2_ALG_SHA384, 427 301 TCG2_BOOT_HASH_ALG_SHA384, 428 302 TPM2_SHA384_DIGEST_SIZE, 429 303 }, 304 + #endif 305 + #if IS_ENABLED(CONFIG_SHA512) 430 306 { 431 307 "sha512", 432 308 TPM2_ALG_SHA512, 433 309 TCG2_BOOT_HASH_ALG_SHA512, 434 310 TPM2_SHA512_DIGEST_SIZE, 435 311 }, 312 + #endif 436 313 }; 437 314 438 - static inline u16 tpm2_algorithm_to_len(enum tpm2_algorithms a) 439 - { 440 - switch (a) { 441 - case TPM2_ALG_SHA1: 442 - return TPM2_SHA1_DIGEST_SIZE; 443 - case TPM2_ALG_SHA256: 444 - return TPM2_SHA256_DIGEST_SIZE; 445 - case TPM2_ALG_SHA384: 446 - return TPM2_SHA384_DIGEST_SIZE; 447 - case TPM2_ALG_SHA512: 448 - return TPM2_SHA512_DIGEST_SIZE; 449 - default: 450 - return 0; 451 - } 452 - } 453 - 454 315 /* NV index attributes */ 455 316 enum tpm_index_attrs { 456 317 TPMA_NV_PPWRITE = 1UL << 0, ··· 531 392 }; 532 393 533 394 /** 534 - * struct tcg2_event_log - Container for managing the platform event log 535 - * 536 - * @log: Address of the log 537 - * @log_position: Current entry position 538 - * @log_size: Log space available 539 - * @found: Boolean indicating if an existing log was discovered 540 - */ 541 - struct tcg2_event_log { 542 - u8 *log; 543 - u32 log_position; 544 - u32 log_size; 545 - bool found; 546 - }; 547 - 548 - /** 549 - * Create a list of digests of the supported PCR banks for a given input data 550 - * 551 - * @dev TPM device 552 - * @input Data 553 - * @length Length of the data to calculate the digest 554 - * @digest_list List of digests to fill in 555 - * 556 - * Return: zero on success, negative errno otherwise 557 - */ 558 - int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 length, 559 - struct tpml_digest_values *digest_list); 560 - 561 - /** 562 - * Get the event size of the specified digests 563 - * 564 - * @digest_list List of digests for the event 565 - * 566 - * Return: Size in bytes of the event 567 - */ 568 - u32 tcg2_event_get_size(struct tpml_digest_values *digest_list); 569 - 570 - /** 571 - * tcg2_get_active_pcr_banks 572 - * 573 - * @dev TPM device 574 - * @active_pcr_banks Bitmask of PCR algorithms supported 575 - * 576 - * Return: zero on success, negative errno otherwise 577 - */ 578 - int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks); 579 - 580 - /** 581 - * tcg2_log_append - Append an event to an event log 582 - * 583 - * @pcr_index Index of the PCR 584 - * @event_type Type of event 585 - * @digest_list List of digests to add 586 - * @size Size of event 587 - * @event Event data 588 - * @log Log buffer to append the event to 589 - */ 590 - void tcg2_log_append(u32 pcr_index, u32 event_type, 591 - struct tpml_digest_values *digest_list, u32 size, 592 - const u8 *event, u8 *log); 593 - 594 - /** 595 - * Extend the PCR with specified digests 596 - * 597 - * @dev TPM device 598 - * @pcr_index Index of the PCR 599 - * @digest_list List of digests to extend 600 - * 601 - * Return: zero on success, negative errno otherwise 602 - */ 603 - int tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, 604 - struct tpml_digest_values *digest_list); 605 - 606 - /** 607 - * Read the PCR into a list of digests 608 - * 609 - * @dev TPM device 610 - * @pcr_index Index of the PCR 611 - * @digest_list List of digests to extend 612 - * 613 - * Return: zero on success, negative errno otherwise 614 - */ 615 - int tcg2_pcr_read(struct udevice *dev, u32 pcr_index, 616 - struct tpml_digest_values *digest_list); 617 - 618 - /** 619 - * Measure data into the TPM PCRs and the platform event log. 620 - * 621 - * @dev TPM device 622 - * @log Platform event log 623 - * @pcr_index Index of the PCR 624 - * @size Size of the data or 0 for event only 625 - * @data Pointer to the data or NULL for event only 626 - * @event_type Event log type 627 - * @event_size Size of the event 628 - * @event Pointer to the event 629 - * 630 - * Return: zero on success, negative errno otherwise 631 - */ 632 - int tcg2_measure_data(struct udevice *dev, struct tcg2_event_log *elog, 633 - u32 pcr_index, u32 size, const u8 *data, u32 event_type, 634 - u32 event_size, const u8 *event); 635 - 636 - #define tcg2_measure_event(dev, elog, pcr_index, event_type, size, event) \ 637 - tcg2_measure_data(dev, elog, pcr_index, 0, NULL, event_type, size, \ 638 - event) 639 - 640 - /** 641 - * Prepare the event log buffer. This function tries to discover an existing 642 - * event log in memory from a previous bootloader stage. If such a log exists 643 - * and the PCRs are not extended, the log is "replayed" to extend the PCRs. 644 - * If no log is discovered, create the log header. 645 - * 646 - * @dev TPM device 647 - * @elog Platform event log. The log pointer and log_size 648 - * members must be initialized to either 0 or to a valid 649 - * memory region, in which case any existing log 650 - * discovered will be copied to the specified memory 651 - * region. 652 - * @ignore_existing_log Boolean to indicate whether or not to ignore an 653 - * existing platform log in memory 654 - * 655 - * Return: zero on success, negative errno otherwise 656 - */ 657 - int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, 658 - bool ignore_existing_log); 659 - 660 - /** 661 - * Begin measurements. 662 - * 663 - * @dev TPM device 664 - * @elog Platform event log. The log pointer and log_size 665 - * members must be initialized to either 0 or to a valid 666 - * memory region, in which case any existing log 667 - * discovered will be copied to the specified memory 668 - * region. 669 - * @ignore_existing_log Boolean to indicate whether or not to ignore an 670 - * existing platform log in memory 671 - * 672 - * Return: zero on success, negative errno otherwise 673 - */ 674 - int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, 675 - bool ignore_existing_log); 676 - 677 - /** 678 - * Stop measurements and record separator events. 679 - * 680 - * @dev TPM device 681 - * @elog Platform event log 682 - * @error Boolean to indicate whether an error ocurred or not 683 - */ 684 - void tcg2_measurement_term(struct udevice *dev, struct tcg2_event_log *elog, 685 - bool error); 686 - 687 - /** 688 - * Get the platform event log address and size. 689 - * 690 - * @dev TPM device 691 - * @addr Address of the log 692 - * @size Size of the log 693 - * 694 - * Return: zero on success, negative errno otherwise 695 - */ 696 - int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size); 697 - 698 - /** 699 - * Get the first TPM2 device found. 700 - * 701 - * @dev TPM device 702 - * 703 - * Return: zero on success, negative errno otherwise 704 - */ 705 - int tcg2_platform_get_tpm2(struct udevice **dev); 706 - 707 - /** 708 - * Platform-specific function for handling TPM startup errors 709 - * 710 - * @dev TPM device 711 - * @rc The TPM response code 712 - */ 713 - void tcg2_platform_startup_error(struct udevice *dev, int rc); 714 - 715 - /** 716 395 * Issue a TPM2_Startup command. 717 396 * 718 397 * @dev TPM device ··· 835 514 * tpm2_get_pcr_info() - get the supported, active PCRs and number of banks 836 515 * 837 516 * @dev: TPM device 838 - * @supported_pcr: bitmask with the algorithms supported 839 - * @active_pcr: bitmask with the active algorithms 840 - * @pcr_banks: number of PCR banks 517 + * @pcrs: struct tpml_pcr_selection of available PCRs 841 518 * 842 519 * @return 0 on success, code of operation or negative errno on failure 843 520 */ 844 - int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr, 845 - u32 *pcr_banks); 521 + int tpm2_get_pcr_info(struct udevice *dev, struct tpml_pcr_selection *pcrs); 846 522 847 523 /** 848 524 * Issue a TPM2_DictionaryAttackLockReset command. ··· 1029 705 const char *tpm2_algorithm_name(enum tpm2_algorithms); 1030 706 1031 707 /** 1032 - * tpm2_algorithm_to_mask() - Get a TCG hash mask for algorithm 708 + * tpm2_algorithm_to_len() - Return an algorithm length for supported algorithm id 1033 709 * 1034 - * @hash_alg: TCG defined algorithm 1035 - * Return: TCG hashing algorithm bitmaps (or 0 if algo not supported) 710 + * @algorithm_id: algorithm defined in enum tpm2_algorithms 711 + * Return: len or 0 if not supported 1036 712 */ 1037 - u32 tpm2_algorithm_to_mask(enum tpm2_algorithms); 713 + u16 tpm2_algorithm_to_len(enum tpm2_algorithms algo); 714 + 715 + /* 716 + * When measured boot is enabled via EFI or bootX commands all the algorithms 717 + * above are selected by our Kconfigs. Due to U-Boots nature of being small there 718 + * are cases where we need some functionality from the TPM -- e.g storage or RNG 719 + * but we don't want to support measurements. 720 + * 721 + * The choice of hash algorithms are determined by the platform and the TPM 722 + * configuration. Failing to cap a PCR in a bank which the platform left 723 + * active is a security vulnerability. It permits the unsealing of secrets 724 + * if an attacker can replay a good set of measurements into an unused bank. 725 + * 726 + * On top of that a previous stage bootloader (e.g TF-A), migh pass an eventlog 727 + * since it doesn't have a TPM driver, which U-Boot needs to replace. The algorit h 728 + * choice is a compile time option in that case and we need to make sure we conform. 729 + * 730 + * Add a variable here that sums the supported algorithms U-Boot was compiled 731 + * with so we can refuse to do measurements if we don't support all of them 732 + */ 733 + 734 + /** 735 + * tpm2_allow_extend() - Check if extending PCRs is allowed and safe 736 + * 737 + * @dev: TPM device 738 + * Return: true if allowed 739 + */ 740 + bool tpm2_allow_extend(struct udevice *dev); 741 + 742 + /** 743 + * tpm2_is_active_pcr() - check the pcr_select. If at least one of the PCRs 744 + * supports the algorithm add it on the active ones 745 + * 746 + * @selection: PCR selection structure 747 + * Return: True if the algorithm is active 748 + */ 749 + bool tpm2_is_active_pcr(struct tpms_pcr_selection *selection); 1038 750 1039 751 #endif /* __TPM_V2_H */
+348
include/tpm_tcg2.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Defines APIs and structures that adhere to 4 + * https://trustedcomputinggroup.org/resource/pc-client-specific-platform-firmware-profile-specification/ 5 + * https://trustedcomputinggroup.org/resource/tcg-efi-protocol-specification/ 6 + * 7 + * Copyright (c) 2020 Linaro Limited 8 + */ 9 + 10 + #ifndef __TPM_TCG_V2_H 11 + #define __TPM_TCG_V2_H 12 + 13 + #include <tpm-v2.h> 14 + 15 + /* 16 + * event types, cf. 17 + * "TCG Server Management Domain Firmware Profile Specification", 18 + * rev 1.00, 2020-05-01 19 + */ 20 + #define EV_POST_CODE ((u32)0x00000001) 21 + #define EV_NO_ACTION ((u32)0x00000003) 22 + #define EV_SEPARATOR ((u32)0x00000004) 23 + #define EV_ACTION ((u32)0x00000005) 24 + #define EV_TAG ((u32)0x00000006) 25 + #define EV_S_CRTM_CONTENTS ((u32)0x00000007) 26 + #define EV_S_CRTM_VERSION ((u32)0x00000008) 27 + #define EV_CPU_MICROCODE ((u32)0x00000009) 28 + #define EV_PLATFORM_CONFIG_FLAGS ((u32)0x0000000A) 29 + #define EV_TABLE_OF_DEVICES ((u32)0x0000000B) 30 + #define EV_COMPACT_HASH ((u32)0x0000000C) 31 + 32 + /* 33 + * event types, cf. 34 + * "TCG PC Client Platform Firmware Profile Specification", Family "2.0" 35 + * Level 00 Version 1.05 Revision 23, May 7, 2021 36 + */ 37 + #define EV_EFI_EVENT_BASE ((u32)0x80000000) 38 + #define EV_EFI_VARIABLE_DRIVER_CONFIG ((u32)0x80000001) 39 + #define EV_EFI_VARIABLE_BOOT ((u32)0x80000002) 40 + #define EV_EFI_BOOT_SERVICES_APPLICATION ((u32)0x80000003) 41 + #define EV_EFI_BOOT_SERVICES_DRIVER ((u32)0x80000004) 42 + #define EV_EFI_RUNTIME_SERVICES_DRIVER ((u32)0x80000005) 43 + #define EV_EFI_GPT_EVENT ((u32)0x80000006) 44 + #define EV_EFI_ACTION ((u32)0x80000007) 45 + #define EV_EFI_PLATFORM_FIRMWARE_BLOB ((u32)0x80000008) 46 + #define EV_EFI_HANDOFF_TABLES ((u32)0x80000009) 47 + #define EV_EFI_PLATFORM_FIRMWARE_BLOB2 ((u32)0x8000000A) 48 + #define EV_EFI_HANDOFF_TABLES2 ((u32)0x8000000B) 49 + #define EV_EFI_VARIABLE_BOOT2 ((u32)0x8000000C) 50 + #define EV_EFI_HCRTM_EVENT ((u32)0x80000010) 51 + #define EV_EFI_VARIABLE_AUTHORITY ((u32)0x800000E0) 52 + #define EV_EFI_SPDM_FIRMWARE_BLOB ((u32)0x800000E1) 53 + #define EV_EFI_SPDM_FIRMWARE_CONFIG ((u32)0x800000E2) 54 + 55 + #define EFI_CALLING_EFI_APPLICATION \ 56 + "Calling EFI Application from Boot Option" 57 + #define EFI_RETURNING_FROM_EFI_APPLICATION \ 58 + "Returning from EFI Application from Boot Option" 59 + #define EFI_EXIT_BOOT_SERVICES_INVOCATION \ 60 + "Exit Boot Services Invocation" 61 + #define EFI_EXIT_BOOT_SERVICES_FAILED \ 62 + "Exit Boot Services Returned with Failure" 63 + #define EFI_EXIT_BOOT_SERVICES_SUCCEEDED \ 64 + "Exit Boot Services Returned with Success" 65 + #define EFI_DTB_EVENT_STRING \ 66 + "DTB DATA" 67 + 68 + /** 69 + * struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information 70 + * 71 + * @algorithm_id: algorithm defined in enum tpm2_algorithms 72 + * @digest_size: size of the algorithm 73 + */ 74 + struct tcg_efi_spec_id_event_algorithm_size { 75 + u16 algorithm_id; 76 + u16 digest_size; 77 + } __packed; 78 + 79 + /** 80 + * SHA1 Event Log Entry Format 81 + * 82 + * @pcr_index: PCRIndex event extended to 83 + * @event_type: Type of event (see EFI specs) 84 + * @digest: Value extended into PCR index 85 + * @event_size: Size of event 86 + * @event: Event data 87 + */ 88 + struct tcg_pcr_event { 89 + u32 pcr_index; 90 + u32 event_type; 91 + u8 digest[TPM2_SHA1_DIGEST_SIZE]; 92 + u32 event_size; 93 + u8 event[]; 94 + } __packed; 95 + 96 + /** 97 + * tcg2_get_pcr_info() - get the supported, active PCRs and number of banks 98 + * 99 + * @dev: TPM device 100 + * @supported_pcr: bitmask with the algorithms supported 101 + * @active_pcr: bitmask with the active algorithms 102 + * @pcr_banks: number of PCR banks 103 + * 104 + * @return 0 on success, code of operation or negative errno on failure 105 + */ 106 + int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr, 107 + u32 *pcr_banks); 108 + 109 + /** 110 + * Crypto Agile Log Entry Format 111 + * 112 + * @pcr_index: PCRIndex event extended to 113 + * @event_type: Type of event 114 + * @digests: List of digestsextended to PCR index 115 + * @event_size: Size of the event data 116 + * @event: Event data 117 + */ 118 + struct tcg_pcr_event2 { 119 + u32 pcr_index; 120 + u32 event_type; 121 + struct tpml_digest_values digests; 122 + u32 event_size; 123 + u8 event[]; 124 + } __packed; 125 + 126 + /** 127 + * struct TCG_EfiSpecIDEventStruct - content of the event log header 128 + * 129 + * @signature: signature, set to Spec ID Event03 130 + * @platform_class: class defined in TCG ACPI Specification 131 + * Client Common Header. 132 + * @spec_version_minor: minor version 133 + * @spec_version_major: major version 134 + * @spec_version_errata: major version 135 + * @uintn_size: size of the efi_uintn_t fields used in various 136 + * data structures used in this specification. 137 + * 0x01 indicates u32 and 0x02 indicates u64 138 + * @number_of_algorithms: hashing algorithms used in this event log 139 + * @digest_sizes: array of number_of_algorithms pairs 140 + * 1st member defines the algorithm id 141 + * 2nd member defines the algorithm size 142 + */ 143 + struct tcg_efi_spec_id_event { 144 + u8 signature[16]; 145 + u32 platform_class; 146 + u8 spec_version_minor; 147 + u8 spec_version_major; 148 + u8 spec_errata; 149 + u8 uintn_size; 150 + u32 number_of_algorithms; 151 + struct tcg_efi_spec_id_event_algorithm_size digest_sizes[]; 152 + } __packed; 153 + 154 + #define TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03 "Spec ID Event03" 155 + #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2 2 156 + #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 0 157 + #define TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2 2 158 + /** 159 + * struct tcg2_event_log - Container for managing the platform event log 160 + * 161 + * @log: Address of the log 162 + * @log_position: Current entry position 163 + * @log_size: Log space available 164 + * @found: Boolean indicating if an existing log was discovered 165 + */ 166 + struct tcg2_event_log { 167 + u8 *log; 168 + u32 log_position; 169 + u32 log_size; 170 + bool found; 171 + }; 172 + 173 + /** 174 + * Create a list of digests of the supported PCR banks for a given input data 175 + * 176 + * @dev TPM device 177 + * @input Data 178 + * @length Length of the data to calculate the digest 179 + * @digest_list List of digests to fill in 180 + * 181 + * Return: zero on success, negative errno otherwise 182 + */ 183 + int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 length, 184 + struct tpml_digest_values *digest_list); 185 + 186 + /** 187 + * Get the event size of the specified digests 188 + * 189 + * @digest_list List of digests for the event 190 + * 191 + * Return: Size in bytes of the event 192 + */ 193 + u32 tcg2_event_get_size(struct tpml_digest_values *digest_list); 194 + 195 + /** 196 + * tcg2_get_active_pcr_banks 197 + * 198 + * @dev TPM device 199 + * @active_pcr_banks Bitmask of PCR algorithms supported 200 + * 201 + * Return: zero on success, negative errno otherwise 202 + */ 203 + int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks); 204 + 205 + /** 206 + * tcg2_log_append - Append an event to an event log 207 + * 208 + * @pcr_index Index of the PCR 209 + * @event_type Type of event 210 + * @digest_list List of digests to add 211 + * @size Size of event 212 + * @event Event data 213 + * @log Log buffer to append the event to 214 + */ 215 + void tcg2_log_append(u32 pcr_index, u32 event_type, 216 + struct tpml_digest_values *digest_list, u32 size, 217 + const u8 *event, u8 *log); 218 + 219 + /** 220 + * Extend the PCR with specified digests 221 + * 222 + * @dev TPM device 223 + * @pcr_index Index of the PCR 224 + * @digest_list List of digests to extend 225 + * 226 + * Return: zero on success, negative errno otherwise 227 + */ 228 + int tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, 229 + struct tpml_digest_values *digest_list); 230 + 231 + /** 232 + * Read the PCR into a list of digests 233 + * 234 + * @dev TPM device 235 + * @pcr_index Index of the PCR 236 + * @digest_list List of digests to extend 237 + * 238 + * Return: zero on success, negative errno otherwise 239 + */ 240 + int tcg2_pcr_read(struct udevice *dev, u32 pcr_index, 241 + struct tpml_digest_values *digest_list); 242 + 243 + /** 244 + * Measure data into the TPM PCRs and the platform event log. 245 + * 246 + * @dev TPM device 247 + * @log Platform event log 248 + * @pcr_index Index of the PCR 249 + * @size Size of the data or 0 for event only 250 + * @data Pointer to the data or NULL for event only 251 + * @event_type Event log type 252 + * @event_size Size of the event 253 + * @event Pointer to the event 254 + * 255 + * Return: zero on success, negative errno otherwise 256 + */ 257 + int tcg2_measure_data(struct udevice *dev, struct tcg2_event_log *elog, 258 + u32 pcr_index, u32 size, const u8 *data, u32 event_type, 259 + u32 event_size, const u8 *event); 260 + 261 + #define tcg2_measure_event(dev, elog, pcr_index, event_type, size, event) \ 262 + tcg2_measure_data(dev, elog, pcr_index, 0, NULL, event_type, size, \ 263 + event) 264 + 265 + /** 266 + * Prepare the event log buffer. This function tries to discover an existing 267 + * event log in memory from a previous bootloader stage. If such a log exists 268 + * and the PCRs are not extended, the log is "replayed" to extend the PCRs. 269 + * If no log is discovered, create the log header. 270 + * 271 + * @dev TPM device 272 + * @elog Platform event log. The log pointer and log_size 273 + * members must be initialized to either 0 or to a valid 274 + * memory region, in which case any existing log 275 + * discovered will be copied to the specified memory 276 + * region. 277 + * @ignore_existing_log Boolean to indicate whether or not to ignore an 278 + * existing platform log in memory 279 + * 280 + * Return: zero on success, negative errno otherwise 281 + */ 282 + int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, 283 + bool ignore_existing_log); 284 + 285 + /** 286 + * Begin measurements. 287 + * 288 + * @dev TPM device 289 + * @elog Platform event log. The log pointer and log_size 290 + * members must be initialized to either 0 or to a valid 291 + * memory region, in which case any existing log 292 + * discovered will be copied to the specified memory 293 + * region. 294 + * @ignore_existing_log Boolean to indicate whether or not to ignore an 295 + * existing platform log in memory 296 + * 297 + * Return: zero on success, negative errno otherwise 298 + */ 299 + int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, 300 + bool ignore_existing_log); 301 + 302 + /** 303 + * Stop measurements and record separator events. 304 + * 305 + * @dev TPM device 306 + * @elog Platform event log 307 + * @error Boolean to indicate whether an error ocurred or not 308 + */ 309 + void tcg2_measurement_term(struct udevice *dev, struct tcg2_event_log *elog, 310 + bool error); 311 + 312 + /** 313 + * Get the platform event log address and size. 314 + * 315 + * @dev TPM device 316 + * @addr Address of the log 317 + * @size Size of the log 318 + * 319 + * Return: zero on success, negative errno otherwise 320 + */ 321 + int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size); 322 + 323 + /** 324 + * Get the first TPM2 device found. 325 + * 326 + * @dev TPM device 327 + * 328 + * Return: zero on success, negative errno otherwise 329 + */ 330 + int tcg2_platform_get_tpm2(struct udevice **dev); 331 + 332 + /** 333 + * Platform-specific function for handling TPM startup errors 334 + * 335 + * @dev TPM device 336 + * @rc The TPM response code 337 + */ 338 + void tcg2_platform_startup_error(struct udevice *dev, int rc); 339 + 340 + /** 341 + * tcg2_algorithm_to_mask() - Get a TCG hash mask for algorithm 342 + * 343 + * @hash_alg: TCG defined algorithm 344 + * Return: TCG hashing algorithm bitmaps (or 0 if algo not supported) 345 + */ 346 + u32 tcg2_algorithm_to_mask(enum tpm2_algorithms); 347 + 348 + #endif /* __TPM_TCG_V2_H */
+3 -3
lib/Kconfig
··· 439 439 depends on DM 440 440 imply DM_RNG 441 441 select SHA1 442 - select SHA256 443 - select SHA384 444 - select SHA512 445 442 help 446 443 This enables support for TPMs which can be used to provide security 447 444 features for your board. The TPM can be connected via LPC or I2C ··· 449 446 command to interactive the TPM. Driver model support is provided 450 447 for the low-level TPM interface, but only one TPM is supported at 451 448 a time by the TPM library. 449 + For size reasons only SHA1 is selected which is supported on TPM1.2. 450 + If you want a fully functional TPM enable all hashing algorithms. 451 + If you enabled measured boot all hashing algorithms are selected. 452 452 453 453 config SPL_TPM 454 454 bool "Trusted Platform Module (TPM) Support in SPL"
+2
lib/Makefile
··· 61 61 obj-$(CONFIG_TPM) += tpm_api.o 62 62 obj-$(CONFIG_TPM_V1) += tpm-v1.o 63 63 obj-$(CONFIG_TPM_V2) += tpm-v2.o 64 + obj-$(CONFIG_EFI_TCG2_PROTOCOL) += tpm_tcg2.o 65 + obj-$(CONFIG_MEASURED_BOOT) += tpm_tcg2.o 64 66 endif 65 67 66 68 obj-$(CONFIG_$(SPL_TPL_)CRC8) += crc8.o
+1 -2
lib/efi_loader/efi_tcg2.c
··· 16 16 #include <malloc.h> 17 17 #include <smbios.h> 18 18 #include <version_string.h> 19 - #include <tpm-v2.h> 20 19 #include <tpm_api.h> 21 20 #include <u-boot/hash-checksum.h> 22 21 #include <linux/unaligned/be_byteshift.h> ··· 277 276 /* Supported and active PCRs */ 278 277 capability->hash_algorithm_bitmap = 0; 279 278 capability->active_pcr_banks = 0; 280 - ret = tpm2_get_pcr_info(dev, &capability->hash_algorithm_bitmap, 279 + ret = tcg2_get_pcr_info(dev, &capability->hash_algorithm_bitmap, 281 280 &capability->active_pcr_banks, 282 281 &capability->number_of_pcr_banks); 283 282 if (ret) {
+7
lib/efi_selftest/efi_selftest_fdt.c
··· 227 227 return EFI_ST_FAILURE; 228 228 } 229 229 } 230 + if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL_MEASURE_DTB)) { 231 + str = get_property(u"kaslr-seed", u"chosen"); 232 + if (str) { 233 + efi_st_error("kaslr-seed with measured fdt\n"); 234 + return EFI_ST_FAILURE; 235 + } 236 + } 230 237 if (IS_ENABLED(CONFIG_RISCV)) { 231 238 u32 fdt_hartid; 232 239
+52 -715
lib/tpm-v2.c
··· 10 10 #include <tpm_api.h> 11 11 #include <tpm-common.h> 12 12 #include <tpm-v2.h> 13 + #include <tpm_tcg2.h> 13 14 #include <u-boot/sha1.h> 14 15 #include <u-boot/sha256.h> 15 16 #include <u-boot/sha512.h> ··· 22 23 23 24 #include "tpm-utils.h" 24 25 25 - int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks) 26 - { 27 - u32 supported = 0; 28 - u32 pcr_banks = 0; 29 - u32 active = 0; 30 - int rc; 31 - 32 - rc = tpm2_get_pcr_info(dev, &supported, &active, &pcr_banks); 33 - if (rc) 34 - return rc; 35 - 36 - *active_pcr_banks = active; 37 - 38 - return 0; 39 - } 40 - 41 - u32 tcg2_event_get_size(struct tpml_digest_values *digest_list) 42 - { 43 - u32 len; 44 - size_t i; 45 - 46 - len = offsetof(struct tcg_pcr_event2, digests); 47 - len += offsetof(struct tpml_digest_values, digests); 48 - for (i = 0; i < digest_list->count; ++i) { 49 - u16 l = tpm2_algorithm_to_len(digest_list->digests[i].hash_alg); 50 - 51 - if (!l) 52 - continue; 53 - 54 - len += l + offsetof(struct tpmt_ha, digest); 55 - } 56 - len += sizeof(u32); 57 - 58 - return len; 59 - } 60 - 61 - int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 length, 62 - struct tpml_digest_values *digest_list) 63 - { 64 - u8 final[sizeof(union tpmu_ha)]; 65 - sha256_context ctx_256; 66 - sha512_context ctx_512; 67 - sha1_context ctx; 68 - u32 active; 69 - size_t i; 70 - u32 len; 71 - int rc; 72 - 73 - rc = tcg2_get_active_pcr_banks(dev, &active); 74 - if (rc) 75 - return rc; 76 - 77 - digest_list->count = 0; 78 - for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { 79 - if (!(active & hash_algo_list[i].hash_mask)) 80 - continue; 81 - 82 - switch (hash_algo_list[i].hash_alg) { 83 - case TPM2_ALG_SHA1: 84 - sha1_starts(&ctx); 85 - sha1_update(&ctx, input, length); 86 - sha1_finish(&ctx, final); 87 - len = TPM2_SHA1_DIGEST_SIZE; 88 - break; 89 - case TPM2_ALG_SHA256: 90 - sha256_starts(&ctx_256); 91 - sha256_update(&ctx_256, input, length); 92 - sha256_finish(&ctx_256, final); 93 - len = TPM2_SHA256_DIGEST_SIZE; 94 - break; 95 - case TPM2_ALG_SHA384: 96 - sha384_starts(&ctx_512); 97 - sha384_update(&ctx_512, input, length); 98 - sha384_finish(&ctx_512, final); 99 - len = TPM2_SHA384_DIGEST_SIZE; 100 - break; 101 - case TPM2_ALG_SHA512: 102 - sha512_starts(&ctx_512); 103 - sha512_update(&ctx_512, input, length); 104 - sha512_finish(&ctx_512, final); 105 - len = TPM2_SHA512_DIGEST_SIZE; 106 - break; 107 - default: 108 - printf("%s: unsupported algorithm %x\n", __func__, 109 - hash_algo_list[i].hash_alg); 110 - continue; 111 - } 112 - 113 - digest_list->digests[digest_list->count].hash_alg = 114 - hash_algo_list[i].hash_alg; 115 - memcpy(&digest_list->digests[digest_list->count].digest, final, 116 - len); 117 - digest_list->count++; 118 - } 119 - 120 - return 0; 121 - } 122 - 123 - void tcg2_log_append(u32 pcr_index, u32 event_type, 124 - struct tpml_digest_values *digest_list, u32 size, 125 - const u8 *event, u8 *log) 126 - { 127 - size_t len; 128 - size_t pos; 129 - u32 i; 130 - 131 - pos = offsetof(struct tcg_pcr_event2, pcr_index); 132 - put_unaligned_le32(pcr_index, log); 133 - pos = offsetof(struct tcg_pcr_event2, event_type); 134 - put_unaligned_le32(event_type, log + pos); 135 - pos = offsetof(struct tcg_pcr_event2, digests) + 136 - offsetof(struct tpml_digest_values, count); 137 - put_unaligned_le32(digest_list->count, log + pos); 138 - 139 - pos = offsetof(struct tcg_pcr_event2, digests) + 140 - offsetof(struct tpml_digest_values, digests); 141 - for (i = 0; i < digest_list->count; ++i) { 142 - u16 hash_alg = digest_list->digests[i].hash_alg; 143 - 144 - len = tpm2_algorithm_to_len(hash_alg); 145 - if (!len) 146 - continue; 147 - 148 - pos += offsetof(struct tpmt_ha, hash_alg); 149 - put_unaligned_le16(hash_alg, log + pos); 150 - pos += offsetof(struct tpmt_ha, digest); 151 - memcpy(log + pos, (u8 *)&digest_list->digests[i].digest, len); 152 - pos += len; 153 - } 154 - 155 - put_unaligned_le32(size, log + pos); 156 - pos += sizeof(u32); 157 - memcpy(log + pos, event, size); 158 - } 159 - 160 - static int tcg2_log_append_check(struct tcg2_event_log *elog, u32 pcr_index, 161 - u32 event_type, 162 - struct tpml_digest_values *digest_list, 163 - u32 size, const u8 *event) 164 - { 165 - u32 event_size; 166 - u8 *log; 167 - 168 - event_size = size + tcg2_event_get_size(digest_list); 169 - if (elog->log_position + event_size > elog->log_size) { 170 - printf("%s: log too large: %u + %u > %u\n", __func__, 171 - elog->log_position, event_size, elog->log_size); 172 - return -ENOBUFS; 173 - } 174 - 175 - log = elog->log + elog->log_position; 176 - elog->log_position += event_size; 177 - 178 - tcg2_log_append(pcr_index, event_type, digest_list, size, event, log); 179 - 180 - return 0; 181 - } 182 - 183 - static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log *elog) 184 - { 185 - struct tcg_efi_spec_id_event *ev; 186 - struct tcg_pcr_event *log; 187 - u32 event_size; 188 - u32 count = 0; 189 - u32 log_size; 190 - u32 active; 191 - size_t i; 192 - u16 len; 193 - int rc; 194 - 195 - rc = tcg2_get_active_pcr_banks(dev, &active); 196 - if (rc) 197 - return rc; 198 - 199 - event_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes); 200 - for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { 201 - if (!(active & hash_algo_list[i].hash_mask)) 202 - continue; 203 - 204 - switch (hash_algo_list[i].hash_alg) { 205 - case TPM2_ALG_SHA1: 206 - case TPM2_ALG_SHA256: 207 - case TPM2_ALG_SHA384: 208 - case TPM2_ALG_SHA512: 209 - count++; 210 - break; 211 - default: 212 - continue; 213 - } 214 - } 215 - 216 - event_size += 1 + 217 - (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count); 218 - log_size = offsetof(struct tcg_pcr_event, event) + event_size; 219 - 220 - if (log_size > elog->log_size) { 221 - printf("%s: log too large: %u > %u\n", __func__, log_size, 222 - elog->log_size); 223 - return -ENOBUFS; 224 - } 225 - 226 - log = (struct tcg_pcr_event *)elog->log; 227 - put_unaligned_le32(0, &log->pcr_index); 228 - put_unaligned_le32(EV_NO_ACTION, &log->event_type); 229 - memset(&log->digest, 0, sizeof(log->digest)); 230 - put_unaligned_le32(event_size, &log->event_size); 231 - 232 - ev = (struct tcg_efi_spec_id_event *)log->event; 233 - strlcpy((char *)ev->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, 234 - sizeof(ev->signature)); 235 - put_unaligned_le32(0, &ev->platform_class); 236 - ev->spec_version_minor = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2; 237 - ev->spec_version_major = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2; 238 - ev->spec_errata = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2; 239 - ev->uintn_size = sizeof(size_t) / sizeof(u32); 240 - put_unaligned_le32(count, &ev->number_of_algorithms); 241 - 242 - count = 0; 243 - for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { 244 - if (!(active & hash_algo_list[i].hash_mask)) 245 - continue; 246 - 247 - len = hash_algo_list[i].hash_len; 248 - if (!len) 249 - continue; 250 - 251 - put_unaligned_le16(hash_algo_list[i].hash_alg, 252 - &ev->digest_sizes[count].algorithm_id); 253 - put_unaligned_le16(len, &ev->digest_sizes[count].digest_size); 254 - count++; 255 - } 256 - 257 - *((u8 *)ev + (event_size - 1)) = 0; 258 - elog->log_position = log_size; 259 - 260 - return 0; 261 - } 262 - 263 - static int tcg2_replay_eventlog(struct tcg2_event_log *elog, 264 - struct udevice *dev, 265 - struct tpml_digest_values *digest_list, 266 - u32 log_position) 267 - { 268 - const u32 offset = offsetof(struct tcg_pcr_event2, digests) + 269 - offsetof(struct tpml_digest_values, digests); 270 - u32 event_size; 271 - u32 count; 272 - u16 algo; 273 - u32 pcr; 274 - u32 pos; 275 - u16 len; 276 - u8 *log; 277 - int rc; 278 - u32 i; 279 - 280 - while (log_position + offset < elog->log_size) { 281 - log = elog->log + log_position; 282 - 283 - pos = offsetof(struct tcg_pcr_event2, pcr_index); 284 - pcr = get_unaligned_le32(log + pos); 285 - pos = offsetof(struct tcg_pcr_event2, event_type); 286 - if (!get_unaligned_le32(log + pos)) 287 - return 0; 288 - 289 - pos = offsetof(struct tcg_pcr_event2, digests) + 290 - offsetof(struct tpml_digest_values, count); 291 - count = get_unaligned_le32(log + pos); 292 - if (count > ARRAY_SIZE(hash_algo_list) || 293 - (digest_list->count && digest_list->count != count)) 294 - return 0; 295 - 296 - pos = offsetof(struct tcg_pcr_event2, digests) + 297 - offsetof(struct tpml_digest_values, digests); 298 - for (i = 0; i < count; ++i) { 299 - pos += offsetof(struct tpmt_ha, hash_alg); 300 - if (log_position + pos + sizeof(u16) >= elog->log_size) 301 - return 0; 302 - 303 - algo = get_unaligned_le16(log + pos); 304 - pos += offsetof(struct tpmt_ha, digest); 305 - switch (algo) { 306 - case TPM2_ALG_SHA1: 307 - case TPM2_ALG_SHA256: 308 - case TPM2_ALG_SHA384: 309 - case TPM2_ALG_SHA512: 310 - len = tpm2_algorithm_to_len(algo); 311 - break; 312 - default: 313 - return 0; 314 - } 315 - 316 - if (digest_list->count) { 317 - if (algo != digest_list->digests[i].hash_alg || 318 - log_position + pos + len >= elog->log_size) 319 - return 0; 320 - 321 - memcpy(digest_list->digests[i].digest.sha512, 322 - log + pos, len); 323 - } 324 - 325 - pos += len; 326 - } 327 - 328 - if (log_position + pos + sizeof(u32) >= elog->log_size) 329 - return 0; 330 - 331 - event_size = get_unaligned_le32(log + pos); 332 - pos += event_size + sizeof(u32); 333 - if (log_position + pos > elog->log_size) 334 - return 0; 335 - 336 - if (digest_list->count) { 337 - rc = tcg2_pcr_extend(dev, pcr, digest_list); 338 - if (rc) 339 - return rc; 340 - } 341 - 342 - log_position += pos; 343 - } 344 - 345 - elog->log_position = log_position; 346 - elog->found = true; 347 - return 0; 348 - } 349 - 350 - static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog) 351 - { 352 - struct tpml_digest_values digest_list; 353 - struct tcg_efi_spec_id_event *event; 354 - struct tcg_pcr_event *log; 355 - u32 log_active; 356 - u32 calc_size; 357 - u32 active; 358 - u32 count; 359 - u32 evsz; 360 - u32 mask; 361 - u16 algo; 362 - u16 len; 363 - int rc; 364 - u32 i; 365 - u16 j; 366 - 367 - if (elog->log_size <= offsetof(struct tcg_pcr_event, event)) 368 - return 0; 369 - 370 - log = (struct tcg_pcr_event *)elog->log; 371 - if (get_unaligned_le32(&log->pcr_index) != 0 || 372 - get_unaligned_le32(&log->event_type) != EV_NO_ACTION) 373 - return 0; 374 - 375 - for (i = 0; i < sizeof(log->digest); i++) { 376 - if (log->digest[i]) 377 - return 0; 378 - } 379 - 380 - evsz = get_unaligned_le32(&log->event_size); 381 - if (evsz < offsetof(struct tcg_efi_spec_id_event, digest_sizes) || 382 - evsz + offsetof(struct tcg_pcr_event, event) > elog->log_size) 383 - return 0; 384 - 385 - event = (struct tcg_efi_spec_id_event *)log->event; 386 - if (memcmp(event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, 387 - sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) 388 - return 0; 389 - 390 - if (event->spec_version_minor != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 || 391 - event->spec_version_major != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2) 392 - return 0; 393 - 394 - count = get_unaligned_le32(&event->number_of_algorithms); 395 - if (count > ARRAY_SIZE(hash_algo_list)) 396 - return 0; 397 - 398 - calc_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes) + 399 - (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count) + 400 - 1; 401 - if (evsz != calc_size) 402 - return 0; 403 - 404 - rc = tcg2_get_active_pcr_banks(dev, &active); 405 - if (rc) 406 - return rc; 407 - 408 - digest_list.count = 0; 409 - log_active = 0; 410 - 411 - for (i = 0; i < count; ++i) { 412 - algo = get_unaligned_le16(&event->digest_sizes[i].algorithm_id); 413 - mask = tpm2_algorithm_to_mask(algo); 414 - 415 - if (!(active & mask)) 416 - return 0; 417 - 418 - switch (algo) { 419 - case TPM2_ALG_SHA1: 420 - case TPM2_ALG_SHA256: 421 - case TPM2_ALG_SHA384: 422 - case TPM2_ALG_SHA512: 423 - len = get_unaligned_le16(&event->digest_sizes[i].digest_size); 424 - if (tpm2_algorithm_to_len(algo) != len) 425 - return 0; 426 - digest_list.digests[digest_list.count++].hash_alg = algo; 427 - break; 428 - default: 429 - return 0; 430 - } 431 - 432 - log_active |= mask; 433 - } 434 - 435 - /* Ensure the previous firmware extended all the PCRs. */ 436 - if (log_active != active) 437 - return 0; 438 - 439 - /* Read PCR0 to check if previous firmware extended the PCRs or not. */ 440 - rc = tcg2_pcr_read(dev, 0, &digest_list); 441 - if (rc) 442 - return rc; 443 - 444 - for (i = 0; i < digest_list.count; ++i) { 445 - len = tpm2_algorithm_to_len(digest_list.digests[i].hash_alg); 446 - for (j = 0; j < len; ++j) { 447 - if (digest_list.digests[i].digest.sha512[j]) 448 - break; 449 - } 450 - 451 - /* PCR is non-zero; it has been extended, so skip extending. */ 452 - if (j != len) { 453 - digest_list.count = 0; 454 - break; 455 - } 456 - } 457 - 458 - return tcg2_replay_eventlog(elog, dev, &digest_list, 459 - offsetof(struct tcg_pcr_event, event) + 460 - evsz); 461 - } 462 - 463 - int tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, 464 - struct tpml_digest_values *digest_list) 465 - { 466 - u32 rc; 467 - u32 i; 468 - 469 - for (i = 0; i < digest_list->count; i++) { 470 - u32 alg = digest_list->digests[i].hash_alg; 471 - 472 - rc = tpm2_pcr_extend(dev, pcr_index, alg, 473 - (u8 *)&digest_list->digests[i].digest, 474 - tpm2_algorithm_to_len(alg)); 475 - if (rc) { 476 - printf("%s: error pcr:%u alg:%08x\n", __func__, 477 - pcr_index, alg); 478 - return rc; 479 - } 480 - } 481 - 482 - return 0; 483 - } 484 - 485 - int tcg2_pcr_read(struct udevice *dev, u32 pcr_index, 486 - struct tpml_digest_values *digest_list) 487 - { 488 - struct tpm_chip_priv *priv; 489 - u32 rc; 490 - u32 i; 491 - 492 - priv = dev_get_uclass_priv(dev); 493 - if (!priv) 494 - return -ENODEV; 495 - 496 - for (i = 0; i < digest_list->count; i++) { 497 - u32 alg = digest_list->digests[i].hash_alg; 498 - u8 *digest = (u8 *)&digest_list->digests[i].digest; 499 - 500 - rc = tpm2_pcr_read(dev, pcr_index, priv->pcr_select_min, alg, 501 - digest, tpm2_algorithm_to_len(alg), NULL); 502 - if (rc) { 503 - printf("%s: error pcr:%u alg:%08x\n", __func__, 504 - pcr_index, alg); 505 - return rc; 506 - } 507 - } 508 - 509 - return 0; 510 - } 511 - 512 - int tcg2_measure_data(struct udevice *dev, struct tcg2_event_log *elog, 513 - u32 pcr_index, u32 size, const u8 *data, u32 event_type, 514 - u32 event_size, const u8 *event) 515 - { 516 - struct tpml_digest_values digest_list; 517 - int rc; 518 - 519 - if (data) 520 - rc = tcg2_create_digest(dev, data, size, &digest_list); 521 - else 522 - rc = tcg2_create_digest(dev, event, event_size, &digest_list); 523 - if (rc) 524 - return rc; 525 - 526 - rc = tcg2_pcr_extend(dev, pcr_index, &digest_list); 527 - if (rc) 528 - return rc; 529 - 530 - return tcg2_log_append_check(elog, pcr_index, event_type, &digest_list, 531 - event_size, event); 532 - } 533 - 534 - int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, 535 - bool ignore_existing_log) 536 - { 537 - struct tcg2_event_log log; 538 - int rc; 539 - 540 - elog->log_position = 0; 541 - elog->found = false; 542 - 543 - rc = tcg2_platform_get_log(dev, (void **)&log.log, &log.log_size); 544 - if (!rc) { 545 - log.log_position = 0; 546 - log.found = false; 547 - 548 - if (!ignore_existing_log) { 549 - rc = tcg2_log_parse(dev, &log); 550 - if (rc) 551 - return rc; 552 - } 553 - 554 - if (elog->log_size) { 555 - if (log.found) { 556 - if (elog->log_size < log.log_position) 557 - return -ENOBUFS; 558 - 559 - /* 560 - * Copy the discovered log into the user buffer 561 - * if there's enough space. 562 - */ 563 - memcpy(elog->log, log.log, log.log_position); 564 - } 565 - 566 - unmap_physmem(log.log, MAP_NOCACHE); 567 - } else { 568 - elog->log = log.log; 569 - elog->log_size = log.log_size; 570 - } 571 - 572 - elog->log_position = log.log_position; 573 - elog->found = log.found; 574 - } 575 - 576 - /* 577 - * Initialize the log buffer if no log was discovered and the buffer is 578 - * valid. User's can pass in their own buffer as a fallback if no 579 - * memory region is found. 580 - */ 581 - if (!elog->found && elog->log_size) 582 - rc = tcg2_log_init(dev, elog); 583 - 584 - return rc; 585 - } 586 - 587 - int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, 588 - bool ignore_existing_log) 589 - { 590 - int rc; 591 - 592 - rc = tcg2_platform_get_tpm2(dev); 593 - if (rc) 594 - return rc; 595 - 596 - rc = tpm_auto_start(*dev); 597 - if (rc) 598 - return rc; 599 - 600 - rc = tcg2_log_prepare_buffer(*dev, elog, ignore_existing_log); 601 - if (rc) { 602 - tcg2_measurement_term(*dev, elog, true); 603 - return rc; 604 - } 605 - 606 - rc = tcg2_measure_event(*dev, elog, 0, EV_S_CRTM_VERSION, 607 - strlen(version_string) + 1, 608 - (u8 *)version_string); 609 - if (rc) { 610 - tcg2_measurement_term(*dev, elog, true); 611 - return rc; 612 - } 613 - 614 - return 0; 615 - } 616 - 617 - void tcg2_measurement_term(struct udevice *dev, struct tcg2_event_log *elog, 618 - bool error) 619 - { 620 - u32 event = error ? 0x1 : 0xffffffff; 621 - int i; 622 - 623 - for (i = 0; i < 8; ++i) 624 - tcg2_measure_event(dev, elog, i, EV_SEPARATOR, sizeof(event), 625 - (const u8 *)&event); 626 - 627 - if (elog->log) 628 - unmap_physmem(elog->log, MAP_NOCACHE); 629 - } 630 - 631 - __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) 632 - { 633 - const __be32 *addr_prop; 634 - const __be32 *size_prop; 635 - int asize; 636 - int ssize; 637 - 638 - *addr = NULL; 639 - *size = 0; 640 - 641 - addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); 642 - if (!addr_prop) 643 - addr_prop = dev_read_prop(dev, "linux,sml-base", &asize); 644 - 645 - size_prop = dev_read_prop(dev, "tpm_event_log_size", &ssize); 646 - if (!size_prop) 647 - size_prop = dev_read_prop(dev, "linux,sml-size", &ssize); 648 - 649 - if (addr_prop && size_prop) { 650 - u64 a = of_read_number(addr_prop, asize / sizeof(__be32)); 651 - u64 s = of_read_number(size_prop, ssize / sizeof(__be32)); 652 - 653 - *addr = map_physmem(a, s, MAP_NOCACHE); 654 - *size = (u32)s; 655 - } else { 656 - struct ofnode_phandle_args args; 657 - phys_addr_t a; 658 - fdt_size_t s; 659 - 660 - if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, 661 - 0, &args)) 662 - return -ENODEV; 663 - 664 - a = ofnode_get_addr_size(args.node, "reg", &s); 665 - if (a == FDT_ADDR_T_NONE) 666 - return -ENOMEM; 667 - 668 - *addr = map_physmem(a, s, MAP_NOCACHE); 669 - *size = (u32)s; 670 - } 671 - 672 - return 0; 673 - } 674 - 675 - __weak int tcg2_platform_get_tpm2(struct udevice **dev) 676 - { 677 - for_each_tpm_device(*dev) { 678 - if (tpm_get_version(*dev) == TPM_V2) 679 - return 0; 680 - } 681 - 682 - return -ENODEV; 683 - } 684 - 685 - __weak void tcg2_platform_startup_error(struct udevice *dev, int rc) {} 686 - 687 26 u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode) 688 27 { 689 28 const u8 command_v2[12] = { ··· 857 196 858 197 if (!digest) 859 198 return -EINVAL; 199 + 200 + if (!tpm2_allow_extend(dev)) { 201 + log_err("Cannot extend PCRs if all the TPM enabled algorithms are not supported\n"); 202 + return -EINVAL; 203 + } 860 204 /* 861 205 * Fill the command structure starting from the first buffer: 862 206 * - the digest ··· 1056 400 return 0; 1057 401 } 1058 402 1059 - static bool tpm2_is_active_pcr(struct tpms_pcr_selection *selection) 1060 - { 1061 - int i; 1062 - 1063 - /* 1064 - * check the pcr_select. If at least one of the PCRs supports the 1065 - * algorithm add it on the active ones 1066 - */ 1067 - for (i = 0; i < selection->size_of_select; i++) { 1068 - if (selection->pcr_select[i]) 1069 - return true; 1070 - } 1071 - 1072 - return false; 1073 - } 1074 - 1075 - int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr, 1076 - u32 *pcr_banks) 403 + int tpm2_get_pcr_info(struct udevice *dev, struct tpml_pcr_selection *pcrs) 1077 404 { 1078 405 u8 response[(sizeof(struct tpms_capability_data) - 1079 406 offsetof(struct tpms_capability_data, data))]; 1080 - struct tpml_pcr_selection pcrs; 1081 407 u32 num_pcr; 1082 408 size_t i; 1083 409 u32 ret; 1084 410 1085 - *supported_pcr = 0; 1086 - *active_pcr = 0; 1087 - *pcr_banks = 0; 1088 - memset(response, 0, sizeof(response)); 1089 411 ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1); 1090 412 if (ret) 1091 413 return ret; 1092 414 1093 - pcrs.count = get_unaligned_be32(response); 415 + pcrs->count = get_unaligned_be32(response); 1094 416 /* 1095 - * We only support 5 algorithms for now so check against that 417 + * We only support 4 algorithms for now so check against that 1096 418 * instead of TPM2_NUM_PCR_BANKS 1097 419 */ 1098 - if (pcrs.count > ARRAY_SIZE(hash_algo_list) || 1099 - pcrs.count < 1) { 1100 - printf("%s: too many pcrs: %u\n", __func__, pcrs.count); 420 + if (pcrs->count > 4 || pcrs->count < 1) { 421 + printf("%s: too many pcrs: %u\n", __func__, pcrs->count); 1101 422 return -EMSGSIZE; 1102 423 } 1103 424 ··· 1105 426 if (ret) 1106 427 return ret; 1107 428 1108 - for (i = 0; i < pcrs.count; i++) { 429 + for (i = 0; i < pcrs->count; i++) { 1109 430 /* 1110 431 * Definition of TPMS_PCR_SELECTION Structure 1111 432 * hash: u16 ··· 1125 446 hash_offset + offsetof(struct tpms_pcr_selection, 1126 447 pcr_select); 1127 448 1128 - pcrs.selection[i].hash = 449 + pcrs->selection[i].hash = 1129 450 get_unaligned_be16(response + hash_offset); 1130 - pcrs.selection[i].size_of_select = 451 + pcrs->selection[i].size_of_select = 1131 452 __get_unaligned_be(response + size_select_offset); 1132 - if (pcrs.selection[i].size_of_select > TPM2_PCR_SELECT_MAX) { 453 + if (pcrs->selection[i].size_of_select > TPM2_PCR_SELECT_MAX) { 1133 454 printf("%s: pcrs selection too large: %u\n", __func__, 1134 - pcrs.selection[i].size_of_select); 455 + pcrs->selection[i].size_of_select); 1135 456 return -ENOBUFS; 1136 457 } 1137 458 /* copy the array of pcr_select */ 1138 - memcpy(pcrs.selection[i].pcr_select, response + pcr_select_offset, 1139 - pcrs.selection[i].size_of_select); 459 + memcpy(pcrs->selection[i].pcr_select, response + pcr_select_offset, 460 + pcrs->selection[i].size_of_select); 1140 461 } 1141 - 1142 - for (i = 0; i < pcrs.count; i++) { 1143 - u32 hash_mask = tpm2_algorithm_to_mask(pcrs.selection[i].hash); 1144 - 1145 - if (hash_mask) { 1146 - *supported_pcr |= hash_mask; 1147 - if (tpm2_is_active_pcr(&pcrs.selection[i])) 1148 - *active_pcr |= hash_mask; 1149 - } else { 1150 - printf("%s: unknown algorithm %x\n", __func__, 1151 - pcrs.selection[i].hash); 1152 - } 1153 - } 1154 - 1155 - *pcr_banks = pcrs.count; 1156 462 1157 463 return 0; 1158 464 } ··· 1541 847 return 0; 1542 848 } 1543 849 850 + bool tpm2_is_active_pcr(struct tpms_pcr_selection *selection) 851 + { 852 + int i; 853 + 854 + for (i = 0; i < selection->size_of_select; i++) { 855 + if (selection->pcr_select[i]) 856 + return true; 857 + } 858 + 859 + return false; 860 + } 861 + 1544 862 enum tpm2_algorithms tpm2_name_to_algorithm(const char *name) 1545 863 { 1546 864 size_t i; ··· 1566 884 return ""; 1567 885 } 1568 886 1569 - u32 tpm2_algorithm_to_mask(enum tpm2_algorithms algo) 887 + u16 tpm2_algorithm_to_len(enum tpm2_algorithms algo) 1570 888 { 1571 889 size_t i; 1572 890 1573 - for (i = 0; i < ARRAY_SIZE(hash_algo_list); i++) { 891 + for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { 1574 892 if (hash_algo_list[i].hash_alg == algo) 1575 - return hash_algo_list[i].hash_mask; 893 + return hash_algo_list[i].hash_len; 1576 894 } 1577 895 1578 896 return 0; 1579 897 } 898 + 899 + bool tpm2_allow_extend(struct udevice *dev) 900 + { 901 + struct tpml_pcr_selection pcrs; 902 + size_t i; 903 + int rc; 904 + 905 + rc = tpm2_get_pcr_info(dev, &pcrs); 906 + if (rc) 907 + return false; 908 + 909 + for (i = 0; i < pcrs.count; i++) { 910 + if (tpm2_is_active_pcr(&pcrs.selection[i]) && 911 + !tpm2_algorithm_to_len(pcrs.selection[i].hash)) 912 + return false; 913 + } 914 + 915 + return true; 916 + }
+731
lib/tpm_tcg2.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Copyright (c) 2023 Linaro Limited 4 + */ 5 + 6 + #include <dm.h> 7 + #include <dm/of_access.h> 8 + #include <tpm_api.h> 9 + #include <tpm-common.h> 10 + #include <tpm-v2.h> 11 + #include <tpm_tcg2.h> 12 + #include <u-boot/sha1.h> 13 + #include <u-boot/sha256.h> 14 + #include <u-boot/sha512.h> 15 + #include <version_string.h> 16 + #include <asm/io.h> 17 + #include <linux/bitops.h> 18 + #include <linux/unaligned/be_byteshift.h> 19 + #include <linux/unaligned/generic.h> 20 + #include <linux/unaligned/le_byteshift.h> 21 + #include "tpm-utils.h" 22 + 23 + int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr, 24 + u32 *pcr_banks) 25 + { 26 + u8 response[(sizeof(struct tpms_capability_data) - 27 + offsetof(struct tpms_capability_data, data))]; 28 + struct tpml_pcr_selection pcrs; 29 + size_t i; 30 + u32 ret; 31 + 32 + *supported_pcr = 0; 33 + *active_pcr = 0; 34 + *pcr_banks = 0; 35 + memset(response, 0, sizeof(response)); 36 + 37 + ret = tpm2_get_pcr_info(dev, &pcrs); 38 + if (ret) 39 + return ret; 40 + 41 + for (i = 0; i < pcrs.count; i++) { 42 + u32 hash_mask = tcg2_algorithm_to_mask(pcrs.selection[i].hash); 43 + 44 + if (hash_mask) { 45 + *supported_pcr |= hash_mask; 46 + if (tpm2_is_active_pcr(&pcrs.selection[i])) 47 + *active_pcr |= hash_mask; 48 + } else { 49 + printf("%s: unknown algorithm %x\n", __func__, 50 + pcrs.selection[i].hash); 51 + } 52 + } 53 + 54 + *pcr_banks = pcrs.count; 55 + 56 + return 0; 57 + } 58 + 59 + int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks) 60 + { 61 + u32 supported = 0; 62 + u32 pcr_banks = 0; 63 + u32 active = 0; 64 + int rc; 65 + 66 + rc = tcg2_get_pcr_info(dev, &supported, &active, &pcr_banks); 67 + if (rc) 68 + return rc; 69 + 70 + *active_pcr_banks = active; 71 + 72 + return 0; 73 + } 74 + 75 + u32 tcg2_event_get_size(struct tpml_digest_values *digest_list) 76 + { 77 + u32 len; 78 + size_t i; 79 + 80 + len = offsetof(struct tcg_pcr_event2, digests); 81 + len += offsetof(struct tpml_digest_values, digests); 82 + for (i = 0; i < digest_list->count; ++i) { 83 + u16 l = tpm2_algorithm_to_len(digest_list->digests[i].hash_alg); 84 + 85 + if (!l) 86 + continue; 87 + 88 + len += l + offsetof(struct tpmt_ha, digest); 89 + } 90 + len += sizeof(u32); 91 + 92 + return len; 93 + } 94 + 95 + int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 length, 96 + struct tpml_digest_values *digest_list) 97 + { 98 + u8 final[sizeof(union tpmu_ha)]; 99 + sha256_context ctx_256; 100 + sha512_context ctx_512; 101 + sha1_context ctx; 102 + u32 active; 103 + size_t i; 104 + u32 len; 105 + int rc; 106 + 107 + rc = tcg2_get_active_pcr_banks(dev, &active); 108 + if (rc) 109 + return rc; 110 + 111 + digest_list->count = 0; 112 + for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { 113 + if (!(active & hash_algo_list[i].hash_mask)) 114 + continue; 115 + 116 + switch (hash_algo_list[i].hash_alg) { 117 + case TPM2_ALG_SHA1: 118 + sha1_starts(&ctx); 119 + sha1_update(&ctx, input, length); 120 + sha1_finish(&ctx, final); 121 + len = TPM2_SHA1_DIGEST_SIZE; 122 + break; 123 + case TPM2_ALG_SHA256: 124 + sha256_starts(&ctx_256); 125 + sha256_update(&ctx_256, input, length); 126 + sha256_finish(&ctx_256, final); 127 + len = TPM2_SHA256_DIGEST_SIZE; 128 + break; 129 + case TPM2_ALG_SHA384: 130 + sha384_starts(&ctx_512); 131 + sha384_update(&ctx_512, input, length); 132 + sha384_finish(&ctx_512, final); 133 + len = TPM2_SHA384_DIGEST_SIZE; 134 + break; 135 + case TPM2_ALG_SHA512: 136 + sha512_starts(&ctx_512); 137 + sha512_update(&ctx_512, input, length); 138 + sha512_finish(&ctx_512, final); 139 + len = TPM2_SHA512_DIGEST_SIZE; 140 + break; 141 + default: 142 + printf("%s: unsupported algorithm %x\n", __func__, 143 + hash_algo_list[i].hash_alg); 144 + continue; 145 + } 146 + 147 + digest_list->digests[digest_list->count].hash_alg = 148 + hash_algo_list[i].hash_alg; 149 + memcpy(&digest_list->digests[digest_list->count].digest, final, 150 + len); 151 + digest_list->count++; 152 + } 153 + 154 + return 0; 155 + } 156 + 157 + void tcg2_log_append(u32 pcr_index, u32 event_type, 158 + struct tpml_digest_values *digest_list, u32 size, 159 + const u8 *event, u8 *log) 160 + { 161 + size_t len; 162 + size_t pos; 163 + u32 i; 164 + 165 + pos = offsetof(struct tcg_pcr_event2, pcr_index); 166 + put_unaligned_le32(pcr_index, log); 167 + pos = offsetof(struct tcg_pcr_event2, event_type); 168 + put_unaligned_le32(event_type, log + pos); 169 + pos = offsetof(struct tcg_pcr_event2, digests) + 170 + offsetof(struct tpml_digest_values, count); 171 + put_unaligned_le32(digest_list->count, log + pos); 172 + 173 + pos = offsetof(struct tcg_pcr_event2, digests) + 174 + offsetof(struct tpml_digest_values, digests); 175 + for (i = 0; i < digest_list->count; ++i) { 176 + u16 hash_alg = digest_list->digests[i].hash_alg; 177 + 178 + len = tpm2_algorithm_to_len(hash_alg); 179 + if (!len) 180 + continue; 181 + 182 + pos += offsetof(struct tpmt_ha, hash_alg); 183 + put_unaligned_le16(hash_alg, log + pos); 184 + pos += offsetof(struct tpmt_ha, digest); 185 + memcpy(log + pos, (u8 *)&digest_list->digests[i].digest, len); 186 + pos += len; 187 + } 188 + 189 + put_unaligned_le32(size, log + pos); 190 + pos += sizeof(u32); 191 + memcpy(log + pos, event, size); 192 + } 193 + 194 + static int tcg2_log_append_check(struct tcg2_event_log *elog, u32 pcr_index, 195 + u32 event_type, 196 + struct tpml_digest_values *digest_list, 197 + u32 size, const u8 *event) 198 + { 199 + u32 event_size; 200 + u8 *log; 201 + 202 + event_size = size + tcg2_event_get_size(digest_list); 203 + if (elog->log_position + event_size > elog->log_size) { 204 + printf("%s: log too large: %u + %u > %u\n", __func__, 205 + elog->log_position, event_size, elog->log_size); 206 + return -ENOBUFS; 207 + } 208 + 209 + log = elog->log + elog->log_position; 210 + elog->log_position += event_size; 211 + 212 + tcg2_log_append(pcr_index, event_type, digest_list, size, event, log); 213 + 214 + return 0; 215 + } 216 + 217 + static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log *elog) 218 + { 219 + struct tcg_efi_spec_id_event *ev; 220 + struct tcg_pcr_event *log; 221 + u32 event_size; 222 + u32 count = 0; 223 + u32 log_size; 224 + u32 active; 225 + size_t i; 226 + u16 len; 227 + int rc; 228 + 229 + rc = tcg2_get_active_pcr_banks(dev, &active); 230 + if (rc) 231 + return rc; 232 + 233 + event_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes); 234 + for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { 235 + if (!(active & hash_algo_list[i].hash_mask)) 236 + continue; 237 + 238 + switch (hash_algo_list[i].hash_alg) { 239 + case TPM2_ALG_SHA1: 240 + case TPM2_ALG_SHA256: 241 + case TPM2_ALG_SHA384: 242 + case TPM2_ALG_SHA512: 243 + count++; 244 + break; 245 + default: 246 + continue; 247 + } 248 + } 249 + 250 + event_size += 1 + 251 + (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count); 252 + log_size = offsetof(struct tcg_pcr_event, event) + event_size; 253 + 254 + if (log_size > elog->log_size) { 255 + printf("%s: log too large: %u > %u\n", __func__, log_size, 256 + elog->log_size); 257 + return -ENOBUFS; 258 + } 259 + 260 + log = (struct tcg_pcr_event *)elog->log; 261 + put_unaligned_le32(0, &log->pcr_index); 262 + put_unaligned_le32(EV_NO_ACTION, &log->event_type); 263 + memset(&log->digest, 0, sizeof(log->digest)); 264 + put_unaligned_le32(event_size, &log->event_size); 265 + 266 + ev = (struct tcg_efi_spec_id_event *)log->event; 267 + strlcpy((char *)ev->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, 268 + sizeof(ev->signature)); 269 + put_unaligned_le32(0, &ev->platform_class); 270 + ev->spec_version_minor = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2; 271 + ev->spec_version_major = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2; 272 + ev->spec_errata = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2; 273 + ev->uintn_size = sizeof(size_t) / sizeof(u32); 274 + put_unaligned_le32(count, &ev->number_of_algorithms); 275 + 276 + count = 0; 277 + for (i = 0; i < ARRAY_SIZE(hash_algo_list); ++i) { 278 + if (!(active & hash_algo_list[i].hash_mask)) 279 + continue; 280 + 281 + len = hash_algo_list[i].hash_len; 282 + if (!len) 283 + continue; 284 + 285 + put_unaligned_le16(hash_algo_list[i].hash_alg, 286 + &ev->digest_sizes[count].algorithm_id); 287 + put_unaligned_le16(len, &ev->digest_sizes[count].digest_size); 288 + count++; 289 + } 290 + 291 + *((u8 *)ev + (event_size - 1)) = 0; 292 + elog->log_position = log_size; 293 + 294 + return 0; 295 + } 296 + 297 + static int tcg2_replay_eventlog(struct tcg2_event_log *elog, 298 + struct udevice *dev, 299 + struct tpml_digest_values *digest_list, 300 + u32 log_position) 301 + { 302 + const u32 offset = offsetof(struct tcg_pcr_event2, digests) + 303 + offsetof(struct tpml_digest_values, digests); 304 + u32 event_size; 305 + u32 count; 306 + u16 algo; 307 + u32 pcr; 308 + u32 pos; 309 + u16 len; 310 + u8 *log; 311 + int rc; 312 + u32 i; 313 + 314 + while (log_position + offset < elog->log_size) { 315 + log = elog->log + log_position; 316 + 317 + pos = offsetof(struct tcg_pcr_event2, pcr_index); 318 + pcr = get_unaligned_le32(log + pos); 319 + pos = offsetof(struct tcg_pcr_event2, event_type); 320 + if (!get_unaligned_le32(log + pos)) 321 + return 0; 322 + 323 + pos = offsetof(struct tcg_pcr_event2, digests) + 324 + offsetof(struct tpml_digest_values, count); 325 + count = get_unaligned_le32(log + pos); 326 + if (count > ARRAY_SIZE(hash_algo_list) || 327 + (digest_list->count && digest_list->count != count)) 328 + return 0; 329 + 330 + pos = offsetof(struct tcg_pcr_event2, digests) + 331 + offsetof(struct tpml_digest_values, digests); 332 + for (i = 0; i < count; ++i) { 333 + pos += offsetof(struct tpmt_ha, hash_alg); 334 + if (log_position + pos + sizeof(u16) >= elog->log_size) 335 + return 0; 336 + 337 + algo = get_unaligned_le16(log + pos); 338 + pos += offsetof(struct tpmt_ha, digest); 339 + switch (algo) { 340 + case TPM2_ALG_SHA1: 341 + case TPM2_ALG_SHA256: 342 + case TPM2_ALG_SHA384: 343 + case TPM2_ALG_SHA512: 344 + len = tpm2_algorithm_to_len(algo); 345 + break; 346 + default: 347 + return 0; 348 + } 349 + 350 + if (digest_list->count) { 351 + if (algo != digest_list->digests[i].hash_alg || 352 + log_position + pos + len >= elog->log_size) 353 + return 0; 354 + 355 + memcpy(digest_list->digests[i].digest.sha512, 356 + log + pos, len); 357 + } 358 + 359 + pos += len; 360 + } 361 + 362 + if (log_position + pos + sizeof(u32) >= elog->log_size) 363 + return 0; 364 + 365 + event_size = get_unaligned_le32(log + pos); 366 + pos += event_size + sizeof(u32); 367 + if (log_position + pos > elog->log_size) 368 + return 0; 369 + 370 + if (digest_list->count) { 371 + rc = tcg2_pcr_extend(dev, pcr, digest_list); 372 + if (rc) 373 + return rc; 374 + } 375 + 376 + log_position += pos; 377 + } 378 + 379 + elog->log_position = log_position; 380 + elog->found = true; 381 + return 0; 382 + } 383 + 384 + static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog) 385 + { 386 + struct tpml_digest_values digest_list; 387 + struct tcg_efi_spec_id_event *event; 388 + struct tcg_pcr_event *log; 389 + u32 log_active; 390 + u32 calc_size; 391 + u32 active; 392 + u32 count; 393 + u32 evsz; 394 + u32 mask; 395 + u16 algo; 396 + u16 len; 397 + int rc; 398 + u32 i; 399 + u16 j; 400 + 401 + if (elog->log_size <= offsetof(struct tcg_pcr_event, event)) 402 + return 0; 403 + 404 + log = (struct tcg_pcr_event *)elog->log; 405 + if (get_unaligned_le32(&log->pcr_index) != 0 || 406 + get_unaligned_le32(&log->event_type) != EV_NO_ACTION) 407 + return 0; 408 + 409 + for (i = 0; i < sizeof(log->digest); i++) { 410 + if (log->digest[i]) 411 + return 0; 412 + } 413 + 414 + evsz = get_unaligned_le32(&log->event_size); 415 + if (evsz < offsetof(struct tcg_efi_spec_id_event, digest_sizes) || 416 + evsz + offsetof(struct tcg_pcr_event, event) > elog->log_size) 417 + return 0; 418 + 419 + event = (struct tcg_efi_spec_id_event *)log->event; 420 + if (memcmp(event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, 421 + sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) 422 + return 0; 423 + 424 + if (event->spec_version_minor != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 || 425 + event->spec_version_major != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2) 426 + return 0; 427 + 428 + count = get_unaligned_le32(&event->number_of_algorithms); 429 + if (count > ARRAY_SIZE(hash_algo_list)) 430 + return 0; 431 + 432 + calc_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes) + 433 + (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count) + 434 + 1; 435 + if (evsz != calc_size) 436 + return 0; 437 + 438 + rc = tcg2_get_active_pcr_banks(dev, &active); 439 + if (rc) 440 + return rc; 441 + 442 + digest_list.count = 0; 443 + log_active = 0; 444 + 445 + for (i = 0; i < count; ++i) { 446 + algo = get_unaligned_le16(&event->digest_sizes[i].algorithm_id); 447 + mask = tcg2_algorithm_to_mask(algo); 448 + 449 + if (!(active & mask)) 450 + return 0; 451 + 452 + switch (algo) { 453 + case TPM2_ALG_SHA1: 454 + case TPM2_ALG_SHA256: 455 + case TPM2_ALG_SHA384: 456 + case TPM2_ALG_SHA512: 457 + len = get_unaligned_le16(&event->digest_sizes[i].digest_size); 458 + if (tpm2_algorithm_to_len(algo) != len) 459 + return 0; 460 + digest_list.digests[digest_list.count++].hash_alg = algo; 461 + break; 462 + default: 463 + return 0; 464 + } 465 + 466 + log_active |= mask; 467 + } 468 + 469 + /* Ensure the previous firmware extended all the PCRs. */ 470 + if (log_active != active) 471 + return 0; 472 + 473 + /* Read PCR0 to check if previous firmware extended the PCRs or not. */ 474 + rc = tcg2_pcr_read(dev, 0, &digest_list); 475 + if (rc) 476 + return rc; 477 + 478 + for (i = 0; i < digest_list.count; ++i) { 479 + len = tpm2_algorithm_to_len(digest_list.digests[i].hash_alg); 480 + for (j = 0; j < len; ++j) { 481 + if (digest_list.digests[i].digest.sha512[j]) 482 + break; 483 + } 484 + 485 + /* PCR is non-zero; it has been extended, so skip extending. */ 486 + if (j != len) { 487 + digest_list.count = 0; 488 + break; 489 + } 490 + } 491 + 492 + return tcg2_replay_eventlog(elog, dev, &digest_list, 493 + offsetof(struct tcg_pcr_event, event) + 494 + evsz); 495 + } 496 + 497 + int tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, 498 + struct tpml_digest_values *digest_list) 499 + { 500 + u32 rc; 501 + u32 i; 502 + 503 + for (i = 0; i < digest_list->count; i++) { 504 + u32 alg = digest_list->digests[i].hash_alg; 505 + 506 + rc = tpm2_pcr_extend(dev, pcr_index, alg, 507 + (u8 *)&digest_list->digests[i].digest, 508 + tpm2_algorithm_to_len(alg)); 509 + if (rc) { 510 + printf("%s: error pcr:%u alg:%08x\n", __func__, 511 + pcr_index, alg); 512 + return rc; 513 + } 514 + } 515 + 516 + return 0; 517 + } 518 + 519 + int tcg2_pcr_read(struct udevice *dev, u32 pcr_index, 520 + struct tpml_digest_values *digest_list) 521 + { 522 + struct tpm_chip_priv *priv; 523 + u32 rc; 524 + u32 i; 525 + 526 + priv = dev_get_uclass_priv(dev); 527 + if (!priv) 528 + return -ENODEV; 529 + 530 + for (i = 0; i < digest_list->count; i++) { 531 + u32 alg = digest_list->digests[i].hash_alg; 532 + u8 *digest = (u8 *)&digest_list->digests[i].digest; 533 + 534 + rc = tpm2_pcr_read(dev, pcr_index, priv->pcr_select_min, alg, 535 + digest, tpm2_algorithm_to_len(alg), NULL); 536 + if (rc) { 537 + printf("%s: error pcr:%u alg:%08x\n", __func__, 538 + pcr_index, alg); 539 + return rc; 540 + } 541 + } 542 + 543 + return 0; 544 + } 545 + 546 + int tcg2_measure_data(struct udevice *dev, struct tcg2_event_log *elog, 547 + u32 pcr_index, u32 size, const u8 *data, u32 event_type, 548 + u32 event_size, const u8 *event) 549 + { 550 + struct tpml_digest_values digest_list; 551 + int rc; 552 + 553 + if (data) 554 + rc = tcg2_create_digest(dev, data, size, &digest_list); 555 + else 556 + rc = tcg2_create_digest(dev, event, event_size, &digest_list); 557 + if (rc) 558 + return rc; 559 + 560 + rc = tcg2_pcr_extend(dev, pcr_index, &digest_list); 561 + if (rc) 562 + return rc; 563 + 564 + return tcg2_log_append_check(elog, pcr_index, event_type, &digest_list, 565 + event_size, event); 566 + } 567 + 568 + int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, 569 + bool ignore_existing_log) 570 + { 571 + struct tcg2_event_log log; 572 + int rc; 573 + 574 + elog->log_position = 0; 575 + elog->found = false; 576 + 577 + rc = tcg2_platform_get_log(dev, (void **)&log.log, &log.log_size); 578 + if (!rc) { 579 + log.log_position = 0; 580 + log.found = false; 581 + 582 + if (!ignore_existing_log) { 583 + rc = tcg2_log_parse(dev, &log); 584 + if (rc) 585 + return rc; 586 + } 587 + 588 + if (elog->log_size) { 589 + if (log.found) { 590 + if (elog->log_size < log.log_position) 591 + return -ENOBUFS; 592 + 593 + /* 594 + * Copy the discovered log into the user buffer 595 + * if there's enough space. 596 + */ 597 + memcpy(elog->log, log.log, log.log_position); 598 + } 599 + 600 + unmap_physmem(log.log, MAP_NOCACHE); 601 + } else { 602 + elog->log = log.log; 603 + elog->log_size = log.log_size; 604 + } 605 + 606 + elog->log_position = log.log_position; 607 + elog->found = log.found; 608 + } 609 + 610 + /* 611 + * Initialize the log buffer if no log was discovered and the buffer is 612 + * valid. User's can pass in their own buffer as a fallback if no 613 + * memory region is found. 614 + */ 615 + if (!elog->found && elog->log_size) 616 + rc = tcg2_log_init(dev, elog); 617 + 618 + return rc; 619 + } 620 + 621 + int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, 622 + bool ignore_existing_log) 623 + { 624 + int rc; 625 + 626 + rc = tcg2_platform_get_tpm2(dev); 627 + if (rc) 628 + return rc; 629 + 630 + rc = tpm_auto_start(*dev); 631 + if (rc) 632 + return rc; 633 + 634 + rc = tcg2_log_prepare_buffer(*dev, elog, ignore_existing_log); 635 + if (rc) { 636 + tcg2_measurement_term(*dev, elog, true); 637 + return rc; 638 + } 639 + 640 + rc = tcg2_measure_event(*dev, elog, 0, EV_S_CRTM_VERSION, 641 + strlen(version_string) + 1, 642 + (u8 *)version_string); 643 + if (rc) { 644 + tcg2_measurement_term(*dev, elog, true); 645 + return rc; 646 + } 647 + 648 + return 0; 649 + } 650 + 651 + void tcg2_measurement_term(struct udevice *dev, struct tcg2_event_log *elog, 652 + bool error) 653 + { 654 + u32 event = error ? 0x1 : 0xffffffff; 655 + int i; 656 + 657 + for (i = 0; i < 8; ++i) 658 + tcg2_measure_event(dev, elog, i, EV_SEPARATOR, sizeof(event), 659 + (const u8 *)&event); 660 + 661 + if (elog->log) 662 + unmap_physmem(elog->log, MAP_NOCACHE); 663 + } 664 + 665 + __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) 666 + { 667 + const __be32 *addr_prop; 668 + const __be32 *size_prop; 669 + int asize; 670 + int ssize; 671 + 672 + *addr = NULL; 673 + *size = 0; 674 + 675 + addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); 676 + if (!addr_prop) 677 + addr_prop = dev_read_prop(dev, "linux,sml-base", &asize); 678 + 679 + size_prop = dev_read_prop(dev, "tpm_event_log_size", &ssize); 680 + if (!size_prop) 681 + size_prop = dev_read_prop(dev, "linux,sml-size", &ssize); 682 + 683 + if (addr_prop && size_prop) { 684 + u64 a = of_read_number(addr_prop, asize / sizeof(__be32)); 685 + u64 s = of_read_number(size_prop, ssize / sizeof(__be32)); 686 + 687 + *addr = map_physmem(a, s, MAP_NOCACHE); 688 + *size = (u32)s; 689 + } else { 690 + struct ofnode_phandle_args args; 691 + phys_addr_t a; 692 + fdt_size_t s; 693 + 694 + if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, 695 + 0, &args)) 696 + return -ENODEV; 697 + 698 + a = ofnode_get_addr_size(args.node, "reg", &s); 699 + if (a == FDT_ADDR_T_NONE) 700 + return -ENOMEM; 701 + 702 + *addr = map_physmem(a, s, MAP_NOCACHE); 703 + *size = (u32)s; 704 + } 705 + 706 + return 0; 707 + } 708 + 709 + __weak int tcg2_platform_get_tpm2(struct udevice **dev) 710 + { 711 + for_each_tpm_device(*dev) { 712 + if (tpm_get_version(*dev) == TPM_V2) 713 + return 0; 714 + } 715 + 716 + return -ENODEV; 717 + } 718 + 719 + u32 tcg2_algorithm_to_mask(enum tpm2_algorithms algo) 720 + { 721 + size_t i; 722 + 723 + for (i = 0; i < ARRAY_SIZE(hash_algo_list); i++) { 724 + if (hash_algo_list[i].hash_alg == algo) 725 + return hash_algo_list[i].hash_mask; 726 + } 727 + 728 + return 0; 729 + } 730 + 731 + __weak void tcg2_platform_startup_error(struct udevice *dev, int rc) {}