[10/15] libstb/tss2: Add multiple TSS wrapping functions
diff mbox series

Message ID 20200125001510.708149-11-maurosr@linux.vnet.ibm.com
State New
Headers show
Series
  • libstb: Advance TSS and mbedtls infrastructure.
Related show

Commit Message

Mauro S. M. Rodrigues Jan. 25, 2020, 12:15 a.m. UTC
In this commit we add some fundamental TSS operations:
 - TSS_NV_ReadPublic
 - TSS_NV_Read
 - TSS_NV_Write
 - TSS_NV_WriteLock
 - TSS_NV_Define_Space
 - TSS_PCR_Extend
 - TSS_PCR_Read
 - TSS_Get_Random_Number

Signed-off-by: Mauro S. M. Rodrigues <maurosr@linux.vnet.ibm.com>
Signed-off-by: Eric Richter <erichte@linux.ibm.com>
---
 libstb/tss2/Makefile.inc |   4 +-
 libstb/tss2/tssskiboot.c | 503 +++++++++++++++++++++++++++++++++++++++
 libstb/tss2/tssskiboot.h |  62 +++++
 3 files changed, 567 insertions(+), 2 deletions(-)
 create mode 100644 libstb/tss2/tssskiboot.c
 create mode 100644 libstb/tss2/tssskiboot.h

Comments

Stewart Smith Jan. 26, 2020, 3:30 a.m. UTC | #1
On Fri, Jan 24, 2020, at 4:15 PM, Mauro S. M. Rodrigues wrote:
> In this commit we add some fundamental TSS operations:
>  - TSS_NV_ReadPublic
>  - TSS_NV_Read
>  - TSS_NV_Write
>  - TSS_NV_WriteLock
>  - TSS_NV_Define_Space
>  - TSS_PCR_Extend
>  - TSS_PCR_Read
>  - TSS_Get_Random_Number

This naming convention is both ugly and not consistent with skiboot coding style.

> 
> Signed-off-by: Mauro S. M. Rodrigues <maurosr@linux.vnet.ibm.com>
> Signed-off-by: Eric Richter <erichte@linux.ibm.com>
> ---
>  libstb/tss2/Makefile.inc |   4 +-
>  libstb/tss2/tssskiboot.c | 503 +++++++++++++++++++++++++++++++++++++++
>  libstb/tss2/tssskiboot.h |  62 +++++
>  3 files changed, 567 insertions(+), 2 deletions(-)
>  create mode 100644 libstb/tss2/tssskiboot.c
>  create mode 100644 libstb/tss2/tssskiboot.h
> 
> diff --git a/libstb/tss2/Makefile.inc b/libstb/tss2/Makefile.inc
> index 5fa4e6752..d85433d9c 100644
> --- a/libstb/tss2/Makefile.inc
> +++ b/libstb/tss2/Makefile.inc
> @@ -13,10 +13,10 @@ TSS2LIB_SRCS = tss.c tss20.c tssauth.c tssauth20.c 
> tssccattributes.c
>  TSS2LIB_SRCS += tssmarshal.c tssprint.c tssprintcmd.c tssproperties.c
>  TSS2LIB_SRCS += tssresponsecode.c tsstransmit.c tssutils.c tssntc.c
>  TSS2LIB_SRCS += Commands.c CommandAttributeData.c Unmarshal.c
> -TSS2LIB_SRCS += tssdevskiboot.c 
> +TSS2LIB_SRCS += tssdevskiboot.c
>  
>  TSS2_SRCS = $(addprefix ibmtpm20tss/utils/,$(TSS2LIB_SRCS)) tpm2.c
> -TSS2_SRCS += tpm2.c
> +TSS2_SRCS += tpm2.c tssskiboot.c
>  
>  #tsscryptombed.c tsscryptouv.c tssdevuv.c tssuv.c
>  #tssskiboot.c eventlog.c eventlib.c tpm_nv.c opalcreate.c
> diff --git a/libstb/tss2/tssskiboot.c b/libstb/tss2/tssskiboot.c
> new file mode 100644
> index 000000000..f6171fb97
> --- /dev/null
> +++ b/libstb/tss2/tssskiboot.c
> @@ -0,0 +1,503 @@
> +/********************************************************************************/
> +/*										*/
> +/*			 Skiboot Support Interface  				*/

Need SPDX format header.

> +/*										*/
> +/* (c) Copyright IBM Corporation 2019						*/
> +/*										*/
> +/* All rights reserved.								*/
> +/* 										*/
> +/* Redistribution and use in source and binary forms, with or 
> without		*/
> +/* modification, are permitted provided that the following conditions 
> are	*/
> +/* met:										*/
> +/* 										*/
> +/* Redistributions of source code must retain the above copyright 
> notice,	*/
> +/* this list of conditions and the following disclaimer.			*/
> +/* 										*/
> +/* Redistributions in binary form must reproduce the above 
> copyright		*/
> +/* notice, this list of conditions and the following disclaimer in 
> the		*/
> +/* documentation and/or other materials provided with the 
> distribution.		*/
> +/* 										*/
> +/* Neither the names of the IBM Corporation nor the names of its		*/
> +/* contributors may be used to endorse or promote products derived 
> from		*/
> +/* this software without specific prior written permission.			*/
> +/* 										*/
> +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
> CONTRIBUTORS		*/
> +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
> NOT		*/
> +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
> FOR	*/
> +/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
> COPYRIGHT		*/
> +/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
> INCIDENTAL,	*/
> +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT		*/
> +/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
> USE,	*/
> +/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
> ANY	*/
> +/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
> TORT		*/
> +/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
> USE	*/
> +/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
> DAMAGE.		*/
> +/********************************************************************************/
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <stdint.h>
> +#include <tpm2.h>
> +#include <tssskiboot.h>
> +
> +#include <ibmtss/tss.h>
> +#include <ibmtss/tssfile.h>
> +#include <ibmtss/tssmarshal.h>
> +#include <ibmtss/tssresponsecode.h>
> +#include <ibmtss/Startup_fp.h>
> +#include <ibmtss/tssprint.h>
> +#include "tssproperties.h"
> +
> +static TSS_CONTEXT *context = NULL;

