mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-21 06:49:35 +00:00
tss2: Add TPM2 Software Stack (TSS2) support
A Trusted Platform Module (TPM) Software Stack (TSS) provides logic to compose and submit TPM commands and parse responses. A limited number of TPM commands may be accessed via the EFI TCG2 protocol. This protocol exposes functionality that is primarily geared toward TPM usage within the context of Secure Boot. For all other TPM commands, however, such as sealing and unsealing, this protocol does not provide any help, with the exception of passthrough command submission. The SubmitCommand method allows a caller to send raw commands to the system's TPM and to receive the corresponding response. These command/response pairs are formatted using the TPM wire protocol. To construct commands in this way, and to parse the TPM's response, it is necessary to, first, possess knowledge of the various TPM structures, and, second, of the TPM wire protocol itself. As such, this patch includes implementations of various grub_tpm2_* functions (inventoried below), and logic to write and read command and response buffers, respectively, using the TPM wire protocol. Functions: - grub_tpm2_create(), - grub_tpm2_createprimary(), - grub_tpm2_evictcontrol(), - grub_tpm2_flushcontext(), - grub_tpm2_load(), - grub_tpm2_pcr_read(), - grub_tpm2_policygetdigest(), - grub_tpm2_policypcr(), - grub_tpm2_readpublic(), - grub_tpm2_startauthsession(), - grub_tpm2_unseal(), - grub_tpm2_loadexternal(), - grub_tpm2_hash(), - grub_tpm2_verifysignature(), - grub_tpm2_policyauthorize(), - grub_tpm2_testparms(). Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com> Signed-off-by: Gary Lin <glin@suse.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Tested-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
1 parent
63a78f4b4d
commit
35c9904df4
6 files changed
+1410
No files matched your search
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2022 Microsoft Corporation
|
||||
* Copyright (C) 2024 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/efi/tpm.h>
|
||||
#include <grub/mm.h>
|
||||
|
||||
#include <tcg2.h>
|
||||
|
||||
static grub_err_t
|
||||
tcg2_get_caps (grub_efi_tpm2_protocol_t *protocol, int *tpm2, grub_size_t *max_output_size)
|
||||
{
|
||||
grub_efi_status_t status;
|
||||
static bool has_caps = 0;
|
||||
static EFI_TCG2_BOOT_SERVICE_CAPABILITY caps =
|
||||
{
|
||||
.Size = (grub_uint8_t) sizeof (caps)
|
||||
};
|
||||
|
||||
if (has_caps)
|
||||
goto exit;
|
||||
|
||||
status = protocol->get_capability (protocol, &caps);
|
||||
if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag)
|
||||
return GRUB_ERR_FILE_NOT_FOUND;
|
||||
|
||||
has_caps = 1;
|
||||
|
||||
exit:
|
||||
if (tpm2 != NULL)
|
||||
*tpm2 = caps.TPMPresentFlag;
|
||||
if (max_output_size != NULL)
|
||||
*max_output_size = caps.MaxResponseSize;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
tcg2_get_protocol (grub_efi_tpm2_protocol_t **protocol)
|
||||
{
|
||||
static grub_guid_t tpm2_guid = EFI_TPM2_GUID;
|
||||
static grub_efi_tpm2_protocol_t *tpm2_protocol = NULL;
|
||||
int tpm2;
|
||||
grub_efi_handle_t *handles;
|
||||
grub_efi_uintn_t num_handles;
|
||||
grub_efi_handle_t tpm2_handle;
|
||||
grub_err_t err = GRUB_ERR_FILE_NOT_FOUND;
|
||||
|
||||
if (tpm2_protocol != NULL)
|
||||
{
|
||||
*protocol = tpm2_protocol;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL,
|
||||
&num_handles);
|
||||
if (handles == NULL || num_handles == 0)
|
||||
return err;
|
||||
|
||||
tpm2_handle = handles[0];
|
||||
|
||||
tpm2_protocol = grub_efi_open_protocol (tpm2_handle, &tpm2_guid,
|
||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (tpm2_protocol == NULL)
|
||||
goto exit;
|
||||
|
||||
err = tcg2_get_caps (tpm2_protocol, &tpm2, NULL);
|
||||
if (err != GRUB_ERR_NONE || tpm2 == 0)
|
||||
goto exit;
|
||||
|
||||
*protocol = tpm2_protocol;
|
||||
err = GRUB_ERR_NONE;
|
||||
|
||||
exit:
|
||||
grub_free (handles);
|
||||
return err;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_tcg2_get_max_output_size (grub_size_t *size)
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_size_t max;
|
||||
grub_efi_tpm2_protocol_t *protocol;
|
||||
|
||||
if (size == NULL)
|
||||
return GRUB_ERR_BAD_ARGUMENT;
|
||||
|
||||
err = tcg2_get_protocol (&protocol);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
err = tcg2_get_caps (protocol, NULL, &max);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
*size = max;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_tcg2_submit_command (grub_size_t input_size,
|
||||
grub_uint8_t *input,
|
||||
grub_size_t output_size,
|
||||
grub_uint8_t *output)
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_efi_status_t status;
|
||||
grub_efi_tpm2_protocol_t *protocol;
|
||||
|
||||
if (input_size == 0 || input == NULL ||
|
||||
output_size == 0 || output == NULL)
|
||||
return GRUB_ERR_BAD_ARGUMENT;
|
||||
|
||||
err = tcg2_get_protocol (&protocol);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
status = protocol->submit_command (protocol, input_size, input,
|
||||
output_size, output);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
return GRUB_ERR_INVALID_COMMAND;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
Reference in new issue
Block a user