1 
2 /*
3  * Licensed Materials - Property of IBM
4  *
5  * trousers - An open source TCG Software Stack
6  *
7  * (C) Copyright International Business Machines Corp. 2004-2006
8  *
9  */
10 
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <inttypes.h>
15 
16 #include "trousers/tss.h"
17 #include "trousers/trousers.h"
18 #include "trousers_types.h"
19 #include "spi_utils.h"
20 #include "capabilities.h"
21 #include "tsplog.h"
22 #include "obj.h"
23 
24 
25 TSS_RESULT
Tspi_TPM_SelfTestFull(TSS_HTPM hTPM)26 Tspi_TPM_SelfTestFull(TSS_HTPM hTPM)	/*  in */
27 {
28 	TSS_RESULT result;
29 	TSS_HCONTEXT tspContext;
30 
31 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
32 		return result;
33 
34 	return TCS_API(tspContext)->SelfTestFull(tspContext);
35 }
36 
37 TSS_RESULT
Tspi_TPM_CertifySelfTest(TSS_HTPM hTPM,TSS_HKEY hKey,TSS_VALIDATION * pValidationData)38 Tspi_TPM_CertifySelfTest(TSS_HTPM hTPM,				/* in */
39 			 TSS_HKEY hKey,				/* in */
40 			 TSS_VALIDATION *pValidationData)	/* in, out */
41 {
42 	TCPA_RESULT result;
43 	TPM_AUTH keyAuth;
44 	UINT64 offset = 0;
45 	TCPA_DIGEST digest;
46 	TCPA_NONCE antiReplay;
47 	UINT32 outDataSize;
48 	BYTE *outData;
49 	TSS_HPOLICY hPolicy;
50 	TCS_KEY_HANDLE keyTCSKeyHandle;
51 	BYTE *keyData = NULL;
52 	UINT32 keyDataSize;
53 	TSS_KEY keyContainer;
54 	TPM_AUTH *pKeyAuth;
55 	TSS_BOOL useAuth;
56 	TSS_HCONTEXT tspContext;
57 	Trspi_HashCtx hashCtx;
58 
59 
60 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
61 		return result;
62 
63 	if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE,
64 					    &hPolicy, &useAuth)))
65 		return result;
66 
67 	if ((result = obj_rsakey_get_tcs_handle(hKey, &keyTCSKeyHandle)))
68 		return result;
69 
70 	if (pValidationData == NULL) {
71 		if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE),
72 					       (BYTE **)antiReplay.nonce))) {
73 			LogError("Failed creating random nonce");
74 			return TSPERR(TSS_E_INTERNAL_ERROR);
75 		}
76 	} else {
77 		if (pValidationData->ulExternalDataLength < sizeof(antiReplay.nonce))
78 			return TSPERR(TSS_E_BAD_PARAMETER);
79 
80 		memcpy(antiReplay.nonce, pValidationData->rgbExternalData,
81 		       sizeof(antiReplay.nonce));
82 	}
83 
84 	if (useAuth) {
85 		LogDebug("Uses Auth");
86 
87 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
88 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifySelfTest);
89 		result |= Trspi_HashUpdate(&hashCtx, sizeof(TCPA_NONCE), antiReplay.nonce);
90 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
91 			return result;
92 
93 		if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_CertifySelfTest, hPolicy, FALSE,
94 						      &digest, &keyAuth)))
95 			return result;
96 		pKeyAuth = &keyAuth;
97 	} else {
98 		LogDebug("No Auth");
99 		pKeyAuth = NULL;
100 	}
101 
102 	if ((result = TCS_API(tspContext)->CertifySelfTest(tspContext, keyTCSKeyHandle, antiReplay,
103 							   pKeyAuth, &outDataSize, &outData)))
104 		return result;
105 
106 	/* validate auth */
107 	if (useAuth) {
108 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
109 		result |= Trspi_Hash_UINT32(&hashCtx, result);
110 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifySelfTest);
111 		result |= Trspi_Hash_UINT32(&hashCtx, outDataSize);
112 		result |= Trspi_HashUpdate(&hashCtx, outDataSize, outData);
113 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
114 			return result;
115 
116 		if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, &keyAuth)))
117 			return result;
118 	}
119 
120 	if (pValidationData == NULL) {
121 		if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
122 				       TSS_TSPATTRIB_KEYBLOB_BLOB, &keyDataSize, &keyData))) {
123 			LogError("Failed call to GetAttribData to get key blob");
124 			return TSPERR(TSS_E_INTERNAL_ERROR);
125 		}
126 
127 		offset = 0;
128 		__tspi_memset(&keyContainer, 0, sizeof(TSS_KEY));
129 		if ((result = UnloadBlob_TSS_KEY(&offset, keyData, &keyContainer)))
130 			return result;
131 
132 		result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
133 		result |= Trspi_HashUpdate(&hashCtx, strlen("Test Passed"), (BYTE *)"Test Passed");
134 		result |= Trspi_HashUpdate(&hashCtx, sizeof(TCPA_NONCE), antiReplay.nonce);
135 		result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CertifySelfTest);
136 		if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
137 			return result;
138 
139 		if ((result = Trspi_Verify(TSS_HASH_SHA1, digest.digest, 20,
140 					 keyContainer.pubKey.key, keyContainer.pubKey.keyLength,
141 					 outData, outDataSize))) {
142 			free(outData);
143 			free_key_refs(&keyContainer);
144 			return TSPERR(TSS_E_VERIFICATION_FAILED);
145 		}
146 
147 	} else {
148 		pValidationData->ulDataLength = sizeof(TCPA_NONCE) + sizeof(UINT32) +
149 						strlen("Test Passed");
150 		pValidationData->rgbData = calloc_tspi(tspContext, pValidationData->ulDataLength);
151 		if (pValidationData->rgbData == NULL) {
152 			LogError("malloc of %u bytes failed.", pValidationData->ulDataLength);
153 			pValidationData->ulDataLength = 0;
154 			return TSPERR(TSS_E_OUTOFMEMORY);
155 		}
156 		offset = 0;
157 		Trspi_LoadBlob(&offset, strlen("Test Passed"), pValidationData->rgbData,
158 			       (BYTE *)"Test Passed");
159 		Trspi_LoadBlob(&offset, sizeof(TCPA_NONCE), pValidationData->rgbData,
160 			       antiReplay.nonce);
161 		Trspi_LoadBlob_UINT32(&offset, TPM_ORD_CertifySelfTest, pValidationData->rgbData);
162 		pValidationData->ulValidationDataLength = outDataSize;
163 		pValidationData->rgbValidationData = calloc_tspi(tspContext, outDataSize);
164 		if (pValidationData->rgbValidationData == NULL) {
165 			free_tspi(tspContext, pValidationData->rgbData);
166 			pValidationData->rgbData = NULL;
167 			pValidationData->ulDataLength = 0;
168 			LogError("malloc of %u bytes failed.",
169 				 pValidationData->ulValidationDataLength);
170 			pValidationData->ulValidationDataLength = 0;
171 			return TSPERR(TSS_E_OUTOFMEMORY);
172 		}
173 		memcpy(pValidationData->rgbValidationData, outData, outDataSize);
174 		free(outData);
175 	}
176 
177 	return TSS_SUCCESS;
178 }
179 
180 TSS_RESULT
Tspi_TPM_GetTestResult(TSS_HTPM hTPM,UINT32 * pulTestResultLength,BYTE ** prgbTestResult)181 Tspi_TPM_GetTestResult(TSS_HTPM hTPM,			/* in */
182 		       UINT32 * pulTestResultLength,	/* out */
183 		       BYTE ** prgbTestResult)		/* out */
184 {
185 	TSS_HCONTEXT tspContext;
186 	TSS_RESULT result;
187 
188 	if (pulTestResultLength == NULL || prgbTestResult == NULL)
189 		return TSPERR(TSS_E_BAD_PARAMETER);
190 
191 	if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
192 		return result;
193 
194 	if ((result = TCS_API(tspContext)->GetTestResult(tspContext, pulTestResultLength,
195 							 prgbTestResult)))
196 		return result;
197 
198 	if ((result = __tspi_add_mem_entry(tspContext, *prgbTestResult))) {
199 		free(*prgbTestResult);
200 		*prgbTestResult = NULL;
201 		*pulTestResultLength = 0;
202 	}
203 
204 	return TSS_SUCCESS;
205 }
206 
207