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