[SeaBIOS] [PATCH 2/3] Support for TPM Physical Presence Interface

Igor Mammedov imammedo at redhat.com
Fri May 15 17:23:50 CEST 2015


On Fri,  8 May 2015 13:45:47 -0400
Stefan Berger <stefanb at linux.vnet.ibm.com> wrote:

> This patch implements the specification found here:
> 
> http://www.trustedcomputinggroup.org/resources/tcg_physical_presence_interface_specification
> 
> It adds the necessary BIOS code so that for example an administrator can send
> messages from the OS to the BIOS for the BIOS to change the state of the TPM
> upon reboot. With the help of this interface, an administrator does not have
> to manually interact with the BIOS.
> 
> As an example, on Linux the root use can send an opcode to the BIOS through the
> TPM's sysfs entries following the opcodes listed in table 2 of the above
> specs. To for example disable and deactivate the TPM, the root user would
> send opcode '7' to the BIOS:
> 
> #> cd /sys/devices/pnp0/00:0?/ppi
> 
> #> echo 7 > request
> 
> #> reboot
> 
> To exchange data between the OS and SeaBIOS, we use the TIS's vendor
> specific extensions in locations 0xf90-fff where RAM locations reside
> that are not reset during a machine reboot. This memory is initialized
> and two locations receive a 32 bit value 'TCG_MAGIC' that the ACPI code
> and SeaBIOS are looking for to accept the memory. If after a reboot the
Why do you need to look for TCG_MAGIC?
buffer is at the fixed known address so BIOS could just use it, in addition
it will save 8 bytes of precious low memory.

Also I'd pass buffer address via fwcfg file instead of hardcoding it
in QEMU and SeaBIOS.

