All of lore.kernel.org
 help / color / mirror / Atom feed
* [tpm2] Re: NVRAM Write and Read using Esys API(s)
@ 2020-05-13 19:21 Roberts, William C
  0 siblings, 0 replies; 5+ messages in thread
From: Roberts, William C @ 2020-05-13 19:21 UTC (permalink / raw)
  To: tpm2

[-- Attachment #1: Type: text/plain, Size: 12830 bytes --]

> -----Original Message-----
> From: muthu.smk(a)gmail.com [mailto:muthu.smk(a)gmail.com]
> Sent: Wednesday, May 13, 2020 12:51 PM
> To: tpm2(a)lists.01.org
> Subject: [tpm2] NVRAM Write and Read using Esys API(s)
> 
> Hi Williams,
> 
> I am using the test code used to read and write in to NV ram.  I am facing below
> challenges if i tried to read already written data from NVRAM.
> 
> 1) Test code attached defined create the context (ectx) , create random number ,
> define NV ram , write the random number in to NVRAM (offset 0x1000001) and
> read it back from NV Ram (from same offset 0x1000001)
> 
> 2) But if i try to run this code twice or thrise , am getting below NVRAM already
> defined rc code. I can understand that we should not defined the nv ram space
> which already defined and used.
> How to avoid this ? by defining nvram ONLY once and write it ONLY once and
> finally read it AS MUCH times we want ?  Below details are related to this request

You can call Esys_GetCapability() and see what NV indices are defined. The command
Line tool tpm2_getcap does this, like so:
tpm2_getcap handles-nv-index

You can use that tool as an example of how to do it.

> 
> Error code:
> 0x0000014c - description: NV Index or persistend object already defined
> 0x00000284 - description: value is out of range or is not correct for the context
> 
> 3) Query is : is it possible to define nvram "ONLY ONCE" with the API shared the
> test code and then create a function "createrandom" number to use the same

Call getcap, see if it's defined, if defined, don't define it....

> context (ects) to generate randumnumber then call separate "write_nvram"
> function with random number as input and ask to write in the same offset .
> Finally calling another function "read_nvram" to read it back from the same
> nvram's offset when ever we want ? i tried this approach but am getting segfault
> with above error .
> What am i missing here ?

Segfaults are likely your code is just broken.

> 
> 3.1) Ideally in single application , i need to achieve "tpm2_nvdefine",
> "tpm2_nvwrite" and "tpm2_nvread() tools API(s) functionality" in different calls
> or flow.
> 3.2) Also how to check whether "write" already done (i tried checking nv_index is
> true - means whether it already has some value) , but it failed ?

If you do what the tool tpm2_nvreadpublic does, you can check for the written bit.
 
> 
> 4) Also how to check what was the content that already present in the nvram
> offset (0x1000001) before i do write the "random number" second time in to the
> same offset ? this is to ensure the "random number" that i am planning to write
> was valid one ?

Read it out, if it's not what you want, write it.

> 
> I remember studying that, once u write in to NVRAM offset , we cant able to RE-
> WRITE it in the same offset(0x1000001). Whether that is the same case for
> SIMULATOR as well (or) this feature is only for real tpm hardware?

No generally you can write as many times as you want... there are tricks you can do to make
It locked after write (writelocked iirc)

Below is a command line example of doing it...

tpm2_nvdefine 
nv-index: 0x1000000

tpm2_nvreadpublic 0x1000000
0x1000000:
  name: 000b1195f36a21c8219055ad0803c39e7e81d06cdb2eee2b7cf93dd83e01d4273828
  hash algorithm:
    friendly: sha256
    value: 0xB
  attributes:
    friendly: ownerwrite|authwrite|ownerread|authread
    value: 0x6000600
  size: 2048

# you can do this as much as you want, but it can wear the memory in the TPM
# depending on memory technology the vendor used.
echo "hello" | tpm2_nvwrite -C o 0x1000000 -i-
echo `tpm2_nvread -C o -s5 0x1000000`
hello

tpm2_nvreadpublic 0x1000000
0x1000000:
  name: 000b287c9b1b06fab6e51bd26e98ea89460574e97a3d2ef995eb35f7e23db7e94f67
  hash algorithm:
    friendly: sha256
    value: 0xB
  attributes:
    friendly: ownerwrite|authwrite|ownerread|authread|written
    value: 0x6000620
  size: 2048

> 
> 6)After nvwrite i tried to use "tpm2_pcrlist" command line tool application, by
> which it shows the nv ram memory location , tried using tpm2_nvread () to read
> the content but i could not able to see any data (random number) that i used to
> write via this test application . dont know why ?

tpm2_pcrlist is not for NVs.... you want:
tpm2_getcap handles-nv-index

> 
> 7) After i manually ran the below clear API , now the test code is working fine
> (refer Test code log shown below..). This confirms we can reallocate already
> defined nv ram memory.
> #tpm2_nvrelease -x 0x1000001 -a 0x40000001

Tpm2_clear will clear the owner hierarchy, including NV ram objects declared in that hierarchy,
so define will work again, because you deleted it.

> 
> 
> 8)If i try to read it manually via below tpm2_nvread command with offset
> 0x1000001 am getting below error
> 
> #tpm2_nvread -x 0x1000001 -a 0x40000001 -o 0 -s 20
> ERROR: Failed to read NVRAM public area at index 0x1000001 (16777217).
> Error:0x18b
> ERROR: Unable to run tpm2_nvread
> 
> /* Tried to use below tools command , am always getting the same error even if
> we give the different nvram off set tpm2_nvwrite -x 0x1c00002 helloworld
> ERROR: Reading the public part of the nv index failed with: 0x18b
> ERROR: Unable to run tpm2_nvwrite
> 
> tpm2_nvwrite -x 0x1c00012 -a 0x40000001 helloworld
> ERROR: Reading the public part of the nv index failed with: 0x18b
> ERROR: Unable to run tpm2_nvwrite
> 
> 
> /* Try to read the nvlist of SIM , it returns nothing !!!
> #tpm2_nvlist <returns nothing>
> 
> Any points will be great help for me.
> 
> ---------------------------------------------------------------------------------------------------
> --------------------------------------------------------------
> Test code log after above "tpm2_nvrelease":
> Initializing
> init_rand()
> init_rsa()
> init_ecc()
> Engine name: TPM2-TSS engine for OpenSSL
> Init result: 1
> Setting owner auth to empty auth.
> Setting parent auth to empty auth.
> ERROR:tcti:src/tss2-tcti/tcti-device.c:440:Tss2_Tcti_Device_Init() Failed to open
> device file /dev/tpm0: No such file or directory
> WARNING:tcti:src/tss2-tcti/tctildr.c:62:tcti_from_init() TCTI init for function
> 0x7fc67376d18b failed with a000a
> WARNING:tcti:src/tss2-tcti/tctildr.c:92:tcti_from_info() Could not initialize TCTI
> named: tcti-device
> ERROR:tcti:src/tss2-tcti/tctildr-dl.c:150:tcti_from_file() Could not initialize TCTI
> file: libtss2-tcti-default.so
>  No of bytes written by GenRandom : 64
> b6c9e1d028f2c893c56a089165f9f38c09232180ba5bb66b35c5652cb51ab61b237ecfe
> 8ece5d7f14a3323fee1dca0e641a0f20c7689100e3c804b82d6a2497f
> Created NV Index: 0x1000001
> ESYS_TR: 0x418367
> ESYS_TR2: 0x418368
> Writing the random number written in NV Ram
> Data buffer size used to write into NVRam: 64
> Reading the random number written in NV Ram
> b6c9e1d028f2c893c56a089165f9f38c09232180ba5bb66b35c5652cb51ab61b237ecfe
> 8ece5d7f14a3323fee1dca0e641a0f20c7689100e3c804b82d6a2497f
> *** SUCCESS ***
> ---------------------
> 
> TEST CODE :
> 
> int nv_write_read()
> {
> 
> 	ESYS_CONTEXT *ectx = NULL;
> 
> 	ESYS_TR nv_index = 0;
> 	ESYS_TR nv_index2 = 0;
> 
> 	 int rc = 1;
> 
> 
> 	/*
> 	 * create a connection to the TPM letting ESAPI choose how to get there.
> 	 * If you need more control, you can use tcti and tcti-ldr libraries to
> 	 * get a TCTI pointer to use for the tcti argument of Esys_Initialize.
> 	 */
> 	rc = Esys_Initialize(&ectx,
> 			NULL,  // let it find the TCTI
> 			NULL); // Use whatever ABI
> 	if (rc != TSS2_RC_SUCCESS) {
> 		printf("Esys_Initialize Failed: 0x%x\n", rc);
> 		return 1;
> 	}
> 
> 
>         rc = Esys_GetRandom(ectx,
>                         ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
>                         64, &bytes);
>         if (rc != TSS2_RC_SUCCESS) {
>                 printf("Esys_GetRandom Failed: %s\n", Tss2_RC_Decode(rc));
>                 exit(1);
>         }
> 
>     	printf(" No of bytes written by GenRandom : %d\n",bytes->size);
>     	size_t i;
>     	for (i = 0; i < bytes->size; i++) {
>         	printf("%02x", bytes->buffer[i]);
>     	}
> 
>     	printf("\n");
> 
> 	/* build a template for the NV index */
> 	TPM2B_NV_PUBLIC pub_templ = {
> 		/* this is counter intuitive, but it tells the TSS2 library to calculate
> this for us */
> 		.size = 0,
> 		/* The things that define what NV index we are creating */
> 		.nvPublic = {
> 			/* uses sha256 to identify the tpm object by name */
> 			.nameAlg = TPM2_ALG_SHA256,
> 			/* allows the owner password or index password r/w
> access */
> 			.attributes = TPMA_NV_OWNERWRITE |
> 				TPMA_NV_OWNERREAD            |
> 				TPMA_NV_AUTHWRITE            |
> 				TPMA_NV_AUTHREAD,
> 			/* can hold 64 bytes of data */
> 			.dataSize = 64,
> 			/* Create at NV Index 1 or 0x1000001 */
> 			.nvIndex = TPM2_HR_NV_INDEX + 1
> 		},
> 	};
> 
> 
> 	/* Ok, define the space and store the nv_index for future use */
> 	rc = Esys_NV_DefineSpace(
> 	    ectx,
> 		ESYS_TR_RH_OWNER, /* create an NV index in the owner
> hierarchy */
> 	    ESYS_TR_PASSWORD, /* auth as the owner with a password, which is
> empty */
> 	    ESYS_TR_NONE,
> 	    ESYS_TR_NONE,
> 	    NULL,
> 	    &pub_templ,
> 	    &nv_index);
> 	if (rc != TSS2_RC_SUCCESS) {
> 		printf("Esys_NV_DefineSpace Failed: 0x%x\n", rc);
> 		goto out;
> 	}
> 
> 	/* Note if you need to set the owner hierarchy auth value you use:
> 	 * TSS2_RC Esys_TR_SetAuth(
> 	 *     ESYS_CONTEXT *esysContext,
>          *     ESYS_TR handle,
>          *     TPM2B_AUTH const *authValue);
> 	 */
> 
> 	printf("Created NV Index: 0x%x\n", pub_templ.nvPublic.nvIndex);
> 	printf("ESYS_TR: 0x%x\n", nv_index);
> 
> 	/*
> 	 * Note: if we need to convert the nvIndex into an ESYS_TR, the below
> will
> 	 * do it. Its not required for this case, since Esys_NV_Define gives us an
> 	 * ESYS_TR.
> 	 */
> 	rc = Esys_TR_FromTPMPublic(
> 		ectx,
> 		TPM2_HR_NV_INDEX + 1,
> 		ESYS_TR_NONE,
> 		ESYS_TR_NONE,
> 		ESYS_TR_NONE,
> 		&nv_index2);
> 	if (rc != TSS2_RC_SUCCESS) {
> 		printf("Esys_TR_FromTPMPublic Failed: 0x%x\n", rc);
> 		goto out;
> 	}
> 
> 	printf("ESYS_TR2: 0x%x\n", nv_index2);
> 
> 	/* copy some data into a buffer to send to the TPM */
> 	TPM2B_MAX_NV_BUFFER write_data = { 0 };
> 	memcpy(write_data.buffer, bytes->buffer, bytes->size);
> 	write_data.size = bytes->size;
> 
> 	printf("Writing the random number written in NV Ram\n");
>     	printf("Data buffer size used to write into NVRam:
> %d\n",write_data.size);
> 	/*
> 	 * Write the data to the TPM NV index at offset 0
> 	 */
> 	rc = Esys_NV_Write(
> 	    ectx,
> 	    nv_index, /* authenticate to the NV index using the NV index
> password */
> 	    nv_index, /* the nv index to write to */
> 	    ESYS_TR_PASSWORD,
> 		ESYS_TR_NONE,
> 		ESYS_TR_NONE,
> 	    &write_data,
> 	    0);
> 	if (rc != TSS2_RC_SUCCESS) {
> 		printf("Esys_NV_Write Failed: 0x%x\n", rc);
> 		goto out;
> 	}
> 
> 	/* Read the data back, and just for fun, we will use nv_index2
> 	 * to prove it's pointing to the same NV location in the TPM.
> 	 */
> 	TPM2B_MAX_NV_BUFFER *read_data = NULL;
> 	rc = Esys_NV_Read(
> 	    ectx,
> 	    nv_index2, /* authenticate to the NV index using the NV index
> password */
> 	    nv_index2, /* the nv index to read from */
> 	    ESYS_TR_PASSWORD,
> 	    ESYS_TR_NONE,
> 	    ESYS_TR_NONE,
> 	    bytes->size,
> 	    0,
> 	    &read_data);
> 	if (rc != TSS2_RC_SUCCESS) {
> 		printf("Esys_NV_Read Failed: 0x%x\n", rc);
> 		goto out;
> 	}
> 
> 	/* Print things as a string from the TPM carefully!
> 	 * Injected traffic via MITM means that you cannot trust this
> 	 * to be null terminated.
> 	 */
> 	printf("Reading the random number written in NV Ram\n");
>     	for (i = 0; i < read_data->size; i++) {
>         	printf("%02x", read_data->buffer[i]);
>     	}
> 	printf("\n");
> 
> 	Esys_Free(read_data);
> 	rc = 0;
> 
> out:
> 
> 	/* remove the NV space */
> 	if (nv_index) {
> 		int rc2 = Esys_NV_UndefineSpace(
> 			ectx,
> 			ESYS_TR_RH_OWNER,
> 			nv_index,
> 			ESYS_TR_PASSWORD,
> 			ESYS_TR_NONE,
> 			ESYS_TR_NONE);
> 		if (rc2 != TSS2_RC_SUCCESS) {
> 			printf("Esys_NV_UndefineSpace Failed: 0x%x\n", rc2);
> 			rc = 1;
> 		}
> 	}
> 
> 	Esys_Finalize(&ectx);
> 
>         printf("Exit from nv_write_read()\n");
> 	return rc;
> }
> _______________________________________________
> tpm2 mailing list -- tpm2(a)lists.01.org
> To unsubscribe send an email to tpm2-leave(a)lists.01.org
> %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [tpm2] Re: NVRAM Write and Read using Esys API(s)
@ 2020-05-19 14:47 Roberts, William C
  0 siblings, 0 replies; 5+ messages in thread
From: Roberts, William C @ 2020-05-19 14:47 UTC (permalink / raw)
  To: tpm2

