diff --git a/examples/BUILD b/examples/BUILD index db7184b..b54382d 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -224,6 +224,8 @@ cc_binary( "htool_spi.c", "htool_statistics.c", "htool_statistics.h", + "htool_tpm.c", + "htool_tpm.h", "htool_target_control.c", "htool_target_control.h", "htool_update_failure_reasons.h", diff --git a/examples/htool.c b/examples/htool.c index e2dc011..a34fef0 100644 --- a/examples/htool.c +++ b/examples/htool.c @@ -52,6 +52,7 @@ #include "htool_srtm.h" #include "htool_statistics.h" #include "htool_target_control.h" +#include "htool_tpm.h" #include "htool_usb.h" #include "protocol/authz_record.h" #include "protocol/chipinfo.h" @@ -1758,6 +1759,30 @@ static const struct htool_cmd CMDS[] = { "other output files are not required."}, {}}, }, + { + .verbs = (const char*[]){"tpm", "get_mode", NULL}, + .desc = "Get the current TPM mode.", + .params = (const struct htool_param[]){{}}, + .func = htool_get_tpm_mode, + }, + { + .verbs = (const char*[]){"tpm", "set_mode", "disabled", NULL}, + .desc = "Set the TPM mode to DISABLED.", + .params = (const struct htool_param[]){{}}, + .func = htool_set_tpm_mode, + }, + { + .verbs = (const char*[]){"tpm", "set_mode", "tpm_spi", NULL}, + .desc = "Set the TPM mode to TPM_SPI.", + .params = (const struct htool_param[]){{}}, + .func = htool_set_tpm_mode, + }, + { + .verbs = (const char*[]){"tpm", "set_mode", "spi_nor_mailbox", NULL}, + .desc = "Set the TPM mode to SPI_NOR_MAILBOX.", + .params = (const struct htool_param[]){{}}, + .func = htool_set_tpm_mode, + }, {}, }; diff --git a/examples/htool_tpm.c b/examples/htool_tpm.c new file mode 100644 index 0000000..ca7f0fa --- /dev/null +++ b/examples/htool_tpm.c @@ -0,0 +1,88 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "htool_tpm.h" + +#include +#include +#include + +#include "host_commands.h" +#include "htool.h" +#include "htool_cmd.h" +#include "transports/libhoth_device.h" + +int htool_set_tpm_mode(const struct htool_invocation* inv) { + struct libhoth_device* dev = htool_libhoth_device(); + if (!dev) { + return -1; + } + + const char* mode_str = inv->cmd->verbs[2]; + + uint32_t mode; + if (strcmp(mode_str, "disabled") == 0) { + mode = TPM_MODE_DISABLED; + } else if (strcmp(mode_str, "tpm_spi") == 0) { + mode = TPM_MODE_TPM_SPI; + } else if (strcmp(mode_str, "spi_nor_mailbox") == 0) { + mode = TPM_MODE_SPI_NOR_MAILBOX; + } else { + fprintf(stderr, "Invalid mode value: %s\n", mode_str); + fprintf(stderr, "Valid modes are: disabled, tpm_spi, spi_nor_mailbox\n"); + return -1; + } + + struct tpm_mode req = { + .mode = mode, + }; + + return libhoth_hostcmd_exec( + dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_SET_TPM_MODE, 0, &req, + sizeof(req), NULL, 0, NULL); +} + +int htool_get_tpm_mode(const struct htool_invocation* inv) { + struct libhoth_device* dev = htool_libhoth_device(); + if (!dev) { + return -1; + } + + struct tpm_mode resp; + int ret = libhoth_hostcmd_exec( + dev, HOTH_CMD_BOARD_SPECIFIC_BASE + HOTH_PRV_CMD_GET_TPM_MODE, 0, NULL, 0, + &resp, sizeof(resp), NULL); + if (ret) { + return ret; + } + + const char* mode_str; + switch (resp.mode) { + case TPM_MODE_DISABLED: + mode_str = "DISABLED"; + break; + case TPM_MODE_TPM_SPI: + mode_str = "TPM_SPI"; + break; + case TPM_MODE_SPI_NOR_MAILBOX: + mode_str = "SPI_NOR_MAILBOX"; + break; + default: + mode_str = "UNKNOWN"; + break; + } + printf("TPM mode: %s (%u)\n", mode_str, resp.mode); + + return 0; +} diff --git a/examples/htool_tpm.h b/examples/htool_tpm.h new file mode 100644 index 0000000..6fe0129 --- /dev/null +++ b/examples/htool_tpm.h @@ -0,0 +1,46 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LIBHOTH_EXAMPLES_HTOOL_TPM_H_ +#define LIBHOTH_EXAMPLES_HTOOL_TPM_H_ + +#include "htool_cmd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HOTH_PRV_CMD_SET_TPM_MODE 0x0051 +#define HOTH_PRV_CMD_GET_TPM_MODE 0x0052 + +enum ec_tpm_mode { + TPM_MODE_DISABLED = 0, // Turn the TPM off: typically used to turn off one + // TPM in 1x2Socket mode + TPM_MODE_TPM_SPI = 1, // TPM SPI wire protocol (TCG standard) + TPM_MODE_SPI_NOR_MAILBOX = 2, // SPI EEPROM protocol tunneled through the + // mailbox/host command +}; +struct tpm_mode { + uint8_t mode; // enum ec_tpm_mode + uint8_t reserved[3]; +} __attribute__((packed, aligned(4))); + +int htool_set_tpm_mode(const struct htool_invocation* inv); +int htool_get_tpm_mode(const struct htool_invocation* inv); + +#ifdef __cplusplus +} +#endif + +#endif // LIBHOTH_EXAMPLES_HTOOL_TPM_H_ diff --git a/examples/meson.build b/examples/meson.build index 5092fd7..889f715 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -58,6 +58,8 @@ executable( 'htool_security_certificates.c', 'htool_security_tokens.h', 'htool_security_tokens.c', + 'htool_tpm.h', + 'htool_tpm.c', git_version_h, ], dependencies: [libusb],