static void grub_efi_configure_pci(grub_efi_handle_t handle) { grub_efi_device_path_t *path, *parent; grub_efi_handle_t parent_handle; grub_efi_pci_io_t *pci_proto; grub_efi_pci_root_io_t *pci_root_proto; grub_efi_status_t status; path = grub_efi_get_device_path(handle); parent = find_parent_device_path(path); if (!parent) return; status = grub_efi_locate_device_path (&device_path_guid, &parent, &parent_handle); if (status != GRUB_EFI_SUCCESS) return; pci_proto = grub_efi_open_protocol (parent_handle, &pci_io_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); pci_root_proto = grub_efi_open_protocol (parent_handle, &pci_root_io_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (pci_proto || pci_root_proto) { if (pci_proto) { Call_Service_4 (pci_proto->attributes, pci_proto, grub_efi_pci_io_attribute_operation_enable, GRUB_EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | GRUB_EFI_PCI_IO_ATTRIBUTE_VGA_IO | GRUB_EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO, NULL); grub_efi_configure_pci (parent_handle); } else { grub_uint8_t value = 0x33; Call_Service_5 (pci_root_proto->pci.write, pci_root_proto, grub_efi_pci_io_width_uint8, 0x91, 1, &value); Call_Service_5 (pci_root_proto->pci.write, pci_root_proto, grub_efi_pci_io_width_uint8, 0x92, 1, &value); } } grub_free(parent); }
grub_efi_loaded_image_t * grub_efi_get_loaded_image (grub_efi_handle_t image_handle) { return grub_efi_open_protocol (image_handle, &loaded_image_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); }
void grub_efi_setup_gfx_pci(grub_efi_handle_t handle) { grub_efi_uint64_t romsize; grub_efi_uint16_t *header; void *vrom; grub_efi_pci_io_t *pci_proto; pci_proto = grub_efi_open_protocol (handle, &pci_io_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (!pci_proto) return; romsize = pci_proto->rom_size; if (!romsize || romsize > 65536 || !pci_proto->rom_image) return; /* Copy the ROM */ vrom = grub_efi_allocate_runtime_pages(0xc0000, 16); if (!vrom) return; header = vrom; if (*header == 0xaa55) return; grub_efi_configure_pci(handle); grub_memcpy(vrom, pci_proto->rom_image, romsize); }
static struct grub_efidisk_data * make_devices (void) { grub_efi_uintn_t num_handles; grub_efi_handle_t *handles; grub_efi_handle_t *handle; struct grub_efidisk_data *devices = 0; /* Find handles which support the disk io interface. */ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &block_io_guid, 0, &num_handles); if (! handles) return 0; /* Make a linked list of devices. */ for (handle = handles; num_handles--; handle++) { grub_efi_device_path_t *dp; grub_efi_device_path_t *ldp; struct grub_efidisk_data *d; grub_efi_block_io_t *bio; dp = grub_efi_get_device_path (*handle); if (! dp) continue; ldp = find_last_device_path (dp); if (! ldp) /* This is empty. Why? */ continue; bio = grub_efi_open_protocol (*handle, &block_io_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (! bio) /* This should not happen... Why? */ continue; d = grub_malloc (sizeof (*d)); if (! d) { /* Uggh. */ grub_free (handles); return 0; } d->handle = *handle; d->device_path = dp; d->last_device_path = ldp; d->block_io = bio; d->next = devices; devices = d; } grub_free (handles); return devices; }
static grub_err_t grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, grub_size_t size, grub_uint8_t pcr, const char *description) { EFI_TCG2_EVENT *event; grub_efi_status_t status; grub_efi_tpm2_protocol_t *tpm; tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (!grub_tpm2_present (tpm)) return 0; event = grub_zalloc (sizeof (EFI_TCG2_EVENT) + grub_strlen (description) + 1); if (!event) return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate TPM event buffer")); event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER); event->Header.HeaderVersion = 1; event->Header.PCRIndex = pcr; event->Header.EventType = EV_IPL; event->Size = sizeof (*event) - sizeof (event->Event) + grub_strlen (description) + 1; grub_memcpy (event->Event, description, grub_strlen (description) + 1); status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, buf, (grub_uint64_t) size, event); switch (status) { case GRUB_EFI_SUCCESS: return 0; case GRUB_EFI_DEVICE_ERROR: return grub_error (GRUB_ERR_IO, N_("Command failed")); case GRUB_EFI_INVALID_PARAMETER: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); case GRUB_EFI_BUFFER_TOO_SMALL: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); case GRUB_EFI_NOT_FOUND: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); default: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); } }
static grub_err_t grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, grub_size_t size, grub_uint8_t pcr, const char *description) { grub_tpm_event_t *event; grub_efi_status_t status; grub_efi_tpm_protocol_t *tpm; grub_efi_physical_address_t lastevent; grub_uint32_t algorithm; grub_uint32_t eventnum = 0; tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (!grub_tpm1_present (tpm)) return 0; event = grub_zalloc (sizeof (*event) + grub_strlen (description) + 1); if (!event) return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate TPM event buffer")); event->PCRIndex = pcr; event->EventType = EV_IPL; event->EventSize = grub_strlen (description) + 1; grub_memcpy (event->Event, description, event->EventSize); algorithm = TCG_ALG_SHA; status = efi_call_7 (tpm->log_extend_event, tpm, buf, (grub_uint64_t) size, algorithm, event, &eventnum, &lastevent); switch (status) { case GRUB_EFI_SUCCESS: return 0; case GRUB_EFI_DEVICE_ERROR: return grub_error (GRUB_ERR_IO, N_("Command failed")); case GRUB_EFI_INVALID_PARAMETER: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); case GRUB_EFI_BUFFER_TOO_SMALL: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); case GRUB_EFI_NOT_FOUND: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); default: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); } }
int uefi_mount (void) { grub_efi_handle_t dev_handle = grub_efidisk_get_current_bdev_handle(); grub_efi_status_t status; if (!dev_handle) return 0; file_system = grub_efi_open_protocol (dev_handle, &simple_file_system_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (!file_system) return 0; status = Call_Service_2 (file_system->open_volume, file_system, &root); if (status != GRUB_EFI_SUCCESS) return 0; return 1; }
static grub_err_t grub_tpm2_execute (grub_efi_handle_t tpm_handle, PassThroughToTPM_InputParamBlock *inbuf, PassThroughToTPM_OutputParamBlock *outbuf) { grub_efi_status_t status; grub_efi_tpm2_protocol_t *tpm; grub_uint32_t inhdrsize = sizeof (*inbuf) - sizeof (inbuf->TPMOperandIn); grub_uint32_t outhdrsize = sizeof (*outbuf) - sizeof (outbuf->TPMOperandOut); tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (!grub_tpm2_present (tpm)) return 0; /* UEFI TPM protocol takes the raw operand block, no param block header. */ status = efi_call_5 (tpm->submit_command, tpm, inbuf->IPBLength - inhdrsize, inbuf->TPMOperandIn, outbuf->OPBLength - outhdrsize, outbuf->TPMOperandOut); switch (status) { case GRUB_EFI_SUCCESS: return 0; case GRUB_EFI_DEVICE_ERROR: return grub_error (GRUB_ERR_IO, N_("Command failed")); case GRUB_EFI_INVALID_PARAMETER: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); case GRUB_EFI_BUFFER_TOO_SMALL: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); case GRUB_EFI_NOT_FOUND: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); default: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); } }
grub_efi_device_path_t * grub_efi_get_device_path (grub_efi_handle_t handle) { return grub_efi_open_protocol (handle, &device_path_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); }
grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size, grub_uint8_t pcr, const char *description) { grub_efi_handle_t tpm_handle; grub_efi_status_t status; grub_efi_tpm_protocol_t *tpm; grub_efi_tpm2_protocol_t *tpm2; grub_efi_physical_address_t lastevent; grub_efi_uint8_t protocol_version; grub_uint32_t eventnum = 0; grub_uint32_t algorithm; Event *event; EFI_TCG2_EVENT *event2; if (!grub_tpm_handle_find(&tpm_handle, &protocol_version)) { return 0; } if (protocol_version == 1) { tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (!grub_tpm_present(tpm)) { return 0; } event = grub_zalloc(sizeof (Event) + grub_strlen(description) + 1); if (!event) { grub_printf("No buffer\n"); return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate TPM event buffer")); } event->pcrindex = pcr; event->eventtype = 0x0d; event->eventsize = grub_strlen(description) + 1; grub_memcpy(event->event, description, event->eventsize); algorithm = 0x00000004; /* SHA 1 */ status = efi_call_7 (tpm->log_extend_event, tpm, buf, (grub_uint64_t) size, algorithm, event, &eventnum, &lastevent); switch (status) { case GRUB_EFI_SUCCESS: return 0; case GRUB_EFI_DEVICE_ERROR: return grub_error (GRUB_ERR_IO, N_("Command failed")); case GRUB_EFI_INVALID_PARAMETER: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); case GRUB_EFI_BUFFER_TOO_SMALL: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); case GRUB_EFI_NOT_FOUND: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); default: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); } } else { tpm2 = grub_efi_open_protocol (tpm_handle, &tpm2_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (!grub_tpm2_present(tpm2)) { return 0; } event2 = grub_zalloc(sizeof (Event) + grub_strlen(description) + 1); if (!event2) { grub_printf("No buffer\n"); return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate TPM event buffer")); } event2->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER); event2->Header.HeaderVersion = 1; event2->Header.PCRIndex = pcr; event2->Header.EventType = 0x0d; event2->Size = sizeof(*event2) - sizeof(event2->Event) + grub_strlen(description) + 1; grub_memcpy(event2->Event, description, grub_strlen(description) + 1); status = efi_call_5 (tpm2->hash_log_extend_event, tpm2, 0, buf, (grub_uint64_t) size, event2); switch (status) { case GRUB_EFI_SUCCESS: return 0; case GRUB_EFI_DEVICE_ERROR: return grub_error (GRUB_ERR_IO, N_("Command failed")); case GRUB_EFI_INVALID_PARAMETER: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); case GRUB_EFI_BUFFER_TOO_SMALL: return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); case GRUB_EFI_NOT_FOUND: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); default: return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("Unknown TPM error")); } } }