why statically allocate this here?

> +
> +TPM_RC get_context(void){
> +	TPM_RC rc = TPM_RC_SUCCESS;
> +
> +	if(!context){
> +		rc = TSS_Create(&context);
> +		if(rc)
> +			return rc;
> +		context->tpm_device = tpm2_get_device();
> +		context->tpm_driver = tpm2_get_driver();
> +		context->tssInterfaceType = "skiboot";
> +	}
> +	return rc;
> +}
> +
> +static void traceError(const char *command, TPM_RC rc)
> +{
> +	const char *msg;
> +	const char *submsg;
> +	const char *num;
> +	printf("%s: failed, rc %08x\n", command, rc);
> +	TSS_ResponseCode_toString(&msg, &submsg, &num, rc);
> +	printf("%s%s%s\n", msg, submsg, num);
> +}

This is very not-skiboot. NAK.
Use prlog() directly.

> +TPM_RC TSS_NV_Read_Public(TPMI_RH_NV_INDEX nvIndex)
> +{
> +	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
> +	unsigned int sessionAttributes0 = 0;
> +	unsigned int sessionAttributes1 = 0;
> +	unsigned int sessionAttributes2 = 0;
> +	NV_ReadPublic_Out *out;
> +	NV_ReadPublic_In *in;
> +	TPM_RC rc;
> +
> +	in = zalloc(sizeof(NV_ReadPublic_In));
> +	if (!in)
> +		return 1;
> +	out = zalloc(sizeof(NV_ReadPublic_Out));
> +	if (!out) {
> +		free(in);
> +		return 1;
> +	}
> +
> +	in->nvIndex = nvIndex;
> +
> +	rc = get_context();
> +	if (rc)
> +		goto cleanup;
> +
> +	rc = TSS_Execute(context,
> +			 (RESPONSE_PARAMETERS *) out,
> +			 (COMMAND_PARAMETERS *) in,
> +			 NULL,
> +			 TPM_CC_NV_ReadPublic,
> +			 sessionHandle0, NULL, sessionAttributes0,
> +			 sessionHandle1, NULL, sessionAttributes1,
> +			 sessionHandle2, NULL, sessionAttributes2,
> +			 TPM_RH_NULL, NULL, 0);

Does this end up doing *synchronous* i2c operations?

> +
> +cleanup:
> +	free(in);
> +	free(out);
> +
> +	return rc? 1: 0 ;
> +}
> +
> +
> +TPM_RC TSS_NV_Read(TPMI_RH_NV_INDEX nvIndex, void *buf, size_t 
> bufsize, uint64_t off)
> +{
> +	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
> +	unsigned int sessionAttributes0 = 0;
> +	unsigned int sessionAttributes1 = 0;
> +	unsigned int sessionAttributes2 = 0;
> +	NV_Read_Out *out;
> +	NV_Read_In *in;
> +	int rc;
> +
> +	in = zalloc(sizeof(NV_Read_In));
> +	if (!in)
> +		return -1;
> +	out = zalloc(sizeof(NV_Read_Out));
> +	if (!out) {
> +		free(in);
> +		return -1;
> +	}
> +
> +	in->nvIndex = nvIndex;
> +	in->offset = off;
> +	in->size = bufsize;
> +
> +	rc = get_context();
> +	if (rc)
> +		goto cleanup;
> +
> +	// TODO: Wrap this in multiple reads based on NV Buffer Max (1024)
> +	// TODO: Maybe use getcap to make sure.

Why not fix this TODO now?

Also, C style comments please.

> +	rc = TSS_Execute(context,
> +		(RESPONSE_PARAMETERS *) out,
> +		(COMMAND_PARAMETERS *) in,
> +		NULL,
> +		TPM_CC_NV_Read,
> +		sessionHandle0, NULL, sessionAttributes0,
> +		sessionHandle1, NULL, sessionAttributes1,
> +		sessionHandle2, NULL, sessionAttributes2,
> +		TPM_RH_NULL, NULL, 0);
> +
> +	if (!rc) {
> +		if (out->data.b.size < bufsize)
> +			bufsize = out->data.b.size;
> +		memcpy(buf, out->data.b.buffer, bufsize);
> +	}
> +
> +cleanup:
> +	free(in);
> +	free(out);
> +
> +	return rc;
> +}
> +
> +
> +TPM_RC TSS_NV_Write(TPMI_RH_NV_INDEX nvIndex, void *buf, size_t 
> bufsize, uint64_t off)
> +{
> +	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
> +	unsigned int sessionAttributes0 = 0;
> +	unsigned int sessionAttributes1 = 0;
> +	unsigned int sessionAttributes2 = 0;
> +	NV_Write_In *in;
> +	int rc;
> +
> +	in = zalloc(sizeof(NV_Read_In));
> +	if (!in)
> +		return -1;
> +
> +	in->nvIndex = nvIndex;
> +	in->offset = off;
> +
> +	rc = TSS_TPM2B_Create(&in->data.b, buf, bufsize, 
> sizeof(in->data.t.buffer));
> +	if (rc)
> +		goto cleanup;
> +
> +	rc = get_context();
> +	if (rc)
> +		goto cleanup;
> +
> +	// TODO: Wrap this in multiple writes based on NV Buffer Max (1024)

why not address this TODO now?

> +	rc = TSS_Execute(context,
> +			 NULL,
> +			 (COMMAND_PARAMETERS *) in,
> +			 NULL,
> +			 TPM_CC_NV_Read,
> +			 sessionHandle0, NULL, sessionAttributes0,
> +			 sessionHandle1, NULL, sessionAttributes1,
> +			 sessionHandle2, NULL, sessionAttributes2,
> +			 TPM_RH_NULL, NULL, 0);
> +
> +cleanup:
> +	free(in);
> +	return rc;
> +}
> +
> +
> +TPM_RC TSS_NV_WriteLock(TPMI_RH_NV_INDEX nvIndex)
> +{
> +	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
> +	unsigned int sessionAttributes0 = 0;
> +	unsigned int sessionAttributes1 = 0;
> +	unsigned int sessionAttributes2 = 0;
> +	NV_WriteLock_In *in;
> +	int rc;
> +
> +	in = zalloc(sizeof(NV_Read_In));
> +	if (!in)
> +		return -1;
> +	in->authHandle = 'p';
> +	in->nvIndex = nvIndex;
> +
> +	rc = get_context();
> +	if (rc)
> +		goto cleanup;
> +
> +	rc = TSS_Execute(context,
> +			 NULL,
> +			 (COMMAND_PARAMETERS *) in,
> +			 NULL,
> +			 TPM_CC_NV_Read,
> +			 sessionHandle0, NULL, sessionAttributes0,
> +			 sessionHandle1, NULL, sessionAttributes1,
> +			 sessionHandle2, NULL, sessionAttributes2,
> +			 TPM_RH_NULL, NULL, 0);
> +
> +cleanup:
> +	free(in);
> +	return rc;
> +}
> +
> +
> +int TSS_NV_Define_Space(TPMI_RH_NV_INDEX nvIndex, const char hierarchy,
> +			const char hierarchy_authorization,
> +			uint16_t dataSize)
> +{
> +	TPMA_NV nvAttributes, setAttributes, clearAttributes;
> +	//NOTE(maurosr): we don't care with session values so far
> +	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
> +	unsigned int sessionAttributes0 = 0;
> +	unsigned int sessionAttributes1 = 0;
> +	unsigned int sessionAttributes2 = 0;
> +
> +
> +	TPMI_ALG_HASH nalg = TPM_ALG_SHA256;
> +	char typeChar = 'o';
> +	const char *nvPassword = NULL, *parentPassword = NULL;
> +
> +	NV_DefineSpace_In *in = calloc(1, sizeof(NV_DefineSpace_In));
> +	TPM_RC rc;
> +
> +	nvAttributes.val = 0;
> +	setAttributes.val = TPMA_NVA_NO_DA;
> +	clearAttributes.val = 0;
> +
> +
> +	if(!in)
> +		return 1;
> +
> +	rc = get_context();
> +	if(rc)
> +		goto cleanup;
> +
> +
> +	switch(hierarchy_authorization){
> +		case 'o':
> +			nvAttributes.val |= TPMA_NVA_OWNERWRITE | TPMA_NVA_OWNERREAD;
> +			break;
> +		case 'p':
> +			nvAttributes.val |= TPMA_NVA_PPWRITE | TPMA_NVA_PPREAD;
> +			break;
> +		case '\0':
> +			nvAttributes.val |= TPMA_NVA_AUTHWRITE | TPMA_NVA_AUTHREAD;
> +			break;
> +		default:
> +			printf("Invalid value for hierarchy authorization");

use prlog() not printf()

> +			rc = 1;
> +			goto cleanup;
> +	}
> +	switch(hierarchy){
> +		case 'p':
> +			in->authHandle = TPM_RH_PLATFORM;
> +			nvAttributes.val |= TPMA_NVA_PLATFORMCREATE;
> +			break;
> +		case 'o':
> +			in->authHandle = TPM_RH_OWNER;
> +			break;
> +		default:
> +			printf("Invalid value for hierarchy");
> +			rc = 1;
> +			goto cleanup;
> +	}
> +
> +	if (typeChar == 'o')
> +		nvAttributes.val |= TPMA_NVA_ORDINARY;
> +	else{
> +		printf("TypeChar is set to somehing other than 'o', please add code 
> to support that\n");

prlog() not printf()

> +		rc = 1;
> +		goto cleanup;
> +	}
> +
> +	/*
> +	 * NOTE(maurosr): This should receive proper piece of code for 
> password
> +	 * handling when it becomes a parameter for this function.
> +	 * Ideally the code in here should just use TSS's parameters handling
> +	 * helpers, such helpers don't exist yet, but we should extract them 
> from
> +	 * the main function of the binary utils living in TSS code.
> +	 * */
> +	if (nvPassword == NULL)
> +		in->auth.b.size = 0;
> +	else{
> +		printf("Password is not NULL, you need to add code for supporting 
> this case. Aborting...\n");

prlog().

> +		rc = 1;
> +		goto cleanup;
> +	}
> +	// Empty policy, support for non-empty should be added

C style comments only.

> +	in->publicInfo.nvPublic.authPolicy.t.size = 0;
> +	in->publicInfo.nvPublic.nvIndex = nvIndex;
> +	// Default alg is SHA256, support for customizing this should be 
> added.

C style comments only.

> +	in->publicInfo.nvPublic.nameAlg = nalg;
> +	/*
> +	 * 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 = nvAttributes;
> +	in->publicInfo.nvPublic.attributes.val |= setAttributes.val;
> +	in->publicInfo.nvPublic.attributes.val &= ~(clearAttributes.val);
> +	in->publicInfo.nvPublic.dataSize = dataSize;
> +
> +	rc = TSS_Execute(context,
> +			 NULL,
> +			 (COMMAND_PARAMETERS *)in,
> +			 NULL,
> +			 TPM_CC_NV_DefineSpace,
> +			 sessionHandle0, parentPassword, sessionAttributes0,
> +			 sessionHandle1, NULL, sessionAttributes1,
> +			 sessionHandle2, NULL, sessionAttributes2,
> +			 TPM_RH_NULL, NULL, 0);
> +	if(rc)
> +		traceError("TSS_NV_Define_Space", rc);
> +
> +
> +cleanup:
> +	free(in);
> +	return rc? 1: 0 ;

why throw away the error?

> +}
> +
> +/**
> + * @brief Extends a PCR using the given hashes and digest
> + * @param pcrHandle	The PCR to be extended
> + * @param hashes	A pointer to an array of hash algorithms, each one
> + * 			used to extend its respective PCR bank.
> + * @param hashes_len	The length of hashes array.
> + * @param digest	The digest data.
> + */

What is this annotation and is it something that's used anywhere else in skiboot code?

> +int TSS_PCR_Extend(TPMI_DH_PCR pcrHandle, TPMI_ALG_HASH *hashes,
> +		   uint8_t hashes_len, const char *digest)
> +{
> +	PCR_Extend_In *in = calloc(1, sizeof(PCR_Extend_In));
> +	uint32_t rc = 1;
> +
> +	if(!in || (strlen(digest) > sizeof(TPMU_HA)) )
> +		return 1;
> +	if(hashes_len >= HASH_COUNT)
> +		goto exit;
> +	rc = get_context();
> +	if(rc)
> +		goto exit;
> +
> +	in->digests.count = hashes_len;
> +	in->pcrHandle = pcrHandle;
> +	for(int i=0; i < hashes_len; i++){
> +		in->digests.digests[i].hashAlg = hashes[i];
> +		// memset zeroes first to assure the digest data is zero padded.

C style comment only

> +		memset((uint8_t*) &in->digests.digests[i].digest, 0, 
> sizeof(TPMU_HA));
> +		memcpy((uint8_t*) &in->digests.digests[i].digest, digest, 
> strlen(digest));

strlen() makes me nervous

> +	}
> +	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 !=  0){
> +		traceError("TSS_PCR_Extend", rc);
> +	}
> +exit:
> +	free(in);
> +	return rc? 1: 0;
> +}
> +
> +/**
> + * @brief Reads the PCR content
> + * @param
> + */
> +int TSS_PCR_Read(TPMI_DH_PCR pcrHandle, TPMI_ALG_HASH *hashes,
> +		 uint8_t hashes_len)
> +{
> +	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RH_NULL;
> +	unsigned int sessionAttributes0 = 0;
> +	PCR_Read_Out *out;
> +	PCR_Read_In *in;
> +	uint32_t rc = 1;
> +
> +	if (hashes_len >= HASH_COUNT)
> +		return 1;
> +
> +	in = calloc(1, sizeof(PCR_Read_In));
> +	if (!in)
> +		return 1;
> +
> +	out = calloc(1, sizeof(PCR_Read_Out));
> +	if (!out)
> +		goto cleanup_in;
> +
> +	rc = get_context();
> +
> +	if (rc)
> +		goto cleanup_all;
> +
> +	in->pcrSelectionIn.count = hashes_len;
> +	for( int i=0; i < hashes_len; i++){
> +		in->pcrSelectionIn.pcrSelections[i].hash = 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[pcrHandle/8] = 1 << 
> (pcrHandle % 8);
> +	}
> +	rc = TSS_Execute(context,
> +			 (RESPONSE_PARAMETERS *) out,
> +			 (COMMAND_PARAMETERS *) in,
> +			 NULL,
> +			 TPM_CC_PCR_Read,
> +                         sessionHandle0, NULL, sessionAttributes0,
> +			 TPM_RH_NULL, NULL, 0);
> +	if (rc !=  0)
> +		traceError("newTSS_PCR_Read", rc);
> +
> +cleanup_all:
> +	free(out);
> +cleanup_in:
> +	free(in);
> +	return rc? 1: 0;
> +}
> +
> +int TSS_Get_Random_Number(char *buffer, size_t len){
> +	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
> +	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
> +	unsigned int sessionAttributes0 = 0;
> +	unsigned int sessionAttributes1 = 0;
> +	unsigned int sessionAttributes2 = 0;
> +	TSS_CONTEXT *tssContext = NULL;
> +	GetRandom_Out out;
> +	GetRandom_In in;
> +	TPM_RC rc = 0;
> +
> +	in.bytesRequested = len;
> +        rc = TSS_Execute(tssContext,
> +                         (RESPONSE_PARAMETERS *)&out,
> +                         (COMMAND_PARAMETERS *)&in,
> +                         NULL, TPM_CC_GetRandom,
> +			 sessionHandle0, NULL, sessionAttributes0,
> +                         sessionHandle1, NULL, sessionAttributes1,
> +                         sessionHandle2, NULL, sessionAttributes2,
> +                         TPM_RH_NULL, NULL, 0);
> +	if (rc != 0)
> +		return -1;
> +	memcpy(buffer, out.randomBytes.t.buffer, len);
> +	return rc;
> +}
> diff --git a/libstb/tss2/tssskiboot.h b/libstb/tss2/tssskiboot.h
> new file mode 100644
> index 000000000..524292f80
> --- /dev/null
> +++ b/libstb/tss2/tssskiboot.h
> @@ -0,0 +1,62 @@
> +/********************************************************************************/

SPDX tag and comment

> +/*										*/
> +/*		SKIBOOT Interface			  			*/
> +/*										*/
> +/* (c) Copyright IBM Corporation 2019.						*/
> +/*										*/
> +/* All rights reserved.								*/
> +/* 										*/
> +/* Redistribution and use in source and binary forms, with or 
> without		*/
> +/* modification, are permitted provided that the following conditions 
> are	*/
> +/* met:										*/
> +/* 										*/
> +/* Redistributions of source code must retain the above copyright 
> notice,	*/
> +/* this list of conditions and the following disclaimer.			*/
> +/* 										*/
> +/* Redistributions in binary form must reproduce the above 
> copyright		*/
> +/* notice, this list of conditions and the following disclaimer in 
> the		*/
> +/* documentation and/or other materials provided with the 
> distribution.		*/
> +/* 										*/
> +/* Neither the names of the IBM Corporation nor the names of its		*/
> +/* contributors may be used to endorse or promote products derived 
> from		*/
> +/* this software without specific prior written permission.			*/
> +/* 										*/
> +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
> CONTRIBUTORS		*/
> +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
> NOT		*/
> +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
> FOR	*/
> +/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
> COPYRIGHT		*/
> +/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
> INCIDENTAL,	*/
> +/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT		*/
> +/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
> USE,	*/
> +/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
> ANY	*/
> +/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
> TORT		*/
> +/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
> USE	*/
> +/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
> DAMAGE.		*/
> +/********************************************************************************/
> +#ifdef __SKIBOOT__
> +
> +#ifndef TSSSKIBOOT_H
> +#define TSSSKIBOOT_H
> +
> +#include <ibmtss/tss.h>
> +#include <ibmtss/tssresponsecode.h>
> +#include <ibmtss/tssmarshal.h>
> +#include "tssproperties.h"
> +
> +TPM_RC get_context(void);
> +TPM_RC TSS_NV_Read_Public(TPMI_RH_NV_INDEX nvIndex);
> +TPM_RC TSS_NV_Read(TPMI_RH_NV_INDEX nvIndex, void *buf, size_t bufsize,
> +		   uint64_t off);
> +TPM_RC TSS_NV_Write(TPMI_RH_NV_INDEX nvIndex, void *buf, size_t 
> bufsize,
> +		    uint64_t off);
> +TPM_RC TSS_NV_WriteLock(TPMI_RH_NV_INDEX nvIndex);
> +int TSS_NV_Define_Space(TPMI_RH_NV_INDEX nvIndex, const char hierarchy,
> +			const char hierarchy_authorization,
> +			uint16_t dataSize);
> +int TSS_PCR_Extend(TPMI_DH_PCR pcrHandle, TPMI_ALG_HASH *v_hashes,
> +                   uint8_t hashes_len, const char *digest);
> +int TSS_PCR_Read(TPMI_DH_PCR pcrHandle, TPMI_ALG_HASH *hashes,
> +		 uint8_t hashes_len);
> +int TSS_Get_Random_Number(char *buffer, size_t len);
> +#endif /* TSSSKIBOOT_H */
> +#endif /* __SKIBOOT__ */
> -- 
> 2.24.1
> 
> _______________________________________________
> Skiboot mailing list
> Skiboot@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot
>

Patch
diff mbox series

diff --git a/libstb/tss2/Makefile.inc b/libstb/tss2/Makefile.inc
index 5fa4e6752..d85433d9c 100644
--- a/libstb/tss2/Makefile.inc
+++ b/libstb/tss2/Makefile.inc
@@ -13,10 +13,10 @@  TSS2LIB_SRCS = tss.c tss20.c tssauth.c tssauth20.c tssccattributes.c
 TSS2LIB_SRCS += tssmarshal.c tssprint.c tssprintcmd.c tssproperties.c
 TSS2LIB_SRCS += tssresponsecode.c tsstransmit.c tssutils.c tssntc.c
 TSS2LIB_SRCS += Commands.c CommandAttributeData.c Unmarshal.c
-TSS2LIB_SRCS += tssdevskiboot.c 
+TSS2LIB_SRCS += tssdevskiboot.c
 
 TSS2_SRCS = $(addprefix ibmtpm20tss/utils/,$(TSS2LIB_SRCS)) tpm2.c
-TSS2_SRCS += tpm2.c
+TSS2_SRCS += tpm2.c tssskiboot.c
 
 #tsscryptombed.c tsscryptouv.c tssdevuv.c tssuv.c
 #tssskiboot.c eventlog.c eventlib.c tpm_nv.c opalcreate.c
diff --git a/libstb/tss2/tssskiboot.c b/libstb/tss2/tssskiboot.c
new file mode 100644
index 000000000..f6171fb97
--- /dev/null
+++ b/libstb/tss2/tssskiboot.c
@@ -0,0 +1,503 @@ 
+/********************************************************************************/
+/*										*/
+/*			 Skiboot Support Interface  				*/
+/*										*/
+/* (c) Copyright IBM Corporation 2019						*/
+/*										*/
+/* All rights reserved.								*/
+/* 										*/
+/* Redistribution and use in source and binary forms, with or without		*/
+/* modification, are permitted provided that the following conditions are	*/
+/* met:										*/
+/* 										*/
+/* Redistributions of source code must retain the above copyright notice,	*/
+/* this list of conditions and the following disclaimer.			*/
+/* 										*/
+/* Redistributions in binary form must reproduce the above copyright		*/
+/* notice, this list of conditions and the following disclaimer in the		*/
+/* documentation and/or other materials provided with the distribution.		*/
+/* 										*/
+/* Neither the names of the IBM Corporation nor the names of its		*/
+/* contributors may be used to endorse or promote products derived from		*/
+/* this software without specific prior written permission.			*/
+/* 										*/
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS		*/
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT		*/
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR	*/
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT		*/
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,	*/
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT		*/
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,	*/
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY	*/
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT		*/
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE	*/
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.		*/
+/********************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <tpm2.h>
+#include <tssskiboot.h>
+
+#include <ibmtss/tss.h>
+#include <ibmtss/tssfile.h>
+#include <ibmtss/tssmarshal.h>
+#include <ibmtss/tssresponsecode.h>
+#include <ibmtss/Startup_fp.h>
+#include <ibmtss/tssprint.h>
+#include "tssproperties.h"
+
+static TSS_CONTEXT *context = NULL;
+
+TPM_RC get_context(void){
+	TPM_RC rc = TPM_RC_SUCCESS;
+
+	if(!context){
+		rc = TSS_Create(&context);
+		if(rc)
+			return rc;
+		context->tpm_device = tpm2_get_device();
+		context->tpm_driver = tpm2_get_driver();
+		context->tssInterfaceType = "skiboot";
+	}
+	return rc;
+}
+
+static void traceError(const char *command, TPM_RC rc)
+{
+	const char *msg;
+	const char *submsg;
+	const char *num;
+	printf("%s: failed, rc %08x\n", command, rc);
+	TSS_ResponseCode_toString(&msg, &submsg, &num, rc);
+	printf("%s%s%s\n", msg, submsg, num);
+}
+
+TPM_RC TSS_NV_Read_Public(TPMI_RH_NV_INDEX nvIndex)
+{
+	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
+	unsigned int sessionAttributes0 = 0;
+	unsigned int sessionAttributes1 = 0;
+	unsigned int sessionAttributes2 = 0;
+	NV_ReadPublic_Out *out;
+	NV_ReadPublic_In *in;
+	TPM_RC rc;
+
+	in = zalloc(sizeof(NV_ReadPublic_In));
+	if (!in)
+		return 1;
+	out = zalloc(sizeof(NV_ReadPublic_Out));
+	if (!out) {
+		free(in);
+		return 1;
+	}
+
+	in->nvIndex = nvIndex;
+
+	rc = get_context();
+	if (rc)
+		goto cleanup;
+
+	rc = TSS_Execute(context,
+			 (RESPONSE_PARAMETERS *) out,
+			 (COMMAND_PARAMETERS *) in,
+			 NULL,
+			 TPM_CC_NV_ReadPublic,
+			 sessionHandle0, NULL, sessionAttributes0,
+			 sessionHandle1, NULL, sessionAttributes1,
+			 sessionHandle2, NULL, sessionAttributes2,
+			 TPM_RH_NULL, NULL, 0);
+
+cleanup:
+	free(in);
+	free(out);
+
+	return rc? 1: 0 ;
+}
+
+
+TPM_RC TSS_NV_Read(TPMI_RH_NV_INDEX nvIndex, void *buf, size_t bufsize, uint64_t off)
+{
+	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
+	unsigned int sessionAttributes0 = 0;
+	unsigned int sessionAttributes1 = 0;
+	unsigned int sessionAttributes2 = 0;
+	NV_Read_Out *out;
+	NV_Read_In *in;
+	int rc;
+
+	in = zalloc(sizeof(NV_Read_In));
+	if (!in)
+		return -1;
+	out = zalloc(sizeof(NV_Read_Out));
+	if (!out) {
+		free(in);
+		return -1;
+	}
+
+	in->nvIndex = nvIndex;
+	in->offset = off;
+	in->size = bufsize;
+
+	rc = get_context();
+	if (rc)
+		goto cleanup;
+
+	// TODO: Wrap this in multiple reads based on NV Buffer Max (1024)
+	// TODO: Maybe use getcap to make sure.
+	rc = TSS_Execute(context,
+		(RESPONSE_PARAMETERS *) out,
+		(COMMAND_PARAMETERS *) in,
+		NULL,
+		TPM_CC_NV_Read,
+		sessionHandle0, NULL, sessionAttributes0,
+		sessionHandle1, NULL, sessionAttributes1,
+		sessionHandle2, NULL, sessionAttributes2,
+		TPM_RH_NULL, NULL, 0);
+
+	if (!rc) {
+		if (out->data.b.size < bufsize)
+			bufsize = out->data.b.size;
+		memcpy(buf, out->data.b.buffer, bufsize);
+	}
+
+cleanup:
+	free(in);
+	free(out);
+
+	return rc;
+}
+
+
+TPM_RC TSS_NV_Write(TPMI_RH_NV_INDEX nvIndex, void *buf, size_t bufsize, uint64_t off)
+{
+	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
+	unsigned int sessionAttributes0 = 0;
+	unsigned int sessionAttributes1 = 0;
+	unsigned int sessionAttributes2 = 0;
+	NV_Write_In *in;
+	int rc;
+
+	in = zalloc(sizeof(NV_Read_In));
+	if (!in)
+		return -1;
+
+	in->nvIndex = nvIndex;
+	in->offset = off;
+
+	rc = TSS_TPM2B_Create(&in->data.b, buf, bufsize, sizeof(in->data.t.buffer));
+	if (rc)
+		goto cleanup;
+
+	rc = get_context();
+	if (rc)
+		goto cleanup;
+
+	// TODO: Wrap this in multiple writes based on NV Buffer Max (1024)
+	rc = TSS_Execute(context,
+			 NULL,
+			 (COMMAND_PARAMETERS *) in,
+			 NULL,
+			 TPM_CC_NV_Read,
+			 sessionHandle0, NULL, sessionAttributes0,
+			 sessionHandle1, NULL, sessionAttributes1,
+			 sessionHandle2, NULL, sessionAttributes2,
+			 TPM_RH_NULL, NULL, 0);
+
+cleanup:
+	free(in);
+	return rc;
+}
+
+
+TPM_RC TSS_NV_WriteLock(TPMI_RH_NV_INDEX nvIndex)
+{
+	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
+	unsigned int sessionAttributes0 = 0;
+	unsigned int sessionAttributes1 = 0;
+	unsigned int sessionAttributes2 = 0;
+	NV_WriteLock_In *in;
+	int rc;
+
+	in = zalloc(sizeof(NV_Read_In));
+	if (!in)
+		return -1;
+	in->authHandle = 'p';
+	in->nvIndex = nvIndex;
+
+	rc = get_context();
+	if (rc)
+		goto cleanup;
+
+	rc = TSS_Execute(context,
+			 NULL,
+			 (COMMAND_PARAMETERS *) in,
+			 NULL,
+			 TPM_CC_NV_Read,
+			 sessionHandle0, NULL, sessionAttributes0,
+			 sessionHandle1, NULL, sessionAttributes1,
+			 sessionHandle2, NULL, sessionAttributes2,
+			 TPM_RH_NULL, NULL, 0);
+
+cleanup:
+	free(in);
+	return rc;
+}
+
+
+int TSS_NV_Define_Space(TPMI_RH_NV_INDEX nvIndex, const char hierarchy,
+			const char hierarchy_authorization,
+			uint16_t dataSize)
+{
+	TPMA_NV nvAttributes, setAttributes, clearAttributes;
+	//NOTE(maurosr): we don't care with session values so far
+	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
+	unsigned int sessionAttributes0 = 0;
+	unsigned int sessionAttributes1 = 0;
+	unsigned int sessionAttributes2 = 0;
+
+
+	TPMI_ALG_HASH nalg = TPM_ALG_SHA256;
+	char typeChar = 'o';
+	const char *nvPassword = NULL, *parentPassword = NULL;
+
+	NV_DefineSpace_In *in = calloc(1, sizeof(NV_DefineSpace_In));
+	TPM_RC rc;
+
+	nvAttributes.val = 0;
+	setAttributes.val = TPMA_NVA_NO_DA;
+	clearAttributes.val = 0;
+
+
+	if(!in)
+		return 1;
+
+	rc = get_context();
+	if(rc)
+		goto cleanup;
+
+
+	switch(hierarchy_authorization){
+		case 'o':
+			nvAttributes.val |= TPMA_NVA_OWNERWRITE | TPMA_NVA_OWNERREAD;
+			break;
+		case 'p':
+			nvAttributes.val |= TPMA_NVA_PPWRITE | TPMA_NVA_PPREAD;
+			break;
+		case '\0':
+			nvAttributes.val |= TPMA_NVA_AUTHWRITE | TPMA_NVA_AUTHREAD;
+			break;
+		default:
+			printf("Invalid value for hierarchy authorization");
+			rc = 1;
+			goto cleanup;
+	}
+	switch(hierarchy){
+		case 'p':
+			in->authHandle = TPM_RH_PLATFORM;
+			nvAttributes.val |= TPMA_NVA_PLATFORMCREATE;
+			break;
+		case 'o':
+			in->authHandle = TPM_RH_OWNER;
+			break;
+		default:
+			printf("Invalid value for hierarchy");
+			rc = 1;
+			goto cleanup;
+	}
+
+	if (typeChar == 'o')
+		nvAttributes.val |= TPMA_NVA_ORDINARY;
+	else{
+		printf("TypeChar is set to somehing other than 'o', please add code to support that\n");
+		rc = 1;
+		goto cleanup;
+	}
+
+	/*
+	 * NOTE(maurosr): This should receive proper piece of code for password
+	 * handling when it becomes a parameter for this function.
+	 * Ideally the code in here should just use TSS's parameters handling
+	 * helpers, such helpers don't exist yet, but we should extract them from
+	 * the main function of the binary utils living in TSS code.
+	 * */
+	if (nvPassword == NULL)
+		in->auth.b.size = 0;
+	else{
+		printf("Password is not NULL, you need to add code for supporting this case. Aborting...\n");
+		rc = 1;
+		goto cleanup;
+	}
+	// Empty policy, support for non-empty should be added
+	in->publicInfo.nvPublic.authPolicy.t.size = 0;
+	in->publicInfo.nvPublic.nvIndex = nvIndex;
+	// Default alg is SHA256, support for customizing this should be added.
+	in->publicInfo.nvPublic.nameAlg = nalg;
+	/*
+	 * 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 = nvAttributes;
+	in->publicInfo.nvPublic.attributes.val |= setAttributes.val;
+	in->publicInfo.nvPublic.attributes.val &= ~(clearAttributes.val);
+	in->publicInfo.nvPublic.dataSize = dataSize;
+
+	rc = TSS_Execute(context,
+			 NULL,
+			 (COMMAND_PARAMETERS *)in,
+			 NULL,
+			 TPM_CC_NV_DefineSpace,
+			 sessionHandle0, parentPassword, sessionAttributes0,
+			 sessionHandle1, NULL, sessionAttributes1,
+			 sessionHandle2, NULL, sessionAttributes2,
+			 TPM_RH_NULL, NULL, 0);
+	if(rc)
+		traceError("TSS_NV_Define_Space", rc);
+
+
+cleanup:
+	free(in);
+	return rc? 1: 0 ;
+}
+
+/**
+ * @brief Extends a PCR using the given hashes and digest
+ * @param pcrHandle	The PCR to be extended
+ * @param hashes	A pointer to an array of hash algorithms, each one
+ * 			used to extend its respective PCR bank.
+ * @param hashes_len	The length of hashes array.
+ * @param digest	The digest data.
+ */
+int TSS_PCR_Extend(TPMI_DH_PCR pcrHandle, TPMI_ALG_HASH *hashes,
+		   uint8_t hashes_len, const char *digest)
+{
+	PCR_Extend_In *in = calloc(1, sizeof(PCR_Extend_In));
+	uint32_t rc = 1;
+
+	if(!in || (strlen(digest) > sizeof(TPMU_HA)) )
+		return 1;
+	if(hashes_len >= HASH_COUNT)
+		goto exit;
+	rc = get_context();
+	if(rc)
+		goto exit;
+
+	in->digests.count = hashes_len;
+	in->pcrHandle = pcrHandle;
+	for(int i=0; i < hashes_len; i++){
+		in->digests.digests[i].hashAlg = 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));
+		memcpy((uint8_t*) &in->digests.digests[i].digest, digest, strlen(digest));
+	}
+	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 !=  0){
+		traceError("TSS_PCR_Extend", rc);
+	}
+exit:
+	free(in);
+	return rc? 1: 0;
+}
+
+/**
+ * @brief Reads the PCR content
+ * @param
+ */
+int TSS_PCR_Read(TPMI_DH_PCR pcrHandle, TPMI_ALG_HASH *hashes,
+		 uint8_t hashes_len)
+{
+	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RH_NULL;
+	unsigned int sessionAttributes0 = 0;
+	PCR_Read_Out *out;
+	PCR_Read_In *in;
+	uint32_t rc = 1;
+
+	if (hashes_len >= HASH_COUNT)
+		return 1;
+
+	in = calloc(1, sizeof(PCR_Read_In));
+	if (!in)
+		return 1;
+
+	out = calloc(1, sizeof(PCR_Read_Out));
+	if (!out)
+		goto cleanup_in;
+
+	rc = get_context();
+
+	if (rc)
+		goto cleanup_all;
+
+	in->pcrSelectionIn.count = hashes_len;
+	for( int i=0; i < hashes_len; i++){
+		in->pcrSelectionIn.pcrSelections[i].hash = 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[pcrHandle/8] = 1 << (pcrHandle % 8);
+	}
+	rc = TSS_Execute(context,
+			 (RESPONSE_PARAMETERS *) out,
+			 (COMMAND_PARAMETERS *) in,
+			 NULL,
+			 TPM_CC_PCR_Read,
+                         sessionHandle0, NULL, sessionAttributes0,
+			 TPM_RH_NULL, NULL, 0);
+	if (rc !=  0)
+		traceError("newTSS_PCR_Read", rc);
+
+cleanup_all:
+	free(out);
+cleanup_in:
+	free(in);
+	return rc? 1: 0;
+}
+
+int TSS_Get_Random_Number(char *buffer, size_t len){
+	TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
+	TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
+	unsigned int sessionAttributes0 = 0;
+	unsigned int sessionAttributes1 = 0;
+	unsigned int sessionAttributes2 = 0;
+	TSS_CONTEXT *tssContext = NULL;
+	GetRandom_Out out;
+	GetRandom_In in;
+	TPM_RC rc = 0;
+
+	in.bytesRequested = len;
+        rc = TSS_Execute(tssContext,
+                         (RESPONSE_PARAMETERS *)&out,
+                         (COMMAND_PARAMETERS *)&in,
+                         NULL, TPM_CC_GetRandom,
+			 sessionHandle0, NULL, sessionAttributes0,
+                         sessionHandle1, NULL, sessionAttributes1,
+                         sessionHandle2, NULL, sessionAttributes2,
+                         TPM_RH_NULL, NULL, 0);
+	if (rc != 0)
+		return -1;
+	memcpy(buffer, out.randomBytes.t.buffer, len);
+	return rc;
+}
diff --git a/libstb/tss2/tssskiboot.h b/libstb/tss2/tssskiboot.h
new file mode 100644
index 000000000..524292f80
--- /dev/null
+++ b/libstb/tss2/tssskiboot.h
@@ -0,0 +1,62 @@ 
+/********************************************************************************/
+/*										*/
+/*		SKIBOOT Interface			  			*/
+/*										*/
+/* (c) Copyright IBM Corporation 2019.						*/
+/*										*/
+/* All rights reserved.								*/
+/* 										*/
+/* Redistribution and use in source and binary forms, with or without		*/
+/* modification, are permitted provided that the following conditions are	*/
+/* met:										*/
+/* 										*/
+/* Redistributions of source code must retain the above copyright notice,	*/
+/* this list of conditions and the following disclaimer.			*/
+/* 										*/
+/* Redistributions in binary form must reproduce the above copyright		*/
+/* notice, this list of conditions and the following disclaimer in the		*/
+/* documentation and/or other materials provided with the distribution.		*/
+/* 										*/
+/* Neither the names of the IBM Corporation nor the names of its		*/
+/* contributors may be used to endorse or promote products derived from		*/
+/* this software without specific prior written permission.			*/
+/* 										*/
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS		*/
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT		*/
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR	*/
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT		*/
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,	*/
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT		*/
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,	*/
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY	*/
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT		*/
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE	*/
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.		*/
+/********************************************************************************/
+#ifdef __SKIBOOT__
+
+#ifndef TSSSKIBOOT_H
+#define TSSSKIBOOT_H
+
+#include <ibmtss/tss.h>
+#include <ibmtss/tssresponsecode.h>
+#include <ibmtss/tssmarshal.h>
+#include "tssproperties.h"
+
+TPM_RC get_context(void);
+TPM_RC TSS_NV_Read_Public(TPMI_RH_NV_INDEX nvIndex);
+TPM_RC TSS_NV_Read(TPMI_RH_NV_INDEX nvIndex, void *buf, size_t bufsize,
+		   uint64_t off);
+TPM_RC TSS_NV_Write(TPMI_RH_NV_INDEX nvIndex, void *buf, size_t bufsize,
+		    uint64_t off);
+TPM_RC TSS_NV_WriteLock(TPMI_RH_NV_INDEX nvIndex);
+int TSS_NV_Define_Space(TPMI_RH_NV_INDEX nvIndex, const char hierarchy,
+			const char hierarchy_authorization,
+			uint16_t dataSize);
+int TSS_PCR_Extend(TPMI_DH_PCR pcrHandle, TPMI_ALG_HASH *v_hashes,
+                   uint8_t hashes_len, const char *digest);
+int TSS_PCR_Read(TPMI_DH_PCR pcrHandle, TPMI_ALG_HASH *hashes,
+		 uint8_t hashes_len);
+int TSS_Get_Random_Number(char *buffer, size_t len);
+#endif /* TSSSKIBOOT_H */
+#endif /* __SKIBOOT__ */