[-- Attachment #1: Type: text/plain, Size: 33112 bytes --]

I see that your auth handle should be an ESYS_TR for the authorization. It's currently
The raw tpm handle for the Owner Hiearchy. ESYS will not understand this.

You can authorize to an NV Index using the auth the hierarchy the NV was created in, or the
NV index. Think of it as two ways to access the NV Index, Hierarchy password
Or per-nv-index password. This is controllable via attributes OWNER_<XXX>
And AUTH_<XXX> attributes.

Just pass the same ESYS_TR that is the NV Index as the auth handle as well.

I have no idea where that error code is coming from, perhaps it’s a bug in Esys
And it's not formatting the error code properly....

> -----Original Message-----
> From: Muthukumar S [mailto:muthu.smk(a)gmail.com]
> Sent: Monday, May 18, 2020 12:08 PM
> To: Roberts, William C <william.c.roberts(a)intel.com>
> Cc: tpm2(a)lists.01.org
> Subject: Re: [tpm2] NVRAM Write and Read using Esys API(s)
> 
> Hi Roberts ,
> 
> Once again thanks a lot for your guidance.  I have looked in to nv.sh from the
> tpm2-tools folder and find out how to use the
> tpm2 define , tpm2 write and read it back . Now it is working as expected.
> Below are the commands and its output:
> 
> 
> root(a)muthu-vb:~/work# ./tpm2_nvdefine -Q -x 0x1000001 -a 0x40000001 -s 32 -t
> "ownerread|policywrite|ownerwrite"
> 
> root(a)muthu-vb:~/work#
> 
> root(a)muthu-vb:~/work# ./tpm2_nvwrite -Q -x 0x1000001 -a 0x40000001
> nv.test_w
> 
> root(a)muthu-vb:~/work# ./tpm2_nvread -x 0x1000001 -a 0x40000001
> 
> pleafoo23abc
> 
> �������������������
> 
> root(a)muthu-vb:~/work/tpm2/tpm_evo/install/bin#
> 
> 
> 
> 
> Now, i tried used the test application to just read it back from the above
> 0x1000001 offset .  The sample code (pls find attachment)
> 
> has read function which uses Esys_NV_Read () api to read the offset.  But am
> getting error code with "70018"  , i could not able to find much details from
> tpm2_rc_decode of this error.
> 
> 
> 
> 
> From the debug log (ref attachment : debug_log.txt)  , i could see "Esys handle
> does not exist" (70018). What i suppose to do to get this handle and make
> Esys_NV_Read () successfully read from already defined offset ?
> 
> 
> 
> 
> 
> Previous to this error , i was getting 0x12f (which is nothing but
> TPM2_RC_AUTH_UNAVAILABLE) . So what i did was , i given the 'authHandle =
> 0x40000001" and set this value as second argument
> 
> 
> of Esys_NV_Read Api  . After doing that , am getting this "Esys handle does not
> exist" (70018)   error , let me know what am i missing here. Attached "log file" as
> well for your reference along with test code.
> 
> 
> 
> 
> Also tried to "nv_define" once again and then try to read it back . Since it doesn't
> make sense, because we have already defined using command line  and written
> data in to it.
> 
> So i believe there is no point in doing nv define and then reading it back . Hope
> nv_define is not required here ?
> 
> 
> 
> 
> NOTE : This test code also have "get_random number" and , "nv_write" functions
> implemented . As i said to you earlier , i want to generate random number and
> then write in to nvram and read it back .  Since the "nv_read" itself not happening
> by which the offset was already well defined and data already written in to it
> using command line tool API , i could not able to proceed further.
> 
> 
> 
> 
> 
> 
> 
> BR,
> 
> Muthukumar
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> On Fri, May 15, 2020 at 8:24 PM Roberts, William C <william.c.roberts(a)intel.com
> <mailto:william.c.roberts(a)intel.com> > wrote:
> 
> 
> 	> -----Original Message-----
> 	> From: Muthukumar S [mailto:muthu.smk(a)gmail.com
> <mailto:muthu.smk(a)gmail.com> ]
> 	> Sent: Friday, May 15, 2020 7:58 AM
> 	> To: Roberts, William C <william.c.roberts(a)intel.com
> <mailto:william.c.roberts(a)intel.com> >
> 	> Cc: tpm2(a)lists.01.org <mailto:tpm2(a)lists.01.org>
> 	> Subject: Re: [tpm2] NVRAM Write and Read using Esys API(s)
> 	>
> 	> Hi Williams C,
> 	> Thanks for your quick response. As you suggested , i have tried below
> options
> 	>
> 	> I tried to get the index of nvram of sim that am working using
> tpm2_getcap tools
> 	> API .Bellow are the tpm2_getcap capabilities that i found by reading the
> 	> tpm2_getcap code . Request you to share me some pointers of using
> 	> tpm2_getcap() .
> 	>
> 	>
> 	>
> 	> Available capability from tpm2_getcap.c
> 	>
> 	>         .capability_string = "algorithms"
> 	>
> 	>         .capability_string = "commands"
> 	>
> 	>         .capability_string = "properties-fixed",
> 	>
> 	>         .capability_string = "properties-variable",
> 	>
> 	>         .capability_string = "ecc-curves",
> 	>
> 	>         .capability_string = "handles-transient",
> 	>
> 	>         .capability_string = "handles-persistent",
> 	>
> 	>         .capability_string = "handles-permanent",
> 	>
> 	>         .capability_string = "handles-pcr",
> 	>
> 	>         .capability_string = "handles-nv-index",
> 	>
> 	>         .capability_string = "handles-loaded-session",
> 	>
> 	>         .capability_string = "handles-saved-session",
> 	>
> 	>
> 	>
> 	>
> 	> In the above list , i tried all "capability string " but i could't able to see
> the below
> 	> output given by tpm2_nvlist (which i used to get with different tpm-
> tools version
> 	> that i used earlier) .
> 	>
> 
> 	Put the tool in a debugger and look at the arguments passed to
> Esys_GetCapability and mimic it.
> 	It's time you learn how to fish.
> 
> 	>
> 	>
> 	>
> 	> # tpm2_nvlist
> 	>
> 	> O/P
> 	>
> 	> 1 NV indexes defined.
> 	>
> 	>  0. NV Index: 0x1500015
> 	>
> 	>  {
> 	>
> 	>  Hash algorithm(nameAlg):11
> 	>
> 	> The Index attributes(attributes):0x64014001
> 	>
> 	>        The size of the data area(dataSize):32
> 	>
> 	>           }
> 	>
> 	>
> 	>
> 	>
> 	> 1) Even though this tpm2_nvlist that was there in my current tpm2-
> tools version
> 	> (tpm2-tools-3.X) ,by which it is not showing me any output .
> 	>
> 	> #tpm2_nvlist
> 	>
> 	> #
> 	>
> 
> 	I don't know if your trying to ask something here, are you?
> 
> 	>
> 	>
> 	>
> 	>
> 	>
> 	>
> 	> 2) Tried get_cap of "handles-permanent" , which shows me below
> values as
> 	> shown below , but not sure how to get the index of particular tpm bank
> 
> 	Banks are for PCRs, ie PCR0 can have a SHA1 and SH256 bank.
> 
> 	>
> 	> #/tpm2/tpm_evo/tpm2-tools-3.X/tools# ./tpm2_getcap --
> capability="handles-
> 	> permanent"
> 
> 	Stop using 3.X its deprecated, grab the latest 4.X release and build it.
> 	The tools actually work.
> 
> 	>
> 	> 0x40000001
> 	>
> 	> 0x40000007
> 	>
> 	> 0x40000009
> 	>
> 	> 0x4000000a
> 	>
> 	> 0x4000000b
> 	>
> 	> 0x4000000c
> 	>
> 	> 0x4000000d
> 
> 	Those are not NV handles, NV Handles start with 0x10
> 
> 	>
> 	>
> 	>
> 	>
> 	> 2)Also tried reading pcr list using tpm2_getcap . Is the below offset(s)
> are stands
> 	> for ?
> 	>
> 	> # ./tpm2_getcap --capability="handles-pcr"
> 
> 	Again, NV Indexes ARE NOT PCR's.
> 
> 	>
> 	> 0x00000000
> 	>
> 	> 0x00000001
> 	>
> 	> 0x00000002
> 	>
> 	> 0x00000003
> 	>
> 	> 0x00000004
> 	>
> 	> 0x00000005
> 	>
> 	> 0x00000006
> 	>
> 	> 2.1) Request you to share me few points on how to use the
> "tpm2_getcap() and
> 	> get the offset ?
> 	>
> 
> 	Debuggers are your friend.
> 
> 	>
> 	>
> 	> Since none of the above tools API helped me or am i missing some thing
> to read
> 	> the output of NVRAM index ?
> 
> 	I would upgrade to newer tools. If you must stay in the 3.X land, then
> copy what the test
> 	scripts are doing, they do it completely. Look for nv.sh.
> 
> 	>
> 	> 3) Without knowing the offset , tried to define offset from 0x1500015
> and trying
> 	> to write and read back , here nvdefine works along with nvwrite ..but
> nvread fails
> 	> with "auth" issue. Please refere below sequence and associated errors
> 	>
> 	>
> 	> 3.1) Tried defining nvram using tpm2_nvdefine - Succeeded with out
> any error  --
> 	> given -a 0x40000001 (TPM_RH_OWNER Access) , if i define with
> 0x4000000C
> 	> (TPM_RH_OWNER , i got the same result during tpm2_nvread . Here
> removing "-t
> 	> 0x2000A" option and then doing nvdefine also throws me the same
> error shown
> 	> in point 3.3 during nvread
> 	>
> 	> #./tpm2_nvdefine -x 0x1500016 -a 0x40000001 -s 32 -t 0x2000A
> 
> 	Offhand, I don't know what the 0x2000A mask is, so I would have to look
> it up, but I am not going to.
> 	Use string masks.
> 
> 	If you just upgrade to a 4.x tools, it should work. I remember some issues
> with attributes on the 3.X branch
> 	Tools.
> 
> 	>
> 	> #
> 	>
> 	>
> 	>
> 	>
> 	> 3.2) Tried NVWRITE in the same offset 0x1500015  - Succeeded without
> any error
> 	>
> 	> # ./tpm2_nvwrite -x 0x1500015 -L test_helloworld
> 	>
> 	> #
> 	>
> 	>
> 	>
> 	>
> 	> 3.3) Reading back the same offset -x1500015 , which throws below error
> stating
> 	> TPM2_RC_NV_UNINITIALIZED. Since i have initialized it as said above
> point 3.1  ,
> 	> what am i missing here ?
> 
> 	Upgrade your tools, and the example I showed yesterday should work.
> 
> 	>
> 	>
> 	>
> 	>
> 	> Below are the OPTIONS I have by tpm2_nvread:
> 	>
> 	> as you suggested  to use (echo `tpm2_nvread -C o -s5 0x1500015`
> command)
> 	>
> 	> I cant see -C (this might be due to tools version 3.X ? . If it is not the
> latest , can't
> 	> we able to use the below APIs ?
> 	>
> 	>
> 	>
> 	>
> 	> # ./tpm2_nvread
> 	>
> 	> Usage: tpm2_nvread [<options>]
> 	>
> 	> Where <options> are:
> 	>
> 	>     [ -x | --index=<value>] [ -a | --auth-handle=<value>] [ -f | --
> output=<value>] [
> 	> -s | --size=<value>]
> 	>
> 	>     [ -o | --offset=<value>] [ -P | --handle-passwd=<value>] [ -S | --
> input-session-
> 	> handle=<value>] [ -L | --set-list=<value>]
> 	>
> 	>     [ -F | --pcr-input-file=<value>]
> 	>
> 	>
> 	>
> 	>
> 	> # ./tpm2_nvread -x 0x1500015 -a 0x40000001 -s 32
> 	>
> 	> ERROR: Failed to read NVRAM area at index 0x1500015 (22020117).
> Error:0x14a
> 	>
> 	> ERROR: Unable to run ./tpm2_nvread
> 	>
> 	>
> 	>
> 	>
> 	> # tpm2_rc_decode 0x14a
> 	>
> 	> error layer
> 	>
> 	>   hex: 0x0
> 	>
> 	>   identifier: TSS2_TPM_RC_LAYER
> 	>
> 	>   description: Error produced by the TPM
> 	>
> 	> format 0 error code
> 	>
> 	>   hex: 0x4a
> 	>
> 	>   name: TPM2_RC_NV_UNINITIALIZED
> 	>
> 	>   description: an NV Index is used before being initialized or the state
> saved by
> 	> TPM2_Shutdown(STATE) could not be restored
> 	>
> 	>
> 	>
> 	>
> 	> 3.4) Tried reading the same offset 0x1500015 without giving '-a'
> 	> (TPM2_RH_OWNER) access , but the results shown
> NV_AUTHORIZATION. So i
> 	> understood
> 	>
> 	> if we defined with -a auth permission then we need to give the same
> permission
> 	> while reading the content from the same offset. Is my understanding is
> correct ?
> 	>
> 	>
> 	>
> 	>
> 	> # ./tpm2_nvread -x 0x1500015 -s 32
> 	>
> 	>
> 	> ERROR: Failed to read NVRAM area at index 0x1500015 (22020117).
> Error:0x149
> 	> ERROR: Unable to run ./tpm2_nvread
> 	>
> 	>
> 	> # tpm2_rc_decode 0x149
> 	> error layer
> 	>   hex: 0x0
> 	>   identifier: TSS2_TPM_RC_LAYER
> 	>   description: Error produced by the TPM format 0 error code
> 	>   hex: 0x49
> 	>   name: TPM2_RC_NV_AUTHORIZATION
> 	>   description: NV access authorization fails in command actions (this
> failure does
> 	> not affect lockout.action)
> 	>
> 	>
> 	>
> 	>
> 	>
> 	> 4) Tried to use tpm2_readpublic to read above written offset 0x1500015
> , getting
> 	> 0x184 (value is out of range or is not correct for the context) what am i
> missing
> 	> here ?
> 	>
> 	> # ./tpm2_readpublic
> 	> Usage: tpm2_readpublic [<options>]
> 	> Where <options> are:
> 	>     [ -H | --object=<value>] [ -o | --opu=<value>] [ -c | --context-
> object=<value>]
> 	> [ -f | --format=<value>]
> 	>
> 	>
> 	>
> 	>
> 	> # ./tpm2_readpublic -H 0x1500015
> 	> ERROR: TPM2_ReadPublic error: rval = 0x184
> 	> ERROR: Unable to run ./tpm2_readpublic
> 	> root(a)muthu-vb:~/work/tpm2/tpm_evo/install/bin#
> ./tpm2_readpublic -H
> 	> 0x1500015 --opu file
> 	> ERROR: TPM2_ReadPublic error: rval = 0x184
> 	> ERROR: Unable to run ./tpm2_readpublic
> 	> root(a)muthu-vb:~/work/tpm2/tpm_evo/install/bin#
> ./tpm2_rc_decode 0x184
> 	> error layer
> 	>   hex: 0x0
> 	>   identifier: TSS2_TPM_RC_LAYER
> 	>   description: Error produced by the TPM
> 	> format 1 error code
> 	>   hex: 0x04
> 	>   identifier: TPM2_RC_VALUE
> 	>   description: value is out of range or is not correct for the context
> 	> handle
> 	>   hex:0x100
> 	>   identifier:  TPM2_RC_1
> 	>   description:  (null)
> 	>
> 	>
> 	>
> 	> #
> 	>
> 	>
> 	>
> 	>
> 	>
> 	> 5)Tried releasing the same offset using nvrelease that too works fine
> 	>
> 	> #./tpm2_nvrelease -x 0x1500015 -a 0x40000001
> 	>
> 	> #
> 	>
> 	>
> 	>
> 	>
> 	> As per my request raised by yesterday . I need to define an offset in nv
> ram then
> 	> write content only once and read it back when ever required.  During
> every
> 	> second write , i need to read the offset (you suggested to use
> 	> tpm2_nvreadpubic() , but i struck with usage of this "nvread public api"
> command
> 	> as well (results are just shown above)
> 	>
> 	>
> 	>
> 	>
> 	> As per today's experiments , i cant able able to achieve the (nvread)
> using
> 	> command line API . Let me know what am i missing here .
> 	>
> 	>
> 	>
> 	>
> 	> Looking forward for your valuable reply.
> 	>
> 	>
> 	>
> 	>
> 	> Thanks,
> 	>
> 	> Muthukumar
> 	>
> 	>
> 	>
> 	>
> 	>
> 	>
> 	>
> 	> On Thu, May 14, 2020 at 12:51 AM Roberts, William C
> 	> <william.c.roberts(a)intel.com <mailto:william.c.roberts(a)intel.com>
> <mailto:william.c.roberts(a)intel.com <mailto:william.c.roberts(a)intel.com> > >
> wrote:
> 	>
> 	>
> 	>       > -----Original Message-----
> 	>       > From: muthu.smk(a)gmail.com <mailto:muthu.smk(a)gmail.com>
> <mailto:muthu.smk(a)gmail.com <mailto:muthu.smk(a)gmail.com> >
> 	> [mailto:muthu.smk(a)gmail.com <mailto:muthu.smk(a)gmail.com>
> <mailto:muthu.smk(a)gmail.com <mailto:muthu.smk(a)gmail.com> > ]
> 	>       > Sent: Wednesday, May 13, 2020 12:51 PM
> 	>       > To: tpm2(a)lists.01.org <mailto:tpm2(a)lists.01.org>
> <mailto:tpm2(a)lists.01.org <mailto:tpm2(a)lists.01.org> >
> 	>       > Subject: [tpm2] NVRAM Write and Read using Esys API(s)
> 	>       >
> 	>       > Hi Williams,
> 	>       >
> 	>       > I am using the test code used to read and write in to NV ram.  I am
> 	> facing below
> 	>       > challenges if i tried to read already written data from NVRAM.
> 	>       >
> 	>       > 1) Test code attached defined create the context (ectx) , create
> random
> 	> number ,
> 	>       > define NV ram , write the random number in to NVRAM (offset
> 	> 0x1000001) and
> 	>       > read it back from NV Ram (from same offset 0x1000001)
> 	>       >
> 	>       > 2) But if i try to run this code twice or thrise , am getting below
> NVRAM
> 	> already
> 	>       > defined rc code. I can understand that we should not defined the
> nv
> 	> ram space
> 	>       > which already defined and used.
> 	>       > How to avoid this ? by defining nvram ONLY once and write it ONLY
> 	> once and
> 	>       > finally read it AS MUCH times we want ?  Below details are related
> to
> 	> this request
> 	>
> 	>       You can call Esys_GetCapability() and see what NV indices are
> defined.
> 	> The command
> 	>       Line tool tpm2_getcap does this, like so:
> 	>       tpm2_getcap handles-nv-index
> 	>
> 	>       You can use that tool as an example of how to do it.
> 	>
> 	>       >
> 	>       > Error code:
> 	>       > 0x0000014c - description: NV Index or persistend object already
> defined
> 	>       > 0x00000284 - description: value is out of range or is not correct for
> the
> 	> context
> 	>       >
> 	>       > 3) Query is : is it possible to define nvram "ONLY ONCE" with the
> API
> 	> shared the
> 	>       > test code and then create a function "createrandom" number to
> use
> 	> the same
> 	>
> 	>       Call getcap, see if it's defined, if defined, don't define it....
> 	>
> 	>       > context (ects) to generate randumnumber then call separate
> 	> "write_nvram"
> 	>       > function with random number as input and ask to write in the
> same
> 	> offset .
> 	>       > Finally calling another function "read_nvram" to read it back from
> the
> 	> same
> 	>       > nvram's offset when ever we want ? i tried this approach but am
> 	> getting segfault
> 	>       > with above error .
> 	>       > What am i missing here ?
> 	>
> 	>       Segfaults are likely your code is just broken.
> 	>
> 	>       >
> 	>       > 3.1) Ideally in single application , i need to achieve
> "tpm2_nvdefine",
> 	>       > "tpm2_nvwrite" and "tpm2_nvread() tools API(s) functionality" in
> 	> different calls
> 	>       > or flow.
> 	>       > 3.2) Also how to check whether "write" already done (i tried
> checking
> 	> nv_index is
> 	>       > true - means whether it already has some value) , but it failed ?
> 	>
> 	>       If you do what the tool tpm2_nvreadpublic does, you can check for
> the
> 	> written bit.
> 	>
> 	>       >
> 	>       > 4) Also how to check what was the content that already present in
> the
> 	> nvram
> 	>       > offset (0x1000001) before i do write the "random number" second
> time
> 	> in to the
> 	>       > same offset ? this is to ensure the "random number" that i am
> planning
> 	> to write
> 	>       > was valid one ?
> 	>
> 	>       Read it out, if it's not what you want, write it.
> 	>
> 	>       >
> 	>       > I remember studying that, once u write in to NVRAM offset , we
> cant
> 	> able to RE-
> 	>       > WRITE it in the same offset(0x1000001). Whether that is the same
> case
> 	> for
> 	>       > SIMULATOR as well (or) this feature is only for real tpm hardware?
> 	>
> 	>       No generally you can write as many times as you want... there are
> tricks
> 	> you can do to make
> 	>       It locked after write (writelocked iirc)
> 	>
> 	>       Below is a command line example of doing it...
> 	>
> 	>       tpm2_nvdefine
> 	>       nv-index: 0x1000000
> 	>
> 	>       tpm2_nvreadpublic 0x1000000
> 	>       0x1000000:
> 	>         name:
> 	>
> 000b1195f36a21c8219055ad0803c39e7e81d06cdb2eee2b7cf93dd83e01d4273828
> 	>         hash algorithm:
> 	>           friendly: sha256
> 	>           value: 0xB
> 	>         attributes:
> 	>           friendly: ownerwrite|authwrite|ownerread|authread
> 	>           value: 0x6000600
> 	>         size: 2048
> 	>
> 	>       # you can do this as much as you want, but it can wear the memory
> in the
> 	> TPM
> 	>       # depending on memory technology the vendor used.
> 	>       echo "hello" | tpm2_nvwrite -C o 0x1000000 -i-
> 	>       echo `tpm2_nvread -C o -s5 0x1000000`
> 	>       hello
> 	>
> 	>       tpm2_nvreadpublic 0x1000000
> 	>       0x1000000:
> 	>         name:
> 	>
> 000b287c9b1b06fab6e51bd26e98ea89460574e97a3d2ef995eb35f7e23db7e94f67
> 	>         hash algorithm:
> 	>           friendly: sha256
> 	>           value: 0xB
> 	>         attributes:
> 	>           friendly: ownerwrite|authwrite|ownerread|authread|written
> 	>           value: 0x6000620
> 	>         size: 2048
> 	>
> 	>       >
> 	>       > 6)After nvwrite i tried to use "tpm2_pcrlist" command line tool
> 	> application, by
> 	>       > which it shows the nv ram memory location , tried using
> tpm2_nvread ()
> 	> to read
> 	>       > the content but i could not able to see any data (random number)
> that i
> 	> used to
> 	>       > write via this test application . dont know why ?
> 	>
> 	>       tpm2_pcrlist is not for NVs.... you want:
> 	>       tpm2_getcap handles-nv-index
> 	>
> 	>       >
> 	>       > 7) After i manually ran the below clear API , now the test code is
> 	> working fine
> 	>       > (refer Test code log shown below..). This confirms we can
> reallocate
> 	> already
> 	>       > defined nv ram memory.
> 	>       > #tpm2_nvrelease -x 0x1000001 -a 0x40000001
> 	>
> 	>       Tpm2_clear will clear the owner hierarchy, including NV ram objects
> 	> declared in that hierarchy,
> 	>       so define will work again, because you deleted it.
> 	>
> 	>       >
> 	>       >
> 	>       > 8)If i try to read it manually via below tpm2_nvread command with
> 	> offset
> 	>       > 0x1000001 am getting below error
> 	>       >
> 	>       > #tpm2_nvread -x 0x1000001 -a 0x40000001 -o 0 -s 20
> 	>       > ERROR: Failed to read NVRAM public area at index 0x1000001
> 	> (16777217).
> 	>       > Error:0x18b
> 	>       > ERROR: Unable to run tpm2_nvread
> 	>       >
> 	>       > /* Tried to use below tools command , am always getting the same
> 	> error even if
> 	>       > we give the different nvram off set tpm2_nvwrite -x 0x1c00002
> 	> helloworld
> 	>       > ERROR: Reading the public part of the nv index failed with: 0x18b
> 	>       > ERROR: Unable to run tpm2_nvwrite
> 	>       >
> 	>       > tpm2_nvwrite -x 0x1c00012 -a 0x40000001 helloworld
> 	>       > ERROR: Reading the public part of the nv index failed with: 0x18b
> 	>       > ERROR: Unable to run tpm2_nvwrite
> 	>       >
> 	>       >
> 	>       > /* Try to read the nvlist of SIM , it returns nothing !!!
> 	>       > #tpm2_nvlist <returns nothing>
> 	>       >
> 	>       > Any points will be great help for me.
> 	>       >
> 	>       > ---------------------------------------------------------------------------------
> ------
> 	> ------------
> 	>       > --------------------------------------------------------------
> 	>       > Test code log after above "tpm2_nvrelease":
> 	>       > Initializing
> 	>       > init_rand()
> 	>       > init_rsa()
> 	>       > init_ecc()
> 	>       > Engine name: TPM2-TSS engine for OpenSSL
> 	>       > Init result: 1
> 	>       > Setting owner auth to empty auth.
> 	>       > Setting parent auth to empty auth.
> 	>       > ERROR:tcti:src/tss2-tcti/tcti-device.c:440:Tss2_Tcti_Device_Init()
> Failed
> 	> to open
> 	>       > device file /dev/tpm0: No such file or directory
> 	>       > WARNING:tcti:src/tss2-tcti/tctildr.c:62:tcti_from_init() TCTI init for
> 	> function
> 	>       > 0x7fc67376d18b failed with a000a
> 	>       > WARNING:tcti:src/tss2-tcti/tctildr.c:92:tcti_from_info() Could not
> 	> initialize TCTI
> 	>       > named: tcti-device
> 	>       > ERROR:tcti:src/tss2-tcti/tctildr-dl.c:150:tcti_from_file() Could not
> 	> initialize TCTI
> 	>       > file: libtss2-tcti-default.so
> 	>       >  No of bytes written by GenRandom : 64
> 	>       >
> 	>
> b6c9e1d028f2c893c56a089165f9f38c09232180ba5bb66b35c5652cb51ab61b237ecfe
> 	>       > 8ece5d7f14a3323fee1dca0e641a0f20c7689100e3c804b82d6a2497f
> 	>       > Created NV Index: 0x1000001
> 	>       > ESYS_TR: 0x418367
> 	>       > ESYS_TR2: 0x418368
> 	>       > Writing the random number written in NV Ram
> 	>       > Data buffer size used to write into NVRam: 64
> 	>       > Reading the random number written in NV Ram
> 	>       >
> 	>
> b6c9e1d028f2c893c56a089165f9f38c09232180ba5bb66b35c5652cb51ab61b237ecfe
> 	>       > 8ece5d7f14a3323fee1dca0e641a0f20c7689100e3c804b82d6a2497f
> 	>       > *** SUCCESS ***
> 	>       > ---------------------
> 	>       >
> 	>       > TEST CODE :
> 	>       >
> 	>       > int nv_write_read()
> 	>       > {
> 	>       >
> 	>       >       ESYS_CONTEXT *ectx = NULL;
> 	>       >
> 	>       >       ESYS_TR nv_index = 0;
> 	>       >       ESYS_TR nv_index2 = 0;
> 	>       >
> 	>       >        int rc = 1;
> 	>       >
> 	>       >
> 	>       >       /*
> 	>       >        * create a connection to the TPM letting ESAPI choose how to
> get
> 	> there.
> 	>       >        * If you need more control, you can use tcti and tcti-ldr libraries
> to
> 	>       >        * get a TCTI pointer to use for the tcti argument of
> Esys_Initialize.
> 	>       >        */
> 	>       >       rc = Esys_Initialize(&ectx,
> 	>       >                       NULL,  // let it find the TCTI
> 	>       >                       NULL); // Use whatever ABI
> 	>       >       if (rc != TSS2_RC_SUCCESS) {
> 	>       >               printf("Esys_Initialize Failed: 0x%x\n", rc);
> 	>       >               return 1;
> 	>       >       }
> 	>       >
> 	>       >
> 	>       >         rc = Esys_GetRandom(ectx,
> 	>       >                         ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
> 	>       >                         64, &bytes);
> 	>       >         if (rc != TSS2_RC_SUCCESS) {
> 	>       >                 printf("Esys_GetRandom Failed: %s\n",
> Tss2_RC_Decode(rc));
> 	>       >                 exit(1);
> 	>       >         }
> 	>       >
> 	>       >       printf(" No of bytes written by GenRandom : %d\n",bytes-
> >size);
> 	>       >       size_t i;
> 	>       >       for (i = 0; i < bytes->size; i++) {
> 	>       >               printf("%02x", bytes->buffer[i]);
> 	>       >       }
> 	>       >
> 	>       >       printf("\n");
> 	>       >
> 	>       >       /* build a template for the NV index */
> 	>       >       TPM2B_NV_PUBLIC pub_templ = {
> 	>       >               /* this is counter intuitive, but it tells the TSS2 library to
> calculate
> 	>       > this for us */
> 	>       >               .size = 0,
> 	>       >               /* The things that define what NV index we are creating */
> 	>       >               .nvPublic = {
> 	>       >                       /* uses sha256 to identify the tpm object by name */
> 	>       >                       .nameAlg = TPM2_ALG_SHA256,
> 	>       >                       /* allows the owner password or index password r/w
> 	>       > access */
> 	>       >                       .attributes = TPMA_NV_OWNERWRITE |
> 	>       >                               TPMA_NV_OWNERREAD            |
> 	>       >                               TPMA_NV_AUTHWRITE            |
> 	>       >                               TPMA_NV_AUTHREAD,
> 	>       >                       /* can hold 64 bytes of data */
> 	>       >                       .dataSize = 64,
> 	>       >                       /* Create at NV Index 1 or 0x1000001 */
> 	>       >                       .nvIndex = TPM2_HR_NV_INDEX + 1
> 	>       >               },
> 	>       >       };
> 	>       >
> 	>       >
> 	>       >       /* Ok, define the space and store the nv_index for future use
> */
> 	>       >       rc = Esys_NV_DefineSpace(
> 	>       >           ectx,
> 	>       >               ESYS_TR_RH_OWNER, /* create an NV index in the owner
> 	>       > hierarchy */
> 	>       >           ESYS_TR_PASSWORD, /* auth as the owner with a password,
> 	> which is
> 	>       > empty */
> 	>       >           ESYS_TR_NONE,
> 	>       >           ESYS_TR_NONE,
> 	>       >           NULL,
> 	>       >           &pub_templ,
> 	>       >           &nv_index);
> 	>       >       if (rc != TSS2_RC_SUCCESS) {
> 	>       >               printf("Esys_NV_DefineSpace Failed: 0x%x\n", rc);
> 	>       >               goto out;
> 	>       >       }
> 	>       >
> 	>       >       /* Note if you need to set the owner hierarchy auth value you
> use:
> 	>       >        * TSS2_RC Esys_TR_SetAuth(
> 	>       >        *     ESYS_CONTEXT *esysContext,
> 	>       >          *     ESYS_TR handle,
> 	>       >          *     TPM2B_AUTH const *authValue);
> 	>       >        */
> 	>       >
> 	>       >       printf("Created NV Index: 0x%x\n",
> pub_templ.nvPublic.nvIndex);
> 	>       >       printf("ESYS_TR: 0x%x\n", nv_index);
> 	>       >
> 	>       >       /*
> 	>       >        * Note: if we need to convert the nvIndex into an ESYS_TR, the
> 	> below
> 	>       > will
> 	>       >        * do it. Its not required for this case, since Esys_NV_Define
> gives us
> 	> an
> 	>       >        * ESYS_TR.
> 	>       >        */
> 	>       >       rc = Esys_TR_FromTPMPublic(
> 	>       >               ectx,
> 	>       >               TPM2_HR_NV_INDEX + 1,
> 	>       >               ESYS_TR_NONE,
> 	>       >               ESYS_TR_NONE,
> 	>       >               ESYS_TR_NONE,
> 	>       >               &nv_index2);
> 	>       >       if (rc != TSS2_RC_SUCCESS) {
> 	>       >               printf("Esys_TR_FromTPMPublic Failed: 0x%x\n", rc);
> 	>       >               goto out;
> 	>       >       }
> 	>       >
> 	>       >       printf("ESYS_TR2: 0x%x\n", nv_index2);
> 	>       >
> 	>       >       /* copy some data into a buffer to send to the TPM */
> 	>       >       TPM2B_MAX_NV_BUFFER write_data = { 0 };
> 	>       >       memcpy(write_data.buffer, bytes->buffer, bytes->size);
> 	>       >       write_data.size = bytes->size;
> 	>       >
> 	>       >       printf("Writing the random number written in NV Ram\n");
> 	>       >       printf("Data buffer size used to write into NVRam:
> 	>       > %d\n",write_data.size);
> 	>       >       /*
> 	>       >        * Write the data to the TPM NV index at offset 0
> 	>       >        */
> 	>       >       rc = Esys_NV_Write(
> 	>       >           ectx,
> 	>       >           nv_index, /* authenticate to the NV index using the NV index
> 	>       > password */
> 	>       >           nv_index, /* the nv index to write to */
> 	>       >           ESYS_TR_PASSWORD,
> 	>       >               ESYS_TR_NONE,
> 	>       >               ESYS_TR_NONE,
> 	>       >           &write_data,
> 	>       >           0);
> 	>       >       if (rc != TSS2_RC_SUCCESS) {
> 	>       >               printf("Esys_NV_Write Failed: 0x%x\n", rc);
> 	>       >               goto out;
> 	>       >       }
> 	>       >
> 	>       >       /* Read the data back, and just for fun, we will use nv_index2
> 	>       >        * to prove it's pointing to the same NV location in the TPM.
> 	>       >        */
> 	>       >       TPM2B_MAX_NV_BUFFER *read_data = NULL;
> 	>       >       rc = Esys_NV_Read(
> 	>       >           ectx,
> 	>       >           nv_index2, /* authenticate to the NV index using the NV
> index
> 	>       > password */
> 	>       >           nv_index2, /* the nv index to read from */
> 	>       >           ESYS_TR_PASSWORD,
> 	>       >           ESYS_TR_NONE,
> 	>       >           ESYS_TR_NONE,
> 	>       >           bytes->size,
> 	>       >           0,
> 	>       >           &read_data);
> 	>       >       if (rc != TSS2_RC_SUCCESS) {
> 	>       >               printf("Esys_NV_Read Failed: 0x%x\n", rc);
> 	>       >               goto out;
> 	>       >       }
> 	>       >
> 	>       >       /* Print things as a string from the TPM carefully!
> 	>       >        * Injected traffic via MITM means that you cannot trust this
> 	>       >        * to be null terminated.
> 	>       >        */
> 	>       >       printf("Reading the random number written in NV Ram\n");
> 	>       >       for (i = 0; i < read_data->size; i++) {
> 	>       >               printf("%02x", read_data->buffer[i]);
> 	>       >       }
> 	>       >       printf("\n");
> 	>       >
> 	>       >       Esys_Free(read_data);
> 	>       >       rc = 0;
> 	>       >
> 	>       > out:
> 	>       >
> 	>       >       /* remove the NV space */
> 	>       >       if (nv_index) {
> 	>       >               int rc2 = Esys_NV_UndefineSpace(
> 	>       >                       ectx,
> 	>       >                       ESYS_TR_RH_OWNER,
> 	>       >                       nv_index,
> 	>       >                       ESYS_TR_PASSWORD,
> 	>       >                       ESYS_TR_NONE,
> 	>       >                       ESYS_TR_NONE);
> 	>       >               if (rc2 != TSS2_RC_SUCCESS) {
> 	>       >                       printf("Esys_NV_UndefineSpace Failed: 0x%x\n", rc2);
> 	>       >                       rc = 1;
> 	>       >               }
> 	>       >       }
> 	>       >
> 	>       >       Esys_Finalize(&ectx);
> 	>       >
> 	>       >         printf("Exit from nv_write_read()\n");
> 	>       >       return rc;
> 	>       > }
> 	>       > _______________________________________________
> 	>       > tpm2 mailing list -- tpm2(a)lists.01.org <mailto:tpm2(a)lists.01.org>
> <mailto:tpm2(a)lists.01.org <mailto:tpm2(a)lists.01.org> >
> 	>       > To unsubscribe send an email to tpm2-leave(a)lists.01.org
> <mailto:tpm2-leave(a)lists.01.org>  <mailto:tpm2- <mailto:tpm2->
> 	> leave(a)lists.01.org <mailto:leave(a)lists.01.org> >
> 	>       > %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
> 	>
> 
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [tpm2] Re: NVRAM Write and Read using Esys API(s)
@ 2020-05-18 17:08 Muthukumar S
  0 siblings, 0 replies; 5+ messages in thread
