[Skiboot] [PATCH 4/8] libstb/tss2: Add TSS wrapping functions - just FYI

Kenneth Goldman kgoldman at us.ibm.com
Tue Jun 2 07:13:57 AEST 2020


FYI, I don't see any issue with these because they are stand alone commands
with no retained TPM volatile state.  It also is in skiboot, which may go
directly to the TPM.

In general though, if you go through a resource manager, you should create
the TSS context once and delete it at the end.  Otherwise, the delete will
close the connection and the resource manager will flush objects and
sessions.

--
Ken Goldman   kgoldman at us.ibm.com
914-945-2415 (862-2415)




From:	"Mauro S. M. Rodrigues" <maurosr at linux.vnet.ibm.com>
To:	skiboot at lists.ozlabs.org
Cc:	nayna at linux.ibm.com
Date:	06/01/2020 04:36 PM
Subject:	[EXTERNAL] [Skiboot] [PATCH 4/8] libstb/tss2: Add TSS wrapping
            functions
Sent by:	"Skiboot" <skiboot-bounces
            +kgoldman=us.ibm.com at lists.ozlabs.org>



In this commit we add some fundamental TSS operations:
 - tss_nv_read_public
 - tss_nv_read
 - tss_nv_write
 - tss_nv_write_lock
 - tss_nv_define_space
 - tss_nv_undefine_space
 - tss_get_defined_nv_indices
 - tss_pcr_extend
 - tss_pcr_read
 - tss_get_random_number
 - tss_set_platform_auth

Co-authored-by: Eric Richter <erichte at linux.ibm.com>
Co-authored-by: Ryan Grimm <grimm at linux.ibm.com>
Signed-off-by: Mauro S. M. Rodrigues <maurosr at linux.vnet.ibm.com>
---
 libstb/tss2/tssskiboot.c | 727 +++++++++++++++++++++++++++++++++++++++
 libstb/tss2/tssskiboot.h |  26 ++
 2 files changed, 753 insertions(+)
 create mode 100644 libstb/tss2/tssskiboot.c
 create mode 100644 libstb/tss2/tssskiboot.h

