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