From: Muthukumar S @ 2020-05-18 17:08 UTC (permalink / raw)
  To: tpm2

[-- Attachment #1: Type: text/plain, Size: 30530 bytes --]

Hi Roberts ,

Once again thanks a lot for your guidance.  I have looked in to nv.sh from
the tpm2-tools folder and find out how to use the
tpm2 define , tpm2 write and read it back . Now it is working as expected.
Below are the commands and its output:

root(a)muthu-vb:~/work# ./tpm2_nvdefine -Q -x 0x1000001 -a 0x40000001 -s 32
-t "ownerread|policywrite|ownerwrite"

root(a)muthu-vb:~/work#

root(a)muthu-vb:~/work# ./tpm2_nvwrite -Q -x 0x1000001 -a 0x40000001 nv.test_w

root(a)muthu-vb:~/work# ./tpm2_nvread -x 0x1000001 -a 0x40000001

pleafoo23abc

�������������������

root(a)muthu-vb:~/work/tpm2/tpm_evo/install/bin#


Now, i tried used the test application to just read it back from the above*
0x1000001 offset* .  The sample code (pls find attachment)

has read function which uses Esys_NV_Read () api to read the offset.  But
am getting error code with "*70018*"  , i could not able to find much
details from tpm2_rc_decode of this error.


From the debug log (ref attachment : debug_log.txt)  , i could see "Esys
handle does not exist" (70018). What i suppose to do to get this handle and
make Esys_NV_Read () successfully read from already defined offset ?


Previous to this error , i was getting 0x12f (which is nothing but
TPM2_RC_AUTH_UNAVAILABLE) . So what i did was , i given the 'authHandle =
0x40000001" and set this value as second argument

of Esys_NV_Read Api  . After doing that , am getting this "Esys handle does
not exist" (70018)   error , let me know what am i missing here. Attached
"log file" as well for your reference along with test code.


Also tried to "nv_define" once again and then try to read it back . Since
it doesn't make sense, because we have already defined using command line
 and written data in to it.

So i believe there is no point in doing nv define and then reading it back
. Hope nv_define is not required here ?


*NOTE *: This test code also have "get_random number" and , "nv_write"
functions implemented . As i said to you earlier , i want to generate
random number and then write in to nvram and read it back .  Since the
"nv_read" itself not happening by which the offset was already well defined
and data already written in to it using command line tool API , i could not
able to proceed further.



BR,

Muthukumar









On Fri, May 15, 2020 at 8:24 PM Roberts, William C <
william.c.roberts(a)intel.com> wrote:

> > -----Original Message-----
> > From: Muthukumar S [mailto:muthu.smk(a)gmail.com]
> > Sent: Friday, May 15, 2020 7:58 AM
> > To: Roberts, William C <william.c.roberts(a)intel.com>
> > Cc: tpm2(a)lists.01.org
> > Subject: Re: [tpm2] NVRAM Write and Read using Esys API(s)
> >
> > Hi Williams C,
> > Thanks for your quick response. As you suggested , i have tried below
> options
> >
> > I tried to get the index of nvram of sim that am working using
> tpm2_getcap tools
> > API .Bellow are the tpm2_getcap capabilities that i found by reading the
> > tpm2_getcap code . Request you to share me some pointers of using
> > tpm2_getcap() .
> >
> >
> >
> > Available capability from tpm2_getcap.c
> >
> >         .capability_string = "algorithms"
> >
> >         .capability_string = "commands"
> >
> >         .capability_string = "properties-fixed",
> >
> >         .capability_string = "properties-variable",
> >
> >         .capability_string = "ecc-curves",
> >
> >         .capability_string = "handles-transient",
> >
> >         .capability_string = "handles-persistent",
> >
> >         .capability_string = "handles-permanent",
> >
> >         .capability_string = "handles-pcr",
> >
> >         .capability_string = "handles-nv-index",
> >
> >         .capability_string = "handles-loaded-session",
> >
> >         .capability_string = "handles-saved-session",
> >
> >
> >
> >
> > In the above list , i tried all "capability string " but i could't able
> to see the below
> > output given by tpm2_nvlist (which i used to get with different
> tpm-tools version
> > that i used earlier) .
> >
>
> Put the tool in a debugger and look at the arguments passed to
> Esys_GetCapability and mimic it.
> It's time you learn how to fish.
>
> >
> >
> >
> > # tpm2_nvlist
> >
> > O/P
> >
> > 1 NV indexes defined.
> >
> >  0. NV Index: 0x1500015
> >
> >  {
> >
> >  Hash algorithm(nameAlg):11
> >
> > The Index attributes(attributes):0x64014001
> >
> >        The size of the data area(dataSize):32
> >
> >           }
> >
> >
> >
> >
> > 1) Even though this tpm2_nvlist that was there in my current tpm2-tools
> version
> > (tpm2-tools-3.X) ,by which it is not showing me any output .
> >
> > #tpm2_nvlist
> >
> > #
> >
>
> I don't know if your trying to ask something here, are you?
>
> >
> >
> >
> >
> >
> >
> > 2) Tried get_cap of "handles-permanent" , which shows me below values as
> > shown below , but not sure how to get the index of particular tpm bank
>
> Banks are for PCRs, ie PCR0 can have a SHA1 and SH256 bank.
>
> >
> > #/tpm2/tpm_evo/tpm2-tools-3.X/tools# ./tpm2_getcap --capability="handles-
> > permanent"
>
> Stop using 3.X its deprecated, grab the latest 4.X release and build it.
> The tools actually work.
>
> >
> > 0x40000001
> >
> > 0x40000007
> >
> > 0x40000009
> >
> > 0x4000000a
> >
> > 0x4000000b
> >
> > 0x4000000c
> >
> > 0x4000000d
>
> Those are not NV handles, NV Handles start with 0x10
>
> >
> >
> >
> >
> > 2)Also tried reading pcr list using tpm2_getcap . Is the below offset(s)
> are stands
> > for ?
> >
> > # ./tpm2_getcap --capability="handles-pcr"
>
> Again, NV Indexes ARE NOT PCR's.
>
> >
> > 0x00000000
> >
> > 0x00000001
> >
> > 0x00000002
> >
> > 0x00000003
> >
> > 0x00000004
> >
> > 0x00000005
> >
> > 0x00000006
> >
> > 2.1) Request you to share me few points on how to use the "tpm2_getcap()
> and
> > get the offset ?
> >
>
> Debuggers are your friend.
>
> >
> >
> > Since none of the above tools API helped me or am i missing some thing
> to read
> > the output of NVRAM index ?
>
> I would upgrade to newer tools. If you must stay in the 3.X land, then
> copy what the test
> scripts are doing, they do it completely. Look for nv.sh.
>
> >
> > 3) Without knowing the offset , tried to define offset from 0x1500015
> and trying
> > to write and read back , here nvdefine works along with nvwrite ..but
> nvread fails
> > with "auth" issue. Please refere below sequence and associated errors
> >
> >
> > 3.1) Tried defining nvram using tpm2_nvdefine - Succeeded with out any
> error  --
> > given -a 0x40000001 (TPM_RH_OWNER Access) , if i define with 0x4000000C
> > (TPM_RH_OWNER , i got the same result during tpm2_nvread . Here removing
> "-t
> > 0x2000A" option and then doing nvdefine also throws me the same error
> shown
> > in point 3.3 during nvread
> >
> > #./tpm2_nvdefine -x 0x1500016 -a 0x40000001 -s 32 -t 0x2000A
>
> Offhand, I don't know what the 0x2000A mask is, so I would have to look it
> up, but I am not going to.
> Use string masks.
>
> If you just upgrade to a 4.x tools, it should work. I remember some issues
> with attributes on the 3.X branch
> Tools.
>
> >
> > #
> >
> >
> >
> >
> > 3.2) Tried NVWRITE in the same offset 0x1500015  - Succeeded without any
> error
> >
> > # ./tpm2_nvwrite -x 0x1500015 -L test_helloworld
> >
> > #
> >
> >
> >
> >
> > 3.3) Reading back the same offset -x1500015 , which throws below error
> stating
> > TPM2_RC_NV_UNINITIALIZED. Since i have initialized it as said above
> point 3.1  ,
> > what am i missing here ?
>
> Upgrade your tools, and the example I showed yesterday should work.
>
> >
> >
> >
> >
> > Below are the OPTIONS I have by tpm2_nvread:
> >
> > as you suggested  to use (echo `tpm2_nvread -C o -s5 0x1500015` command)
> >
> > I cant see -C (this might be due to tools version 3.X ? . If it is not
> the latest , can't
> > we able to use the below APIs ?
> >
> >
> >
> >
> > # ./tpm2_nvread
> >
> > Usage: tpm2_nvread [<options>]
> >
> > Where <options> are:
> >
> >     [ -x | --index=<value>] [ -a | --auth-handle=<value>] [ -f |
> --output=<value>] [
> > -s | --size=<value>]
> >
> >     [ -o | --offset=<value>] [ -P | --handle-passwd=<value>] [ -S |
> --input-session-
> > handle=<value>] [ -L | --set-list=<value>]
> >
> >     [ -F | --pcr-input-file=<value>]
> >
> >
> >
> >
> > # ./tpm2_nvread -x 0x1500015 -a 0x40000001 -s 32
> >
> > ERROR: Failed to read NVRAM area at index 0x1500015 (22020117).
> Error:0x14a
> >
> > ERROR: Unable to run ./tpm2_nvread
> >
> >
> >
> >
> > # tpm2_rc_decode 0x14a
> >
> > error layer
> >
> >   hex: 0x0
> >
> >   identifier: TSS2_TPM_RC_LAYER
> >
> >   description: Error produced by the TPM
> >
> > format 0 error code
> >
> >   hex: 0x4a
> >
> >   name: TPM2_RC_NV_UNINITIALIZED
> >
> >   description: an NV Index is used before being initialized or the state
> saved by
> > TPM2_Shutdown(STATE) could not be restored
> >
> >
> >
> >
> > 3.4) Tried reading the same offset 0x1500015 without giving '-a'
> > (TPM2_RH_OWNER) access , but the results shown NV_AUTHORIZATION. So i
> > understood
> >
> > if we defined with -a auth permission then we need to give the same
> permission
> > while reading the content from the same offset. Is my understanding is
> correct ?
> >
> >
> >
> >
> > # ./tpm2_nvread -x 0x1500015 -s 32
> >
> >
> > ERROR: Failed to read NVRAM area at index 0x1500015 (22020117).
> Error:0x149
> > ERROR: Unable to run ./tpm2_nvread
> >
> >
> > # tpm2_rc_decode 0x149
> > error layer
> >   hex: 0x0
> >   identifier: TSS2_TPM_RC_LAYER
> >   description: Error produced by the TPM format 0 error code
> >   hex: 0x49
> >   name: TPM2_RC_NV_AUTHORIZATION
> >   description: NV access authorization fails in command actions (this
> failure does
> > not affect lockout.action)
> >
> >
> >
> >
> >
> > 4) Tried to use tpm2_readpublic to read above written offset 0x1500015 ,
> getting
> > 0x184 (value is out of range or is not correct for the context) what am
> i missing
> > here ?
> >
> > # ./tpm2_readpublic
> > Usage: tpm2_readpublic [<options>]
> > Where <options> are:
> >     [ -H | --object=<value>] [ -o | --opu=<value>] [ -c |
> --context-object=<value>]
> > [ -f | --format=<value>]
> >
> >
> >
> >
> > # ./tpm2_readpublic -H 0x1500015
> > ERROR: TPM2_ReadPublic error: rval = 0x184
> > ERROR: Unable to run ./tpm2_readpublic
> > root(a)muthu-vb:~/work/tpm2/tpm_evo/install/bin# ./tpm2_readpublic -H
> > 0x1500015 --opu file
> > ERROR: TPM2_ReadPublic error: rval = 0x184
> > ERROR: Unable to run ./tpm2_readpublic
> > root(a)muthu-vb:~/work/tpm2/tpm_evo/install/bin# ./tpm2_rc_decode 0x184
> > error layer
> >   hex: 0x0
> >   identifier: TSS2_TPM_RC_LAYER
> >   description: Error produced by the TPM
> > format 1 error code
> >   hex: 0x04
> >   identifier: TPM2_RC_VALUE
> >   description: value is out of range or is not correct for the context
> > handle
> >   hex:0x100
> >   identifier:  TPM2_RC_1
> >   description:  (null)
> >
> >
> >
> > #
> >
> >
> >
> >
> >
> > 5)Tried releasing the same offset using nvrelease that too works fine
> >
> > #./tpm2_nvrelease -x 0x1500015 -a 0x40000001
> >
> > #
> >
> >
> >
> >
> > As per my request raised by yesterday . I need to define an offset in nv
> ram then
> > write content only once and read it back when ever required.  During
> every
> > second write , i need to read the offset (you suggested to use
> > tpm2_nvreadpubic() , but i struck with usage of this "nvread public api"
> command
> > as well (results are just shown above)
> >
> >
> >
> >
> > As per today's experiments , i cant able able to achieve the (nvread)
> using
> > command line API . Let me know what am i missing here .
> >
> >
> >
> >
> > Looking forward for your valuable reply.
> >
> >
> >
> >
> > Thanks,
> >
> > Muthukumar
> >
> >
> >
> >
> >
> >
> >
> > On Thu, May 14, 2020 at 12:51 AM Roberts, William C
> > <william.c.roberts(a)intel.com <mailto:william.c.roberts(a)intel.com> >
> wrote:
> >
> >
> >       > -----Original Message-----
> >       > From: muthu.smk(a)gmail.com <mailto:muthu.smk(a)gmail.com>
> > [mailto:muthu.smk(a)gmail.com <mailto:muthu.smk(a)gmail.com> ]
> >       > Sent: Wednesday, May 13, 2020 12:51 PM
> >       > To: tpm2(a)lists.01.org <mailto:tpm2(a)lists.01.org>
> >       > Subject: [tpm2] NVRAM Write and Read using Esys API(s)
> >       >
> >       > Hi Williams,
> >       >
> >       > I am using the test code used to read and write in to NV ram.  I
> am
> > facing below
> >       > challenges if i tried to read already written data from NVRAM.
> >       >
> >       > 1) Test code attached defined create the context (ectx) , create
> random
> > number ,
> >       > define NV ram , write the random number in to NVRAM (offset
> > 0x1000001) and
> >       > read it back from NV Ram (from same offset 0x1000001)
> >       >
> >       > 2) But if i try to run this code twice or thrise , am getting
> below NVRAM
> > already
> >       > defined rc code. I can understand that we should not defined the
> nv
> > ram space
> >       > which already defined and used.
> >       > How to avoid this ? by defining nvram ONLY once and write it ONLY
> > once and
> >       > finally read it AS MUCH times we want ?  Below details are
> related to
> > this request
> >
> >       You can call Esys_GetCapability() and see what NV indices are
> defined.
> > The command
> >       Line tool tpm2_getcap does this, like so:
> >       tpm2_getcap handles-nv-index
> >
> >       You can use that tool as an example of how to do it.
> >
> >       >
> >       > Error code:
> >       > 0x0000014c - description: NV Index or persistend object already
> defined
> >       > 0x00000284 - description: value is out of range or is not
> correct for the
> > context
> >       >
> >       > 3) Query is : is it possible to define nvram "ONLY ONCE" with
> the API
> > shared the
> >       > test code and then create a function "createrandom" number to use
> > the same
> >
> >       Call getcap, see if it's defined, if defined, don't define it....
> >
> >       > context (ects) to generate randumnumber then call separate
> > "write_nvram"
> >       > function with random number as input and ask to write in the same
> > offset .
> >       > Finally calling another function "read_nvram" to read it back
> from the
> > same
> >       > nvram's offset when ever we want ? i tried this approach but am
> > getting segfault
> >       > with above error .
> >       > What am i missing here ?
> >
> >       Segfaults are likely your code is just broken.
> >
> >       >
> >       > 3.1) Ideally in single application , i need to achieve
> "tpm2_nvdefine",
> >       > "tpm2_nvwrite" and "tpm2_nvread() tools API(s) functionality" in
> > different calls
> >       > or flow.
> >       > 3.2) Also how to check whether "write" already done (i tried
> checking
> > nv_index is
> >       > true - means whether it already has some value) , but it failed ?
> >
> >       If you do what the tool tpm2_nvreadpublic does, you can check for
> the
> > written bit.
> >
> >       >
> >       > 4) Also how to check what was the content that already present
> in the
> > nvram
> >       > offset (0x1000001) before i do write the "random number" second
> time
> > in to the
> >       > same offset ? this is to ensure the "random number" that i am
> planning
> > to write
> >       > was valid one ?
> >
> >       Read it out, if it's not what you want, write it.
> >
> >       >
> >       > I remember studying that, once u write in to NVRAM offset , we
> cant
> > able to RE-
> >       > WRITE it in the same offset(0x1000001). Whether that is the same
> case
> > for
> >       > SIMULATOR as well (or) this feature is only for real tpm
> hardware?
> >
> >       No generally you can write as many times as you want... there are
> tricks
> > you can do to make
> >       It locked after write (writelocked iirc)
> >
> >       Below is a command line example of doing it...
> >
> >       tpm2_nvdefine
> >       nv-index: 0x1000000
> >
> >       tpm2_nvreadpublic 0x1000000
> >       0x1000000:
> >         name:
> > 000b1195f36a21c8219055ad0803c39e7e81d06cdb2eee2b7cf93dd83e01d4273828
> >         hash algorithm:
> >           friendly: sha256
> >           value: 0xB
> >         attributes:
> >           friendly: ownerwrite|authwrite|ownerread|authread
> >           value: 0x6000600
> >         size: 2048
> >
> >       # you can do this as much as you want, but it can wear the memory
> in the
> > TPM
> >       # depending on memory technology the vendor used.
> >       echo "hello" | tpm2_nvwrite -C o 0x1000000 -i-
> >       echo `tpm2_nvread -C o -s5 0x1000000`
> >       hello
> >
> >       tpm2_nvreadpublic 0x1000000
> >       0x1000000:
> >         name:
> > 000b287c9b1b06fab6e51bd26e98ea89460574e97a3d2ef995eb35f7e23db7e94f67
> >         hash algorithm:
> >           friendly: sha256
> >           value: 0xB
> >         attributes:
> >           friendly: ownerwrite|authwrite|ownerread|authread|written
> >           value: 0x6000620
> >         size: 2048
> >
> >       >
> >       > 6)After nvwrite i tried to use "tpm2_pcrlist" command line tool
> > application, by
> >       > which it shows the nv ram memory location , tried using
> tpm2_nvread ()
> > to read
> >       > the content but i could not able to see any data (random number)
> that i
> > used to
> >       > write via this test application . dont know why ?
> >
> >       tpm2_pcrlist is not for NVs.... you want:
> >       tpm2_getcap handles-nv-index
> >
> >       >
> >       > 7) After i manually ran the below clear API , now the test code
> is
> > working fine
> >       > (refer Test code log shown below..). This confirms we can
> reallocate
> > already
> >       > defined nv ram memory.
> >       > #tpm2_nvrelease -x 0x1000001 -a 0x40000001
> >
> >       Tpm2_clear will clear the owner hierarchy, including NV ram objects
> > declared in that hierarchy,
> >       so define will work again, because you deleted it.
> >
> >       >
> >       >
> >       > 8)If i try to read it manually via below tpm2_nvread command with
> > offset
> >       > 0x1000001 am getting below error
> >       >
> >       > #tpm2_nvread -x 0x1000001 -a 0x40000001 -o 0 -s 20
> >       > ERROR: Failed to read NVRAM public area at index 0x1000001
> > (16777217).
> >       > Error:0x18b
> >       > ERROR: Unable to run tpm2_nvread
> >       >
> >       > /* Tried to use below tools command , am always getting the same
> > error even if
> >       > we give the different nvram off set tpm2_nvwrite -x 0x1c00002
> > helloworld
> >       > ERROR: Reading the public part of the nv index failed with: 0x18b
> >       > ERROR: Unable to run tpm2_nvwrite
> >       >
> >       > tpm2_nvwrite -x 0x1c00012 -a 0x40000001 helloworld
> >       > ERROR: Reading the public part of the nv index failed with: 0x18b
> >       > ERROR: Unable to run tpm2_nvwrite
> >       >
> >       >
> >       > /* Try to read the nvlist of SIM , it returns nothing !!!
> >       > #tpm2_nvlist <returns nothing>
> >       >
> >       > Any points will be great help for me.
> >       >
> >       >
> ---------------------------------------------------------------------------------------
> > ------------
> >       > --------------------------------------------------------------
> >       > Test code log after above "tpm2_nvrelease":
> >       > Initializing
> >       > init_rand()
> >       > init_rsa()
> >       > init_ecc()
> >       > Engine name: TPM2-TSS engine for OpenSSL
> >       > Init result: 1
> >       > Setting owner auth to empty auth.
> >       > Setting parent auth to empty auth.
> >       >
> ERROR:tcti:src/tss2-tcti/tcti-device.c:440:Tss2_Tcti_Device_Init() Failed
> > to open
> >       > device file /dev/tpm0: No such file or directory
> >       > WARNING:tcti:src/tss2-tcti/tctildr.c:62:tcti_from_init() TCTI
> init for
> > function
> >       > 0x7fc67376d18b failed with a000a
> >       > WARNING:tcti:src/tss2-tcti/tctildr.c:92:tcti_from_info() Could
> not
> > initialize TCTI
> >       > named: tcti-device
> >       > ERROR:tcti:src/tss2-tcti/tctildr-dl.c:150:tcti_from_file() Could
> not
> > initialize TCTI
> >       > file: libtss2-tcti-default.so
> >       >  No of bytes written by GenRandom : 64
> >       >
> > b6c9e1d028f2c893c56a089165f9f38c09232180ba5bb66b35c5652cb51ab61b237ecfe
> >       > 8ece5d7f14a3323fee1dca0e641a0f20c7689100e3c804b82d6a2497f
> >       > Created NV Index: 0x1000001
> >       > ESYS_TR: 0x418367
> >       > ESYS_TR2: 0x418368
> >       > Writing the random number written in NV Ram
> >       > Data buffer size used to write into NVRam: 64
> >       > Reading the random number written in NV Ram
> >       >
> > b6c9e1d028f2c893c56a089165f9f38c09232180ba5bb66b35c5652cb51ab61b237ecfe
> >       > 8ece5d7f14a3323fee1dca0e641a0f20c7689100e3c804b82d6a2497f
> >       > *** SUCCESS ***
> >       > ---------------------
> >       >
> >       > TEST CODE :
> >       >
> >       > int nv_write_read()
> >       > {
> >       >
> >       >       ESYS_CONTEXT *ectx = NULL;
> >       >
> >       >       ESYS_TR nv_index = 0;
> >       >       ESYS_TR nv_index2 = 0;
> >       >
> >       >        int rc = 1;
> >       >
> >       >
> >       >       /*
> >       >        * create a connection to the TPM letting ESAPI choose how
> to get
> > there.
> >       >        * If you need more control, you can use tcti and tcti-ldr
> libraries to
> >       >        * get a TCTI pointer to use for the tcti argument of
> Esys_Initialize.
> >       >        */
> >       >       rc = Esys_Initialize(&ectx,
> >       >                       NULL,  // let it find the TCTI
> >       >                       NULL); // Use whatever ABI
> >       >       if (rc != TSS2_RC_SUCCESS) {
> >       >               printf("Esys_Initialize Failed: 0x%x\n", rc);
> >       >               return 1;
> >       >       }
> >       >
> >       >
> >       >         rc = Esys_GetRandom(ectx,
> >       >                         ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
> >       >                         64, &bytes);
> >       >         if (rc != TSS2_RC_SUCCESS) {
> >       >                 printf("Esys_GetRandom Failed: %s\n",
> Tss2_RC_Decode(rc));
> >       >                 exit(1);
> >       >         }
> >       >
> >       >       printf(" No of bytes written by GenRandom :
> %d\n",bytes->size);
> >       >       size_t i;
> >       >       for (i = 0; i < bytes->size; i++) {
> >       >               printf("%02x", bytes->buffer[i]);
> >       >       }
> >       >
> >       >       printf("\n");
> >       >
> >       >       /* build a template for the NV index */
> >       >       TPM2B_NV_PUBLIC pub_templ = {
> >       >               /* this is counter intuitive, but it tells the
> TSS2 library to calculate
> >       > this for us */
> >       >               .size = 0,
> >       >               /* The things that define what NV index we are
> creating */
> >       >               .nvPublic = {
> >       >                       /* uses sha256 to identify the tpm object
> by name */
> >       >                       .nameAlg = TPM2_ALG_SHA256,
> >       >                       /* allows the owner password or index
> password r/w
> >       > access */
> >       >                       .attributes = TPMA_NV_OWNERWRITE |
> >       >                               TPMA_NV_OWNERREAD            |
> >       >                               TPMA_NV_AUTHWRITE            |
> >       >                               TPMA_NV_AUTHREAD,
> >       >                       /* can hold 64 bytes of data */
> >       >                       .dataSize = 64,
> >       >                       /* Create at NV Index 1 or 0x1000001 */
> >       >                       .nvIndex = TPM2_HR_NV_INDEX + 1
> >       >               },
> >       >       };
> >       >
> >       >
> >       >       /* Ok, define the space and store the nv_index for future
> use */
> >       >       rc = Esys_NV_DefineSpace(
> >       >           ectx,
> >       >               ESYS_TR_RH_OWNER, /* create an NV index in the
> owner
> >       > hierarchy */
> >       >           ESYS_TR_PASSWORD, /* auth as the owner with a password,
> > which is
> >       > empty */
> >       >           ESYS_TR_NONE,
> >       >           ESYS_TR_NONE,
> >       >           NULL,
> >       >           &pub_templ,
> >       >           &nv_index);
> >       >       if (rc != TSS2_RC_SUCCESS) {
> >       >               printf("Esys_NV_DefineSpace Failed: 0x%x\n", rc);
> >       >               goto out;
> >       >       }
> >       >
> >       >       /* Note if you need to set the owner hierarchy auth value
> you use:
> >       >        * TSS2_RC Esys_TR_SetAuth(
> >       >        *     ESYS_CONTEXT *esysContext,
> >       >          *     ESYS_TR handle,
> >       >          *     TPM2B_AUTH const *authValue);
> >       >        */
> >       >
> >       >       printf("Created NV Index: 0x%x\n",
> pub_templ.nvPublic.nvIndex);
> >       >       printf("ESYS_TR: 0x%x\n", nv_index);
> >       >
> >       >       /*
> >       >        * Note: if we need to convert the nvIndex into an
> ESYS_TR, the
> > below
> >       > will
> >       >        * do it. Its not required for this case, since
> Esys_NV_Define gives us
> > an
> >       >        * ESYS_TR.
> >       >        */
> >       >       rc = Esys_TR_FromTPMPublic(
> >       >               ectx,
> >       >               TPM2_HR_NV_INDEX + 1,
> >       >               ESYS_TR_NONE,
> >       >               ESYS_TR_NONE,
> >       >               ESYS_TR_NONE,
> >       >               &nv_index2);
> >       >       if (rc != TSS2_RC_SUCCESS) {
> >       >               printf("Esys_TR_FromTPMPublic Failed: 0x%x\n", rc);
> >       >               goto out;
> >       >       }
> >       >
> >       >       printf("ESYS_TR2: 0x%x\n", nv_index2);
> >       >
> >       >       /* copy some data into a buffer to send to the TPM */
> >       >       TPM2B_MAX_NV_BUFFER write_data = { 0 };
> >       >       memcpy(write_data.buffer, bytes->buffer, bytes->size);
> >       >       write_data.size = bytes->size;
> >       >
> >       >       printf("Writing the random number written in NV Ram\n");
> >       >       printf("Data buffer size used to write into NVRam:
> >       > %d\n",write_data.size);
> >       >       /*
> >       >        * Write the data to the TPM NV index at offset 0
> >       >        */
> >       >       rc = Esys_NV_Write(
> >       >           ectx,
> >       >           nv_index, /* authenticate to the NV index using the NV
> index
> >       > password */
> >       >           nv_index, /* the nv index to write to */
> >       >           ESYS_TR_PASSWORD,
> >       >               ESYS_TR_NONE,
> >       >               ESYS_TR_NONE,
> >       >           &write_data,
> >       >           0);
> >       >       if (rc != TSS2_RC_SUCCESS) {
> >       >               printf("Esys_NV_Write Failed: 0x%x\n", rc);
> >       >               goto out;
> >       >       }
> >       >
> >       >       /* Read the data back, and just for fun, we will use
> nv_index2
> >       >        * to prove it's pointing to the same NV location in the
> TPM.
> >       >        */
> >       >       TPM2B_MAX_NV_BUFFER *read_data = NULL;
> >       >       rc = Esys_NV_Read(
> >       >           ectx,
> >       >           nv_index2, /* authenticate to the NV index using the
> NV index
> >       > password */
> >       >           nv_index2, /* the nv index to read from */
> >       >           ESYS_TR_PASSWORD,
> >       >           ESYS_TR_NONE,
> >       >           ESYS_TR_NONE,
> >       >           bytes->size,
> >       >           0,
> >       >           &read_data);
> >       >       if (rc != TSS2_RC_SUCCESS) {
> >       >               printf("Esys_NV_Read Failed: 0x%x\n", rc);
> >       >               goto out;
> >       >       }
> >       >
> >       >       /* Print things as a string from the TPM carefully!
> >       >        * Injected traffic via MITM means that you cannot trust
> this
> >       >        * to be null terminated.
> >       >        */
> >       >       printf("Reading the random number written in NV Ram\n");
> >       >       for (i = 0; i < read_data->size; i++) {
> >       >               printf("%02x", read_data->buffer[i]);
> >       >       }
> >       >       printf("\n");
> >       >
> >       >       Esys_Free(read_data);
> >       >       rc = 0;
> >       >
> >       > out:
> >       >
> >       >       /* remove the NV space */
> >       >       if (nv_index) {
> >       >               int rc2 = Esys_NV_UndefineSpace(
> >       >                       ectx,
> >       >                       ESYS_TR_RH_OWNER,
> >       >                       nv_index,
> >       >                       ESYS_TR_PASSWORD,
> >       >                       ESYS_TR_NONE,
> >       >                       ESYS_TR_NONE);
> >       >               if (rc2 != TSS2_RC_SUCCESS) {
> >       >                       printf("Esys_NV_UndefineSpace Failed:
> 0x%x\n", rc2);
> >       >                       rc = 1;
> >       >               }
> >       >       }
> >       >
> >       >       Esys_Finalize(&ectx);
> >       >
> >       >         printf("Exit from nv_write_read()\n");
> >       >       return rc;
> >       > }
> >       > _______________________________________________
> >       > tpm2 mailing list -- tpm2(a)lists.01.org <mailto:tpm2(a)lists.01.org
> >
> >       > To unsubscribe send an email to tpm2-leave(a)lists.01.org <mailto:
> tpm2-
> > leave(a)lists.01.org>
> >       > %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
> >
>
>

[-- Attachment #2: attachment.htm --]
[-- Type: text/html, Size: 51539 bytes --]

[-- Attachment #3: test_nv_read.c --]
[-- Type: application/octet-stream, Size: 14161 bytes --]

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/engine.h>
#include <string.h>
#include <assert.h>
#include <tss2/tss2_mu.h>
#include <tss2/tss2_esys.h>
#include <tpm2-tss-engine.h>
#include <tss2/tss2_tcti.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ERR printf
ESYS_TR authHandle = 0x40000001;

struct optn {
    const char *filename; /*added const for tpmread*/
    char *rnd_filename;

    TPMI_ALG_PUBLIC alg;
    TPMI_ECC_CURVE curve;
    int exponent;
    char *ownerpw;
    char *password;
    TPM2_HANDLE parent;
    char *parentpw;
    int keysize;
    int verbose;
}opt;

TPM2B_NV_PUBLIC pub_templ = {
/* this is counter intuitive, but it tells the TSS2 library to calculate this for us */
        .size = 0,
        /* The things that define what NV index we are creating */
        .nvPublic = {
                /* uses sha256 to identify the tpm object by name */
                .nameAlg = TPM2_ALG_SHA256,
                /* allows the owner password or index password r/w access */
                .attributes = TPMA_NV_OWNERWRITE |
                        TPMA_NV_OWNERREAD        |
                        TPMA_NV_AUTHWRITE        |
                        TPMA_NV_AUTHREAD,
                /* can hold 64 bytes of data */
                .dataSize = 64,
                /* Create at NV Index 1 or 0x1000001 */
                .nvIndex = TPM2_HR_NV_INDEX + 1
        },
};

TPM2B_DIGEST *get_randnum(ESYS_CONTEXT *ectx , TPM2B_DIGEST *rand_bytes); 
ESYS_TR define_nvram(ESYS_CONTEXT *ectx , ESYS_TR nv_index);

TPM2_DATA *tpm2Data = NULL;
RSA *rsa = NULL;
ESYS_CONTEXT *ectx=NULL;
TPM2B_DIGEST *rand_bytes = NULL;
TPM2B_DIGEST *rand_bytes_buffer = NULL;
TPM2B_DIGEST *data = NULL;
ESYS_TR nv_index = 0;
ESYS_TR st_index = 0;
ESYS_TR from_index = 0;
ESYS_TR base_index = 0;
ESYS_TR nv_index2 = 0;
TPM2B_MAX_NV_BUFFER *read_buff = NULL;
TPM2B_MAX_NV_BUFFER write_data = { 0 } ;
int nv_read(ESYS_CONTEXT *ectx,TPM2B_DIGEST *bytes_to_read, TPM2B_MAX_NV_BUFFER *read_buff);
TPM2B_MAX_NV_BUFFER nv_write(ESYS_CONTEXT *ectx , TPM2B_DIGEST *rand_bytes , ESYS_TR from_index);

int main(void)
{  

    EVP_PKEY *tpm_evp_pkey=NULL;
    
    /* set the default values */
    opt.filename = "./priv_key_2048";
    opt.alg = TPM2_ALG_RSA;
    opt.curve = TPM2_ECC_NIST_P256;
    opt.exponent = 65537;
    opt.ownerpw = NULL;
    opt.password = NULL;
    opt.parent = 0;
    opt.parentpw = NULL;
    opt.keysize = 2048;
    opt.verbose = 0;
    FILE *fptr;

    /* Initialize the tpm2-tss engine */
    ENGINE_load_dynamic();

    /* Openssl 1.1.0 requires the lib-prefix for the engine_id */
    ENGINE *tpm_engine = ENGINE_by_id("tpm2tss");
    if (!tpm_engine)
        tpm_engine = ENGINE_by_id("libtpm2tss");
    if (tpm_engine == NULL) {
        ERR("Could not load tpm2tss engine\n");
        return 1;
    }

    int init_res = ENGINE_init(tpm_engine);
    printf("Engine name: %s\nInit result: %d \n", ENGINE_get_name(tpm_engine),
         init_res);
    if (!init_res)
        return 1;

    if (!ENGINE_ctrl(tpm_engine, TPM2TSS_SET_OWNERAUTH, 0, opt.ownerpw, NULL)) {
        ERR("Could not set ownerauth\n");
        return 1;
    }

    if (!ENGINE_ctrl(tpm_engine, TPM2TSS_SET_PARENTAUTH, 0, opt.parentpw, NULL)) {
        ERR("Could not set parentauth\n");
        return 1;
    }

#if 0 
    /* Defining NVRAM */
    printf("Defining NVRAM space to store randomnum\n");
    base_index = define_nvram(ectx, st_index);
#endif
    
    /* Reading already stored data from NVRAM*/
    printf("READ RandomNumber from NVRAM from offset 0x1000001\n");
    nv_read(ectx,rand_bytes,read_buff);

    Esys_Finalize(&ectx);
    printf("*** NVWrite & NVReadCompleted !!!***\n");
    return 0;
}

/*
 *Read the random number data already stored from NVRAM
 *
 */
int nv_read(ESYS_CONTEXT *ectx,TPM2B_DIGEST *bytes_to_read, TPM2B_MAX_NV_BUFFER *read_buff)
{
    printf("Inside nv_read()\n");
    int rc , i;
    
    printf("Created NV Index: 0x%x\n", pub_templ.nvPublic.nvIndex);
    printf("ESYS_TR: 0x%x\n", nv_index);
    //if(nv_index == NULL)
    if(pub_templ.nvPublic.nvIndex != NULL)
    {
	        rc = Esys_Initialize(&ectx,
                        NULL,  // let it find the TCTI
                        NULL); // Use whatever ABI
                if (rc != TSS2_RC_SUCCESS) {
                        //fprintf(stderr, "Esys_Initialize: 0x%x\n", rc);
                        printf("Esys_Initialize Failed and its associated error code: 0x%x\n", rc);
                        return 1;
                }
#if 1
                /*
                * Note: if we need to convert the nvIndex into an ESYS_TR, the below will
                * do it. It may not required for this case, since Esys_NV_Define gives us an
                * ESYS_TR.
                */
                rc = Esys_TR_FromTPMPublic(
                        ectx,
                        TPM2_HR_NV_INDEX + 1,
                        ESYS_TR_NONE,
                        ESYS_TR_NONE,
                        ESYS_TR_NONE,
                        &nv_index2);

                if (rc != TSS2_RC_SUCCESS) {
                        printf("Esys_TR_FromTPMPublic: 0x%x\n", rc);
                        goto out;
                }

                printf("ESYS_TR2: 0x%x\n", nv_index2);
#endif  
                TPM2B_MAX_NV_BUFFER *read_data = NULL;
                rc = Esys_NV_Read(
                ectx,
		authHandle,
                //nv_index2, /* authenticate to the NV index using the NV index password */
                nv_index2, /* the nv index to read from */
                ESYS_TR_PASSWORD,
                ESYS_TR_NONE,
                ESYS_TR_NONE,
		20,
                //bytes_to_read->size,
                0,
                &read_data);
                if (rc != TSS2_RC_SUCCESS) {
                        printf("Esys_NV_Read <ERROR>: 0x%x\n", rc);
                	goto out;
		}

                /* Print things as a string from the TPM carefully!
                * Injected traffic via MITM means that you cannot trust this
                * to be null terminated.
                */

                printf(" No of bytes(Random number) read from NVRAM : %d\n",read_buff->size);
                for (i = 0; i < 10; i++) {
                        printf("%02x", read_data->buffer[i]);
                }
                printf("\n");
    }
    else
    {
	printf("No data avaiable in this NVRAM offset (index) ox%x\n",pub_templ.nvPublic.nvIndex);
    }

	Esys_Free(read_buff);

out :
	/* Clearing ESYS at the end of NVREAD , need to check whether it is the right place do it\n); */
        Esys_Finalize(&ectx);

        printf("Exit from nv_read()\n");
	return 0;
}

/*
 *
 *Define NVRAM space to store the random number generated using tpm
 *
 */
ESYS_TR define_nvram(ESYS_CONTEXT *ectx , ESYS_TR nv_index)
{
               
		printf("Inside define_nvram() to define Space in NVRAM and to store the Random Number into it\n");
		int rc = 1;

		rc = Esys_Initialize(&ectx,
                        NULL,  // let it find the TCTI 
                        NULL); // Use whatever ABI 
                if (rc != TSS2_RC_SUCCESS) {
                        printf("Esys_Initialize Failed and its associated error code: 0x%x\n", rc);
                        return 1;
                }
#if 1
		/* build a template for the NV index */
                TPM2B_NV_PUBLIC pub_templ = {
                /*this is counter intuitive, but it tells the TSS2 library to calculate this for us */
                        .size = 0,
                        /* The things that define what NV index we are creating */
                        .nvPublic = {
                                /* uses sha256 to identify the tpm object by name */
                                .nameAlg = TPM2_ALG_SHA256,
                                /* allows the owner password or index password r/w access */
                                .attributes = TPMA_NV_OWNERWRITE |
                                        TPMA_NV_OWNERREAD        |
                                        TPMA_NV_AUTHWRITE        |
                                        TPMA_NV_AUTHREAD,
                                /* can hold 64 bytes of data */
                                .dataSize = 64,
                                /* Create at NV Index 1 or 0x1000001 */
                                .nvIndex = TPM2_HR_NV_INDEX + 1
                        },
                };
#endif
#if 0
                /*Define the space and store the nv_index for data storage */
                rc = Esys_NV_DefineSpace(
                        ectx,
                        ESYS_TR_RH_OWNER, /* create an NV index in the owner hierarchy */
                        ESYS_TR_PASSWORD, /* auth as the owner with a password, which is empty */
                        ESYS_TR_NONE,
                        ESYS_TR_NONE,
                        NULL,
                        &pub_templ,
                        &nv_index);

                if (rc != TSS2_RC_SUCCESS) {
                        printf("Esys_NV_DefineSpace FAILED: 0x%x\n", rc);
                        goto out;
                }
#endif
                /* Note if we need to set the owner hierarchy auth value need to use:
                * TSS2_RC Esys_TR_SetAuth(
                *     ESYS_CONTEXT *esysContext,
                *     ESYS_TR handle,
                *     TPM2B_AUTH const *authValue);
                */

                printf("Created NV Index: 0x%x\n", pub_templ.nvPublic.nvIndex);
                printf("ESYS_TR: 0x%x\n", nv_index);

                /*
                * Note: if we need to convert the nvIndex into an ESYS_TR, the below will
                * do it.
                */
                rc = Esys_TR_FromTPMPublic(
                        ectx,
                        TPM2_HR_NV_INDEX + 1,
                        ESYS_TR_NONE,
                        ESYS_TR_NONE,
                        ESYS_TR_NONE,
                        &nv_index2);

                if (rc != TSS2_RC_SUCCESS) {
                        printf("Esys_TR_FromTPMPublic <ERROR>: 0x%x\n", rc);
                        goto out;
                
		}

	printf("Exit from define_nvram()\n");
	return nv_index;

out:

        /* remove the NV space */
        if (nv_index) {
                int rc2 = Esys_NV_UndefineSpace(
                        ectx,
                        ESYS_TR_RH_OWNER,
                        nv_index,
                        ESYS_TR_PASSWORD,
                        ESYS_TR_NONE,
                        ESYS_TR_NONE);
                if (rc2 != TSS2_RC_SUCCESS) {
                        printf("Esys_NV_UndefineSpace: 0x%x\n", rc2);
                        rc = 1;
                }
        }

	printf("Error : Exiting from define_nvram()\n");
        return rc;
}

/*
 *Writing random number in to NVRAM offset 0x1000001
 *
 */

TPM2B_MAX_NV_BUFFER nv_write(ESYS_CONTEXT *ectx , TPM2B_DIGEST *rand_bytes , ESYS_TR from_index)
{
      printf("Inside NVWRITE()\n");
      int rc=1;
	  
      /*
      * Note: if we need to convert the nvIndex into an ESYS_TR, the below will
      * do it.
      */
       rc = Esys_TR_FromTPMPublic(
                ectx,
                TPM2_HR_NV_INDEX + 1,
                ESYS_TR_NONE,
                ESYS_TR_NONE,
                ESYS_TR_NONE,
                &nv_index2);

            if (rc != TSS2_RC_SUCCESS) {
                    printf("Esys_TR_FromTPMPublic ERROR: 0x%x\n", rc);
                    goto out;

            }
      
      
      memcpy(write_data.buffer, rand_bytes->buffer, rand_bytes->size);
      write_data.size = rand_bytes->size;

      printf("Data buffer(Random number) size used to write into NVRam: %d\n",write_data.size);
      /*
      * Write the data to the TPM NV index at offset 0
      */
      rc = Esys_NV_Write(
              ectx,
              from_index, /* authenticate to the NV index using the NV index password */
              from_index, /* the nv index to write to */
              ESYS_TR_PASSWORD,
              ESYS_TR_NONE,
              ESYS_TR_NONE,
              &write_data,
      0);
      if (rc != TSS2_RC_SUCCESS) {
              //fprintf(stderr, "Esys_NV_Write: 0x%x\n", rc);
              printf("Esys_NV_Write ERROR------------>: 0x%x\n", rc);
              goto out;
      }

      printf("Exit from NVWRITE()\n");
      
      return write_data;
out:
      /* remove the NV space */
      if (nv_index) {
            int rc2 = Esys_NV_UndefineSpace(
                    ectx,
                    ESYS_TR_RH_OWNER,
                    nv_index,
                    ESYS_TR_PASSWORD,
                    ESYS_TR_NONE,
                    ESYS_TR_NONE);
            if (rc2 != TSS2_RC_SUCCESS) {
                    printf("Esys_NV_UndefineSpace Error: 0x%x\n", rc2);
                    rc = 1;
            }
    }

}

TPM2B_DIGEST *get_randnum(ESYS_CONTEXT *ectx , TPM2B_DIGEST *rand_bytes)
{
      printf("Inside GetRandom Number()\n");
      int rc = 1;
      rc = Esys_Initialize(&ectx,
                 NULL,  // let it find the TCTI 
                 NULL); // Use whatever ABI 
      if (rc != TSS2_RC_SUCCESS) {
             printf("Esys_Initialize Failed and its associated error code: 0x%x\n", rc);
             return 1;
      }

      /* 
      * Generate random number to encrypt the RSA key, which will be used for 
      * VPN connection
      * 
      */
      rc = Esys_GetRandom(ectx,
                     ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
                     64, &rand_bytes);
      if (rc != TSS2_RC_SUCCESS) {
             printf("Esys_GetRandom failed and its associated error code: %s\n", Tss2_RC_Decode(rc));
             exit(1);
       }

      printf(" No of bytes written by GenRandom : %d\n",rand_bytes->size);
      size_t i;
      for (i = 0; i < rand_bytes->size; i++) {
              printf("%02x", rand_bytes->buffer[i]);
      }

      printf("\n");

      printf("Exit from GetRandom Number()\n");

      return rand_bytes;
}


[-- Attachment #4: debug_log.obj --]
[-- Type: application/octet-stream, Size: 1247 bytes --]

root@muthu-vb:~/work/tpm2_app_dev/tpm2_nv_operations_rel_v3# ./bin/test_nvread.c 
Initializing
init_rand()
init_rsa()
init_ecc()
Engine name: TPM2-TSS engine for OpenSSL
Init result: 1 
Setting owner auth to empty auth.
Setting parent auth to empty auth.
READ RandomNumber from NVRAM from offset 0x1000001
Inside nv_read()
Created NV Index: 0x1000001
ESYS_TR: 0x0
ERROR:tcti:src/tss2-tcti/tcti-device.c:440:Tss2_Tcti_Device_Init() Failed to open device file /dev/tpm0: No such file or directory 
WARNING:tcti:src/tss2-tcti/tctildr.c:62:tcti_from_init() TCTI init for function 0x7f2ab50b718b failed with a000a 
WARNING:tcti:src/tss2-tcti/tctildr.c:92:tcti_from_info() Could not initialize TCTI named: tcti-device 
ERROR:tcti:src/tss2-tcti/tctildr-dl.c:150:tcti_from_file() Could not initialize TCTI file: libtss2-tcti-default.so 
ESYS_TR2: 0x418367
ERROR:esys:src/tss2-esys/esys_iutil.c:1086:esys_GetResourceObject() Error: Esys handle does not exist (70018). 
ERROR:esys:src/tss2-esys/api/Esys_NV_Read.c:180:Esys_NV_Read_Async() authHandle unknown. ErrorCode (0x00070018) 
ERROR:esys:src/tss2-esys/api/Esys_NV_Read.c:82:Esys_NV_Read() Error in async function ErrorCode (0x00070018) 
Esys_NV_Read <ERROR>: 0x70018
Segmentation fault (core dumped)


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [tpm2] Re: NVRAM Write and Read using Esys API(s)
@ 2020-05-15 14:54 Roberts, William C
  0 siblings, 0 replies; 5+ messages in thread
From: Roberts, William C @ 2020-05-15 14:54 UTC (permalink / raw)
  To: tpm2

[-- Attachment #1: Type: text/plain, Size: 24580 bytes --]

> -----Original Message-----
> From: Muthukumar S [mailto:muthu.smk(a)gmail.com]
> Sent: Friday, May 15, 2020 7:58 AM
> To: Roberts, William C <william.c.roberts(a)intel.com>
> Cc: tpm2(a)lists.01.org
> Subject: Re: [tpm2] NVRAM Write and Read using Esys API(s)
> 
> Hi Williams C,
> Thanks for your quick response. As you suggested , i have tried below options
> 
> I tried to get the index of nvram of sim that am working using tpm2_getcap tools
> API .Bellow are the tpm2_getcap capabilities that i found by reading the
> tpm2_getcap code . Request you to share me some pointers of using
> tpm2_getcap() .
> 
> 
> 
> Available capability from tpm2_getcap.c
> 
>         .capability_string = "algorithms"
> 
>         .capability_string = "commands"
> 
>         .capability_string = "properties-fixed",
> 
>         .capability_string = "properties-variable",
> 
>         .capability_string = "ecc-curves",
> 
>         .capability_string = "handles-transient",
> 
>         .capability_string = "handles-persistent",
> 
>         .capability_string = "handles-permanent",
> 
>         .capability_string = "handles-pcr",
> 
>         .capability_string = "handles-nv-index",
> 
>         .capability_string = "handles-loaded-session",
> 
>         .capability_string = "handles-saved-session",
> 
> 
> 
> 
> In the above list , i tried all "capability string " but i could't able to see the below
> output given by tpm2_nvlist (which i used to get with different tpm-tools version
> that i used earlier) .
> 

Put the tool in a debugger and look at the arguments passed to Esys_GetCapability and mimic it.
It's time you learn how to fish.

> 
> 
> 
> # tpm2_nvlist
> 
> O/P
> 
> 1 NV indexes defined.
> 
>  0. NV Index: 0x1500015
> 
>  {
> 
>  Hash algorithm(nameAlg):11
> 
> The Index attributes(attributes):0x64014001
> 
>        The size of the data area(dataSize):32
> 
>           }
> 
> 
> 
> 
> 1) Even though this tpm2_nvlist that was there in my current tpm2-tools version
> (tpm2-tools-3.X) ,by which it is not showing me any output .
> 
> #tpm2_nvlist
> 
> #
> 

I don't know if your trying to ask something here, are you?

> 
> 
> 
> 
> 
> 
> 2) Tried get_cap of "handles-permanent" , which shows me below values as
> shown below , but not sure how to get the index of particular tpm bank

Banks are for PCRs, ie PCR0 can have a SHA1 and SH256 bank.

> 
> #/tpm2/tpm_evo/tpm2-tools-3.X/tools# ./tpm2_getcap --capability="handles-
> permanent"

Stop using 3.X its deprecated, grab the latest 4.X release and build it.
The tools actually work.

> 
> 0x40000001
> 
> 0x40000007
> 
> 0x40000009
> 
> 0x4000000a
> 
> 0x4000000b
> 
> 0x4000000c
> 
> 0x4000000d

Those are not NV handles, NV Handles start with 0x10

> 
> 
> 
> 
> 2)Also tried reading pcr list using tpm2_getcap . Is the below offset(s) are stands
> for ?
> 
> # ./tpm2_getcap --capability="handles-pcr"

Again, NV Indexes ARE NOT PCR's.

> 
> 0x00000000
> 
> 0x00000001
> 
> 0x00000002
> 
> 0x00000003
> 
> 0x00000004
> 
> 0x00000005
> 
> 0x00000006
> 
> 2.1) Request you to share me few points on how to use the "tpm2_getcap() and
> get the offset ?
> 

Debuggers are your friend.

> 
> 
> Since none of the above tools API helped me or am i missing some thing to read
> the output of NVRAM index ?

I would upgrade to newer tools. If you must stay in the 3.X land, then copy what the test
scripts are doing, they do it completely. Look for nv.sh.

> 
> 3) Without knowing the offset , tried to define offset from 0x1500015 and trying
> to write and read back , here nvdefine works along with nvwrite ..but nvread fails
> with "auth" issue. Please refere below sequence and associated errors
> 
> 
> 3.1) Tried defining nvram using tpm2_nvdefine - Succeeded with out any error  --
> given -a 0x40000001 (TPM_RH_OWNER Access) , if i define with 0x4000000C
> (TPM_RH_OWNER , i got the same result during tpm2_nvread . Here removing "-t
> 0x2000A" option and then doing nvdefine also throws me the same error shown
> in point 3.3 during nvread
> 
> #./tpm2_nvdefine -x 0x1500016 -a 0x40000001 -s 32 -t 0x2000A

Offhand, I don't know what the 0x2000A mask is, so I would have to look it up, but I am not going to.
Use string masks.

If you just upgrade to a 4.x tools, it should work. I remember some issues with attributes on the 3.X branch
Tools.

> 
> #
> 
> 
> 
> 
> 3.2) Tried NVWRITE in the same offset 0x1500015  - Succeeded without any error
> 
> # ./tpm2_nvwrite -x 0x1500015 -L test_helloworld
> 
> #
> 
> 
> 
> 
> 3.3) Reading back the same offset -x1500015 , which throws below error stating
> TPM2_RC_NV_UNINITIALIZED. Since i have initialized it as said above point 3.1  ,
> what am i missing here ?

