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_CreateMaintenanceArchive(TSS_HTPM hTPM,TSS_BOOL fGenerateRndNumber,UINT32 * pulRndNumberLength,BYTE ** prgbRndNumber,UINT32 * pulArchiveDataLength,BYTE ** prgbArchiveData)26 Tspi_TPM_CreateMaintenanceArchive(TSS_HTPM hTPM,                      /* in */
27                                           TSS_BOOL fGenerateRndNumber,                    /* in */
28                                           UINT32 * pulRndNumberLength,                    /* out */
29                                           BYTE ** prgbRndNumber,                /* out */
30                                           UINT32 * pulArchiveDataLength,        /* out */
31                                           BYTE ** prgbArchiveData)              /* out */
32 {
33           TSS_RESULT result;
34           TSS_HCONTEXT tspContext;
35           TSS_HPOLICY hOwnerPolicy;
36           TPM_AUTH ownerAuth;
37           TCPA_DIGEST digest;
38           Trspi_HashCtx hashCtx;
39 
40           if (pulArchiveDataLength == NULL || prgbArchiveData == NULL)
41                     return TSPERR(TSS_E_BAD_PARAMETER);
42 
43           if (fGenerateRndNumber &&
44               (pulRndNumberLength == NULL || prgbRndNumber == NULL))
45                     return TSPERR(TSS_E_BAD_PARAMETER);
46 
47           if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
48                     return result;
49 
50           if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy)))
51                     return result;
52 
53           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
54           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CreateMaintenanceArchive);
55           result |= Trspi_Hash_BYTE(&hashCtx, fGenerateRndNumber);
56           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
57                     return result;
58 
59           if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_CreateMaintenanceArchive, hOwnerPolicy,
60                                                         FALSE, &digest, &ownerAuth)))
61                     return result;
62 
63           if ((result = TCS_API(tspContext)->CreateMaintenanceArchive(tspContext, fGenerateRndNumber,
64                                                                                     &ownerAuth, pulRndNumberLength,
65                                                                                     prgbRndNumber,
66                                                                                     pulArchiveDataLength,
67                                                                                     prgbArchiveData)))
68                     return result;
69 
70           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
71           result |= Trspi_Hash_UINT32(&hashCtx, result);
72           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_CreateMaintenanceArchive);
73           result |= Trspi_Hash_UINT32(&hashCtx, *pulRndNumberLength);
74           result |= Trspi_HashUpdate(&hashCtx, *pulRndNumberLength, *prgbRndNumber);
75           result |= Trspi_Hash_UINT32(&hashCtx, *pulArchiveDataLength);
76           result |= Trspi_HashUpdate(&hashCtx, *pulArchiveDataLength, *prgbArchiveData);
77           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
78                     goto error1;
79 
80           if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &ownerAuth)))
81                     goto error1;
82 
83           if ((result = __tspi_add_mem_entry(tspContext, *prgbRndNumber)))
84                     goto error1;
85 
86           if ((result = __tspi_add_mem_entry(tspContext, *prgbArchiveData))) {
87                     free_tspi(tspContext, *prgbRndNumber);
88                     goto error2;
89           }
90 
91           return TSS_SUCCESS;
92 error1:
93           free(*prgbRndNumber);
94 error2:
95           free(*prgbArchiveData);
96           return result;
97 }
98 
99 TSS_RESULT
Tspi_TPM_KillMaintenanceFeature(TSS_HTPM hTPM)100 Tspi_TPM_KillMaintenanceFeature(TSS_HTPM hTPM)    /*  in */
101 {
102           TSS_RESULT result;
103           TSS_HCONTEXT tspContext;
104           TSS_HPOLICY hOwnerPolicy;
105           TPM_AUTH ownerAuth;
106           TCPA_DIGEST digest;
107           Trspi_HashCtx hashCtx;
108 
109           if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
110                     return result;
111 
112           if ((result = obj_tpm_get_policy(hTPM, TSS_POLICY_USAGE, &hOwnerPolicy)))
113                     return result;
114 
115           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
116           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KillMaintenanceFeature);
117           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
118                     return result;
119 
120           if ((result = secret_PerformAuth_OIAP(hTPM, TPM_ORD_KillMaintenanceFeature, hOwnerPolicy,
121                                                         FALSE, &digest, &ownerAuth)))
122                     return result;
123 
124           if ((result = TCS_API(tspContext)->KillMaintenanceFeature(tspContext, &ownerAuth)))
125                     return result;
126 
127           result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
128           result |= Trspi_Hash_UINT32(&hashCtx, result);
129           result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_KillMaintenanceFeature);
130           if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
131                     return result;
132 
133           if ((result = obj_policy_validate_auth_oiap(hOwnerPolicy, &digest, &ownerAuth)))
134                     return result;
135 
136           return TSS_SUCCESS;
137 }
138 
139 TSS_RESULT
Tspi_TPM_LoadMaintenancePubKey(TSS_HTPM hTPM,TSS_HKEY hMaintenanceKey,TSS_VALIDATION * pValidationData)140 Tspi_TPM_LoadMaintenancePubKey(TSS_HTPM hTPM,                                   /* in */
141                                      TSS_HKEY hMaintenanceKey,                  /* in */
142                                      TSS_VALIDATION * pValidationData)          /* in, out */
143 {
144           TSS_RESULT result;
145           TSS_HCONTEXT tspContext;
146           TCPA_DIGEST checkSum, digest;
147           TCPA_NONCE nonce;
148           UINT64 offset;
149           UINT32 pubBlobSize;
150           BYTE hashBlob[512], *pubBlob;
151 
152           if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
153                     return result;
154 
155           if (pValidationData == NULL) {
156                     if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE),
157                                                          (BYTE **)nonce.nonce)))
158                               return result;
159           } else {
160                     if (pValidationData->ulExternalDataLength < sizeof(nonce.nonce))
161                               return TSPERR(TSS_E_BAD_PARAMETER);
162 
163                     memcpy(&nonce.nonce, pValidationData->rgbExternalData, sizeof(nonce.nonce));
164           }
165 
166           if ((result = obj_rsakey_get_pub_blob(hMaintenanceKey, &pubBlobSize, &pubBlob)))
167                     return result;
168 
169           if ((result = TCS_API(tspContext)->LoadManuMaintPub(tspContext, nonce, pubBlobSize, pubBlob,
170                                                                           &checkSum)))
171                     return result;
172 
173           offset = 0;
174           Trspi_LoadBlob(&offset, pubBlobSize, hashBlob, pubBlob);
175           Trspi_LoadBlob(&offset, TCPA_SHA1_160_HASH_LEN, hashBlob, (BYTE *)&nonce.nonce);
176 
177           if (pValidationData == NULL) {
178                     if ((result = Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, digest.digest)))
179                               return result;
180 
181                     if (memcmp(&digest.digest, &checkSum.digest, TCPA_SHA1_160_HASH_LEN))
182                               result = TSPERR(TSS_E_FAIL);
183           } else {
184                     if ((pValidationData->rgbData = calloc_tspi(tspContext, offset)) == NULL)
185                               return TSPERR(TSS_E_OUTOFMEMORY);
186 
187                     pValidationData->ulDataLength = offset;
188                     memcpy(pValidationData->rgbData, hashBlob, offset);
189 
190                     if ((pValidationData->rgbValidationData = calloc_tspi(tspContext,
191                                                                                       TPM_SHA1_160_HASH_LEN))
192                          == NULL) {
193                               free_tspi(tspContext, pValidationData->rgbData);
194                               pValidationData->rgbData = NULL;
195                               pValidationData->ulDataLength = 0;
196                               return TSPERR(TSS_E_OUTOFMEMORY);
197                     }
198                     pValidationData->ulValidationDataLength = TCPA_SHA1_160_HASH_LEN;
199 
200                     memcpy(pValidationData->rgbValidationData, checkSum.digest, TCPA_SHA1_160_HASH_LEN);
201           }
202 
203           return result;
204 }
205 
206 TSS_RESULT
Tspi_TPM_CheckMaintenancePubKey(TSS_HTPM hTPM,TSS_HKEY hMaintenanceKey,TSS_VALIDATION * pValidationData)207 Tspi_TPM_CheckMaintenancePubKey(TSS_HTPM hTPM,                                  /* in */
208                                         TSS_HKEY hMaintenanceKey,               /* in */
209                                         TSS_VALIDATION * pValidationData)       /* in, out */
210 {
211           TSS_RESULT result;
212           TSS_HCONTEXT tspContext;
213           TCPA_DIGEST checkSum, digest;
214           TCPA_NONCE nonce;
215           UINT32 pubBlobSize;
216           BYTE *pubBlob;
217           Trspi_HashCtx hashCtx;
218 
219           if ((pValidationData && hMaintenanceKey) || (!pValidationData && !hMaintenanceKey))
220                     return TSPERR(TSS_E_BAD_PARAMETER);
221 
222           if ((result = obj_tpm_get_tsp_context(hTPM, &tspContext)))
223                     return result;
224 
225           if (pValidationData == NULL) {
226                     if ((result = get_local_random(tspContext, FALSE, sizeof(TCPA_NONCE),
227                                                          (BYTE **)nonce.nonce)))
228                               return result;
229           } else {
230                     if (pValidationData->ulExternalDataLength < sizeof(nonce.nonce))
231                               return TSPERR(TSS_E_BAD_PARAMETER);
232 
233                     memcpy(&nonce.nonce, pValidationData->rgbExternalData, sizeof(nonce.nonce));
234           }
235 
236           if ((result = TCS_API(tspContext)->ReadManuMaintPub(tspContext, nonce, &checkSum)))
237                     return result;
238 
239           if (pValidationData == NULL) {
240                     if ((result = obj_rsakey_get_pub_blob(hMaintenanceKey, &pubBlobSize, &pubBlob)))
241                               return result;
242 
243                     result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
244                     result |= Trspi_HashUpdate(&hashCtx, pubBlobSize, pubBlob);
245                     result |= Trspi_HashUpdate(&hashCtx, TCPA_SHA1_160_HASH_LEN, (BYTE *)&nonce.nonce);
246                     if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
247                               return result;
248 
249                     if (memcmp(&digest.digest, &checkSum.digest, TCPA_SHA1_160_HASH_LEN))
250                               result = TSPERR(TSS_E_FAIL);
251 
252                     free_tspi(tspContext, pubBlob);
253           } else {
254                     /* Ignore Data and DataLength, the application must already have this data.
255                      * Do, however, copy out the checksum so that the application can verify */
256                     if ((pValidationData->rgbValidationData = calloc_tspi(tspContext,
257                                                                                       TCPA_SHA1_160_HASH_LEN))
258                          == NULL) {
259                               return TSPERR(TSS_E_OUTOFMEMORY);
260                     }
261 
262                     pValidationData->ulValidationDataLength = TCPA_SHA1_160_HASH_LEN;
263                     memcpy(pValidationData->rgbValidationData, checkSum.digest, TCPA_SHA1_160_HASH_LEN);
264           }
265 
266           return result;
267 }
268 
269