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