Upgrade your tools, and the example I showed yesterday should work.

> 
> 
> 
> 
> Below are the OPTIONS I have by tpm2_nvread:
> 
> as you suggested  to use (echo `tpm2_nvread -C o -s5 0x1500015` command)
> 
> I cant see -C (this might be due to tools version 3.X ? . If it is not the latest , can't
> we able to use the below APIs ?
> 
> 
> 
> 
> # ./tpm2_nvread
> 
> Usage: tpm2_nvread [<options>]
> 
> Where <options> are:
> 
>     [ -x | --index=<value>] [ -a | --auth-handle=<value>] [ -f | --output=<value>] [
> -s | --size=<value>]
> 
>     [ -o | --offset=<value>] [ -P | --handle-passwd=<value>] [ -S | --input-session-
> handle=<value>] [ -L | --set-list=<value>]
> 
>     [ -F | --pcr-input-file=<value>]
> 
> 
> 
> 
> # ./tpm2_nvread -x 0x1500015 -a 0x40000001 -s 32
> 
> ERROR: Failed to read NVRAM area at index 0x1500015 (22020117). Error:0x14a
> 
> ERROR: Unable to run ./tpm2_nvread
> 
> 
> 
> 
> # tpm2_rc_decode 0x14a
> 
> error layer
> 
>   hex: 0x0
> 
>   identifier: TSS2_TPM_RC_LAYER
> 
>   description: Error produced by the TPM
> 
> format 0 error code
> 
>   hex: 0x4a
> 
>   name: TPM2_RC_NV_UNINITIALIZED
> 
>   description: an NV Index is used before being initialized or the state saved by
> TPM2_Shutdown(STATE) could not be restored
> 
> 
> 
> 
> 3.4) Tried reading the same offset 0x1500015 without giving '-a'
> (TPM2_RH_OWNER) access , but the results shown NV_AUTHORIZATION. So i
> understood
> 
> if we defined with -a auth permission then we need to give the same permission
> while reading the content from the same offset. Is my understanding is correct ?
> 
> 
> 
> 
> # ./tpm2_nvread -x 0x1500015 -s 32
> 
> 
> ERROR: Failed to read NVRAM area at index 0x1500015 (22020117). Error:0x149
> ERROR: Unable to run ./tpm2_nvread
> 
> 
> # tpm2_rc_decode 0x149
> error layer
>   hex: 0x0
>   identifier: TSS2_TPM_RC_LAYER
>   description: Error produced by the TPM format 0 error code
>   hex: 0x49
>   name: TPM2_RC_NV_AUTHORIZATION
>   description: NV access authorization fails in command actions (this failure does
> not affect lockout.action)
> 
> 
> 
> 
> 
> 4) Tried to use tpm2_readpublic to read above written offset 0x1500015 , getting
> 0x184 (value is out of range or is not correct for the context) what am i missing
> here ?
> 
> # ./tpm2_readpublic
> Usage: tpm2_readpublic [<options>]
> Where <options> are:
>     [ -H | --object=<value>] [ -o | --opu=<value>] [ -c | --context-object=<value>]
> [ -f | --format=<value>]
> 
> 
> 
> 
> # ./tpm2_readpublic -H 0x1500015
> ERROR: TPM2_ReadPublic error: rval = 0x184
> ERROR: Unable to run ./tpm2_readpublic
> root(a)muthu-vb:~/work/tpm2/tpm_evo/install/bin# ./tpm2_readpublic -H
> 0x1500015 --opu file
> ERROR: TPM2_ReadPublic error: rval = 0x184
> ERROR: Unable to run ./tpm2_readpublic
> root(a)muthu-vb:~/work/tpm2/tpm_evo/install/bin# ./tpm2_rc_decode 0x184
> error layer
>   hex: 0x0
>   identifier: TSS2_TPM_RC_LAYER
>   description: Error produced by the TPM
> format 1 error code
>   hex: 0x04
>   identifier: TPM2_RC_VALUE
>   description: value is out of range or is not correct for the context
> handle
>   hex:0x100
>   identifier:  TPM2_RC_1
>   description:  (null)
> 
> 
> 
> #
> 
> 
> 
> 
> 
> 5)Tried releasing the same offset using nvrelease that too works fine
> 
> #./tpm2_nvrelease -x 0x1500015 -a 0x40000001
> 
> #
> 
> 
> 
> 
> As per my request raised by yesterday . I need to define an offset in nv ram then
> write content only once and read it back when ever required.  During every
> second write , i need to read the offset (you suggested to use
> tpm2_nvreadpubic() , but i struck with usage of this "nvread public api" command
> as well (results are just shown above)
> 
> 
> 
> 
> As per today's experiments , i cant able able to achieve the (nvread) using
> command line API . Let me know what am i missing here .
> 
> 
> 
> 
> Looking forward for your valuable reply.
> 
> 
> 
> 
> Thanks,
> 
> Muthukumar
> 
> 
> 
> 
> 
> 
> 
> On Thu, May 14, 2020 at 12:51 AM Roberts, William C
> <william.c.roberts(a)intel.com <mailto:william.c.roberts(a)intel.com> > wrote:
> 
> 
> 	> -----Original Message-----
> 	> From: muthu.smk(a)gmail.com <mailto:muthu.smk(a)gmail.com>
> [mailto:muthu.smk(a)gmail.com <mailto:muthu.smk(a)gmail.com> ]
> 	> Sent: Wednesday, May 13, 2020 12:51 PM
> 	> To: tpm2(a)lists.01.org <mailto:tpm2(a)lists.01.org>
> 	> Subject: [tpm2] NVRAM Write and Read using Esys API(s)
> 	>
> 	> Hi Williams,
> 	>
> 	> I am using the test code used to read and write in to NV ram.  I am
> facing below
> 	> challenges if i tried to read already written data from NVRAM.
> 	>
> 	> 1) Test code attached defined create the context (ectx) , create random
> number ,
> 	> define NV ram , write the random number in to NVRAM (offset
> 0x1000001) and
> 	> read it back from NV Ram (from same offset 0x1000001)
> 	>
> 	> 2) But if i try to run this code twice or thrise , am getting below NVRAM
> already
> 	> defined rc code. I can understand that we should not defined the nv
> ram space
> 	> which already defined and used.
> 	> How to avoid this ? by defining nvram ONLY once and write it ONLY
> once and
> 	> finally read it AS MUCH times we want ?  Below details are related to
> this request
> 
> 	You can call Esys_GetCapability() and see what NV indices are defined.
> The command
> 	Line tool tpm2_getcap does this, like so:
> 	tpm2_getcap handles-nv-index
> 
> 	You can use that tool as an example of how to do it.
> 
> 	>
> 	> Error code:
> 	> 0x0000014c - description: NV Index or persistend object already defined
> 	> 0x00000284 - description: value is out of range or is not correct for the
> context
> 	>
> 	> 3) Query is : is it possible to define nvram "ONLY ONCE" with the API
> shared the
> 	> test code and then create a function "createrandom" number to use
> the same
> 
> 	Call getcap, see if it's defined, if defined, don't define it....
> 
> 	> context (ects) to generate randumnumber then call separate
> "write_nvram"
> 	> function with random number as input and ask to write in the same
> offset .
> 	> Finally calling another function "read_nvram" to read it back from the
> same
> 	> nvram's offset when ever we want ? i tried this approach but am
> getting segfault
> 	> with above error .
> 	> What am i missing here ?
> 
> 	Segfaults are likely your code is just broken.
> 
> 	>
> 	> 3.1) Ideally in single application , i need to achieve "tpm2_nvdefine",
> 	> "tpm2_nvwrite" and "tpm2_nvread() tools API(s) functionality" in
> different calls
> 	> or flow.
> 	> 3.2) Also how to check whether "write" already done (i tried checking
> nv_index is
> 	> true - means whether it already has some value) , but it failed ?
> 
> 	If you do what the tool tpm2_nvreadpublic does, you can check for the
> written bit.
> 
> 	>
> 	> 4) Also how to check what was the content that already present in the
> nvram
> 	> offset (0x1000001) before i do write the "random number" second time
> in to the
> 	> same offset ? this is to ensure the "random number" that i am planning
> to write
> 	> was valid one ?
> 
> 	Read it out, if it's not what you want, write it.
> 
> 	>
> 	> I remember studying that, once u write in to NVRAM offset , we cant
> able to RE-
> 	> WRITE it in the same offset(0x1000001). Whether that is the same case
> for
> 	> SIMULATOR as well (or) this feature is only for real tpm hardware?
> 
> 	No generally you can write as many times as you want... there are tricks
> you can do to make
> 	It locked after write (writelocked iirc)
> 
> 	Below is a command line example of doing it...
> 
> 	tpm2_nvdefine
> 	nv-index: 0x1000000
> 
> 	tpm2_nvreadpublic 0x1000000
> 	0x1000000:
> 	  name:
> 000b1195f36a21c8219055ad0803c39e7e81d06cdb2eee2b7cf93dd83e01d4273828
> 	  hash algorithm:
> 	    friendly: sha256
> 	    value: 0xB
> 	  attributes:
> 	    friendly: ownerwrite|authwrite|ownerread|authread
> 	    value: 0x6000600
> 	  size: 2048
> 
> 	# you can do this as much as you want, but it can wear the memory in the
> TPM
> 	# depending on memory technology the vendor used.
> 	echo "hello" | tpm2_nvwrite -C o 0x1000000 -i-
> 	echo `tpm2_nvread -C o -s5 0x1000000`
> 	hello
> 
> 	tpm2_nvreadpublic 0x1000000
> 	0x1000000:
> 	  name:
> 000b287c9b1b06fab6e51bd26e98ea89460574e97a3d2ef995eb35f7e23db7e94f67
> 	  hash algorithm:
> 	    friendly: sha256
> 	    value: 0xB
> 	  attributes:
> 	    friendly: ownerwrite|authwrite|ownerread|authread|written
> 	    value: 0x6000620
> 	  size: 2048
> 
> 	>
> 	> 6)After nvwrite i tried to use "tpm2_pcrlist" command line tool
> application, by
> 	> which it shows the nv ram memory location , tried using tpm2_nvread ()
> to read
> 	> the content but i could not able to see any data (random number) that i
> used to
> 	> write via this test application . dont know why ?
> 
> 	tpm2_pcrlist is not for NVs.... you want:
> 	tpm2_getcap handles-nv-index
> 
> 	>
> 	> 7) After i manually ran the below clear API , now the test code is
> working fine
> 	> (refer Test code log shown below..). This confirms we can reallocate
> already
> 	> defined nv ram memory.
> 	> #tpm2_nvrelease -x 0x1000001 -a 0x40000001
> 
> 	Tpm2_clear will clear the owner hierarchy, including NV ram objects
> declared in that hierarchy,
> 	so define will work again, because you deleted it.
> 
> 	>
> 	>
> 	> 8)If i try to read it manually via below tpm2_nvread command with
> offset
> 	> 0x1000001 am getting below error
> 	>
> 	> #tpm2_nvread -x 0x1000001 -a 0x40000001 -o 0 -s 20
> 	> ERROR: Failed to read NVRAM public area at index 0x1000001
> (16777217).
> 	> Error:0x18b
> 	> ERROR: Unable to run tpm2_nvread
> 	>
> 	> /* Tried to use below tools command , am always getting the same
> error even if
> 	> we give the different nvram off set tpm2_nvwrite -x 0x1c00002
> helloworld
> 	> ERROR: Reading the public part of the nv index failed with: 0x18b
> 	> ERROR: Unable to run tpm2_nvwrite
> 	>
> 	> tpm2_nvwrite -x 0x1c00012 -a 0x40000001 helloworld
> 	> ERROR: Reading the public part of the nv index failed with: 0x18b
> 	> ERROR: Unable to run tpm2_nvwrite
> 	>
> 	>
> 	> /* Try to read the nvlist of SIM , it returns nothing !!!
> 	> #tpm2_nvlist <returns nothing>
> 	>
> 	> Any points will be great help for me.
> 	>
> 	> ---------------------------------------------------------------------------------------
> ------------
> 	> --------------------------------------------------------------
> 	> Test code log after above "tpm2_nvrelease":
> 	> Initializing
> 	> init_rand()
> 	> init_rsa()
> 	> init_ecc()
> 	> Engine name: TPM2-TSS engine for OpenSSL
> 	> Init result: 1
> 	> Setting owner auth to empty auth.
> 	> Setting parent auth to empty auth.
> 	> ERROR:tcti:src/tss2-tcti/tcti-device.c:440:Tss2_Tcti_Device_Init() Failed
> to open
> 	> device file /dev/tpm0: No such file or directory
> 	> WARNING:tcti:src/tss2-tcti/tctildr.c:62:tcti_from_init() TCTI init for
> function
> 	> 0x7fc67376d18b failed with a000a
> 	> WARNING:tcti:src/tss2-tcti/tctildr.c:92:tcti_from_info() Could not
> initialize TCTI
> 	> named: tcti-device
> 	> ERROR:tcti:src/tss2-tcti/tctildr-dl.c:150:tcti_from_file() Could not
> initialize TCTI
> 	> file: libtss2-tcti-default.so
> 	>  No of bytes written by GenRandom : 64
> 	>
> b6c9e1d028f2c893c56a089165f9f38c09232180ba5bb66b35c5652cb51ab61b237ecfe
> 	> 8ece5d7f14a3323fee1dca0e641a0f20c7689100e3c804b82d6a2497f
> 	> Created NV Index: 0x1000001
> 	> ESYS_TR: 0x418367
> 	> ESYS_TR2: 0x418368
> 	> Writing the random number written in NV Ram
> 	> Data buffer size used to write into NVRam: 64
> 	> Reading the random number written in NV Ram
> 	>
> b6c9e1d028f2c893c56a089165f9f38c09232180ba5bb66b35c5652cb51ab61b237ecfe
> 	> 8ece5d7f14a3323fee1dca0e641a0f20c7689100e3c804b82d6a2497f
> 	> *** SUCCESS ***
> 	> ---------------------
> 	>
> 	> TEST CODE :
> 	>
> 	> int nv_write_read()
> 	> {
> 	>
> 	>       ESYS_CONTEXT *ectx = NULL;
> 	>
> 	>       ESYS_TR nv_index = 0;
> 	>       ESYS_TR nv_index2 = 0;
> 	>
> 	>        int rc = 1;
> 	>
> 	>
> 	>       /*
> 	>        * create a connection to the TPM letting ESAPI choose how to get
> there.
> 	>        * If you need more control, you can use tcti and tcti-ldr libraries to
> 	>        * get a TCTI pointer to use for the tcti argument of Esys_Initialize.
> 	>        */
> 	>       rc = Esys_Initialize(&ectx,
> 	>                       NULL,  // let it find the TCTI
> 	>                       NULL); // Use whatever ABI
> 	>       if (rc != TSS2_RC_SUCCESS) {
> 	>               printf("Esys_Initialize Failed: 0x%x\n", rc);
> 	>               return 1;
> 	>       }
> 	>
> 	>
> 	>         rc = Esys_GetRandom(ectx,
> 	>                         ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
> 	>                         64, &bytes);
> 	>         if (rc != TSS2_RC_SUCCESS) {
> 	>                 printf("Esys_GetRandom Failed: %s\n", Tss2_RC_Decode(rc));
> 	>                 exit(1);
> 	>         }
> 	>
> 	>       printf(" No of bytes written by GenRandom : %d\n",bytes->size);
> 	>       size_t i;
> 	>       for (i = 0; i < bytes->size; i++) {
> 	>               printf("%02x", bytes->buffer[i]);
> 	>       }
> 	>
> 	>       printf("\n");
> 	>
> 	>       /* build a template for the NV index */
> 	>       TPM2B_NV_PUBLIC pub_templ = {
> 	>               /* this is counter intuitive, but it tells the TSS2 library to calculate
> 	> this for us */
> 	>               .size = 0,
> 	>               /* The things that define what NV index we are creating */
> 	>               .nvPublic = {
> 	>                       /* uses sha256 to identify the tpm object by name */
> 	>                       .nameAlg = TPM2_ALG_SHA256,
> 	>                       /* allows the owner password or index password r/w
> 	> access */
> 	>                       .attributes = TPMA_NV_OWNERWRITE |
> 	>                               TPMA_NV_OWNERREAD            |
> 	>                               TPMA_NV_AUTHWRITE            |
> 	>                               TPMA_NV_AUTHREAD,
> 	>                       /* can hold 64 bytes of data */
> 	>                       .dataSize = 64,
> 	>                       /* Create at NV Index 1 or 0x1000001 */
> 	>                       .nvIndex = TPM2_HR_NV_INDEX + 1
> 	>               },
> 	>       };
> 	>
> 	>
> 	>       /* Ok, define the space and store the nv_index for future use */
> 	>       rc = Esys_NV_DefineSpace(
> 	>           ectx,
> 	>               ESYS_TR_RH_OWNER, /* create an NV index in the owner
> 	> hierarchy */
> 	>           ESYS_TR_PASSWORD, /* auth as the owner with a password,
> which is
> 	> empty */
> 	>           ESYS_TR_NONE,
> 	>           ESYS_TR_NONE,
> 	>           NULL,
> 	>           &pub_templ,
> 	>           &nv_index);
> 	>       if (rc != TSS2_RC_SUCCESS) {
> 	>               printf("Esys_NV_DefineSpace Failed: 0x%x\n", rc);
> 	>               goto out;
> 	>       }
> 	>
> 	>       /* Note if you need to set the owner hierarchy auth value you use:
> 	>        * TSS2_RC Esys_TR_SetAuth(
> 	>        *     ESYS_CONTEXT *esysContext,
> 	>          *     ESYS_TR handle,
> 	>          *     TPM2B_AUTH const *authValue);
> 	>        */
> 	>
> 	>       printf("Created NV Index: 0x%x\n", pub_templ.nvPublic.nvIndex);
> 	>       printf("ESYS_TR: 0x%x\n", nv_index);
> 	>
> 	>       /*
> 	>        * Note: if we need to convert the nvIndex into an ESYS_TR, the
> below
> 	> will
> 	>        * do it. Its not required for this case, since Esys_NV_Define gives us
> an
> 	>        * ESYS_TR.
> 	>        */
> 	>       rc = Esys_TR_FromTPMPublic(
> 	>               ectx,
> 	>               TPM2_HR_NV_INDEX + 1,
> 	>               ESYS_TR_NONE,
> 	>               ESYS_TR_NONE,
> 	>               ESYS_TR_NONE,
> 	>               &nv_index2);
> 	>       if (rc != TSS2_RC_SUCCESS) {
> 	>               printf("Esys_TR_FromTPMPublic Failed: 0x%x\n", rc);
> 	>               goto out;
> 	>       }
> 	>
> 	>       printf("ESYS_TR2: 0x%x\n", nv_index2);
> 	>
> 	>       /* copy some data into a buffer to send to the TPM */
> 	>       TPM2B_MAX_NV_BUFFER write_data = { 0 };
> 	>       memcpy(write_data.buffer, bytes->buffer, bytes->size);
> 	>       write_data.size = bytes->size;
> 	>
> 	>       printf("Writing the random number written in NV Ram\n");
> 	>       printf("Data buffer size used to write into NVRam:
> 	> %d\n",write_data.size);
> 	>       /*
> 	>        * Write the data to the TPM NV index at offset 0
> 	>        */
> 	>       rc = Esys_NV_Write(
> 	>           ectx,
> 	>           nv_index, /* authenticate to the NV index using the NV index
> 	> password */
> 	>           nv_index, /* the nv index to write to */
> 	>           ESYS_TR_PASSWORD,
> 	>               ESYS_TR_NONE,
> 	>               ESYS_TR_NONE,
> 	>           &write_data,
> 	>           0);
> 	>       if (rc != TSS2_RC_SUCCESS) {
> 	>               printf("Esys_NV_Write Failed: 0x%x\n", rc);
> 	>               goto out;
> 	>       }
> 	>
> 	>       /* Read the data back, and just for fun, we will use nv_index2
> 	>        * to prove it's pointing to the same NV location in the TPM.
> 	>        */
> 	>       TPM2B_MAX_NV_BUFFER *read_data = NULL;
> 	>       rc = Esys_NV_Read(
> 	>           ectx,
> 	>           nv_index2, /* authenticate to the NV index using the NV index
> 	> password */
> 	>           nv_index2, /* the nv index to read from */
> 	>           ESYS_TR_PASSWORD,
> 	>           ESYS_TR_NONE,
> 	>           ESYS_TR_NONE,
> 	>           bytes->size,
> 	>           0,
> 	>           &read_data);
> 	>       if (rc != TSS2_RC_SUCCESS) {
> 	>               printf("Esys_NV_Read Failed: 0x%x\n", rc);
> 	>               goto out;
> 	>       }
> 	>
> 	>       /* Print things as a string from the TPM carefully!
> 	>        * Injected traffic via MITM means that you cannot trust this
> 	>        * to be null terminated.
> 	>        */
> 	>       printf("Reading the random number written in NV Ram\n");
> 	>       for (i = 0; i < read_data->size; i++) {
> 	>               printf("%02x", read_data->buffer[i]);
> 	>       }
> 	>       printf("\n");
> 	>
> 	>       Esys_Free(read_data);
> 	>       rc = 0;
> 	>
> 	> out:
> 	>
> 	>       /* remove the NV space */
> 	>       if (nv_index) {
> 	>               int rc2 = Esys_NV_UndefineSpace(
> 	>                       ectx,
> 	>                       ESYS_TR_RH_OWNER,
> 	>                       nv_index,
> 	>                       ESYS_TR_PASSWORD,
> 	>                       ESYS_TR_NONE,
> 	>                       ESYS_TR_NONE);
> 	>               if (rc2 != TSS2_RC_SUCCESS) {
> 	>                       printf("Esys_NV_UndefineSpace Failed: 0x%x\n", rc2);
> 	>                       rc = 1;
> 	>               }
> 	>       }
> 	>
> 	>       Esys_Finalize(&ectx);
> 	>
> 	>         printf("Exit from nv_write_read()\n");
> 	>       return rc;
> 	> }
> 	> _______________________________________________
> 	> tpm2 mailing list -- tpm2(a)lists.01.org <mailto:tpm2(a)lists.01.org>
> 	> To unsubscribe send an email to tpm2-leave(a)lists.01.org <mailto:tpm2-
> leave(a)lists.01.org>
> 	> %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [tpm2] Re: NVRAM Write and Read using Esys API(s)
@ 2020-05-15 12:58 Muthukumar S
  0 siblings, 0 replies; 5+ messages in thread
