]> git.proxmox.com Git - efi-boot-shim.git/blame - tpm.c
Import upstream version 0.9+1474479173.6c180c6
[efi-boot-shim.git] / tpm.c
CommitLineData
d3819813
MTL
1#include <efi.h>
2#include <efilib.h>
3#include <string.h>
4
5#include "tpm.h"
6
7extern UINT8 in_protocol;
8
9#define perror(fmt, ...) ({ \
10 UINTN __perror_ret = 0; \
11 if (!in_protocol) \
12 __perror_ret = Print((fmt), ##__VA_ARGS__); \
13 __perror_ret; \
14 })
15
16
17EFI_GUID tpm_guid = EFI_TPM_GUID;
18EFI_GUID tpm2_guid = EFI_TPM2_GUID;
19
20static BOOLEAN tpm_present(efi_tpm_protocol_t *tpm)
21{
22 EFI_STATUS status;
23 TCG_EFI_BOOT_SERVICE_CAPABILITY caps;
24 UINT32 flags;
25 EFI_PHYSICAL_ADDRESS eventlog, lastevent;
26
27 caps.Size = (UINT8)sizeof(caps);
28 status = uefi_call_wrapper(tpm->status_check, 5, tpm, &caps, &flags,
29 &eventlog, &lastevent);
30
31 if (status != EFI_SUCCESS || caps.TPMDeactivatedFlag
32 || !caps.TPMPresentFlag)
33 return FALSE;
34
35 return TRUE;
36}
37
38static BOOLEAN tpm2_present(efi_tpm2_protocol_t *tpm)
39{
40 EFI_STATUS status;
41 EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
42 EFI_TCG2_BOOT_SERVICE_CAPABILITY_1_0 *caps_1_0;
43
44 caps.Size = (UINT8)sizeof(caps);
45
46 status = uefi_call_wrapper(tpm->get_capability, 2, tpm, &caps);
47
48 if (status != EFI_SUCCESS)
49 return FALSE;
50
51 if (caps.StructureVersion.Major == 1 &&
52 caps.StructureVersion.Minor == 0) {
53 caps_1_0 = (EFI_TCG2_BOOT_SERVICE_CAPABILITY_1_0 *)&caps;
54 if (caps_1_0->TPMPresentFlag)
55 return TRUE;
56 } else {
57 if (caps.TPMPresentFlag)
58 return TRUE;
59 }
60
61 return FALSE;
62}
63
64EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
65 const CHAR8 *description)
66{
67 EFI_STATUS status;
68 efi_tpm_protocol_t *tpm;
69 efi_tpm2_protocol_t *tpm2;
70
71 status = LibLocateProtocol(&tpm2_guid, (VOID **)&tpm2);
72 /* TPM 2.0 */
73 if (status == EFI_SUCCESS) {
74 EFI_TCG2_EVENT *event;
75
76 if (!tpm2_present(tpm2))
77 return EFI_SUCCESS;
78
79 event = AllocatePool(sizeof(*event) + strlen(description) + 1);
80 if (!event) {
81 perror(L"Unable to allocate event structure\n");
82 return EFI_OUT_OF_RESOURCES;
83 }
84
85 event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
86 event->Header.HeaderVersion = 1;
87 event->Header.PCRIndex = pcr;
88 event->Header.EventType = 0x0d;
89 event->Size = sizeof(*event) - sizeof(event->Event) + strlen(description) + 1;
90 memcpy(event->Event, description, strlen(description) + 1);
91 status = uefi_call_wrapper(tpm2->hash_log_extend_event, 5, tpm2,
92 0, buf, (UINT64) size, event);
93 FreePool(event);
94 return status;
95 } else {
96 TCG_PCR_EVENT *event;
97 UINT32 algorithm, eventnum = 0;
98 EFI_PHYSICAL_ADDRESS lastevent;
99
100 status = LibLocateProtocol(&tpm_guid, (VOID **)&tpm);
101
102 if (status != EFI_SUCCESS)
103 return EFI_SUCCESS;
104
105 if (!tpm_present(tpm))
106 return EFI_SUCCESS;
107
108 event = AllocatePool(sizeof(*event) + strlen(description) + 1);
109
110 if (!event) {
111 perror(L"Unable to allocate event structure\n");
112 return EFI_OUT_OF_RESOURCES;
113 }
114
115 event->PCRIndex = pcr;
116 event->EventType = 0x0d;
117 event->EventSize = strlen(description) + 1;
118 algorithm = 0x00000004;
119 status = uefi_call_wrapper(tpm->log_extend_event, 7, tpm, buf,
120 (UINT64)size, algorithm, event,
121 &eventnum, &lastevent);
122 FreePool(event);
123 return status;
124 }
125
126 return EFI_SUCCESS;
127}