diff --git a/libstb/tss2/tssskiboot.c b/libstb/tss2/tssskiboot.c
new file mode 100644
index 0000000000..5f6d761173
--- /dev/null
+++ b/libstb/tss2/tssskiboot.c
@@ -0,0 +1,727 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/* Copyright 2020 IBM Corp. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <skiboot.h>
+#include <opal-api.h>
+#include <tssskiboot.h>
+#include <tpm_chip.h>
+#include <ibmtss/tssfile.h>
+#include <ibmtss/TPM_Types.h>
+#include <ibmtss/tssmarshal.h>
+#include <ibmtss/tssresponsecode.h>
+
+/*
+ * Helper to string-fy TSS error response codes.
+ */
+static void tss_error_trace(const char *function, TPM_RC rc)
+{
+		 const char *msg;
+		 const char *submsg;
+		 const char *num;
+		 prlog(PR_ERR, "%s: failed, rc %08x\n", function, rc);
+		 TSS_ResponseCode_toString(&msg, &submsg, &num, rc);
+		 prlog(PR_ERR, "%s%s%s\n", msg, submsg, num);
+}
+
+/*
+ * @brief Reads the public and name area of a NV Index.
+ * @param nv_index 		 		 The target NV index to read
public info from.
+ * @param nv_public		 		 buffer to save public are read
from nv index
+ * @param nv_name		 		 buffer to save nv index name.
+ */
+int tss_nv_read_public(TPMI_RH_NV_INDEX nv_index, TPMS_NV_PUBLIC
*nv_public,
+		 		        TPM2B_NAME *nv_name)
+{
+		 NV_ReadPublic_Out *out = NULL;
+		 NV_ReadPublic_In *in = NULL;
+		 TSS_CONTEXT *context = NULL;
+		 TPM_RC rc = OPAL_SUCCESS;
+
+		 if (!nv_public || !nv_name) {
+		 		 rc = OPAL_PARAMETER;
+		 		 goto cleanup;
+		 }
+
+		 in = zalloc(sizeof(NV_ReadPublic_In));
+		 if (!in) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 out = zalloc(sizeof(NV_ReadPublic_Out));
+		 if (!out) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Create(&context);
+		 if (rc) {
+		 		 tss_error_trace("tss_nv_read_public", rc);
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 in->nvIndex = nv_index;
+		 rc = TSS_Execute(context,
+		 		 		  (RESPONSE_PARAMETERS *) out,
+		 		 		  (COMMAND_PARAMETERS *) in,
+		 		 		  NULL,
+		 		 		  TPM_CC_NV_ReadPublic,
+		 		 		  TPM_RH_NULL, NULL, 0);
+		 if (!rc) {
+		 		 memcpy(nv_public, &out->nvPublic, sizeof
(TPMS_NV_PUBLIC));
+		 		 memcpy(nv_name, &out->nvName, sizeof(TPM2B_NAME));
+		 }
+		 else
+		 		 tss_error_trace("tss_nv_read_public", rc);
+cleanup:
+		 free(in);
+		 free(out);
+		 TSS_Delete(context);
+		 return rc;
+}
+
+/* @brief This command reads a value from an area previously defined using
+ * nv_define_space
+ * @param nv_index 		 		 The target NV index to read
from.
+ * @param buffer		 		 buffer to save the data read.
+ * @param buffer_size		 		 size of the buffer, to avoid
overflow.
+ * @param offset		 		 position where to start the nv read
operation.
+ */
+int tss_nv_read(TPMI_RH_NV_INDEX nv_index, void *buffer,
+		 		 size_t buffer_size, uint16_t offset)
+{
+		 TSS_CONTEXT *context = NULL;
+		 NV_Read_Out *out = NULL;
+		 NV_Read_In *in = NULL;
+		 TPM_RC rc = OPAL_SUCCESS;
+
+		 if (!buffer) {
+		 		 rc = OPAL_PARAMETER;
+		 		 goto cleanup;
+		 }
+
+		 in = zalloc(sizeof(NV_Read_In));
+		 if (!in) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 out = zalloc(sizeof(NV_Read_Out));
+		 if (!out) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Create(&context);
+		 if (rc) {
+		 		 tss_error_trace("tss_nv_read", rc);
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 in->nvIndex = nv_index;
+		 in->authHandle = nv_index;
+		 in->offset = offset;
+		 in->size = buffer_size;
+
+		 rc = TSS_Execute(context,
+		 		 		  (RESPONSE_PARAMETERS *) out,
+		 		 		  (COMMAND_PARAMETERS *) in,
+		 		 		  NULL,
+		 		 		  TPM_CC_NV_Read,
+		 		 		  TPM_RS_PW, NULL, 0,
+		 		 		  TPM_RH_NULL, NULL, 0);
+
+		 if (!rc)
+		 		 memcpy(buffer, out->data.b.buffer, buffer_size);
+		 else
+		 		 tss_error_trace("tss_nv_read", rc);
+
+cleanup:
+		 TSS_Delete(context);
+		 free(in);
+		 free(out);
+		 return rc;
+}
+
+/* @brief This command writes a value in an area previously defined using
+ * nv_define_space
+ * @param nv_index 		 		 The target NV index to write to.
+ * @param buffer		 		 buffer containing the data write.
+ * @param buffer_size		 		 size of the buffer to write.
+ * @param offset		 		 position where to start the nv write
operation.
+ */
+int tss_nv_write(TPMI_RH_NV_INDEX nv_index, void *buffer,
+		 		  size_t buffer_size, uint16_t offset)
+{
+		 TSS_CONTEXT *context = NULL;
+		 NV_Write_In *in = NULL;
+		 TPM_RC rc = OPAL_SUCCESS;
+
+		 if (!buffer) {
+		 		 rc = OPAL_PARAMETER;
+		 		 goto cleanup;
+		 }
+
+		 in = zalloc(sizeof(NV_Write_In));
+		 if (!in) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Create(&context);
+		 if (rc) {
+		 		 tss_error_trace("tss_nv_write", rc);
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 in->nvIndex = nv_index;
+		 in->authHandle = TPM_RH_PLATFORM;
+		 in->offset = offset;
+		 rc = TSS_TPM2B_Create(&in->data.b, buffer, buffer_size,
+		 		 		       sizeof(in->data.t.buffer));
+		 if (rc) {
+		 		 tss_error_trace("tss_nv_write", rc);
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Execute(context,
+		 		 		  NULL,
+		 		 		  (COMMAND_PARAMETERS *) in,
+		 		 		  NULL,
+		 		 		  TPM_CC_NV_Write,
+		 		 		  TPM_RS_PW, NULL, 0,
+		 		 		  TPM_RH_NULL, NULL, 0);
+		 if (rc)
+		 		 tss_error_trace("tss_nv_write", rc);
+cleanup:
+		 TSS_Delete(context);
+		 free(in);
+		 return rc;
+}
+
+/*
+ * @brief This command locks an area, pointed by the index and previously
+ * defined using nv_define_space, preventing further writing operations on
it.
+ * @param nv_index 		 		 The target NV index to lock.
+ */
+int tss_nv_write_lock(TPMI_RH_NV_INDEX nv_index)
+{
+		 TSS_CONTEXT *context = NULL;
+		 NV_WriteLock_In *in = NULL;
+		 TPM_RC rc = OPAL_SUCCESS;
+
+		 in = zalloc(sizeof(NV_WriteLock_In));
+		 if (!in) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Create(&context);
+		 if (rc) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 in->authHandle = TPM_RH_PLATFORM;
+		 in->nvIndex = nv_index;
+		 rc = TSS_Execute(context,
+		 		 		  NULL,
+		 		 		  (COMMAND_PARAMETERS *) in,
+		 		 		  NULL,
+		 		 		  TPM_CC_NV_WriteLock,
+		 		 		  TPM_RS_PW, NULL, 0,
+		 		 		  TPM_RH_NULL, NULL, 0);
+		 if (rc)
+		 		 tss_error_trace("tss_nv_write_lock", rc);
+cleanup:
+		 TSS_Delete(context);
+		 free(in);
+		 return rc;
+}
+
+ /*
+ * @brief This command defines the area pointed by nv index and its
attributes.
+ * @param nv_index 		 		 The target NV index to define.
+ * @param data_size		 		 size of the area to be defined.
+ */
+int tss_nv_define_space(TPMI_RH_NV_INDEX nv_index, uint16_t data_size)
+{
+		 NV_DefineSpace_In *in = NULL;
+		 TSS_CONTEXT *context = NULL;
+		 TPM_RC rc = OPAL_SUCCESS;
+
+		 in = zalloc(sizeof(NV_DefineSpace_In));
+		 if (!in) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Create(&context);
+		 if (rc) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 in->authHandle = TPM_RH_PLATFORM;
+
+		 in->publicInfo.nvPublic.nvIndex = nv_index;
+		 in->publicInfo.nvPublic.dataSize = data_size;
+		 /* password is NULL so b.size is 0 */
+		 in->auth.b.size = 0;
+		 /* Empty policy, so size is 0 */
+		 in->publicInfo.nvPublic.authPolicy.t.size = 0;
+		 /* Used algorithm is SHA256 */
+		 in->publicInfo.nvPublic.nameAlg = TPM_ALG_SHA256;
+		 /*
+		  * This carries the flags set according to default settings,
excepting
+		  * for what is set by this function parameters. Further
customization
+		  * will require a different setup for nvAttribute flags as is
done in
+		  * TSS's code.
+		  */
+		 in->publicInfo.nvPublic.attributes.val = (TPMA_NVA_PPWRITE |
+
TPMA_NVA_ORDINARY |
+
TPMA_NVA_WRITE_STCLEAR |
+
TPMA_NVA_AUTHREAD |
+
TPMA_NVA_PLATFORMCREATE |
+
TPMA_NVA_NO_DA);
+
+		 rc = TSS_Execute(context,
+		 		 		  NULL,
+		 		 		  (COMMAND_PARAMETERS *)in,
+		 		 		  NULL,
+		 		 		  TPM_CC_NV_DefineSpace,
+		 		 		  TPM_RS_PW, NULL, 0,
+		 		 		  TPM_RH_NULL, NULL, 0);
+		 if (rc) {
+		 		 tss_error_trace("tss_nv_define_space", rc);
+		 		 switch(rc) {
+		 		 		 case TPM_RC_NV_DEFINED:
+		 		 		 		 rc = OPAL_WRONG_STATE;
+		 		 		 		 break;
+		 		 		 default:
+		 		 		 		 break;
+		 		 }
+		 }
+cleanup:
+		 TSS_Delete(context);
+		 free(in);
+		 return rc;
+}
+
+/*
+ * @brief Extends a PCR using the given hashes and digest
+ * @param pcr_handle		 		 The PCR to be extended
+ * @param alg_hashes		 		 A pointer to an array of hash
algorithms, each
+ * 		 		 		 		 one used to extend its
respective PCR bank.
+ * @param alg_hash_count		 The number of elements in alg_hashes
array
+ * @param digests		 		 The digest data.
+ */
+int tss_pcr_extend(TPMI_DH_PCR pcr_handle, TPMI_ALG_HASH *alg_hashes,
+		 		    uint8_t alg_hash_count, const uint8_t
**digests)
+{
+		 TSS_CONTEXT *context = NULL;
+		 uint32_t rc = OPAL_SUCCESS;
+		 PCR_Extend_In *in = NULL;
+		 uint16_t digest_size;
+
+		 if (!alg_hashes || !digests || pcr_handle >=
IMPLEMENTATION_PCR) {
+		 		 rc = OPAL_PARAMETER;
+		 		 goto cleanup;
+		 }
+
+		 in = zalloc(sizeof(PCR_Extend_In));
+		 if (!in) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Create(&context);
+		 if (rc) {
+		 		 tss_error_trace("tss_pcr_extend", rc);
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 if (alg_hash_count >= HASH_COUNT) {
+		 		 rc = OPAL_PARAMETER;
+		 		 goto cleanup;
+		 }
+
+		 in->digests.count = alg_hash_count;
+		 in->pcrHandle = pcr_handle;
+		 for (uint8_t i=0; i < alg_hash_count; i++) {
+		 		 in->digests.digests[i].hashAlg = alg_hashes[i];
+		 		 /* memset zeroes first to assure the digest data
is zero
+		 		  * padded.*/
+		 		 memset((uint8_t*) &in->digests.digests[i].digest,
0,
+		 		        sizeof(TPMU_HA));
+
+		 		 digest_size = 0;
+		 		 /* Marshal the digest in order to obtain its size.
This is a
+		 		  * commonly used pattern in TSS.
+		 		  */
+		 		 rc = TSS_TPMU_HA_Marshalu((const TPMU_HA *)digests
[i],
+
&digest_size, NULL, NULL ,
+		 		 		 		 		   alg_hashes
[i]);
+		 		 if (rc)
+		 		 		 goto cleanup;
+		 		 memcpy((uint8_t*) &in->digests.digests[i].digest,
digests[i],
+		 		        digest_size);
+		 }
+		 rc = TSS_Execute(context,
+		 		 		  NULL,
+		 		 		  (COMMAND_PARAMETERS *) in,
+		 		 		  NULL,
+		 		 		  TPM_CC_PCR_Extend,
+		 		 		  TPM_RS_PW, NULL, 0,
+		 		 		  TPM_RH_NULL, NULL, 0);
+		 if (rc)
+		 		 tss_error_trace("tss_pcr_extend", rc);
+cleanup:
+		 TSS_Delete(context);
+		 free(in);
+		 return rc;
+}
+
+/*
+ * @brief reads pcr values of a given pcr handle.
+ * @param pcr_handle		 		 The PCR to be extended
+ * @param alg_hashes		 		 A pointer to an array of hash
algorithms, each
+ * 		 		 		 		 one used to extend its
respective PCR bank.
+ * @param alg_hash_count		 The length of alg hashes array
+ */
+int tss_pcr_read(TPMI_DH_PCR pcr_handle, TPMI_ALG_HASH *alg_hashes,
+		 		  uint8_t alg_hash_count)
+{
+		 TSS_CONTEXT *context = NULL;
+		 PCR_Read_Out *out = NULL;
+		 PCR_Read_In *in = NULL;
+		 uint32_t rc = OPAL_SUCCESS;
+
+		 if (!alg_hashes) {
+		 		 rc = OPAL_PARAMETER;
+		 		 goto cleanup;
+		 }
+
+		 in = zalloc(sizeof(PCR_Read_In));
+		 if (!in) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 out = zalloc(sizeof(PCR_Read_Out));
+		 if (!out) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Create(&context);
+		 if (!rc) {
+		 		 tss_error_trace("tss_pcr_read", rc);
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 in->pcrSelectionIn.count = alg_hash_count;
+		 for (int i=0; i < alg_hash_count; i++) {
+		 		 in->pcrSelectionIn.pcrSelections[i].hash =
alg_hashes[i];
+		 		 in->pcrSelectionIn.pcrSelections[i].sizeofSelect =
3;
+		 		 in->pcrSelectionIn.pcrSelections[i].pcrSelect[0] =
0;
+		 		 in->pcrSelectionIn.pcrSelections[i].pcrSelect[1] =
0;
+		 		 in->pcrSelectionIn.pcrSelections[i].pcrSelect[2] =
0;
+		 		 in->pcrSelectionIn.pcrSelections[i].pcrSelect
[pcr_handle/8] = 1 << (pcr_handle % 8);
+		 }
+
+		 rc = TSS_Execute(context,
+		 		 		  (RESPONSE_PARAMETERS *) out,
+		 		 		  (COMMAND_PARAMETERS *) in,
+		 		 		  NULL,
+		 		 		  TPM_CC_PCR_Read,
+		 		 		  TPM_RH_NULL, NULL, 0);
+		 if (rc)
+		 		 tss_error_trace("tss_pcr_read", rc);
+cleanup:
+		 TSS_Delete(context);
+		 free(in);
+		 free(out);
+		 return rc;
+}
+
+/*
+ * @brief returns next bytes_requested bytes from the TPM RNG
+ * @param buffer		 		 Buffer to save the generated numbers.
+ * @param bytes_requested		 How many random bytes are requested.
+ */
+int tss_get_random_number(void *buffer, uint16_t bytes_requested)
+{
+		 TSS_CONTEXT *context = NULL;
+		 GetRandom_Out *out = NULL;
+		 TPM_RC rc = OPAL_SUCCESS;
+		 GetRandom_In *in = NULL;
+		 void *p_buffer = buffer;
+
+		 if (!buffer) {
+		 		 rc = OPAL_PARAMETER;
+		 		 goto cleanup;
+		 }
+
+		 in = zalloc(sizeof(GetRandom_In));
+		 if (!in) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 out = zalloc(sizeof(GetRandom_Out));
+		 if (!out) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Create(&context);
+		 if (rc) {
+		 		 tss_error_trace("tss_get_random_number", rc);
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 /*
+		  * Even though we request a specific number of bytes, there is
no
+		  * guarantee that TPM will return that number of bytes, so we
ask again
+		  * until we reach the desired total of bytes or rng function
fails
+		  */
+		 for (uint16_t bytes_copied = 0; bytes_copied <
bytes_requested; ) {
+		 		 in->bytesRequested = bytes_requested -
bytes_copied;
+		 		 rc = TSS_Execute(context,
+		 		 		 		  (RESPONSE_PARAMETERS
*)out,
+		 		 		 		  (COMMAND_PARAMETERS *)in,
+		 		 		 		  NULL, TPM_CC_GetRandom,
+		 		 		 		  TPM_RH_NULL, NULL, 0);
+		 		 if (!rc){
+		 		 		 memcpy(p_buffer, out->
randomBytes.t.buffer,
+		 		 		        out->randomBytes.t.size);
+		 		 		 bytes_copied += out->
randomBytes.t.size;
+		 		 		 p_buffer += bytes_copied;
+		 		 		 /* explicitly clean up output's buffer
from memory on
+		 		 		  * every iteration, since the size
will vary, to avoid
+		 		 		  * some kind of exploitation.
+		 		 		  */
+		 		 		 memset(out->randomBytes.t.buffer, 0,
+		 		 		        out->randomBytes.t.size);
+
+		 		 }
+		 		 else {
+		 		 		 tss_error_trace
("tss_get_random_number", rc);
+		 		 		 break;
+		 		 }
+		 }
+
+cleanup:
+		 TSS_Delete(context);
+		 free(in);
+		 free(out);
+		 return rc;
+}
+
+/* local helper to generate random password without zeroes */
+static int generate_random_passwd(char *passwd, uint16_t passwd_len)
+{
+		 TPM_RC rc = OPAL_SUCCESS;
+		 char *buffer = NULL;
+		 int bytes_copied;
+		 int i;
+
+		 buffer = zalloc(passwd_len);
+		 if (!buffer) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 bytes_copied = 0;
+		 while ((rc == 0) && (bytes_copied < passwd_len)) {
+		 		 rc = tss_get_random_number(buffer, passwd_len);
+		 		 if (rc)
+		 		 		 goto cleanup;
+
+		 		 /* Copy as many bytes as were received or until
bytes requested */
+		 		 for (i = 0; (i < passwd_len) &&
+		 		 		     (bytes_copied < passwd_len); i++)
{
+
+		 		 		 /* Skip zero bytes */
+		 		 		 if (buffer[i] == 0)
+		 		 		 		 continue;
+		 		 		 passwd[bytes_copied] = buffer[i];
+		 		 		 bytes_copied++;
+		 		 }
+		 }
+cleanup:
+		 free(buffer);
+		 return rc;
+}
+
+/*
+ * @brief This command allows the authorization secret for a hierarchy to
be
+ * changed.
+ */
+int tss_set_platform_auth(void)
+{
+		 HierarchyChangeAuth_In *in =  NULL;
+		 TSS_CONTEXT *context = NULL;
+		 TPM_RC rc = OPAL_SUCCESS;
+		 char *key_passwd = NULL;
+
+		 in = zalloc(sizeof(HierarchyChangeAuth_In));
+		 if (!in) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 key_passwd = zalloc(TSS_AUTH_PASSWD_LEN + 1);
+		 if (!key_passwd) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Create(&context);
+		 if (rc) {
+		 		 tss_error_trace("tss_set_platform_auth", rc);
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 rc = generate_random_passwd(key_passwd,
TSS_AUTH_PASSWD_LEN);
+		 if (rc) {
+		 		 tss_error_trace("Failed to generate the auth
password", rc);
+		 		 goto cleanup;
+		 }
+		 key_passwd[TSS_AUTH_PASSWD_LEN] = 0;
+
+		 in->authHandle = TPM_RH_PLATFORM;
+		 rc = TSS_TPM2B_StringCopy(&in->newAuth.b, key_passwd,
+		 		 		 		   sizeof(in->
newAuth.t.buffer));
+		 if (rc) {
+		 		 tss_error_trace("tss_set_platform_auth", rc);
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Execute(context,
+		 		 		  NULL,
+		 		 		  (COMMAND_PARAMETERS *)in,
+		 		 		  NULL,
+		 		 		  TPM_CC_HierarchyChangeAuth,
+		 		 		  TPM_RS_PW, NULL, 0,
+		 		 		  TPM_RH_NULL, NULL, 0);
+		 if (rc)
+		 		 tss_error_trace("tss_set_platform_auth", rc);
+
+cleanup:
+		 TSS_Delete(context);
+		 free(in);
+		 /* explicitly clean up password from memory to avoid some kind of
+		 * exploitation.
+		 */
+		 memset(key_passwd, 0, TSS_AUTH_PASSWD_LEN + 1);
+		 free(key_passwd);
+		 return rc;
+}
+
+/*
+ * @brief returns a list of defined NV indices
+ * @param pcr_handle		 		 The PCR to be extended
+ * @param alg_hashes		 		 A pointer to an array of hash
algorithms, each
+ * 		 		 		 		 one used to extend its
respective PCR bank.
+ * @param alg_hash_count		 The length of alg hashes array
+ */
+int tss_get_defined_nv_indices(TPMI_RH_NV_INDEX **indices, size_t *count)
+{
+		 TSS_CONTEXT *context = NULL;
+		 GetCapability_In *in = NULL;
+		 GetCapability_Out *out = NULL;
+		 uint32_t rc = OPAL_SUCCESS;
+		 TPML_HANDLE *handles;
+
+		 in = zalloc(sizeof(GetCapability_In));
+		 if (!in) {
+		         rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 out = zalloc(sizeof(GetCapability_Out));
+		 if (!out) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 rc = TSS_Create(&context);
+		 if (rc) {
+		 		 tss_error_trace("tss_check_nv_index", rc);
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 in->capability = 1;
+		 in->property = 0x01000000;
+		 in->propertyCount = 64;
+
+		 rc = TSS_Execute(context,
+		 		 		  (RESPONSE_PARAMETERS *) out,
+		 		 		  (COMMAND_PARAMETERS *) in,
+		 		 		  NULL,
+		 		 		  TPM_CC_GetCapability,
+		 		 		  TPM_RH_NULL, NULL, 0);
+		 if (rc) {
+		 		 tss_error_trace("tss_check_nv_index", rc);
+		 		 goto cleanup;
+		 }
+
+		 handles = (TPML_HANDLE *) &out->capabilityData.data;
+		 *count = handles->count;
+		 *indices = malloc(*count * sizeof(TPMI_RH_NV_INDEX));
+		 if (!indices) {
+		 		 rc = OPAL_NO_MEM;
+		 		 goto cleanup;
+		 }
+
+		 memcpy(*indices, handles->handle, *count * sizeof
(TPMI_RH_NV_INDEX));
+
+cleanup:
+		 TSS_Delete(context);
+		 free(in);
+		 free(out);
+		 return rc;
+}
+
+
+int tss_nv_undefine_space(TPMI_RH_NV_INDEX nv_index)
+{
+		 int rc;
+		 TSS_CONTEXT *context = NULL;
+		 NV_UndefineSpace_In in;
+
+		 rc = TSS_Create(&context);
+		 if (rc) {
+		 		 tss_error_trace("tss_check_nv_undefine_index",
rc);
+		 		 rc = OPAL_NO_MEM;
+		 		 return rc;
+		 }
+
+		 in.authHandle = TPM_RH_PLATFORM;
+		 in.nvIndex = nv_index;
+
+		 rc = TSS_Execute(context, NULL,
+		 		 		  (COMMAND_PARAMETERS *) &in,
+		 		 		  NULL,
+		 		 		  TPM_CC_NV_UndefineSpace,
+		 		 		  TPM_RS_PW, NULL, 0,
+		 		 		  TPM_RH_NULL, NULL, 0);
+		 if (rc)
+		 		 tss_error_trace("tss_check_nv_index", rc);
+
+		 TSS_Delete(context);
+		 return rc;
+}
diff --git a/libstb/tss2/tssskiboot.h b/libstb/tss2/tssskiboot.h
new file mode 100644
index 0000000000..0b8cb74a65
--- /dev/null
+++ b/libstb/tss2/tssskiboot.h
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/* Copyright 2020 IBM Corp. */
+
+#ifndef TSSSKIBOOT_H
+#define TSSSKIBOOT_H
+
+#include <ibmtss/tss.h>
+
+#define TSS_AUTH_PASSWD_LEN 32
+int tss_nv_read_public(TPMI_RH_NV_INDEX nv_index, TPMS_NV_PUBLIC
*nv_public,
+		 		        TPM2B_NAME *nv_name);
+int tss_nv_read(TPMI_RH_NV_INDEX nv_index, void *buffer, size_t
buffer_size,
+		 		 uint16_t offset);
+int tss_nv_write(TPMI_RH_NV_INDEX nv_index, void *buffer, size_t
buffer_size,
+		 		  uint16_t offset);
+int tss_nv_write_lock(TPMI_RH_NV_INDEX nv_index);
+int tss_nv_define_space(TPMI_RH_NV_INDEX nv_index, uint16_t data_size);
+int tss_pcr_extend(TPMI_DH_PCR pcr_handle, TPMI_ALG_HASH *alg_hashes,
+		 		    uint8_t hashes_count, const uint8_t **digests);
+int tss_pcr_read(TPMI_DH_PCR pcr_handle, TPMI_ALG_HASH *alg_hashes,
+		 		  uint8_t hashes_count);
+int tss_get_random_number(void *buffer, uint16_t bytes_requested);
+int tss_set_platform_auth(void);
+int tss_get_defined_nv_indices(TPMI_RH_NV_INDEX **indices, size_t *count);
+int tss_nv_undefine_space(TPMI_RH_NV_INDEX nv_index);
+#endif /* TSSSKIBOOT_H */
--
2.26.2

_______________________________________________
Skiboot mailing list
Skiboot at lists.ozlabs.org
https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.ozlabs.org_listinfo_skiboot&d=DwICAg&c=jf_iaSHvJObTbx-siA1ZOg&r=DZCVG43VcL8GTneMZb8k8lEwb-O1GZktFfre1-mlmiA&m=UmyjIq0a1_xvmA1g3OZZ-NcW6Atw2pohxYu-VmdoY_A&s=qOUs8duR8cg3oJoW15sSR3RnnVwiSww8rPZsOsH381U&e=




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/skiboot/attachments/20200601/4b4e5f05/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: graycol.gif
Type: image/gif
Size: 105 bytes
Desc: not available
URL: <http://lists.ozlabs.org/pipermail/skiboot/attachments/20200601/4b4e5f05/attachment-0001.gif>


More information about the Skiboot mailing list