xref: /netbsd-src/crypto/external/cpl/trousers/dist/src/tspi/tspi_maint.c (revision 1023804e3833a0bd94414f2545512128f6502c74)
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