From: Muthukumar S @ 2020-05-15 12:58 UTC (permalink / raw)
  To: tpm2

[-- Attachment #1: Type: text/plain, Size: 22088 bytes --]

Hi Williams C,
Thanks for your quick response. As you suggested , i have tried below
options

I tried to get the index of nvram of sim that am working using tpm2_getcap
tools API .Bellow are the tpm2_getcap capabilities that i found by reading
the tpm2_getcap code . Request you to share me some pointers of using
tpm2_getcap() .

*Available capability from tpm2_getcap.c*

*        .capability_string = "algorithms"*

*        .capability_string = "commands"*

*        .capability_string = "properties-fixed",*

*        .capability_string = "properties-variable",  *

*        .capability_string = "ecc-curves",*

*        .capability_string = "handles-transient",*

*        .capability_string = "handles-persistent",*

*        .capability_string = "handles-permanent",*

*        .capability_string = "handles-pcr",*

*        .capability_string = "handles-nv-index",*

*        .capability_string = "handles-loaded-session",*

*        .capability_string = "handles-saved-session",*


In the above list , i tried all "capability string " but i could't able to
see the below output given by *tpm2_nvlist *(which i used to get with
different tpm-tools version that i used earlier) .


*# tpm2_nvlist*

*O/P*

*1 NV indexes defined.*

* 0. NV Index: 0x1500015*

* {*

* Hash algorithm(nameAlg):11*

*The Index attributes(attributes):0x64014001*

*       The size of the data area(dataSize):32*

*          }*


*1) Even though this tpm2_nvlist that was there in my current tpm2-tools
version (tpm2-tools-3.X) ,by which it is not showing me any output .*

