diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
index 401bb1c..8bd684c 100644
--- a/lib/libtpm/tcgbios.c
+++ b/lib/libtpm/tcgbios.c
@@ -56,6 +56,8 @@ struct tpm_state {
 
 static struct tpm_state tpm_state;
 
+typedef uint8_t tpm_ppi_op;
+
 /********************************************************
   Extensions for TCG-enabled BIOS
  *******************************************************/
@@ -546,3 +548,204 @@ uint32_t tpm_measure_bcv_mbr(uint32_t bootdrv, const uint8_t *addr,
 					  string, strlen(string),
 					  addr + 0x1b8, 0x48);
 }
+
+/****************************************************************
+ * TPM Configuration Menu
+ ****************************************************************/
+
+static int tpm12_read_has_owner(bool *has_owner)
+{
+	struct tpm_rsp_getcap_ownerauth oauth;
+	int ret = tpm12_get_capability(TPM_CAP_PROPERTY, TPM_CAP_PROP_OWNER,
+				       &oauth.hdr, sizeof(oauth));
+	if (ret)
+		return -1;
+
+	*has_owner = oauth.flag;
+
+	return 0;
+}
+
+static int tpm12_enable_tpm(bool enable, bool verbose)
+{
+	struct tpm_permanent_flags pf;
+	int ret = tpm12_read_permanent_flags((char *)&pf, sizeof(pf));
+	if (ret)
+		return -1;
+
+	if (pf.flags[PERM_FLAG_IDX_DISABLE] && !enable)
+		return 0;
+
+	ret = tpm_simple_cmd(0, enable ? TPM_ORD_PHYSICAL_ENABLE
+				       : TPM_ORD_PHYSICAL_DISABLE,
+			     0, 0, TPM_DURATION_TYPE_SHORT);
+	if (ret) {
+		if (enable) {
+			dprintf("TCGBIOS: Enabling the TPM failed.\n");
+		} else {
+			dprintf("TCGBIOS: Disabling the TPM failed.\n");
+		}
+	}
+	return ret;
+}
+
+static int tpm12_activate_tpm(bool activate, bool allow_reset, bool verbose)
+{
+	struct tpm_permanent_flags pf;
+	int ret = tpm12_read_permanent_flags((char *)&pf, sizeof(pf));
+	if (ret)
+		return -1;
+
+	if (pf.flags[PERM_FLAG_IDX_DEACTIVATED] && !activate)
+		return 0;
+
+	if (pf.flags[PERM_FLAG_IDX_DISABLE])
+		return 0;
+
+	ret = tpm_simple_cmd(0, TPM_ORD_PHYSICAL_SET_DEACTIVATED,
+			     1, activate ? 0 : 1,
+			     TPM_DURATION_TYPE_SHORT);
+	if (ret)
+		return ret;
+
+	if (activate && allow_reset) {
+		if (verbose)
+			printf("Requiring a reboot to activate the TPM.\n");
+	}
+
+	return 0;
+}
+
+static int tpm12_enable_activate(int allow_reset, bool verbose)
+{
+	int ret = tpm12_enable_tpm(true, verbose);
+	if (ret)
+		return ret;
+
+	return tpm12_activate_tpm(true, allow_reset, verbose);
+}
+
+static int tpm12_force_clear(bool enable_activate_before,
+			     bool enable_activate_after,
+			     bool verbose)
+{
+	bool has_owner;
+	int ret = tpm12_read_has_owner(&has_owner);
+	if (ret)
+		return -1;
+	if (!has_owner) {
+		if (verbose)
+			printf("TPM does not have an owner.\n");
+		return 0;
+	}
+
+	if (enable_activate_before) {
+		ret = tpm12_enable_activate(false, verbose);
+		if (ret) {
+			dprintf("TCGBIOS: Enabling/activating the TPM failed.\n");
+			return ret;
+		}
+	}
+
+	ret = tpm_simple_cmd(0, TPM_ORD_FORCE_CLEAR,
+			     0, 0, TPM_DURATION_TYPE_SHORT);
+	if (ret)
+		return ret;
+
+	if (!enable_activate_after) {
+		if (verbose)
+			printf("Owner successfully cleared.\n"
+			       "You will need to enable/activate the TPM again.\n\n");
+		return 0;
+	}
+
+	return tpm12_enable_activate(true, verbose);
+}
+
+static int tpm12_set_owner_install(bool allow, bool verbose)
+{
+	bool has_owner;
+	struct tpm_permanent_flags pf;
+	int ret = tpm12_read_has_owner(&has_owner);
+	if (ret)
+		return -1;
+
+	if (has_owner) {
+		if (verbose)
+			printf("Must first remove owner.\n");
+		return 0;
+	}
+
+	ret = tpm12_read_permanent_flags((char *)&pf, sizeof(pf));
+	if (ret)
+		return -1;
+
+	if (pf.flags[PERM_FLAG_IDX_DISABLE]) {
+		if (verbose)
+			printf("TPM must first be enable.\n");
+		return 0;
+	}
+
+	ret = tpm_simple_cmd(0, TPM_ORD_SET_OWNER_INSTALL,
+			     1, allow ? 1 : 0, TPM_DURATION_TYPE_SHORT);
+	if (ret)
+		return ret;
+
+	if (verbose)
+		printf("Installation of owner %s.\n",
+		      allow ? "enabled" : "disabled");
+
+	return 0;
+}
+
+static int tpm12_process_cfg(tpm_ppi_op ppi_op, bool verbose)
+{
+	int ret = 0;
+
+	switch (ppi_op) {
+	case TPM_PPI_OP_NOOP: /* no-op */
+		break;
+
+	case TPM_PPI_OP_ENABLE:
+		ret = tpm12_enable_tpm(true, verbose);
+		break;
+
+	case TPM_PPI_OP_DISABLE:
+		ret = tpm12_enable_tpm(false, verbose);
+		break;
+
+	case TPM_PPI_OP_ACTIVATE:
+		ret = tpm12_activate_tpm(true, true, verbose);
+		break;
+
+	case TPM_PPI_OP_DEACTIVATE:
+		ret = tpm12_activate_tpm(false, true, verbose);
+		break;
+
+	case TPM_PPI_OP_CLEAR:
+		ret = tpm12_force_clear(true, false, verbose);
+		break;
+
+	case TPM_PPI_OP_SET_OWNERINSTALL_TRUE:
+		ret = tpm12_set_owner_install(true, verbose);
+		break;
+
+	case TPM_PPI_OP_SET_OWNERINSTALL_FALSE:
+		ret = tpm12_set_owner_install(false, verbose);
+		break;
+
+	default:
+		break;
+	}
+
+	if (ret)
+		printf("Op %d: An error occurred: 0x%x TPM\n",
+		       ppi_op, ret);
+
+	return ret;
+}
+
+uint32_t tpm_process_opcode(uint8_t op, bool verbose)
+{
+	return tpm12_process_cfg(op, verbose);
+}
diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h
index 3ccfca5..b288778 100644
--- a/lib/libtpm/tcgbios.h
+++ b/lib/libtpm/tcgbios.h
@@ -32,5 +32,6 @@ uint32_t tpm_hash_all(const void *data, uint32_t datalen, void *hashptr);
 uint32_t tpm_measure_bcv_mbr(uint32_t bootdrv, const uint8_t *addr,
                              uint32_t length);
 uint32_t tpm_add_event_separators(uint32_t start_pcr, uint32_t end_pcr);