> signature is found by SeaBIOS, the opcode (sent from the OS) is looked
> at and acted upon.
> 
> The implementation requires an ACPI _DSM method to be implemented for the
> TPM's SSDT. The code in the _DSM will write the administrator's opcode
> into the TIS's RAM locations. The _DSM method is invoked when the root
> user interacts with the entries shown in the above ppi sysfs directory.
> The patch implementing the _DSM will be posted independently.
> 
> This patch supports opcodes 1-11, 14, 21, and 22.
> 
> Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
> ---
>  src/hw/tpm_drivers.h |   1 +
>  src/post.c           |   3 +
>  src/tcgbios.c        | 570 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/tcgbios.h        |  47 +++++
>  4 files changed, 621 insertions(+)
> 
> diff --git a/src/hw/tpm_drivers.h b/src/hw/tpm_drivers.h
> index 34bb12d..83e4a62 100644
> --- a/src/hw/tpm_drivers.h
> +++ b/src/hw/tpm_drivers.h
> @@ -53,6 +53,7 @@ extern struct tpm_driver tpm_drivers[];
>  #define TIS_REG_DATA_FIFO              0x24
>  #define TIS_REG_DID_VID                0xf00
>  #define TIS_REG_RID                    0xf04
> +#define TIS_REG_RAM                    0xfa0
>  
>  #define TIS_STS_VALID                  (1 << 7) /* 0x80 */
>  #define TIS_STS_COMMAND_READY          (1 << 6) /* 0x40 */
> diff --git a/src/post.c b/src/post.c
> index e273c18..4c944c8 100644
> --- a/src/post.c
> +++ b/src/post.c
> @@ -219,6 +219,7 @@ maininit(void)
>  
>      // Setup platform devices.
>      platform_hardware_setup();
> +    tpm_ppi_init();
>  
>      // Start hardware initialization (if threads allowed during optionroms)
>      if (threads_during_optionroms())
> @@ -240,6 +241,8 @@ maininit(void)
>      // Run option roms
>      optionrom_setup();
>  
> +    // Process user-requested TPM state change
> +    tpm_ppi_process();
>      // Allow user to modify overall boot order.
>      interactive_bootmenu();
>      wait_threads();
> diff --git a/src/tcgbios.c b/src/tcgbios.c
> index 3f31231..610ed12 100644
> --- a/src/tcgbios.c
> +++ b/src/tcgbios.c
> @@ -24,6 +24,8 @@
>  #include "bregs.h" // struct bregs
>  #include "sha1.h" // sha1
>  #include "std/smbios.h"
> +#include "malloc.h" // malloc_*
> +#include "fw/paravirt.h" // runningOnQEMU
>  
>  
>  static const u8 Startup_ST_CLEAR[2] = { 0x00, TPM_ST_CLEAR };
> @@ -42,6 +44,11 @@ static const u8 GetCapability_Permanent_Flags[12] = {
>      0x00, 0x00, 0x01, 0x08
>  };
>  
> +static const u8 GetCapability_STClear_Flags[12] = {
> +    0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04,
> +    0x00, 0x00, 0x01, 0x09
> +};
> +
>  static const u8 GetCapability_OwnerAuth[12] = {
>      0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04,
>      0x00, 0x00, 0x01, 0x11
> @@ -89,6 +96,10 @@ static tpm_state_t tpm_state = {
>      .tpm_driver_to_use = TPM_INVALID_DRIVER,
>  };
>  
> +typedef struct {
> +    u8  op;
> +} tpm_bios_cfg_t;
> +
>  
>  /********************************************************
>    Extensions for TCG-enabled BIOS
> @@ -1438,6 +1449,521 @@ tpm_ipl(enum ipltype bootcd, const u8 *addr, u32 length)
>      return rc;
>  }
>  
> +static u32
> +read_stclear_flags(char *buf, int buf_len)
> +{
> +    u32 rc;
> +    u32 returnCode;
> +    struct tpm_res_getcap_stclear_flags stcf;
> +
> +    memset(buf, 0x0, buf_len);
> +
> +    rc = build_and_send_cmd(0, TPM_ORD_GetCapability,
> +                            GetCapability_STClear_Flags,
> +                            sizeof(GetCapability_STClear_Flags),
> +                            (u8 *)&stcf,
> +                            sizeof(struct tpm_res_getcap_stclear_flags),
> +                            &returnCode, TPM_DURATION_TYPE_SHORT);
> +
> +    dprintf(DEBUG_tcg, "TCGBIOS: Return code from TPM_GetCapability() "
> +            "= 0x%08x\n", returnCode);
> +
> +    if (rc || returnCode)
> +        goto err_exit;
> +
> +    memcpy(buf, &stcf.stclear_flags, buf_len);
> +
> +    return 0;
> +
> +err_exit:
> +    dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
> +
> +    tpm_state.tpm_working = 0;
> +    if (rc)
> +        return rc;
> +    return TCG_TCG_COMMAND_ERROR;
> +}
> +
> +
> +static u32
> +assert_physical_presence(int verbose)
> +{
> +    u32 rc = 0;
> +    u32 returnCode;
> +    struct tpm_stclear_flags stcf;
> +
> +    rc = read_stclear_flags((char *)&stcf, sizeof(stcf));
> +    if (rc) {
> +        dprintf(DEBUG_tcg,
> +                "Error reading STClear flags: 0x%08x\n", rc);
> +        return rc;
> +    }
> +
> +    if (stcf.flags[STCLEAR_FLAG_IDX_PHYSICAL_PRESENCE])
> +        /* physical presence already asserted */
> +        return 0;
> +
> +    rc = build_and_send_cmd(0, TPM_ORD_PhysicalPresence,
> +                            PhysicalPresence_CMD_ENABLE,
> +                            sizeof(PhysicalPresence_CMD_ENABLE),
> +                            NULL, 10, &returnCode, TPM_DURATION_TYPE_SHORT);
> +
> +    dprintf(DEBUG_tcg,
> +           "Return code from TSC_PhysicalPresence(CMD_ENABLE) = 0x%08x\n",
> +           returnCode);
> +
> +    if (rc || returnCode) {
> +        if (verbose)
> +            printf("Error: Could not enable physical presence.\n\n");
> +        goto err_exit;
> +    }
> +
> +    rc = build_and_send_cmd(0, TPM_ORD_PhysicalPresence,
> +                            PhysicalPresence_PRESENT,
> +                            sizeof(PhysicalPresence_PRESENT),
> +                            NULL, 10, &returnCode, TPM_DURATION_TYPE_SHORT);
> +
> +    dprintf(DEBUG_tcg,
> +           "Return code from TSC_PhysicalPresence(PRESENT) = 0x%08x\n",
> +           returnCode);
> +
> +    if (rc || returnCode) {
> +        if (verbose)
> +            printf("Error: Could not set presence flag.\n\n");
> +        goto err_exit;
> +    }
> +
> +    return 0;
> +
> +err_exit:
> +    dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
> +
> +    tpm_state.tpm_working = 0;
> +    if (rc)
> +        return rc;
> +    return TCG_TCG_COMMAND_ERROR;
> +}
> +
> +
> +static u32
> +read_permanent_flags(char *buf, int buf_len)
> +{
> +    u32 rc;
> +    u32 returnCode;
> +    struct tpm_res_getcap_perm_flags pf;
> +
> +    memset(buf, 0x0, buf_len);
> +
> +    rc = build_and_send_cmd(0, TPM_ORD_GetCapability,
> +                            GetCapability_Permanent_Flags,
> +                            sizeof(GetCapability_Permanent_Flags),
> +                            (u8 *)&pf,
> +                            sizeof(struct tpm_res_getcap_perm_flags),
> +                            &returnCode, TPM_DURATION_TYPE_SHORT);
> +
> +    dprintf(DEBUG_tcg, "TCGBIOS: Return code from TPM_GetCapability() "
> +            "= 0x%08x\n", returnCode);
> +
> +    if (rc || returnCode)
> +        goto err_exit;
> +
> +    memcpy(buf, &pf.perm_flags, buf_len);
> +
> +    return 0;
> +
> +err_exit:
> +    dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
> +
> +    tpm_state.tpm_working = 0;
> +    if (rc)
> +        return rc;
> +    return TCG_TCG_COMMAND_ERROR;
> +}
> +
> +
> +static u32
> +read_has_owner(u8 *has_owner)
> +{
> +    u32 rc;
> +    u32 returnCode;
> +    struct tpm_res_getcap_ownerauth oauth;
> +
> +    rc = build_and_send_cmd(0, TPM_ORD_GetCapability,
> +                            GetCapability_OwnerAuth,
> +                            sizeof(GetCapability_OwnerAuth),
> +                            (u8 *)&oauth,
> +                            sizeof(struct tpm_res_getcap_ownerauth),
> +                            &returnCode, TPM_DURATION_TYPE_SHORT);
> +
> +    dprintf(DEBUG_tcg, "TCGBIOS: Return code from TPM_GetCapability() "
> +            "= 0x%08x\n", returnCode);
> +
> +    if (rc || returnCode)
> +        goto err_exit;
> +
> +    *has_owner = oauth.flag;
> +
> +    return 0;
> +
> +err_exit:
> +    dprintf(DEBUG_tcg,"TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
> +
> +    tpm_state.tpm_working = 0;
> +    if (rc)
> +        return rc;
> +    return TCG_TCG_COMMAND_ERROR;
> +}
> +
> +
> +static u32
> +disable_tpm(int disable, u32 *returnCode, int verbose)
> +{
> +    u32 rc;
> +    struct tpm_permanent_flags pf;
> +
> +    rc = read_permanent_flags((char *)&pf, sizeof(pf));
> +    if (rc)
> +        return rc;
> +
> +    if (!!pf.flags[PERM_FLAG_IDX_DISABLE] == !!disable) {
> +        if (verbose)
> +            printf("TPM is already %s.\n,",
> +                   disable ? "disabled" : "enabled");
> +        return 0;
> +    }
> +
> +    rc = assert_physical_presence(verbose);
> +    if (rc) {
> +        dprintf(DEBUG_tcg, "TCGBIOS: Asserting physical presence failed.\n");
> +        return rc;
> +    }
> +
> +    rc = build_and_send_cmd(0, disable ? TPM_ORD_PhysicalDisable
> +                                       : TPM_ORD_PhysicalEnable,
> +                            NULL, 0, NULL, 10, returnCode,
> +                            TPM_DURATION_TYPE_SHORT);
> +    dprintf(DEBUG_tcg, "Return code from TPM_Physical%sable = 0x%08x\n",
> +            disable ? "Dis" : "En", *returnCode);
> +
> +    if (rc || *returnCode)
> +        goto err_exit;
> +
> +
> +    return 0;
> +
> +err_exit:
> +    dprintf(DEBUG_tcg, "TCGBIOS: %sabling the TPM failed.\n",
> +            disable ? "Dis" : "En");
> +    dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
> +
> +    tpm_state.tpm_working = 0;
> +    if (rc)
> +        return rc;
> +    return TCG_TCG_COMMAND_ERROR;
> +}
> +
> +
> +static u32
> +deactivate_tpm(int deactivate, int allow_reset, u32 *returnCode, int verbose)
> +{
> +    u32 rc;
> +    struct tpm_permanent_flags pf;
> +
> +    rc = read_permanent_flags((char *)&pf, sizeof(pf));
> +    if (rc)
> +        return rc;
> +
> +    if (!!pf.flags[PERM_FLAG_IDX_DEACTIVATED] == !!deactivate) {
> +        if (verbose)
> +            printf("TPM is already %s.\n",
> +                   deactivate ? "deactivated" : "activated");
> +        return 0;
> +    }
> +
> +    if (pf.flags[PERM_FLAG_IDX_DISABLE]) {
> +        if (verbose)
> +            printf("TPM must first be enabled.\n");
> +        return 0;
> +    }
> +
> +    rc = assert_physical_presence(verbose);
> +    if (rc) {
> +        dprintf(DEBUG_tcg, "TCGBIOS: Asserting physical presence failed.\n");
> +        return rc;
> +    }
> +
> +    rc = build_and_send_cmd(0, TPM_ORD_PhysicalSetDeactivated,
> +                            deactivate ? CommandFlag_TRUE
> +                                       : CommandFlag_FALSE,
> +                            deactivate ? sizeof(CommandFlag_TRUE)
> +                                       : sizeof(CommandFlag_FALSE),
> +                            NULL, 10, returnCode, TPM_DURATION_TYPE_SHORT);
> +
> +    dprintf(DEBUG_tcg,
> +            "Return code from PhysicalSetDeactivated(%d) = 0x%08x\n",
> +            deactivate ? 1 : 0, *returnCode);
> +
> +    if (rc || *returnCode)
> +        goto err_exit;
> +
> +    if (!deactivate && allow_reset) {
> +        if (verbose) {
> +            printf("Requiring a reboot to activate the TPM.\n");
> +
> +            msleep(2000);
> +        }
> +        extern void reset_vector(void) __noreturn;
> +        reset_vector();
> +    }
> +
> +    return 0;
> +
> +err_exit:
> +    dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
> +
> +    tpm_state.tpm_working = 0;
> +    if (rc)
> +        return rc;
> +    return TCG_TCG_COMMAND_ERROR;
> +}
> +
> +
> +static u32
> +enable_activate(int allow_reset, u32 *returnCode, int verbose)
> +{
> +    u32 rc;
> +
> +    rc = disable_tpm(0, returnCode, verbose);
> +    if (rc)
> +        return rc;
> +
> +    rc = deactivate_tpm(0, allow_reset, returnCode, verbose);
> +
> +    return rc;
> +}
> +
> +
> +static u32
> +force_clear(int enable_activate_before, int enable_activate_after,
> +            u32 *returnCode, int verbose)
> +{
> +    u32 rc;
> +    u8 has_owner;
> +
> +    rc = read_has_owner(&has_owner);
> +    if (rc)
> +        return rc;
> +    if (!has_owner) {
> +        if (verbose)
> +            printf("TPM does not have an owner.\n");
> +        return 0;
> +    }
> +
> +    if (enable_activate_before) {
> +        rc = enable_activate(0, returnCode, verbose);
> +        if (rc) {
> +            dprintf(DEBUG_tcg,
> +                    "TCGBIOS: Enabling/activating the TPM failed.\n");
> +            return rc;
> +        }
> +    }
> +
> +    rc = assert_physical_presence(verbose);
> +    if (rc) {
> +        dprintf(DEBUG_tcg, "TCGBIOS: Asserting physical presence failed.\n");
> +        return rc;
> +    }
> +
> +    rc = build_and_send_cmd(0, TPM_ORD_ForceClear,
> +                            NULL, 0, NULL, 10, returnCode,
> +                            TPM_DURATION_TYPE_SHORT);
> +
> +    dprintf(DEBUG_tcg, "Return code from TPM_ForceClear() = 0x%08x\n",
> +            *returnCode);
> +
> +    if (rc || *returnCode)
> +        goto err_exit;
> +
> +    if (!enable_activate_after) {
> +        if (verbose)
> +            printf("Owner successfully cleared.\n"
> +                   "You will need to enable/activate the TPM again.\n\n");
> +        return 0;
> +    }
> +
> +    enable_activate(1, returnCode, verbose);
> +
> +    return 0;
> +
> +err_exit:
> +    dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
> +
> +    tpm_state.tpm_working = 0;
> +    if (rc)
> +        return rc;
> +    return TCG_TCG_COMMAND_ERROR;
> +}
> +
> +
> +static u32
> +set_owner_install(int allow, u32 *returnCode, int verbose)
> +{
> +    u32 rc;
> +    u8 has_owner;
> +    struct tpm_permanent_flags pf;
> +
> +    rc = read_has_owner(&has_owner);
> +    if (rc)
> +        return rc;
> +    if (has_owner) {
> +        if (verbose)
> +            printf("Must first remove owner.\n");
> +        return 0;
> +    }
> +
> +    rc = read_permanent_flags((char *)&pf, sizeof(pf));
> +    if (rc)
> +        return rc;
> +
> +    if (pf.flags[PERM_FLAG_IDX_DISABLE]) {
> +        if (verbose)
> +            printf("TPM must first be enable.\n");
> +        return 0;
> +    }
> +
> +    rc = assert_physical_presence(verbose);
> +    if (rc) {
> +        dprintf(DEBUG_tcg, "TCGBIOS: Asserting physical presence failed.\n");
> +        return rc;
> +    }
> +
> +    rc = build_and_send_cmd(0, TPM_ORD_SetOwnerInstall,
> +                            (allow) ? CommandFlag_TRUE :
> +                                      CommandFlag_FALSE,
> +                            sizeof(CommandFlag_TRUE),
> +                            NULL, 10, returnCode, TPM_DURATION_TYPE_SHORT);
> +
> +    dprintf(DEBUG_tcg, "Return code from TPM_SetOwnerInstall() = 0x%08x\n",
> +            *returnCode);
> +
> +    if (rc || *returnCode)
> +        goto err_exit;
> +
> +    if (verbose)
> +        printf("Installation of owner %s.\n", allow ? "enabled" : "disabled");
> +
> +    return 0;
> +
> +err_exit:
> +    dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
> +    tpm_state.tpm_working = 0;
> +    if (rc)
> +        return rc;
> +    return TCG_TCG_COMMAND_ERROR;
> +}
> +
> +
> +static u32
> +tpm_process_cfg(const tpm_bios_cfg_t *cfg, int verbose,
> +                u32 *returnCode, u8 *next_step)
> +{
> +    u32 rc = 0;
> +
> +    switch (cfg->op) {
> +        case 0: /* no-op */
> +            break;
> +
> +        case 1:
> +            rc = disable_tpm(0, returnCode, verbose);
> +            break;
> +
> +        case 2:
> +            rc = disable_tpm(1, returnCode, verbose);
> +            break;
> +
> +        case 3:
> +            rc = deactivate_tpm(0, 1, returnCode, verbose);
> +            break;
> +
> +        case 4:
> +            rc = deactivate_tpm(1, 1, returnCode, verbose);
> +            break;
> +
> +        case 5:
> +            rc = force_clear(1, 0, returnCode, verbose);
> +            break;
> +
> +        case 6:
> +            rc = enable_activate(1, returnCode, verbose);
> +            break;
> +
> +        case 7:
> +            rc = deactivate_tpm(1, 1, returnCode, verbose);
> +            if (!rc)
> +                rc = disable_tpm(1, returnCode, verbose);
> +            break;
> +
> +        case 8:
> +            rc = set_owner_install(1, returnCode, verbose);
> +            break;
> +
> +        case 9:
> +            rc = set_owner_install(0, returnCode, verbose);
> +            break;
> +
> +        case 10:
> +            *next_step = 8;
> +            rc = enable_activate(1, returnCode, verbose);
> +            /* no reboot happened */
> +            if (!rc)
> +                rc = set_owner_install(1, returnCode, verbose);
> +            break;
> +
> +        case 11:
> +            rc = set_owner_install(0, returnCode, verbose);
> +            if (!rc)
> +                rc = deactivate_tpm(1, 0, returnCode, verbose);
> +            if (!rc)
> +                rc = disable_tpm(1, returnCode, verbose);
> +            break;
> +
> +        case 14:
> +            rc = force_clear(0, 0, returnCode, verbose);
> +            if (!rc)
> +                rc = enable_activate(1, returnCode, verbose);
> +            break;
> +
> +        case 21:
> +            *next_step = 5;
> +            rc = enable_activate(1, returnCode, verbose);
> +            /* no reboot happened */
> +            if (!rc)
> +                rc = force_clear(0, 0, returnCode, verbose);
> +            break;
> +
> +        case 22:
> +            *next_step = 14;
> +            rc = enable_activate(1, returnCode, verbose);
> +            /* no reboot happened */
> +            if (!rc)
> +                rc = force_clear(0, 0, returnCode, verbose);
> +            *next_step = 0;
> +            if (!rc)
> +                rc = enable_activate(1, returnCode, verbose);
> +            break;
> +
> +        default:
> +            break;
> +    }
> +
> +    if (rc)
> +        printf("Op %d: An error occurred: 0x%x\n", cfg->op, rc);
> +
> +    /* no reboot, no next step */
> +    *next_step = 0;
> +
> +    return rc;
> +}
>  
>  u32
>  tpm_add_bootdevice_ipl(u32 bootcd, u32 bootdrv,
> @@ -1484,3 +2010,47 @@ err_exit:
>          return rc;
>      return TCG_TCG_COMMAND_ERROR;
>  }
> +
> +void
> +tpm_ppi_init(void)
> +{
> +    if (runningOnQEMU()) {
> +        struct tpm_ppi *tp = (void *)(TPM_TIS_BASE_ADDRESS + TIS_REG_RAM);
> +
> +        if (tp->sign1 != TCG_MAGIC || tp->sign2 != TCG_MAGIC) {
> +            memset(tp, 0x0, sizeof(*tp));
> +            tp->sign1 = TCG_MAGIC;
> +            tp->sign2 = TCG_MAGIC;
> +            /* set number of bytes that ACPI can read/write */
> +            tp->size = sizeof(tp->opcode) + sizeof(tp->failure) +
> +                       sizeof(tp->recent_opcode) + sizeof(tp->response);
> +        }
> +    }
> +}
> +
> +void
> +tpm_ppi_process(void)
> +{
> +    tpm_bios_cfg_t cfg;
> +
> +    if (runningOnQEMU()) {
> +        struct tpm_ppi *tp = (void *)(TPM_TIS_BASE_ADDRESS + TIS_REG_RAM);
> +
> +        if (tp->sign1 == TCG_MAGIC && tp->sign2 == TCG_MAGIC) {
> +            cfg.op = tp->opcode;
> +            dprintf(DEBUG_tcg, "TCGBIOS: PPI opcode found: 0x%08x\n", tp->opcode);
> +            if (!cfg.op) {
> +                /* intermediate step after a reboot? */
> +                cfg.op = tp->next_step;
> +            } else {
> +                /* last full opcode */
> +                tp->recent_opcode = cfg.op;
> +            }
> +            if (cfg.op) {
> +                printf("Processing TPM PPI opcode %d\n", cfg.op);
> +                tp->failure = (tpm_process_cfg(&cfg, 0, &tp->response,
> +                                               &tp->next_step) != 0);
> +            }
> +        }
> +    }
> +}
> diff --git a/src/tcgbios.h b/src/tcgbios.h
> index 7cf4364..9811827 100644
> --- a/src/tcgbios.h
> +++ b/src/tcgbios.h
> @@ -328,6 +328,36 @@ struct tpm_res_getcap_perm_flags {
>  } PACKED;
>  
>  
> +struct tpm_req_getcap_stclear_flags {
> +    TPM_REQ_HEADER
> +    u32    capArea;
> +    u32    subCapSize;
> +    u32    subCap;
> +} PACKED;
> +
> +
> +struct tpm_stclear_flags {
> +    u16    tag;
> +    u8     flags[5];
> +} PACKED;
> +
> +
> +enum stclearFlagsIndex {
> +    STCLEAR_FLAG_IDX_DEACTIVATED = 0,
> +    STCLEAR_FLAG_IDX_DISABLE_FORCE_CLEAR,
> +    STCLEAR_FLAG_IDX_PHYSICAL_PRESENCE,
> +    STCLEAR_FLAG_IDX_PHYSICAL_PRESENCE_LOCK,
> +    STCLEAR_FLAG_IDX_GLOBAL_LOCK,
> +};
> +
> +
> +struct tpm_res_getcap_stclear_flags {
> +    TPM_RSP_HEADER
> +    u32    size;
> +    struct tpm_stclear_flags stclear_flags;
> +} PACKED;
> +
> +
>  struct tpm_res_getcap_ownerauth {
>      TPM_RSP_HEADER
>      u32    size;
> @@ -378,6 +408,23 @@ enum ipltype {
>      IPL_EL_TORITO_2
>  };
>  
> +/*
> + * physical presence interface
> + */
> +
> +struct tpm_ppi {
> +    u32 sign1;
> +    u16 size;           // number of subsequent bytes for ACPI to access
> +    u8 opcode;          // set by ACPI
> +    u8 failure;         // set by BIOS (0 = success)
> +    u8 recent_opcode;   // set by BIOS
> +    u32 response;       // set by BIOS
> +    u8 next_step;       // BIOS only
> +    u32 sign2;
> +} PACKED;
> +
> +void tpm_ppi_init(void);
> +void tpm_ppi_process(void);
>  
>  struct bregs;
>  void tpm_interrupt_handler32(struct bregs *regs);




More information about the SeaBIOS mailing list