]>
Commit | Line | Data |
---|---|---|
d3819813 MTL |
1 | #include <efi.h> |
2 | #include <efilib.h> | |
3 | #include <string.h> | |
4 | ||
5 | #include "tpm.h" | |
6 | ||
7 | extern 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 | ||
17 | EFI_GUID tpm_guid = EFI_TPM_GUID; | |
18 | EFI_GUID tpm2_guid = EFI_TPM2_GUID; | |
19 | ||
20 | static 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 | ||
38 | static 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 *)∩︀ | |
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 | ||
64 | EFI_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 | } |