+uint32_t tpm_process_opcode(uint8_t op, bool verbose);
 
 #endif /* TCGBIOS_H */
diff --git a/lib/libtpm/tcgbios_int.h b/lib/libtpm/tcgbios_int.h
index b3ab0ad..1893ab2 100644
--- a/lib/libtpm/tcgbios_int.h
+++ b/lib/libtpm/tcgbios_int.h
@@ -14,6 +14,7 @@
 #define TCGBIOS_INT_H
 
 #include <stdint.h>
+#include <stdbool.h>
 
 #include "tpm_drivers.h"
 
@@ -111,6 +112,7 @@ struct tpm_req_getcap {
 #define TPM_CAP_FLAG      0x04
 #define TPM_CAP_PROPERTY  0x05
 #define TPM_CAP_FLAG_PERMANENT  0x108
+#define TPM_CAP_PROP_OWNER      0x111
 #define TPM_CAP_PROP_DURATION   0x120
 
 struct tpm_req_getcap_perm_flags {
@@ -139,6 +141,30 @@ struct tpm_rsp_getcap_perm_flags {
 	struct tpm_permanent_flags perm_flags;
 } __attribute__((packed));
 
+struct tpm_req_getcap_stclear_flags {
+	struct tpm_req_header hdr;
+	uint32_t cap_area;
+	uint32_t sub_cap_size;
+	uint32_t sub_cap;
+} __attribute__((packed));
+
+struct tpm_stclear_flags {
+	uint16_t tag;
+	uint8_t  flags[5];
+} __attribute__((packed));
+
+#define STCLEAR_FLAG_IDX_DEACTIVATED 0
+#define STCLEAR_FLAG_IDX_DISABLE_FORCE_CLEAR 1
+#define STCLEAR_FLAG_IDX_PHYSICAL_PRESENCE 2
+#define STCLEAR_FLAG_IDX_PHYSICAL_PRESENCE_LOCK 3
+#define STCLEAR_FLAG_IDX_GLOBAL_LOCK 4
+
+struct tpm_rsp_getcap_stclear_flags {
+	struct tpm_rsp_header hdr;
+	uint32_t size;
+	struct tpm_stclear_flags stclear_flags;
+} __attribute__((packed));
+
 struct tpm_rsp_getcap_ownerauth {
 	struct tpm_rsp_header hdr;
 	uint32_t size;
@@ -151,4 +177,13 @@ struct tpm_rsp_getcap_durations {
 	uint32_t durations[TPM_NUM_DURATIONS];
 } __attribute__((packed));
 
+#define TPM_PPI_OP_NOOP 0
+#define TPM_PPI_OP_ENABLE 1
+#define TPM_PPI_OP_DISABLE 2
+#define TPM_PPI_OP_ACTIVATE 3
+#define TPM_PPI_OP_DEACTIVATE 4
+#define TPM_PPI_OP_CLEAR 5
+#define TPM_PPI_OP_SET_OWNERINSTALL_TRUE 8
+#define TPM_PPI_OP_SET_OWNERINSTALL_FALSE 9
+
 #endif /* TCGBIOS_INT_H */
diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
index d4a1a72..1a5273f 100644
--- a/lib/libtpm/tpm.code
+++ b/lib/libtpm/tpm.code
@@ -14,6 +14,7 @@
  */
 
 #include <tcgbios.h>
+#include <stdbool.h>
 
 
 /************************************************/
@@ -120,3 +121,14 @@ PRIM(tpm_X2d_measure_X2d_bcv_X2d_mbr)
 	int bootdrv = TOS.u;
 	TOS.n = tpm_measure_bcv_mbr(bootdrv, addr, length);
 MIRP
+
+/*************************************************************/
+/* Process an opcode to change state of the TPM              */
+/* SLOF:   tpm-process-opcode  ( opcode verbose -- errcode)  */
+/* LIBTPM: tpm_process_opcode(opcode, verbose)               */
+/*************************************************************/
+PRIM(tpm_X2d_process_X2d_opcode)
+	int opcode = TOS.u; POP;
+	bool verbose = TOS.u;
+	TOS.n = tpm_process_opcode(opcode, verbose);
+MIRP
diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
index 2d3d75e..9fb30bb 100644
--- a/lib/libtpm/tpm.in
+++ b/lib/libtpm/tpm.in
@@ -23,3 +23,4 @@ cod(tpm-hash-log-extend-event)
 cod(tpm-hash-all)
 cod(tpm-add-event-separators)
 cod(tpm-measure-bcv-mbr)
+cod(tpm-process-opcode)
