1 /*
2 * The Initial Developer of the Original Code is Intel Corporation.
3 * Portions created by Intel Corporation are Copyright (C) 2007 Intel Corporation.
4 * All Rights Reserved.
5 *
6 * trousers - An open source TCG Software Stack
7 *
8 * Author: james.xu@intel.com Rossey.liu@intel.com
9 *
10 * Kent Yoder - updates for new authsession mechanism
11 * (C) International Business Machines Corp. 2007
12 *
13 */
14
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <inttypes.h>
19
20 #include "trousers/tss.h"
21 #include "trousers/trousers.h"
22 #include "trousers_types.h"
23 #include "trousers_types.h"
24 #include "spi_utils.h"
25 #include "capabilities.h"
26 #include "tsplog.h"
27 #include "obj.h"
28 #include "authsess.h"
29
30 TSS_RESULT
Tspi_NV_DefineSpace(TSS_HNVSTORE hNvstore,TSS_HPCRS hReadPcrComposite,TSS_HPCRS hWritePcrComposite)31 Tspi_NV_DefineSpace(TSS_HNVSTORE hNvstore, /* in */
32 TSS_HPCRS hReadPcrComposite, /* in, may be NULL */
33 TSS_HPCRS hWritePcrComposite) /* in, may be NULL*/
34 {
35 TSS_HCONTEXT tspContext;
36 TSS_HTPM hTpm;
37 TSS_RESULT result;
38 UINT32 uiResultLen;
39 BYTE *pResult;
40 UINT32 i;
41
42 TPM_BOOL defined_index = FALSE;
43 NV_DATA_PUBLIC nv_data_public;
44 TSS_BOOL need_authdata = FALSE;
45 TCPA_DIGEST digest;
46 BYTE *pReadPCR;
47 UINT32 pReadPCR_len;
48 BYTE *pWritePCR;
49 UINT32 pWritePCR_len;
50 UINT64 NVPublic_DataSize;
51 BYTE NVPublicData[MAX_PUBLIC_DATA_SIZE];
52 Trspi_HashCtx hashCtx;
53 struct authsess *xsap = NULL;
54
55 if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
56 return result;
57
58 __tspi_memset(&nv_data_public, 0, sizeof(NV_DATA_PUBLIC));
59
60 if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex)))
61 return result;
62
63 if ((result = obj_nvstore_get_datasize(hNvstore, &nv_data_public.dataSize)))
64 return result;
65
66 if ((result = obj_nvstore_get_permission(hNvstore, &nv_data_public.permission.attributes)))
67 return result;
68
69 if ((result = obj_tpm_get(tspContext, &hTpm)))
70 return result;
71
72 if((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0,
73 NULL, &uiResultLen, &pResult)))
74 return result;
75
76 for (i = 0; i < uiResultLen/sizeof(UINT32); i++) {
77 if (nv_data_public.nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) {
78 defined_index = TRUE;
79 break;
80 }
81 }
82 free_tspi(tspContext, pResult);
83
84 if (defined_index) {
85 result = TSPERR(TSS_E_NV_AREA_EXIST);
86 return result;
87 }
88
89 need_authdata = (nv_data_public.permission.attributes
90 & (TPM_NV_PER_AUTHREAD |TPM_NV_PER_AUTHWRITE)) ? TRUE : FALSE;
91
92 nv_data_public.tag = TPM_TAG_NV_DATA_PUBLIC;
93
94 if ((result = obj_nvstore_create_pcrshortinfo(hNvstore, hReadPcrComposite,
95 &pReadPCR_len, &pReadPCR)))
96 return result;
97
98 if ((result = obj_nvstore_create_pcrshortinfo(hNvstore, hWritePcrComposite,
99 &pWritePCR_len, &pWritePCR))) {
100 free_tspi(tspContext, pReadPCR);
101 return result;
102 }
103
104 NVPublic_DataSize = 0;
105 Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_DATA_PUBLIC, NVPublicData);
106 Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.nvIndex, NVPublicData);
107 Trspi_LoadBlob(&NVPublic_DataSize, pReadPCR_len, NVPublicData, pReadPCR);
108 Trspi_LoadBlob(&NVPublic_DataSize, pWritePCR_len, NVPublicData, pWritePCR);
109 Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_ATTRIBUTES, NVPublicData);
110 Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.permission.attributes, NVPublicData);
111 Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bReadSTClear, NVPublicData);
112 Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteSTClear, NVPublicData);
113 Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteDefine, NVPublicData);
114 Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.dataSize, NVPublicData);
115 free_tspi(tspContext, pReadPCR);
116 free_tspi(tspContext, pWritePCR);
117
118 if ((result = authsess_xsap_init(tspContext, hTpm, hNvstore, need_authdata,
119 TPM_ORD_NV_DefineSpace, TPM_ET_OWNER, &xsap))) {
120 if (result == TSPERR(TSS_E_TSP_AUTHREQUIRED))
121 result = TSS_ERROR_CODE(TSS_E_BAD_PARAMETER);
122 return result;
123 }
124
125 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
126 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace);
127 result |= Trspi_HashUpdate(&hashCtx, NVPublic_DataSize, NVPublicData);
128 result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
129 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
130 goto error;
131
132 if ((result = authsess_xsap_hmac(xsap, &digest)))
133 goto error;
134
135 if ((result = TCS_API(tspContext)->NV_DefineOrReleaseSpace(tspContext, NVPublic_DataSize,
136 NVPublicData, xsap->encAuthUse,
137 xsap->pAuth)))
138 goto error;
139
140 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
141 result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
142 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace);
143 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
144 goto error;
145
146 result = authsess_xsap_verify(xsap, &digest);
147 error:
148 authsess_free(xsap);
149
150 return result;
151 }
152
153 TSS_RESULT
Tspi_NV_ReleaseSpace(TSS_HNVSTORE hNvstore)154 Tspi_NV_ReleaseSpace(TSS_HNVSTORE hNvstore) /* in */
155 {
156 TSS_HCONTEXT tspContext;
157 TSS_HTPM hTpm;
158 TSS_RESULT result;
159 UINT32 uiResultLen;
160 BYTE *pResult;
161 UINT32 i;
162 TPM_BOOL defined_index = FALSE;
163 NV_DATA_PUBLIC nv_data_public;
164 TCPA_DIGEST digest;
165 BYTE *pPCR;
166 UINT32 pPCR_len;
167
168 UINT64 NVPublic_DataSize;
169 BYTE NVPublicData[MAX_PUBLIC_DATA_SIZE];
170 Trspi_HashCtx hashCtx;
171 struct authsess *xsap = NULL;
172
173 __tspi_memset(&nv_data_public, 0, sizeof(NV_DATA_PUBLIC));
174
175 if ((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
176 return result;
177
178 if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex)))
179 return result;
180
181 if ((result = obj_nvstore_get_datasize(hNvstore, &nv_data_public.dataSize)))
182 return result;
183
184 if ((result = obj_nvstore_get_permission(hNvstore, &nv_data_public.permission.attributes)))
185 return result;
186
187 if ((result = obj_tpm_get(tspContext, &hTpm)))
188 return result;
189
190 if((result = Tspi_TPM_GetCapability(hTpm, TSS_TPMCAP_NV_LIST, 0,
191 NULL, &uiResultLen, &pResult)))
192 return result;
193
194 for (i = 0; i < uiResultLen/sizeof(UINT32); i++) {
195 if (nv_data_public.nvIndex == Decode_UINT32(pResult + i * sizeof(UINT32))) {
196 defined_index = TRUE;
197 break;
198 }
199 }
200 free_tspi(tspContext, pResult);
201
202 if (!defined_index) {
203 result = TSPERR(TSS_E_NV_AREA_NOT_EXIST);
204 return result;
205 }
206
207 nv_data_public.tag = TPM_TAG_NV_DATA_PUBLIC;
208
209 if ((result = obj_nvstore_create_pcrshortinfo(hNvstore, NULL_HPCRS, &pPCR_len, &pPCR)))
210 return result;
211
212 NVPublic_DataSize = 0;
213 Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_DATA_PUBLIC, NVPublicData);
214 Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.nvIndex, NVPublicData);
215 /* load the read pcr short info */
216 Trspi_LoadBlob(&NVPublic_DataSize, pPCR_len, NVPublicData, pPCR);
217 /* load the write pcr short info */
218 Trspi_LoadBlob(&NVPublic_DataSize, pPCR_len, NVPublicData, pPCR);
219 Trspi_LoadBlob_UINT16(&NVPublic_DataSize, TPM_TAG_NV_ATTRIBUTES, NVPublicData);
220 Trspi_LoadBlob_UINT32(&NVPublic_DataSize,
221 nv_data_public.permission.attributes, NVPublicData);
222 Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bReadSTClear, NVPublicData);
223 Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteSTClear, NVPublicData);
224 Trspi_LoadBlob_BOOL(&NVPublic_DataSize, nv_data_public.bWriteDefine, NVPublicData);
225 /*Trspi_LoadBlob_UINT32(&NVPublic_DataSize, nv_data_public.dataSize, NVPublicData);*/
226 Trspi_LoadBlob_UINT32(&NVPublic_DataSize, 0, NVPublicData);
227 free_tspi(tspContext, pPCR);
228
229 if ((result = authsess_xsap_init(tspContext, hTpm, hNvstore, TSS_AUTH_POLICY_NOT_REQUIRED,
230 TPM_ORD_NV_DefineSpace, TPM_ET_OWNER, &xsap)))
231 return result;
232
233 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
234 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace);
235 result |= Trspi_HashUpdate(&hashCtx, NVPublic_DataSize, NVPublicData);
236 result |= Trspi_Hash_ENCAUTH(&hashCtx, xsap->encAuthUse.authdata);
237 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
238 goto error;
239
240 if ((result = authsess_xsap_hmac(xsap, &digest)))
241 goto error;
242
243 if ((result = TCS_API(tspContext)->NV_DefineOrReleaseSpace(tspContext, NVPublic_DataSize,
244 NVPublicData, xsap->encAuthUse,
245 xsap->pAuth)))
246 goto error;
247
248 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
249 result |= Trspi_Hash_UINT32(&hashCtx, TPM_SUCCESS);
250 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_DefineSpace);
251 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
252 goto error;
253
254 result = authsess_xsap_verify(xsap, &digest);
255 error:
256 authsess_free(xsap);
257
258 return result;
259 }
260
261 TSS_RESULT
Tspi_NV_WriteValue(TSS_HNVSTORE hNvstore,UINT32 offset,UINT32 ulDataLength,BYTE * rgbDataToWrite)262 Tspi_NV_WriteValue(TSS_HNVSTORE hNvstore, /* in */
263 UINT32 offset, /* in */
264 UINT32 ulDataLength, /* in */
265 BYTE* rgbDataToWrite) /* in */
266 {
267 TSS_HCONTEXT tspContext;
268 TSS_HTPM hTpm;
269 TSS_RESULT result;
270 NV_DATA_PUBLIC nv_data_public;
271 UINT32 need_authdata = 0;
272 UINT32 authwrite =0;
273 TSS_HPOLICY hPolicy;
274 TPM_AUTH auth;
275 TCPA_DIGEST digest;
276 Trspi_HashCtx hashCtx;
277
278 if ((ulDataLength != 0) && (rgbDataToWrite == NULL))
279 return TSPERR(TSS_E_BAD_PARAMETER);
280
281 if((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
282 return result;
283
284 if ((result = obj_tpm_get(tspContext, &hTpm)))
285 return result;
286
287 if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex)))
288 return result;
289
290 if ((result = obj_nvstore_get_policy(hNvstore, TSS_POLICY_USAGE, &hPolicy)))
291 return result;
292
293 if (hPolicy) {
294 if ((result = obj_nvstore_get_permission_from_tpm(hNvstore,
295 &nv_data_public.permission.attributes)))
296 return result;
297
298 need_authdata = nv_data_public.permission.attributes
299 & (TPM_NV_PER_AUTHWRITE | TPM_NV_PER_OWNERWRITE);
300
301 authwrite = nv_data_public.permission.attributes & TPM_NV_PER_AUTHWRITE;
302
303 if (need_authdata) {
304 if (!authwrite) {
305 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
306 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValue);
307 result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex);
308 result |= Trspi_Hash_UINT32(&hashCtx, offset);
309 result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength);
310 result |= Trspi_HashUpdate(&hashCtx, ulDataLength, rgbDataToWrite);
311
312 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
313 return result;
314
315 if ((result = secret_PerformAuth_OIAP(hNvstore,
316 TPM_ORD_NV_WriteValue,
317 hPolicy, FALSE, &digest,
318 &auth)))
319 return result;
320
321 if ((result = TCS_API(tspContext)->NV_WriteValue(tspContext,
322 nv_data_public.nvIndex,
323 offset, ulDataLength,
324 rgbDataToWrite, &auth)))
325 return result;
326
327 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
328 result |= Trspi_Hash_UINT32(&hashCtx, result);
329 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValue);
330 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
331 return result;
332
333 if ((result = obj_policy_validate_auth_oiap(hPolicy,
334 &digest, &auth)))
335 return result;
336 } else {
337 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
338 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValueAuth);
339 result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex);
340 result |= Trspi_Hash_UINT32(&hashCtx, offset);
341 result |= Trspi_Hash_UINT32(&hashCtx, ulDataLength);
342 result |= Trspi_HashUpdate(&hashCtx, ulDataLength, rgbDataToWrite);
343
344 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
345 return result;
346
347 if ((result = secret_PerformAuth_OIAP(hNvstore,
348 TPM_ORD_NV_WriteValueAuth,
349 hPolicy, FALSE, &digest,
350 &auth)))
351 return result;
352
353 if ((result = TCS_API(tspContext)->NV_WriteValueAuth(tspContext,
354 nv_data_public.nvIndex,
355 offset, ulDataLength,
356 rgbDataToWrite, &auth)))
357 return result;
358
359 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
360 result |= Trspi_Hash_UINT32(&hashCtx, result);
361 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_WriteValueAuth);
362 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
363 return result;
364
365 if ((result = obj_policy_validate_auth_oiap(hPolicy,
366 &digest, &auth)))
367 return result;
368 }
369 } else {
370 if ((result = TCS_API(tspContext)->NV_WriteValue(tspContext,
371 nv_data_public.nvIndex,
372 offset, ulDataLength,
373 rgbDataToWrite, NULL)))
374 return result;
375 }
376 } else {
377 LogDebug("no policy, so noauthentication");
378 if ((result = TCS_API(tspContext)->NV_WriteValue(tspContext, nv_data_public.nvIndex,
379 offset, ulDataLength,
380 rgbDataToWrite, NULL)))
381 return result;
382 }
383
384 return result;
385 }
386
387 TSS_RESULT
Tspi_NV_ReadValue(TSS_HNVSTORE hNvstore,UINT32 offset,UINT32 * ulDataLength,BYTE ** rgbDataRead)388 Tspi_NV_ReadValue(TSS_HNVSTORE hNvstore, /* in */
389 UINT32 offset, /* in */
390 UINT32* ulDataLength, /* in, out */
391 BYTE** rgbDataRead) /* out */
392 {
393 TSS_HCONTEXT tspContext;
394 TSS_HTPM hTpm;
395 TSS_RESULT result;
396 NV_DATA_PUBLIC nv_data_public;
397 UINT32 need_authdata = 0;
398 UINT32 authread =0;
399 TSS_HPOLICY hPolicy;
400
401 TPM_AUTH auth;
402 TCPA_DIGEST digest;
403 Trspi_HashCtx hashCtx;
404
405 if (ulDataLength == NULL || rgbDataRead == NULL)
406 return TSPERR(TSS_E_BAD_PARAMETER);
407
408 if((result = obj_nvstore_get_tsp_context(hNvstore, &tspContext)))
409 return result;
410
411 if ((result = obj_tpm_get(tspContext, &hTpm)))
412 return result;
413
414 if ((result = obj_nvstore_get_index(hNvstore, &nv_data_public.nvIndex)))
415 return result;
416
417 if ((result = obj_nvstore_get_policy(hNvstore, TSS_POLICY_USAGE, &hPolicy)))
418 return result;
419
420 if (hPolicy) {/*if the policy secret is set*/
421 if ((result = obj_nvstore_get_permission_from_tpm(hNvstore,
422 &nv_data_public.permission.attributes)))
423 return result;
424
425 need_authdata = nv_data_public.permission.attributes
426 & (TPM_NV_PER_AUTHREAD | TPM_NV_PER_OWNERREAD);
427
428 authread = nv_data_public.permission.attributes & TPM_NV_PER_AUTHREAD;
429
430 if (need_authdata) {
431 if (!authread) {
432 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
433 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValue);
434 result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex);
435 result |= Trspi_Hash_UINT32(&hashCtx, offset);
436 result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength);
437
438 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
439 return result;
440
441 if ((result = secret_PerformAuth_OIAP(hNvstore,
442 TPM_ORD_NV_ReadValue,
443 hPolicy, FALSE, &digest,
444 &auth)))
445 return result;
446
447 if ((result = TCS_API(tspContext)->NV_ReadValue(tspContext,
448 nv_data_public.nvIndex,
449 offset, ulDataLength,
450 &auth, rgbDataRead)))
451 return result;
452
453 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
454 result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
455 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValue);
456 result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength);
457 result |= Trspi_HashUpdate(&hashCtx, *ulDataLength, *rgbDataRead);
458 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
459 return result;
460
461 if ((result = obj_policy_validate_auth_oiap(hPolicy,
462 &digest, &auth)))
463 return result;
464 } else {
465 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
466 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValueAuth);
467 result |= Trspi_Hash_UINT32(&hashCtx, nv_data_public.nvIndex);
468 result |= Trspi_Hash_UINT32(&hashCtx, offset);
469 result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength);
470
471 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
472 return result;
473
474 if ((result = secret_PerformAuth_OIAP(hNvstore,
475 TPM_ORD_NV_ReadValueAuth,
476 hPolicy, FALSE, &digest,
477 &auth)))
478 return result;
479
480 if ((result = TCS_API(tspContext)->NV_ReadValueAuth(tspContext,
481 nv_data_public.nvIndex,
482 offset, ulDataLength,
483 &auth, rgbDataRead)))
484 return result;
485
486 result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
487 result |= Trspi_Hash_UINT32(&hashCtx, TSS_SUCCESS);
488 result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_NV_ReadValueAuth);
489 result |= Trspi_Hash_UINT32(&hashCtx, *ulDataLength);
490 result |= Trspi_HashUpdate(&hashCtx, *ulDataLength, *rgbDataRead);
491 if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
492 return result;
493
494 if ((result = obj_policy_validate_auth_oiap(hPolicy,
495 &digest, &auth)))
496 return result;
497 }
498 } else {
499 if ((result = TCS_API(tspContext)->NV_ReadValue(tspContext,
500 nv_data_public.nvIndex,
501 offset, ulDataLength, NULL,
502 rgbDataRead)))
503 return result;
504 }
505 } else {
506 if ((result = TCS_API(tspContext)->NV_ReadValue(tspContext, nv_data_public.nvIndex,
507 offset, ulDataLength, NULL,
508 rgbDataRead)))
509 return result;
510 }
511
512 return result;
513 }
514