#tpm2_nvlist

#



*2) Tried get_cap of "handles-permanent" , which shows me below values as
shown below , but not sure how to get the index of particular tpm bank*

#/tpm2/tpm_evo/tpm2-tools-3.X/tools# ./tpm2_getcap
--capability="handles-permanent"


*0x40000001*

*0x40000007*

*0x40000009*

*0x4000000a*

*0x4000000b*

*0x4000000c*

*0x4000000d*


*2)Also tried reading pcr list using tpm2_getcap . Is the below offset(s)
are stands for ? *

*# ./tpm2_getcap --capability="handles-pcr"*

*0x00000000*

*0x00000001*

*0x00000002*

*0x00000003*

*0x00000004*

*0x00000005*
*0x00000006*

*2.1) Request you to share me few points on how to use the "tpm2_getcap()
and get the offset ? *


*Since none of the above tools API helped me or am i missing some thing to
read the output of NVRAM index ?*

*3) Without knowing the offset , tried to define offset from 0x1500015 and
trying to write and read back , here nvdefine works along with
nvwrite ..but nvread fails with "auth" issue. Please refere*
*below sequence and associated errors  *

*3.1) Tried defining nvram using tpm2_nvdefine - **Succeeded* with out* any
error  -- given -a 0x40000001 (TPM_RH_OWNER Access) , if i define with
0x4000000C (TPM_RH_OWNER , i got the same result during tpm2_nvread . Here
removing "-t 0x2000A" option and then doing nvdefine also throws me the
same error shown in point 3.3 during nvread  *

#./tpm2_nvdefine -x 0x1500016 -a 0x40000001 -s 32 -t 0x2000A

#


*3.2) Tried NVWRITE in the same offset 0x1500015  - Succeeded without any
error*

