+uint32_t tpm_get_permanent_flags(struct tpm_permanent_flags *pflags)
+{
+ const uint8_t command[22] = {
+ 0x0, 0xc1, /* TPM_TAG */
+ 0x0, 0x0, 0x0, 0x16, /* parameter size */
+ 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
+ 0x0, 0x0, 0x0, 0x4, /* TPM_CAP_FLAG_PERM */
+ 0x0, 0x0, 0x0, 0x4, /* subcap size */
+ 0x0, 0x0, 0x1, 0x8, /* subcap value */
+ };
+ const size_t data_size_offset = TPM_HEADER_SIZE;
+ const size_t data_offset = TPM_HEADER_SIZE + sizeof (uint32_t);
+ uint8_t response[COMMAND_BUFFER_SIZE];
+ size_t response_length = sizeof(response);
+ uint32_t err;
+ uint32_t data_size;
+
+ err = tpm_sendrecv_command(command, response, &response_length);
+ if (err)
+ return err;
+ if (unpack_byte_string(response, response_length, "d",
+ data_size_offset, &data_size))
+ return TPM_LIB_ERROR;
+ if (data_size < sizeof(*pflags))
+ return TPM_LIB_ERROR;
+ if (unpack_byte_string(response, response_length, "s",
+ data_offset, pflags, sizeof(*pflags)))
+ return TPM_LIB_ERROR;
+
+ return 0;
+}
+
+uint32_t tpm_get_permissions(uint32_t index, uint32_t *perm)
+{
+ const uint8_t command[22] = {
+ 0x0, 0xc1, /* TPM_TAG */
+ 0x0, 0x0, 0x0, 0x16, /* parameter size */
+ 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
+ 0x0, 0x0, 0x0, 0x11,
+ 0x0, 0x0, 0x0, 0x4,
+ };
+ const size_t index_offset = 18;
+ const size_t perm_offset = 60;
+ uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+ size_t response_length = sizeof(response);
+ uint32_t err;
+
+ if (pack_byte_string(buf, sizeof(buf), "d", 0, command, sizeof(command),
+ index_offset, index))
+ return TPM_LIB_ERROR;
+ err = tpm_sendrecv_command(buf, response, &response_length);
+ if (err)
+ return err;
+ if (unpack_byte_string(response, response_length, "d",
+ perm_offset, perm))
+ return TPM_LIB_ERROR;
+
+ return 0;
+}
+
+#ifdef CONFIG_TPM_FLUSH_RESOURCES
+uint32_t tpm_flush_specific(uint32_t key_handle, uint32_t resource_type)
+{
+ const uint8_t command[18] = {
+ 0x00, 0xc1, /* TPM_TAG */
+ 0x00, 0x00, 0x00, 0x12, /* parameter size */
+ 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
+ 0x00, 0x00, 0x00, 0x00, /* key handle */
+ 0x00, 0x00, 0x00, 0x00, /* resource type */
+ };
+ const size_t key_handle_offset = 10;
+ const size_t resource_type_offset = 14;
+ uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+ size_t response_length = sizeof(response);
+ uint32_t err;
+
+ if (pack_byte_string(buf, sizeof(buf), "sdd",
+ 0, command, sizeof(command),
+ key_handle_offset, key_handle,
+ resource_type_offset, resource_type))
+ return TPM_LIB_ERROR;
+
+ err = tpm_sendrecv_command(buf, response, &response_length);
+ if (err)
+ return err;
+ return 0;
+}
+#endif /* CONFIG_TPM_FLUSH_RESOURCES */
+