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-2007
8 *
9 */
10
11
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.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 #include "authsess.h"
24
25
26 TSS_RESULT
Tspi_Data_Seal(TSS_HENCDATA hEncData,TSS_HKEY hEncKey,UINT32 ulDataLength,BYTE * rgbDataToSeal,TSS_HPCRS hPcrComposite)27 Tspi_Data_Seal(TSS_HENCDATA hEncData, /* in */
28 TSS_HKEY hEncKey, /* in */
29 UINT32 ulDataLength, /* in */
30 BYTE * rgbDataToSeal, /* in */
31 TSS_HPCRS hPcrComposite) /* in */
32 {
33 TPM_DIGEST digest;
34 TSS_RESULT result;
35 TSS_HPOLICY hPolicy, hEncPolicy;
36 BYTE *encData = NULL;
37 BYTE *pcrData = NULL;
38 UINT32 encDataSize;
39 UINT32 pcrDataSize;
40 UINT32 pcrInfoType = TSS_PCRS_STRUCT_DEFAULT;
41 UINT32 sealOrdinal = TPM_ORD_Seal;
42 TCS_KEY_HANDLE tcsKeyHandle;
43 TSS_HCONTEXT tspContext;
44 Trspi_HashCtx hashCtx;
45 BYTE *sealData = NULL;
46 struct authsess *xsap = NULL;
47 #ifdef TSS_BUILD_SEALX
48 UINT32 protectMode;
49 #endif
50
51 if (rgbDataToSeal == NULL)
52 return TSPERR(TSS_E_BAD_PARAMETER);
53
54 if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext)))
55 return result;
56
57 if ((result = obj_rsakey_get_policy(hEncKey, TSS_POLICY_USAGE,
58 &hPolicy, NULL)))
59 return result;
60
61 if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE,
62 &hEncPolicy)))
63 return result;
64
65 if ((result = obj_rsakey_get_tcs_handle(hEncKey, &tcsKeyHandle)))
66 return result;
67
68 #ifdef TSS_BUILD_SEALX
69 /* Get the TSS_TSPATTRIB_ENCDATASEAL_PROTECT_MODE attribute
70 to determine the seal function to invoke */
71 if ((result = obj_encdata_get_seal_protect_mode(hEncData, &protectMode)))
72 return result;
73
74 if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_NO_PROTECT) {
75 sealOrdinal = TPM_ORD_Seal;
76 pcrInfoType = 0;
77 } else if (protectMode == TSS_TSPATTRIB_ENCDATASEAL_PROTECT) {
78 sealOrdinal = TPM_ORD_Sealx;
79 pcrInfoType = TSS_PCRS_STRUCT_INFO_LONG;
80 } else
81 return TSPERR(TSS_E_INTERNAL_ERROR);
82 #endif
83
84 /* If PCR's are of interest */
85 pcrDataSize = 0;
86 if (hPcrComposite) {
87 if ((result = obj_pcrs_create_info_type(hPcrComposite, &pcrInfoType, &pcrDataSize,
88 &pcrData)))
89 return result;
90 }
91
92 if ((result = authsess_xsap_init(tspContext, hEncKey, hEncData, TSS_AUTH_POLICY_REQUIRED,
93 sealOrdinal, TPM_ET_KEYHANDLE, &xsap)))
94 goto error;
95
96 #ifdef TSS_BUILD_SEALX
97 if (sealOrdinal == TPM_ORD_Seal)
98 sealData = rgbDataToSeal;
99 else {
100 if ((sealData = (BYTE *)calloc(1, ulDataLength)) == NULL) {
101 LogError("malloc of %u bytes failed", ulDataLength);
102 result = TSPERR(TSS_E_OUTOFMEMORY);
103 goto error;
104 }
105
106 if ((result =
107 ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID,
108 UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *,
109 BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hEncKey, hEncData,
110 xsap->cb_sealx.alg, sizeof(TPM_NONCE),
111 xsap->auth.NonceEven.nonce,
112 xsap->auth.NonceOdd.nonce,
113 xsap->nonceEvenxSAP.nonce,
114 xsap->nonceOddxSAP.nonce, ulDataLength,
115 rgbDataToSeal, sealData)))
116 goto error;
117 }
118 #else
119 sealData = rgbDataToSeal;
120 #endif
121
122 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
123 result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal);
124 result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
125 result |= Trspi_Hash_UINT32(&hashCtx, pcrDataSize);
126 result |= Trspi_HashUpdate(&hashCtx, pcrDataSize, pcrData);
127 result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength);
128 result |= Trspi_HashUpdate(&hashCtx, ulDataLength, sealData);
129 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
130 goto error;
131 }
132
133 if ((result = authsess_xsap_hmac(xsap, &digest)))
134 goto error;
135
136 #ifdef TSS_BUILD_SEALX
137 if (sealOrdinal == TPM_ORD_Seal) {
138 if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse,
139 pcrDataSize, pcrData, ulDataLength,
140 sealData, xsap->pAuth, &encDataSize,
141 &encData))) {
142 goto error;
143 }
144 } else if (sealOrdinal == TPM_ORD_Sealx) {
145 if ((result = TCS_API(tspContext)->Sealx(tspContext, tcsKeyHandle, &xsap->encAuthUse,
146 pcrDataSize, pcrData, ulDataLength, sealData,
147 xsap->pAuth, &encDataSize, &encData))) {
148 goto error;
149 }
150 } else {
151 result = TSPERR(TSS_E_INTERNAL_ERROR);
152 goto error;
153 }
154 #else
155 if ((result = TCS_API(tspContext)->Seal(tspContext, tcsKeyHandle, &xsap->encAuthUse,
156 pcrDataSize, pcrData, ulDataLength, sealData,
157 xsap->pAuth, &encDataSize, &encData)))
158 goto error;
159 #endif
160
161 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
162 result |= Trspi_Hash_UINT32(&hashCtx, result);
163 result |= Trspi_Hash_UINT32(&hashCtx, sealOrdinal);
164 result |= Trspi_HashUpdate(&hashCtx, encDataSize, encData);
165 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
166 goto error;
167
168 if ((result = authsess_xsap_verify(xsap, &digest)))
169 goto error;
170
171 /* Need to set the object with the blob and the pcr's */
172 if ((result = obj_encdata_set_data(hEncData, encDataSize, encData)))
173 goto error;
174
175 if (pcrDataSize)
176 result = obj_encdata_set_pcr_info(hEncData, pcrInfoType, pcrData);
177
178 error:
179 authsess_free(xsap);
180 free(encData);
181 free(pcrData);
182 if (sealData != rgbDataToSeal)
183 free(sealData);
184 return result;
185 }
186
187 TSS_RESULT
Tspi_Data_Unseal(TSS_HENCDATA hEncData,TSS_HKEY hKey,UINT32 * pulUnsealedDataLength,BYTE ** prgbUnsealedData)188 Tspi_Data_Unseal(TSS_HENCDATA hEncData, /* in */
189 TSS_HKEY hKey, /* in */
190 UINT32 * pulUnsealedDataLength,/* out */
191 BYTE ** prgbUnsealedData) /* out */
192 {
193 UINT64 offset;
194 TPM_AUTH privAuth2;
195 TPM_DIGEST digest;
196 TPM_NONCE authLastNonceEven;
197 TSS_RESULT result;
198 TSS_HPOLICY hPolicy, hEncPolicy;
199 TCS_KEY_HANDLE tcsKeyHandle;
200 TSS_HCONTEXT tspContext;
201 UINT32 ulDataLen, unSealedDataLen;
202 BYTE *data = NULL, *unSealedData = NULL, *maskedData;
203 UINT16 mask;
204 Trspi_HashCtx hashCtx;
205 struct authsess *xsap = NULL;
206
207 if (pulUnsealedDataLength == NULL || prgbUnsealedData == NULL)
208 return TSPERR(TSS_E_BAD_PARAMETER);
209
210 if ((result = obj_encdata_get_tsp_context(hEncData, &tspContext)))
211 return result;
212
213 if ((result = obj_rsakey_get_policy(hKey, TSS_POLICY_USAGE, &hPolicy, NULL)))
214 return result;
215
216 if ((result = obj_encdata_get_policy(hEncData, TSS_POLICY_USAGE, &hEncPolicy)))
217 return result;
218
219 if ((result = obj_encdata_get_data(hEncData, &ulDataLen, &data)))
220 return result == (TSS_E_INVALID_OBJ_ACCESS | TSS_LAYER_TSP) ?
221 TSPERR(TSS_E_ENC_NO_DATA) :
222 result;
223
224 offset = 0;
225 Trspi_UnloadBlob_UINT16(&offset, &mask, data);
226 if (mask == TPM_TAG_STORED_DATA12) {
227 /* The second UINT16 in a TPM_STORED_DATA12 is the entity type. If its non-zero
228 * then we must unmask the unsealed data after it returns from the TCS */
229 Trspi_UnloadBlob_UINT16(&offset, &mask, data);
230 } else
231 mask = 0;
232
233 if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKeyHandle)))
234 goto error;
235
236 if ((result = authsess_xsap_init(tspContext, hKey, hEncData, TSS_AUTH_POLICY_REQUIRED,
237 TPM_ORD_Unseal, TPM_ET_KEYHANDLE, &xsap)))
238 goto error;
239
240 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
241 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal);
242 result |= Trspi_HashUpdate(&hashCtx, ulDataLen, data);
243 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
244 goto error;
245
246 if ((result = authsess_xsap_hmac(xsap, &digest)))
247 goto error;
248
249 if ((result = secret_PerformAuth_OIAP(hEncData, TPM_ORD_Unseal, hEncPolicy, FALSE, &digest,
250 &privAuth2)))
251 goto error;
252
253 if (mask) {
254 /* save off last nonce even to pass to sealx callback */
255 memcpy(authLastNonceEven.nonce, xsap->auth.NonceEven.nonce, sizeof(TPM_NONCE));
256 }
257
258 if ((result = TCS_API(tspContext)->Unseal(tspContext, tcsKeyHandle, ulDataLen, data,
259 xsap->pAuth, &privAuth2, &unSealedDataLen,
260 &unSealedData)))
261 goto error;
262
263 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
264 result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
265 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_Unseal);
266 result |= Trspi_Hash_UINT32(&hashCtx, unSealedDataLen);
267 result |= Trspi_HashUpdate(&hashCtx, unSealedDataLen, unSealedData);
268 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest))) {
269 free(unSealedData);
270 goto error;
271 }
272
273 if ((result = authsess_xsap_verify(xsap, &digest))) {
274 free(unSealedData);
275 goto error;
276 }
277
278 if ((result = obj_policy_validate_auth_oiap(hEncPolicy, &digest, &privAuth2))) {
279 free(unSealedData);
280 goto error;
281 }
282
283 /* If the data is masked, use the callback set up in authsess_xsap_init */
284 if (mask) {
285 maskedData = unSealedData;
286
287 if ((unSealedData = calloc_tspi(tspContext, unSealedDataLen)) == NULL) {
288 free(maskedData);
289 LogError("malloc of %u bytes failed", unSealedDataLen);
290 result = TSPERR(TSS_E_OUTOFMEMORY);
291 goto error;
292 }
293
294 /* XXX pass in out saved-off authLastNonceEven. This conflicts with the
295 * description of the rgbNonceEven parameter in the spec, but without it, its not
296 * possible to compute the MGF1 key */
297 if ((result =
298 ((TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA, TSS_ALGORITHM_ID,
299 UINT32, BYTE *, BYTE *, BYTE *, BYTE *, UINT32, BYTE *,
300 BYTE *))xsap->cb_sealx.callback)(xsap->cb_sealx.appData, hKey, hEncData,
301 xsap->cb_sealx.alg, sizeof(TPM_NONCE),
302 authLastNonceEven.nonce,
303 xsap->auth.NonceOdd.nonce,
304 xsap->nonceEvenxSAP.nonce,
305 xsap->nonceOddxSAP.nonce,
306 unSealedDataLen, maskedData,
307 unSealedData))) {
308 free(maskedData);
309 goto error;
310 }
311
312 free(maskedData);
313 } else {
314 if ((result = __tspi_add_mem_entry(tspContext, unSealedData)))
315 goto error;
316 }
317
318 *pulUnsealedDataLength = unSealedDataLen;
319 *prgbUnsealedData = unSealedData;
320
321 error:
322 authsess_free(xsap);
323 if (data)
324 free_tspi(tspContext, data);
325
326 return result;
327 }
328