# ./tpm2_nvwrite -x 0x1500015 -L test_helloworld

#


*3.3) Reading back the same offset -x1500015 , which throws below error
stating TPM2_RC_NV_UNINITIALIZED. Since i have **initialized** it as said
above point 3.1  , what am i missing here ? *


Below are the OPTIONS I have by tpm2_nvread:

as you suggested  to use (*echo `tpm2_nvread -C o -s5 0x1500015*` command)

I cant see -C (this might be due to tools version 3.X ? . If it is not the
latest , can't we able to use the below APIs ?


# ./tpm2_nvread

Usage: tpm2_nvread [<options>]

Where <options> are:

    [ -x | --index=<value>] [ -a | --auth-handle=<value>] [ -f |
--output=<value>] [ -s | --size=<value>]

    [ -o | --offset=<value>] [ -P | --handle-passwd=<value>] [ -S |
--input-session-handle=<value>] [ -L | --set-list=<value>]

    [ -F | --pcr-input-file=<value>]


# ./tpm2_nvread -x 0x1500015 -a 0x40000001 -s 32

ERROR: Failed to read NVRAM area at index 0x1500015 (22020117). Error:0x14a

ERROR: Unable to run ./tpm2_nvread


# tpm2_rc_decode 0x14a

error layer

  hex: 0x0

  identifier: TSS2_TPM_RC_LAYER

  description: Error produced by the TPM

format 0 error code

  hex: 0x4a

  name: TPM2_RC_NV_UNINITIALIZED

  description: an NV Index is used before being initialized or the state
saved by TPM2_Shutdown(STATE) could not be restored


*3.4) Tried reading the same offset 0x1500015 without giving '-a'
(TPM2_RH_OWNER) access , but the results shown NV_AUTHORIZATION. So i
understood*

