1/*
2 * The Initial Developer of the Original Code is International
3 * Business Machines Corporation. Portions created by IBM
4 * Corporation are Copyright (C) 2005 International Business
5 * Machines Corporation. All Rights Reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the Common Public License as published by
9 * IBM Corporation; either version 1 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * Common Public License for more details.
16 *
17 * You should have received a copy of the Common Public License
18 * along with this program; if not, a copy can be viewed at
19 * http://www.opensource.org/licenses/cpl1.0.php.
20 */
21
22#include "tpm_tspi.h"
23
24TSS_UUID SRK_UUID = TSS_UUID_SRK;
25extern TSS_HCONTEXT hContext;
26
27const char *mapUnknown = "Unknown";
28
29const char *usageSigning = "Signing";
30const char *usageStorage = "Storage";
31const char *usageIdentity = "Identity";
32const char *usageAuthChange = "AuthChange";
33const char *usageBind = "Bind";
34const char *usageLegacy = "Legacy";
35
36const int flagMax = 7;
37const char *flagMap[] = {
38	"!VOLATILE, !MIGRATABLE, !REDIRECTION",
39	"!VOLATILE, !MIGRATABLE,  REDIRECTION",
40	"!VOLATILE,  MIGRATABLE, !REDIRECTION",
41	"!VOLATILE,  MIGRATABLE,  REDIRECTION",
42	" VOLATILE, !MIGRATABLE, !REDIRECTION",
43	" VOLATILE, !MIGRATABLE,  REDIRECTION",
44	" VOLATILE,  MIGRATABLE, !REDIRECTION",
45	" VOLATILE,  MIGRATABLE,  REDIRECTION",
46};
47
48const char *authUsageNever = "Never";
49const char *authUsageAlways = "Always";
50
51const char *algRsa = "RSA";
52const char *algDes = "DES";
53const char *alg3Des = "3DES";
54const char *algSha = "SHA";
55const char *algHmac = "HMAC";
56const char *algAes = "AES";
57
58const char *encNone = "None";
59const char *encRsaPkcs15 = "RSAESPKCSv15";
60const char *encRsaOaepSha1Mgf1 = "RSAESOAEP_SHA1_MGF1";
61
62const char *sigNone = "None";
63const char *sigRsaPkcs15Sha1 = "RSASSAPKCS1v15_SHA1";
64const char *sigRsaPkcs15Der = "RSASSAPKCS1v15_DER";
65
66
67const char *displayKeyUsageMap(UINT32 a_uiData)
68{
69
70	switch (a_uiData) {
71	case TSS_KEYUSAGE_SIGN:
72		return usageSigning;
73
74	case TSS_KEYUSAGE_STORAGE:
75		return usageStorage;
76
77	case TSS_KEYUSAGE_IDENTITY:
78		return usageIdentity;
79
80	case TSS_KEYUSAGE_AUTHCHANGE:
81		return usageAuthChange;
82
83	case TSS_KEYUSAGE_BIND:
84		return usageBind;
85
86	case TSS_KEYUSAGE_LEGACY:
87		return usageLegacy;
88	}
89
90	return mapUnknown;
91}
92
93const char *displayKeyFlagsMap(UINT32 a_uiFlags)
94{
95
96	int iPos = a_uiFlags & flagMax;
97
98	return flagMap[iPos];
99}
100
101const char *displayAuthUsageMap(UINT32 a_uiData)
102{
103
104	switch (a_uiData) {
105	case TPM_AUTH_NEVER:
106		return authUsageNever;
107
108	case TPM_AUTH_ALWAYS:
109		return authUsageAlways;
110	}
111
112	return mapUnknown;
113}
114
115const char *displayAlgorithmMap(UINT32 a_uiData)
116{
117
118	switch (a_uiData) {
119	case TSS_ALG_RSA:
120		return algRsa;
121
122	case TSS_ALG_DES:
123		return algDes;
124
125	case TSS_ALG_3DES:
126		return alg3Des;
127
128	case TSS_ALG_SHA:
129		return algSha;
130
131	case TSS_ALG_HMAC:
132		return algHmac;
133
134	case TSS_ALG_AES:
135		return algAes;
136	}
137
138	return mapUnknown;
139}
140
141const char *displayEncSchemeMap(UINT32 a_uiData)
142{
143
144	switch (a_uiData) {
145	case TSS_ES_NONE:
146		return encNone;
147
148	case TSS_ES_RSAESPKCSV15:
149		return encRsaPkcs15;
150
151	case TSS_ES_RSAESOAEP_SHA1_MGF1:
152		return encRsaOaepSha1Mgf1;
153	}
154
155	return mapUnknown;
156}
157
158const char *displaySigSchemeMap(UINT32 a_uiData)
159{
160
161	switch (a_uiData) {
162	case TSS_SS_NONE:
163		return sigNone;
164
165	case TSS_SS_RSASSAPKCS1V15_SHA1:
166		return sigRsaPkcs15Sha1;
167
168	case TSS_SS_RSASSAPKCS1V15_DER:
169		return sigRsaPkcs15Der;
170	}
171
172	return mapUnknown;
173}
174
175TSS_RESULT displayKey(TSS_HKEY a_hKey)
176{
177
178	TSS_RESULT result;
179	UINT32 uiAttr, uiAttrSize;
180	BYTE *pAttr;
181	UINT32 uiAlg;
182
183	result =
184	    getAttribData(a_hKey, TSS_TSPATTRIB_KEY_INFO,
185			  TSS_TSPATTRIB_KEYINFO_VERSION, &uiAttrSize,
186			  &pAttr);
187	if (result != TSS_SUCCESS)
188		return result;
189	logMsg(_("  Version:   "));
190	logHex(uiAttrSize, pAttr);
191
192	result =
193	    getAttribUint32(a_hKey, TSS_TSPATTRIB_KEY_INFO,
194			    TSS_TSPATTRIB_KEYINFO_USAGE, &uiAttr);
195	if (result != TSS_SUCCESS)
196		return result;
197	logMsg(_("  Usage:     0x%04x (%s)\n"), uiAttr, displayKeyUsageMap(uiAttr));
198
199	result =
200	    getAttribUint32(a_hKey, TSS_TSPATTRIB_KEY_INFO,
201			    TSS_TSPATTRIB_KEYINFO_KEYFLAGS, &uiAttr);
202	if (result != TSS_SUCCESS)
203		return result;
204	logMsg(_("  Flags:     0x%08x (%s)\n"), uiAttr, displayKeyFlagsMap(uiAttr));
205
206	result =
207	    getAttribUint32(a_hKey, TSS_TSPATTRIB_KEY_INFO,
208			    TSS_TSPATTRIB_KEYINFO_AUTHUSAGE, &uiAttr);
209	if (result != TSS_SUCCESS)
210		return result;
211	logMsg(_("  AuthUsage: 0x%02x (%s)\n"), uiAttr, displayAuthUsageMap(uiAttr));
212
213	result =
214	    getAttribUint32(a_hKey, TSS_TSPATTRIB_KEY_INFO,
215			    TSS_TSPATTRIB_KEYINFO_ALGORITHM, &uiAlg);
216	if (result != TSS_SUCCESS)
217		return result;
218	logMsg(_("  Algorithm:         0x%08x (%s)\n"), uiAlg, displayAlgorithmMap(uiAlg));
219
220	result =
221	    getAttribUint32(a_hKey, TSS_TSPATTRIB_KEY_INFO,
222			    TSS_TSPATTRIB_KEYINFO_ENCSCHEME, &uiAttr);
223	if (result != TSS_SUCCESS)
224		return result;
225	logMsg(_("  Encryption Scheme: 0x%08x (%s)\n"), uiAttr, displayEncSchemeMap(uiAttr));
226
227	result =
228	    getAttribUint32(a_hKey, TSS_TSPATTRIB_KEY_INFO,
229			    TSS_TSPATTRIB_KEYINFO_SIGSCHEME, &uiAttr);
230	if (result != TSS_SUCCESS)
231		return result;
232	logMsg(_("  Signature Scheme:  0x%08x (%s)\n"), uiAttr, displaySigSchemeMap(uiAttr));
233
234	if (uiAlg == TSS_ALG_RSA) {
235		result =
236		    getAttribUint32(a_hKey, TSS_TSPATTRIB_RSAKEY_INFO,
237				    TSS_TSPATTRIB_KEYINFO_RSA_KEYSIZE,
238				    &uiAttr);
239		if (result != TSS_SUCCESS)
240			return result;
241		logMsg(_("  Key Size:          %d bits\n"), uiAttr);
242	}
243
244	result =
245	    getAttribData(a_hKey, TSS_TSPATTRIB_RSAKEY_INFO,
246			  TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &uiAttrSize,
247			  &pAttr);
248	if (result != TSS_SUCCESS)
249		return result;
250	logMsg(_("  Public Key:"));
251	logHex(uiAttrSize, pAttr);
252
253	return result;
254}
255
256/*
257 * Not always reliable as this depends on the TSS system.data being intact
258 */
259BOOL isTpmOwned(TSS_HCONTEXT hContext)
260{
261
262	TSS_HKEY hSrk;
263	BOOL iRc = FALSE;
264
265	if (keyGetKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM, SRK_UUID, &hSrk)
266	    != TSS_SUCCESS)
267		goto out;
268
269	iRc = TRUE;
270
271      out:
272	return iRc;
273}
274
275void tspiDebug(const char *a_szName, TSS_RESULT a_iResult)
276{
277
278	logDebug(_("%s success\n"), a_szName);
279}
280
281void tspiError(const char *a_szName, TSS_RESULT a_iResult)
282{
283
284	logError(_("%s failed: 0x%08x - layer=%s, code=%04x (%d), %s\n"),
285		 a_szName, a_iResult, Trspi_Error_Layer(a_iResult),
286		 Trspi_Error_Code(a_iResult),
287		 Trspi_Error_Code(a_iResult),
288		 Trspi_Error_String(a_iResult));
289}
290
291void tspiResult(const char *a_szName, TSS_RESULT a_tResult)
292{
293
294	if (a_tResult == TSS_SUCCESS)
295		tspiDebug(a_szName, a_tResult);
296	else
297		tspiError(a_szName, a_tResult);
298}
299
300BOOL mapTssBool(TSS_BOOL a_bValue)
301{
302	BOOL bRc;
303
304	bRc = a_bValue ? TRUE : FALSE;
305
306	return bRc;
307}
308
309TSS_RESULT contextCreate(TSS_HCONTEXT * a_hContext)
310{
311	TSS_RESULT result = Tspi_Context_Create(a_hContext);
312	tspiResult("Tspi_Context_Create", result);
313
314	return result;
315}
316
317TSS_RESULT contextClose(TSS_HCONTEXT a_hContext)
318{
319
320	TSS_RESULT result = Tspi_Context_FreeMemory(a_hContext, NULL);
321	tspiResult("Tspi_Context_FreeMemory", result);
322
323	result = Tspi_Context_Close(a_hContext);
324	tspiResult("Tspi_Context_Close", result);
325
326	return result;
327}
328
329TSS_RESULT contextConnect(TSS_HCONTEXT a_hContext)
330{
331
332	TSS_RESULT result = Tspi_Context_Connect(a_hContext, NULL);
333	tspiResult("Tspi_Context_Connect", result);
334
335	return result;
336}
337
338
339TSS_RESULT
340contextCreateObject(TSS_HCONTEXT a_hContext,
341		    TSS_FLAG a_fType,
342		    TSS_FLAG a_fAttrs, TSS_HOBJECT * a_hObject)
343{
344	TSS_RESULT result =
345	    Tspi_Context_CreateObject(a_hContext, a_fType, a_fAttrs,
346				      a_hObject);
347	tspiResult("Tspi_Context_CreateObject", result);
348
349	return result;
350}
351
352TSS_RESULT
353contextCloseObject(TSS_HCONTEXT a_hContext, TSS_HOBJECT a_hObject)
354{
355	TSS_RESULT result =
356	    Tspi_Context_CloseObject(a_hContext, a_hObject);
357	tspiResult("Tspi_Context_CloseObject", result);
358
359	return result;
360}
361
362TSS_RESULT contextGetTpm(TSS_HCONTEXT a_hContext, TSS_HTPM * a_hTpm)
363{
364
365	TSS_RESULT result = Tspi_Context_GetTpmObject(a_hContext, a_hTpm);
366	tspiResult("Tspi_Context_GetTpmObject", result);
367
368	return result;
369}
370
371
372TSS_RESULT policyGet(TSS_HOBJECT a_hObject, TSS_HPOLICY * a_hPolicy)
373{
374	TSS_RESULT result =
375	    Tspi_GetPolicyObject(a_hObject, TSS_POLICY_USAGE, a_hPolicy);
376	tspiResult("Tspi_GetPolicyObject", result);
377
378	return result;
379}
380
381TSS_RESULT policyAssign(TSS_HPOLICY a_hPolicy, TSS_HOBJECT a_hObject)
382{
383	TSS_RESULT result =
384	    Tspi_Policy_AssignToObject(a_hPolicy, a_hObject);
385	tspiResult("Tspi_Policy_AssignToObject", result);
386
387	return result;
388}
389
390TSS_RESULT
391policySetSecret(TSS_HPOLICY a_hPolicy,
392		UINT32 a_uiSecretLen, BYTE * a_chSecret)
393{
394	TSS_RESULT result;
395	BYTE wellKnown[] = TSS_WELL_KNOWN_SECRET;
396
397	//If secret is TSS_WELL_KNOWN_SECRET, change secret mode to TSS_SECRET_MODE_SHA1
398	if (a_chSecret &&
399	    a_uiSecretLen == sizeof(wellKnown) &&
400	    !memcmp(a_chSecret, (BYTE *)wellKnown, sizeof(wellKnown)))
401		result =
402			Tspi_Policy_SetSecret(a_hPolicy, TSS_SECRET_MODE_SHA1,
403					a_uiSecretLen, a_chSecret);
404	else
405		result =
406			Tspi_Policy_SetSecret(a_hPolicy, TSS_SECRET_MODE_PLAIN,
407					a_uiSecretLen, a_chSecret);
408	tspiResult("Tspi_Policy_SetSecret", result);
409
410	return result;
411}
412
413TSS_RESULT policyFlushSecret(TSS_HPOLICY a_hPolicy)
414{
415	TSS_RESULT result = Tspi_Policy_FlushSecret(a_hPolicy);
416	tspiResult("Tspi_Policy_FlushSecret", result);
417
418	return result;
419}
420
421TSS_RESULT
422tpmGetPubEk(TSS_HTPM a_hTpm,
423	    TSS_BOOL a_fOwner,
424	    TSS_VALIDATION * a_pValData, TSS_HKEY * a_phEPubKey)
425{
426
427	TSS_RESULT result = Tspi_TPM_GetPubEndorsementKey(a_hTpm, a_fOwner,
428							  a_pValData,
429							  a_phEPubKey);
430	tspiResult("Tspi_TPM_GetPubEndorsementKey", result);
431
432	return result;
433}
434
435TSS_RESULT
436tpmSetStatus(TSS_HTPM a_hTpm, TSS_FLAG a_fStatus, TSS_BOOL a_bValue)
437{
438
439	TSS_RESULT result =
440	    Tspi_TPM_SetStatus(a_hTpm, a_fStatus, a_bValue);
441	tspiResult("Tspi_TPM_SetStatus", result);
442
443	return result;
444}
445
446TSS_RESULT
447tpmGetStatus(TSS_HTPM a_hTpm, TSS_FLAG a_fStatus, TSS_BOOL * a_bValue)
448{
449
450	TSS_RESULT result =
451	    Tspi_TPM_GetStatus(a_hTpm, a_fStatus, a_bValue);
452	tspiResult("Tspi_TPM_GetStatus", result);
453
454	return result;
455}
456
457TSS_RESULT tpmGetRandom(TSS_HTPM a_hTpm, UINT32 a_length, BYTE ** a_data)
458{
459
460	TSS_RESULT result = Tspi_TPM_GetRandom(a_hTpm, a_length, a_data);
461	tspiResult("Tspi_TPM_GetRandom", result);
462
463	return result;
464}
465
466
467TSS_RESULT keyLoadKey(TSS_HKEY a_hKey, TSS_HKEY a_hWrapKey)
468{
469
470	TSS_RESULT result = Tspi_Key_LoadKey(a_hKey, a_hWrapKey);
471	tspiResult("Tspi_Key_LoadKey", result);
472
473	return result;
474}
475
476TSS_RESULT
477keyLoadKeyByUUID(TSS_HCONTEXT a_hContext,
478		 TSS_FLAG a_fStoreType,
479		 TSS_UUID a_uKeyId, TSS_HKEY * a_hKey)
480{
481	TSS_RESULT result =
482	    Tspi_Context_LoadKeyByUUID(a_hContext, a_fStoreType, a_uKeyId,
483				       a_hKey);
484	tspiResult("Tspi_Context_LoadKeyByUUID", result);
485
486	return result;
487}
488
489TSS_RESULT
490keyGetPubKey(TSS_HKEY a_hKey, UINT32 * a_uiKeyLen, BYTE ** a_pKey)
491{
492
493	TSS_RESULT result = Tspi_Key_GetPubKey(a_hKey, a_uiKeyLen, a_pKey);
494	tspiResult("Tspi_Key_GetPubKey", result);
495
496	return result;
497}
498
499TSS_RESULT
500keyGetKeyByUUID(TSS_HCONTEXT a_hContext,
501		TSS_FLAG a_fStoreType,
502		TSS_UUID a_uKeyId, TSS_HKEY * a_hKey)
503{
504
505	TSS_RESULT result =
506	    Tspi_Context_GetKeyByUUID(a_hContext, a_fStoreType, a_uKeyId,
507				      a_hKey);
508	tspiResult("Tspi_Context_GetKeyByUUID", result);
509
510	return result;
511}
512
513TSS_RESULT
514getAttribData(TSS_HOBJECT a_hObject,
515	      TSS_FLAG a_fAttr,
516	      TSS_FLAG a_fSubAttr, UINT32 * a_uiSize, BYTE ** a_pData)
517{
518
519	TSS_RESULT result =
520	    Tspi_GetAttribData(a_hObject, a_fAttr, a_fSubAttr, a_uiSize,
521			       a_pData);
522	tspiResult("Tspi_GetAttribData", result);
523
524	return result;
525}
526
527TSS_RESULT
528getAttribUint32(TSS_HOBJECT a_hObject,
529		TSS_FLAG a_fAttr, TSS_FLAG a_fSubAttr, UINT32 * a_uiData)
530{
531
532	TSS_RESULT result =
533	    Tspi_GetAttribUint32(a_hObject, a_fAttr, a_fSubAttr, a_uiData);
534	tspiResult("Tspi_GetAttribUint32", result);
535
536	return result;
537}
538
539TSS_RESULT
540getCapability(TSS_HTPM a_hTpm,
541	      TSS_FLAG a_fCapArea,
542	      UINT32 a_uiSubCapLen,
543	      BYTE * a_pSubCap, UINT32 * a_uiResultLen, BYTE ** a_pResult)
544{
545	TSS_RESULT result =
546	    Tspi_TPM_GetCapability(a_hTpm, a_fCapArea, a_uiSubCapLen,
547				   a_pSubCap, a_uiResultLen, a_pResult);
548	tspiResult("Tspi_TPM_GetCapability", result);
549
550	return result;
551}
552
553TSS_RESULT
554keyCreateKey(TSS_HKEY a_hKey, TSS_HKEY a_hWrapKey,
555		TSS_HPCRS a_hPcrs)
556{
557	TSS_RESULT result = Tspi_Key_CreateKey(a_hKey, a_hWrapKey, a_hPcrs);
558	tspiResult("Tspi_Key_CreateKey", result);
559
560	return result;
561}
562
563TSS_RESULT dataSeal(TSS_HENCDATA a_hEncdata, TSS_HKEY a_hKey,
564			UINT32 a_len, BYTE * a_data,
565			TSS_HPCRS a_hPcrs)
566{
567
568	TSS_RESULT result =
569		Tspi_Data_Seal(a_hEncdata, a_hKey, a_len, a_data, a_hPcrs);
570	tspiResult("Tspi_Data_Seal", result);
571
572	return result;
573}
574
575TSS_RESULT
576tpmPcrRead(TSS_HTPM a_hTpm, UINT32 a_Idx,
577		UINT32 *a_PcrSize, BYTE **a_PcrValue)
578{
579	TSS_RESULT result =
580		Tspi_TPM_PcrRead(a_hTpm, a_Idx, a_PcrSize, a_PcrValue);
581	tspiResult("Tspi_TPM_PcrRead", result);
582
583	return result;
584}
585
586TSS_RESULT
587pcrcompositeSetPcrValue(TSS_HPCRS a_hPcrs, UINT32 a_Idx,
588			UINT32 a_PcrSize, BYTE *a_PcrValue)
589{
590	TSS_RESULT result =
591		Tspi_PcrComposite_SetPcrValue(a_hPcrs, a_Idx, a_PcrSize, a_PcrValue);
592	tspiResult("Tspi_PcrComposite_SetPcrValue", result);
593
594	return result;
595}
596
597#ifdef TSS_LIB_IS_12
598/*
599 * These getPasswd functions will wrap calls to the other functions and check to see if the TSS
600 * library's context tells us to remove the NULL terminating chars from the end of the password
601 * when unicode is on.
602 */
603char *
604getPasswd12(const char *a_pszPrompt, int* a_iLen, BOOL a_bConfirm)
605{
606	return _getPasswd12( a_pszPrompt, a_iLen, a_bConfirm, useUnicode);
607}
608
609char *_getPasswd12(const char *a_pszPrompt, int* a_iLen, BOOL a_bConfirm, BOOL a_bUseUnicode)
610{
611	UINT32 status;
612	char *passwd;
613
614	passwd = _getPasswd(a_pszPrompt, a_iLen, a_bConfirm, a_bUseUnicode);
615
616	if (passwd && a_bUseUnicode) {
617		/* If we're running against a 1.2 TSS, it will include the null terminating
618		 * characters based on the TSS_TSPATTRIB_SECRET_HASH_MODE attribute of the
619		 * context. If this is set to TSS_TSPATTRIB_HASH_MODE_NOT_NULL, we need to
620		 * trim the two zeros off the end of the unicode string returned by
621		 * Trspi_Native_To_UNICODE. */
622		if (getAttribUint32(hContext, TSS_TSPATTRIB_SECRET_HASH_MODE,
623				    TSS_TSPATTRIB_SECRET_HASH_MODE_POPUP, &status))
624			goto out;
625
626		if (status == TSS_TSPATTRIB_HASH_MODE_NOT_NULL)
627			*a_iLen -= sizeof(TSS_UNICODE);
628	}
629out:
630	return passwd;
631}
632
633TSS_RESULT
634unloadVersionInfo(UINT64 *offset, BYTE *blob, TPM_CAP_VERSION_INFO *v)
635{
636	TSS_RESULT result = Trspi_UnloadBlob_CAP_VERSION_INFO(offset, blob, v);
637	tspiResult("Trspi_UnloadBlob_CAP_VERSION_INFO", result);
638	return result;
639}
640
641TSS_RESULT
642pcrcompositeSetPcrLocality(TSS_HPCRS a_hPcrs, UINT32 localityValue)
643{
644	TSS_RESULT result =
645		Tspi_PcrComposite_SetPcrLocality(a_hPcrs, localityValue);
646	tspiResult("Tspi_PcrComposite_SetPcrLocality", result);
647
648	return result;
649}
650
651TSS_RESULT
652NVDefineSpace(TSS_HNVSTORE hNVStore, TSS_HPCRS hReadPcrComposite ,
653              TSS_HPCRS hWritePcrComposite)
654{
655	TSS_RESULT result =
656	        Tspi_NV_DefineSpace(hNVStore, hReadPcrComposite,
657	                            hWritePcrComposite);
658
659	tspiResult("Tspi_NV_DefineSpace", result);
660
661	return result;
662}
663
664TSS_RESULT
665NVReleaseSpace(TSS_HNVSTORE hNVStore)
666{
667	TSS_RESULT result =
668	        Tspi_NV_ReleaseSpace(hNVStore);
669
670	tspiResult("Tspi_NV_ReleaseSpace", result);
671
672	return result;
673}
674
675TSS_RESULT
676NVWriteValue(TSS_HNVSTORE hNVStore, UINT32 offset,
677             UINT32 ulDataLength, BYTE *rgbDataToWrite)
678{
679	TSS_RESULT result =
680	        Tspi_NV_WriteValue(hNVStore, offset,
681	                           ulDataLength, rgbDataToWrite);
682
683	tspiResult("Tspi_NV_WriteValue", result);
684
685	return result;
686}
687
688TSS_RESULT
689NVReadValue(TSS_HNVSTORE hNVStore, UINT32 offset,
690            UINT32 *ulDataLength, BYTE **rgbDataRead)
691{
692	TSS_RESULT result =
693	        Tspi_NV_ReadValue(hNVStore, offset,
694	                          ulDataLength, rgbDataRead);
695
696	tspiResult("Tspi_NV_ReadValue", result);
697
698	return result;
699}
700
701TSS_RESULT
702unloadNVDataPublic(UINT64 *offset, BYTE *blob, UINT32 blob_len, TPM_NV_DATA_PUBLIC *v)
703{
704	UINT64 off = *offset;
705	TSS_RESULT result;
706	result = Trspi_UnloadBlob_NV_DATA_PUBLIC(&off, blob, NULL);
707	if (result == TSS_SUCCESS) {
708		if (off > blob_len)
709			return TSS_E_BAD_PARAMETER;
710		result = Trspi_UnloadBlob_NV_DATA_PUBLIC(offset, blob, v);
711	}
712	tspiResult("Trspi_UnloadBlob_NV_DATA_PUBLIC", result);
713	return result;
714}
715
716
717#endif
718