*if we defined with -a auth permission then we need to give the same
permission while reading the content from the same offset. Is my
understanding is correct ?*


# ./tpm2_nvread -x 0x1500015 -s 32

ERROR: Failed to read NVRAM area at index 0x1500015 (22020117). Error:0x149
ERROR: Unable to run ./tpm2_nvread

# tpm2_rc_decode 0x149
error layer
  hex: 0x0
  identifier: TSS2_TPM_RC_LAYER
  description: Error produced by the TPM
format 0 error code
  hex: 0x49
  name: TPM2_RC_NV_AUTHORIZATION
  description: NV access authorization fails in command actions (this
failure does not affect lockout.action)


*4) Tried to use tpm2_readpublic to read above written offset 0x1500015 ,
getting 0x184 (value is out of range or is not correct for the context)
what am i missing here ?*

# ./tpm2_readpublic
Usage: tpm2_readpublic [<options>]
Where <options> are:
    [ -H | --object=<value>] [ -o | --opu=<value>] [ -c |
--context-object=<value>] [ -f | --format=<value>]


# ./tpm2_readpublic -H 0x1500015
ERROR: TPM2_ReadPublic error: rval = 0x184
ERROR: Unable to run ./tpm2_readpublic
root(a)muthu-vb:~/work/tpm2/tpm_evo/install/bin# ./tpm2_readpublic -H
0x1500015 --opu file
ERROR: TPM2_ReadPublic error: rval = 0x184
ERROR: Unable to run ./tpm2_readpublic
root(a)muthu-vb:~/work/tpm2/tpm_evo/install/bin# ./tpm2_rc_decode 0x184
error layer
  hex: 0x0
  identifier: TSS2_TPM_RC_LAYER
  description: Error produced by the TPM
format 1 error code
  hex: 0x04
  identifier: TPM2_RC_VALUE
  description: value is out of range or is not correct for the context
handle
  hex:0x100
  identifier:  TPM2_RC_1
  description:  (null)

#


*5)Tried releasing the same offset using nvrelease that too works fine*

#./tpm2_nvrelease -x 0x1500015 -a 0x40000001

#


As per my request raised by yesterday . I need to define an offset in nv
ram then write content only once and read it back when ever required.
During every second write , i need to read the offset (you suggested to use
tpm2_nvreadpubic() , but i struck with usage of this "nvread public api"
command as well (results are just shown above)


As per today's experiments , i cant able able to achieve the (nvread) using
command line API . Let me know what am i missing here .


Looking forward for your valuable reply.


Thanks,

Muthukumar




On Thu, May 14, 2020 at 12:51 AM Roberts, William C <
william.c.roberts(a)intel.com> wrote:

> > -----Original Message-----
> > From: muthu.smk(a)gmail.com [mailto:muthu.smk(a)gmail.com]
> > Sent: Wednesday, May 13, 2020 12:51 PM
> > To: tpm2(a)lists.01.org
> > Subject: [tpm2] NVRAM Write and Read using Esys API(s)
> >
> > Hi Williams,
> >
> > I am using the test code used to read and write in to NV ram.  I am
> facing below
> > challenges if i tried to read already written data from NVRAM.
> >
> > 1) Test code attached defined create the context (ectx) , create random
> number ,
> > define NV ram , write the random number in to NVRAM (offset 0x1000001)
> and
> > read it back from NV Ram (from same offset 0x1000001)
> >
> > 2) But if i try to run this code twice or thrise , am getting below
> NVRAM already
> > defined rc code. I can understand that we should not defined the nv ram
> space
> > which already defined and used.
> > How to avoid this ? by defining nvram ONLY once and write it ONLY once
> and
> > finally read it AS MUCH times we want ?  Below details are related to
> this request
>
> You can call Esys_GetCapability() and see what NV indices are defined. The
> command
> Line tool tpm2_getcap does this, like so:
> tpm2_getcap handles-nv-index
>
> You can use that tool as an example of how to do it.
>
> >
> > Error code:
> > 0x0000014c - description: NV Index or persistend object already defined
> > 0x00000284 - description: value is out of range or is not correct for
> the context
> >
> > 3) Query is : is it possible to define nvram "ONLY ONCE" with the API
> shared the
> > test code and then create a function "createrandom" number to use the
> same
>
> Call getcap, see if it's defined, if defined, don't define it....
>
> > context (ects) to generate randumnumber then call separate "write_nvram"
> > function with random number as input and ask to write in the same offset
> .
> > Finally calling another function "read_nvram" to read it back from the
> same
> > nvram's offset when ever we want ? i tried this approach but am getting
> segfault
> > with above error .
> > What am i missing here ?
>
> Segfaults are likely your code is just broken.
>
> >
> > 3.1) Ideally in single application , i need to achieve "tpm2_nvdefine",
> > "tpm2_nvwrite" and "tpm2_nvread() tools API(s) functionality" in
> different calls
> > or flow.
> > 3.2) Also how to check whether "write" already done (i tried checking
> nv_index is
> > true - means whether it already has some value) , but it failed ?
>
> If you do what the tool tpm2_nvreadpublic does, you can check for the
> written bit.
>
> >
> > 4) Also how to check what was the content that already present in the
> nvram
> > offset (0x1000001) before i do write the "random number" second time in
> to the
> > same offset ? this is to ensure the "random number" that i am planning
> to write
> > was valid one ?
>
> Read it out, if it's not what you want, write it.
>
> >
> > I remember studying that, once u write in to NVRAM offset , we cant able
> to RE-
> > WRITE it in the same offset(0x1000001). Whether that is the same case for
> > SIMULATOR as well (or) this feature is only for real tpm hardware?
>
> No generally you can write as many times as you want... there are tricks
> you can do to make
> It locked after write (writelocked iirc)
>
> Below is a command line example of doing it...
>
> tpm2_nvdefine
> nv-index: 0x1000000
>
> tpm2_nvreadpublic 0x1000000
> 0x1000000:
>   name:
> 000b1195f36a21c8219055ad0803c39e7e81d06cdb2eee2b7cf93dd83e01d4273828
>   hash algorithm:
>     friendly: sha256
>     value: 0xB
>   attributes:
>     friendly: ownerwrite|authwrite|ownerread|authread
>     value: 0x6000600
>   size: 2048
>
> # you can do this as much as you want, but it can wear the memory in the
> TPM
> # depending on memory technology the vendor used.
> echo "hello" | tpm2_nvwrite -C o 0x1000000 -i-
> echo `tpm2_nvread -C o -s5 0x1000000`
> hello
>
> tpm2_nvreadpublic 0x1000000
> 0x1000000:
>   name:
> 000b287c9b1b06fab6e51bd26e98ea89460574e97a3d2ef995eb35f7e23db7e94f67
>   hash algorithm:
>     friendly: sha256
>     value: 0xB
>   attributes:
>     friendly: ownerwrite|authwrite|ownerread|authread|written
>     value: 0x6000620
>   size: 2048
>
> >
> > 6)After nvwrite i tried to use "tpm2_pcrlist" command line tool
> application, by
> > which it shows the nv ram memory location , tried using tpm2_nvread ()
> to read
> > the content but i could not able to see any data (random number) that i
> used to
> > write via this test application . dont know why ?
>
> tpm2_pcrlist is not for NVs.... you want:
> tpm2_getcap handles-nv-index
>
> >
> > 7) After i manually ran the below clear API , now the test code is
> working fine
> > (refer Test code log shown below..). This confirms we can reallocate
> already
> > defined nv ram memory.
> > #tpm2_nvrelease -x 0x1000001 -a 0x40000001
>
> Tpm2_clear will clear the owner hierarchy, including NV ram objects
> declared in that hierarchy,
> so define will work again, because you deleted it.
>
> >
> >
> > 8)If i try to read it manually via below tpm2_nvread command with offset
> > 0x1000001 am getting below error
> >
> > #tpm2_nvread -x 0x1000001 -a 0x40000001 -o 0 -s 20
> > ERROR: Failed to read NVRAM public area at index 0x1000001 (16777217).
> > Error:0x18b
> > ERROR: Unable to run tpm2_nvread
> >
> > /* Tried to use below tools command , am always getting the same error
> even if
> > we give the different nvram off set tpm2_nvwrite -x 0x1c00002 helloworld
> > ERROR: Reading the public part of the nv index failed with: 0x18b
> > ERROR: Unable to run tpm2_nvwrite
> >
> > tpm2_nvwrite -x 0x1c00012 -a 0x40000001 helloworld
> > ERROR: Reading the public part of the nv index failed with: 0x18b
> > ERROR: Unable to run tpm2_nvwrite
> >
> >
> > /* Try to read the nvlist of SIM , it returns nothing !!!
> > #tpm2_nvlist <returns nothing>
> >
> > Any points will be great help for me.
> >
> >
> ---------------------------------------------------------------------------------------------------
> > --------------------------------------------------------------
> > Test code log after above "tpm2_nvrelease":
> > Initializing
> > init_rand()
> > init_rsa()
> > init_ecc()
> > Engine name: TPM2-TSS engine for OpenSSL
> > Init result: 1
> > Setting owner auth to empty auth.
> > Setting parent auth to empty auth.
> > ERROR:tcti:src/tss2-tcti/tcti-device.c:440:Tss2_Tcti_Device_Init()
> Failed to open
> > device file /dev/tpm0: No such file or directory
> > WARNING:tcti:src/tss2-tcti/tctildr.c:62:tcti_from_init() TCTI init for
> function
> > 0x7fc67376d18b failed with a000a
> > WARNING:tcti:src/tss2-tcti/tctildr.c:92:tcti_from_info() Could not
> initialize TCTI
> > named: tcti-device
> > ERROR:tcti:src/tss2-tcti/tctildr-dl.c:150:tcti_from_file() Could not
> initialize TCTI
> > file: libtss2-tcti-default.so
> >  No of bytes written by GenRandom : 64
> > b6c9e1d028f2c893c56a089165f9f38c09232180ba5bb66b35c5652cb51ab61b237ecfe
> > 8ece5d7f14a3323fee1dca0e641a0f20c7689100e3c804b82d6a2497f
> > Created NV Index: 0x1000001
> > ESYS_TR: 0x418367
> > ESYS_TR2: 0x418368
> > Writing the random number written in NV Ram
> > Data buffer size used to write into NVRam: 64
> > Reading the random number written in NV Ram
> > b6c9e1d028f2c893c56a089165f9f38c09232180ba5bb66b35c5652cb51ab61b237ecfe
> > 8ece5d7f14a3323fee1dca0e641a0f20c7689100e3c804b82d6a2497f
> > *** SUCCESS ***
> > ---------------------
> >
> > TEST CODE :
> >
> > int nv_write_read()
> > {
> >
> >       ESYS_CONTEXT *ectx = NULL;
> >
> >       ESYS_TR nv_index = 0;
> >       ESYS_TR nv_index2 = 0;
> >
> >        int rc = 1;
> >
> >
> >       /*
> >        * create a connection to the TPM letting ESAPI choose how to get
> there.
> >        * If you need more control, you can use tcti and tcti-ldr
> libraries to
> >        * get a TCTI pointer to use for the tcti argument of
> Esys_Initialize.
> >        */
> >       rc = Esys_Initialize(&ectx,
> >                       NULL,  // let it find the TCTI
> >                       NULL); // Use whatever ABI
> >       if (rc != TSS2_RC_SUCCESS) {
> >               printf("Esys_Initialize Failed: 0x%x\n", rc);
> >               return 1;
> >       }
> >
> >
> >         rc = Esys_GetRandom(ectx,
> >                         ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
> >                         64, &bytes);
> >         if (rc != TSS2_RC_SUCCESS) {
> >                 printf("Esys_GetRandom Failed: %s\n",
> Tss2_RC_Decode(rc));
> >                 exit(1);
> >         }
> >
> >       printf(" No of bytes written by GenRandom : %d\n",bytes->size);
> >       size_t i;
> >       for (i = 0; i < bytes->size; i++) {
> >               printf("%02x", bytes->buffer[i]);
> >       }
> >
> >       printf("\n");
> >
> >       /* build a template for the NV index */
> >       TPM2B_NV_PUBLIC pub_templ = {
> >               /* this is counter intuitive, but it tells the TSS2
> library to calculate
> > this for us */
> >               .size = 0,
> >               /* The things that define what NV index we are creating */
> >               .nvPublic = {
> >                       /* uses sha256 to identify the tpm object by name
> */
> >                       .nameAlg = TPM2_ALG_SHA256,
> >                       /* allows the owner password or index password r/w
> > access */
> >                       .attributes = TPMA_NV_OWNERWRITE |
> >                               TPMA_NV_OWNERREAD            |
> >                               TPMA_NV_AUTHWRITE            |
> >                               TPMA_NV_AUTHREAD,
> >                       /* can hold 64 bytes of data */
> >                       .dataSize = 64,
> >                       /* Create at NV Index 1 or 0x1000001 */
> >                       .nvIndex = TPM2_HR_NV_INDEX + 1
> >               },
> >       };
> >
> >
> >       /* Ok, define the space and store the nv_index for future use */
> >       rc = Esys_NV_DefineSpace(
> >           ectx,
> >               ESYS_TR_RH_OWNER, /* create an NV index in the owner
> > hierarchy */
> >           ESYS_TR_PASSWORD, /* auth as the owner with a password, which
> is
> > empty */
> >           ESYS_TR_NONE,
> >           ESYS_TR_NONE,
> >           NULL,
> >           &pub_templ,
> >           &nv_index);
> >       if (rc != TSS2_RC_SUCCESS) {
> >               printf("Esys_NV_DefineSpace Failed: 0x%x\n", rc);
> >               goto out;
> >       }
> >
> >       /* Note if you need to set the owner hierarchy auth value you use:
> >        * TSS2_RC Esys_TR_SetAuth(
> >        *     ESYS_CONTEXT *esysContext,
> >          *     ESYS_TR handle,
> >          *     TPM2B_AUTH const *authValue);
> >        */
> >
> >       printf("Created NV Index: 0x%x\n", pub_templ.nvPublic.nvIndex);
> >       printf("ESYS_TR: 0x%x\n", nv_index);
> >
> >       /*
> >        * Note: if we need to convert the nvIndex into an ESYS_TR, the
> below
> > will
> >        * do it. Its not required for this case, since Esys_NV_Define
> gives us an
> >        * ESYS_TR.
> >        */
> >       rc = Esys_TR_FromTPMPublic(
> >               ectx,
> >               TPM2_HR_NV_INDEX + 1,
> >               ESYS_TR_NONE,
> >               ESYS_TR_NONE,
> >               ESYS_TR_NONE,
> >               &nv_index2);
> >       if (rc != TSS2_RC_SUCCESS) {
> >               printf("Esys_TR_FromTPMPublic Failed: 0x%x\n", rc);
> >               goto out;
> >       }
> >
> >       printf("ESYS_TR2: 0x%x\n", nv_index2);
> >
> >       /* copy some data into a buffer to send to the TPM */
> >       TPM2B_MAX_NV_BUFFER write_data = { 0 };
> >       memcpy(write_data.buffer, bytes->buffer, bytes->size);
> >       write_data.size = bytes->size;
> >
> >       printf("Writing the random number written in NV Ram\n");
> >       printf("Data buffer size used to write into NVRam:
> > %d\n",write_data.size);
> >       /*
> >        * Write the data to the TPM NV index at offset 0
> >        */
> >       rc = Esys_NV_Write(
> >           ectx,
> >           nv_index, /* authenticate to the NV index using the NV index
> > password */
> >           nv_index, /* the nv index to write to */
> >           ESYS_TR_PASSWORD,
> >               ESYS_TR_NONE,
> >               ESYS_TR_NONE,
> >           &write_data,
> >           0);
> >       if (rc != TSS2_RC_SUCCESS) {
> >               printf("Esys_NV_Write Failed: 0x%x\n", rc);
> >               goto out;
> >       }
> >
> >       /* Read the data back, and just for fun, we will use nv_index2
> >        * to prove it's pointing to the same NV location in the TPM.
> >        */
> >       TPM2B_MAX_NV_BUFFER *read_data = NULL;
> >       rc = Esys_NV_Read(
> >           ectx,
> >           nv_index2, /* authenticate to the NV index using the NV index
> > password */
> >           nv_index2, /* the nv index to read from */
> >           ESYS_TR_PASSWORD,
> >           ESYS_TR_NONE,
> >           ESYS_TR_NONE,
> >           bytes->size,
> >           0,
> >           &read_data);
> >       if (rc != TSS2_RC_SUCCESS) {
> >               printf("Esys_NV_Read Failed: 0x%x\n", rc);
> >               goto out;
> >       }
> >
> >       /* Print things as a string from the TPM carefully!
> >        * Injected traffic via MITM means that you cannot trust this
> >        * to be null terminated.
> >        */
> >       printf("Reading the random number written in NV Ram\n");
> >       for (i = 0; i < read_data->size; i++) {
> >               printf("%02x", read_data->buffer[i]);
> >       }
> >       printf("\n");
> >
> >       Esys_Free(read_data);
> >       rc = 0;
> >
> > out:
> >
> >       /* remove the NV space */
> >       if (nv_index) {
> >               int rc2 = Esys_NV_UndefineSpace(
> >                       ectx,
> >                       ESYS_TR_RH_OWNER,
> >                       nv_index,
> >                       ESYS_TR_PASSWORD,
> >                       ESYS_TR_NONE,
> >                       ESYS_TR_NONE);
> >               if (rc2 != TSS2_RC_SUCCESS) {
> >                       printf("Esys_NV_UndefineSpace Failed: 0x%x\n",
> rc2);
> >                       rc = 1;
> >               }
> >       }
> >
> >       Esys_Finalize(&ectx);
> >
> >         printf("Exit from nv_write_read()\n");
> >       return rc;
> > }
> > _______________________________________________
> > tpm2 mailing list -- tpm2(a)lists.01.org
> > To unsubscribe send an email to tpm2-leave(a)lists.01.org
> > %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
>

[-- Attachment #2: attachment.htm --]
[-- Type: text/html, Size: 66560 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-05-19 14:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-13 19:21 [tpm2] Re: NVRAM Write and Read using Esys API(s) Roberts, William C
2020-05-15 12:58 Muthukumar S
2020-05-15 14:54 Roberts, William C
2020-05-18 17:08 Muthukumar S
2020-05-19 14:47 Roberts, William C

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.