363
393
return TSS_SUCCESS;
397
obj_context_get_connection_version(TSS_HCONTEXT tspContext, UINT32 *version)
399
struct tsp_object *obj;
400
struct tr_context_obj *context;
402
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
403
return TSPERR(TSS_E_INVALID_HANDLE);
405
context = (struct tr_context_obj *)obj->data;
407
*version = context->current_connection;
409
obj_list_put(&context_list);
415
obj_context_set_connection_policy(TSS_HCONTEXT tspContext, UINT32 policy)
417
struct tsp_object *obj;
418
struct tr_context_obj *context;
421
case TSS_TSPATTRIB_CONTEXT_VERSION_V1_1:
422
case TSS_TSPATTRIB_CONTEXT_VERSION_V1_2:
423
case TSS_TSPATTRIB_CONTEXT_VERSION_AUTO:
426
return TSPERR(TSS_E_INVALID_ATTRIB_DATA);
429
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
430
return TSPERR(TSS_E_INVALID_HANDLE);
432
context = (struct tr_context_obj *)obj->data;
434
context->connection_policy = policy;
436
obj_list_put(&context_list);
442
obj_context_set_transport_key(TSS_HCONTEXT tspContext, TSS_HKEY hKey)
444
struct tsp_object *obj;
445
struct tr_context_obj *context;
447
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
448
return TSPERR(TSS_E_INVALID_HANDLE);
450
context = (struct tr_context_obj *)obj->data;
452
context->transKey = hKey;
454
obj_list_put(&context_list);
460
obj_context_transport_get_mode(TSS_HCONTEXT tspContext, UINT32 value, UINT32 *out)
462
TSS_RESULT result = TSS_SUCCESS;
463
struct tsp_object *obj;
464
struct tr_context_obj *context;
466
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
467
return TSPERR(TSS_E_INVALID_HANDLE);
469
context = (struct tr_context_obj *)obj->data;
472
case TSS_TSPATTRIB_TRANSPORT_NO_DEFAULT_ENCRYPTION:
473
*out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT ?
476
case TSS_TSPATTRIB_TRANSPORT_DEFAULT_ENCRYPTION:
477
*out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT ?
480
case TSS_TSPATTRIB_TRANSPORT_AUTHENTIC_CHANNEL:
481
*out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC ?
484
case TSS_TSPATTRIB_TRANSPORT_EXCLUSIVE:
485
*out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_EXCLUSIVE ?
488
case TSS_TSPATTRIB_TRANSPORT_STATIC_AUTH:
489
*out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_STATIC_AUTH ?
493
LogError("Invalid attribute subflag: 0x%x", value);
494
result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
498
obj_list_put(&context_list);
504
obj_context_transport_get_control(TSS_HCONTEXT tspContext, UINT32 value, UINT32 *out)
506
TSS_RESULT result = TSS_SUCCESS;
507
struct tsp_object *obj;
508
struct tr_context_obj *context;
510
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
511
return TSPERR(TSS_E_INVALID_HANDLE);
513
context = (struct tr_context_obj *)obj->data;
516
case TSS_TSPATTRIB_DISABLE_TRANSPORT:
517
*out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED ? FALSE : TRUE;
519
case TSS_TSPATTRIB_ENABLE_TRANSPORT:
520
*out = context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED ? TRUE : FALSE;
523
LogError("Invalid attribute subflag: 0x%x", value);
524
result = TSPERR(TSS_E_INVALID_ATTRIB_SUBFLAG);
528
obj_list_put(&context_list);
534
obj_context_transport_set_control(TSS_HCONTEXT tspContext, UINT32 value)
536
TSS_RESULT result = TSS_SUCCESS;
537
struct tsp_object *obj;
538
struct tr_context_obj *context;
540
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
541
return TSPERR(TSS_E_INVALID_HANDLE);
543
context = (struct tr_context_obj *)obj->data;
546
case TSS_TSPATTRIB_ENABLE_TRANSPORT:
547
context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED;
548
context->tcs_api = &tcs_transport_api;
550
case TSS_TSPATTRIB_DISABLE_TRANSPORT:
551
context->flags &= ~TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED;
552
context->tcs_api = &tcs_normal_api;
555
LogError("Invalid attribute subflag: 0x%x", value);
556
result = TSPERR(TSS_E_INTERNAL_ERROR);
560
obj_list_put(&context_list);
566
obj_context_transport_set_mode(TSS_HCONTEXT tspContext, UINT32 value)
568
TSS_RESULT result = TSS_SUCCESS;
569
struct tsp_object *obj;
570
struct tr_context_obj *context;
572
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
573
return TSPERR(TSS_E_INVALID_HANDLE);
575
context = (struct tr_context_obj *)obj->data;
578
case TSS_TSPATTRIB_TRANSPORT_NO_DEFAULT_ENCRYPTION:
579
context->flags &= ~TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT;
581
case TSS_TSPATTRIB_TRANSPORT_DEFAULT_ENCRYPTION:
582
context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT;
584
case TSS_TSPATTRIB_TRANSPORT_AUTHENTIC_CHANNEL:
585
context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC;
587
case TSS_TSPATTRIB_TRANSPORT_EXCLUSIVE:
588
context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_EXCLUSIVE;
590
case TSS_TSPATTRIB_TRANSPORT_STATIC_AUTH:
591
context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_STATIC_AUTH;
594
LogError("Invalid attribute subflag: 0x%x", value);
595
result = TSPERR(TSS_E_INTERNAL_ERROR);
599
obj_list_put(&context_list);
606
get_trans_props(TSS_HCONTEXT tspContext, UINT32 *alg, UINT16 *enc)
609
UINT32 algs[] = { TPM_ALG_MGF1, TPM_ALG_AES128, 0 }, a = 0;
610
UINT16 encs[] = { TPM_ES_SYM_OFB, TPM_ES_SYM_CNT, TPM_ES_SYM_CBC_PKCS5PAD, 0 }, e = 0;
612
UINT32 respLen, tcsSubCap32;
618
for (a = 0; algs[a]; a++) {
619
tcsSubCap32 = endian32(algs[a]);
621
if ((result = RPC_GetTPMCapability(tspContext, TPM_CAP_TRANS_ALG, sizeof(UINT32),
622
(BYTE *)&tcsSubCap32, &respLen, &respData)))
625
if (*(TSS_BOOL *)respData == TRUE) {
633
LogError("TPM reports no usable sym algorithms for transport session");
634
return TSPERR(TSS_E_INTERNAL_ERROR);
638
if (*enc || algs[a] == TPM_ALG_MGF1)
641
for (e = 0; encs[e]; e++) {
642
tcsSubCap16 = endian16(encs[e]);
644
if ((result = RPC_GetTPMCapability(tspContext, TPM_CAP_TRANS_ES, sizeof(UINT16),
645
(BYTE *)&tcsSubCap16, &respLen, &respData)))
648
if (*(TSS_BOOL *)respData == TRUE) {
656
LogError("TPM reports no usable sym modes for transport session");
657
return TSPERR(TSS_E_INTERNAL_ERROR);
667
/* called before each TCSP_ExecuteTransport call */
669
obj_context_transport_init(TSS_HCONTEXT tspContext)
671
TSS_RESULT result = TSS_SUCCESS;
672
struct tsp_object *obj;
673
struct tr_context_obj *context;
675
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
676
return TSPERR(TSS_E_INVALID_HANDLE);
678
context = (struct tr_context_obj *)obj->data;
680
/* return immediately if we're not in a transport session */
681
if (!(context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED)) {
682
result = TSPERR(TSS_E_INTERNAL_ERROR);
686
/* if the session is not yet established, setup and call EstablishTransport */
687
if (!(context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_ESTABLISHED)) {
688
if ((result = obj_context_transport_establish(tspContext, context)))
692
context->flags |= TSS_CONTEXT_FLAGS_TRANSPORT_ESTABLISHED;
694
result = TSS_SUCCESS;
696
obj_list_put(&context_list);
702
obj_context_transport_establish(TSS_HCONTEXT tspContext, struct tr_context_obj *context)
705
UINT32 tickLen, secretLen, transPubLen, exclusive = TSS_TCSATTRIB_TRANSPORT_DEFAULT;
706
BYTE *ticks, *secret;
708
Trspi_HashCtx hashCtx;
710
TSS_HPOLICY hTransKeyPolicy;
711
TPM_AUTH auth, *pAuth, *pTransAuth;
712
TCS_KEY_HANDLE tcsTransKey;
713
TSS_BOOL usesAuth = FALSE;
716
BYTE transPubBlob[sizeof(TPM_TRANSPORT_PUBLIC)];
717
BYTE transAuthBlob[sizeof(TPM_TRANSPORT_AUTH)];
720
context->transPub.tag = TPM_TAG_TRANSPORT_PUBLIC;
721
context->transSecret.tag = TPM_TAG_TRANSPORT_AUTH;
723
if ((result = get_local_random(tspContext, FALSE, TPM_SHA1_160_HASH_LEN,
724
(BYTE **)context->transSecret.authData.authdata)))
727
if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_STATIC_AUTH)
728
context->transKey = TPM_KH_TRANSPORT;
730
if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC)
731
context->transPub.transAttributes |= TPM_TRANSPORT_LOG;
733
if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_EXCLUSIVE) {
734
context->transPub.transAttributes |= TPM_TRANSPORT_EXCLUSIVE;
735
exclusive = TSS_TCSATTRIB_TRANSPORT_EXCLUSIVE;
738
/* XXX implement AES128+CTR (Winbond, Infineon), then AES256+CTR (Atmel) */
739
context->transPub.algId = TPM_ALG_MGF1;
740
context->transPub.encScheme = TPM_ES_NONE;
742
if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT) {
743
context->transPub.transAttributes |= TPM_TRANSPORT_ENCRYPT;
745
if (context->transKey == TPM_KH_TRANSPORT) {
746
LogError("No transport key handle has been set yet. Use "
747
"Tspi_Context_SetTransEncryptionKey to set this handle");
748
return TSPERR(TSS_E_INTERNAL_ERROR);
752
if (context->transKey == TPM_KH_TRANSPORT) {
753
secret = context->transSecret.authData.authdata;
754
secretLen = TPM_SHA1_160_HASH_LEN;
757
Trspi_LoadBlob_TRANSPORT_AUTH(&offset, transAuthBlob, &context->transSecret);
760
/* encrypt the sym key with the wrapping RSA key */
761
encKeyLen = sizeof(encKey);
762
if ((result = rsa_encrypt(context->transKey, secretLen, transAuthBlob, &encKeyLen,
767
secretLen = encKeyLen;
771
Trspi_LoadBlob_TRANSPORT_PUBLIC(&offset, transPubBlob, &context->transPub);
772
transPubLen = offset;
774
if (context->transKey != TPM_KH_TRANSPORT) {
775
if ((result = obj_rsakey_get_tcs_handle(context->transKey, &tcsTransKey)))
778
if ((result = obj_rsakey_get_policy(context->transKey, TSS_POLICY_USAGE,
779
&hTransKeyPolicy, &usesAuth)))
783
LogError("Key used to establish a transport session must use auth");
784
return TSPERR(TSS_E_TSP_TRANS_AUTHREQUIRED);
787
tcsTransKey = TPM_KH_TRANSPORT;
789
/* If logging is on, do TPM commands spec rev106 step 8.a */
790
memset(context->transLogDigest.digest, 0, sizeof(TPM_DIGEST));
791
if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC) {
792
context->transLogIn.tag = TPM_TAG_TRANSPORT_LOG_IN;
795
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
796
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_EstablishTransport);
797
result |= Trspi_HashUpdate(&hashCtx, transPubLen, transPubBlob);
798
result |= Trspi_Hash_UINT32(&hashCtx, secretLen);
799
result |= Trspi_HashUpdate(&hashCtx, secretLen, secret);
800
if ((result |= Trspi_HashFinal(&hashCtx, context->transLogIn.parameters.digest)))
804
memset(context->transLogIn.pubKeyHash.digest, 0, sizeof(TPM_DIGEST));
807
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
808
result |= Trspi_Hash_DIGEST(&hashCtx, context->transLogDigest.digest);
809
result |= Trspi_Hash_TRANSPORT_LOG_IN(&hashCtx, &context->transLogIn);
810
if ((result |= Trspi_HashFinal(&hashCtx, context->transLogDigest.digest)))
815
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
816
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_EstablishTransport);
817
result |= Trspi_HashUpdate(&hashCtx, (UINT32)offset, (BYTE *)transPubBlob);
818
result |= Trspi_Hash_UINT32(&hashCtx, secretLen);
819
result |= Trspi_HashUpdate(&hashCtx, secretLen, secret);
820
if ((result |= Trspi_HashFinal(&hashCtx, (BYTE *)&digest)))
823
/* open OIAP session with continueAuthSession = TRUE */
824
if ((result = secret_PerformAuth_OIAP(context->transKey, TPM_ORD_EstablishTransport,
825
hTransKeyPolicy, TRUE, &digest, &auth)))
832
result = RPC_EstablishTransport(tspContext, exclusive, tcsTransKey, transPubLen,
833
transPubBlob, secretLen, secret, pAuth, &context->transMod,
834
&context->transAuth.AuthHandle, &tickLen, &ticks,
835
&context->transAuth.NonceEven);
837
LogError("Establish Transport command failed: %s", Trspi_Error_String(result));
841
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
842
result |= Trspi_Hash_UINT32(&hashCtx, result);
843
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_EstablishTransport);
844
result |= Trspi_Hash_UINT32(&hashCtx, context->transMod);
845
result |= Trspi_HashUpdate(&hashCtx, tickLen, ticks);
846
result |= Trspi_Hash_NONCE(&hashCtx, context->transAuth.NonceEven.nonce);
847
if ((result |= Trspi_HashFinal(&hashCtx, digest.digest)))
851
if ((result = obj_policy_validate_auth_oiap(hTransKeyPolicy, &digest, pAuth)))
857
Trspi_UnloadBlob_CURRENT_TICKS(&offset, ticks, &context->transLogOut.currentTicks);
860
/* If logging is on, do TPM commands spec rev106 step 8.b */
861
if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC) {
862
context->transLogOut.tag = TPM_TAG_TRANSPORT_LOG_OUT;
865
memcpy(context->transLogOut.parameters.digest, digest.digest, sizeof(TPM_DIGEST));
868
context->transLogOut.locality = context->transMod;
870
/* step 8.b iii was done above */
872
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
873
result |= Trspi_Hash_DIGEST(&hashCtx, context->transLogDigest.digest);
874
result |= Trspi_Hash_TRANSPORT_LOG_OUT(&hashCtx, &context->transLogOut);
875
if ((result |= Trspi_HashFinal(&hashCtx, context->transLogDigest.digest)))
879
LogDebug("Transport session established successfully");
881
pTransAuth = &context->transAuth;
882
pTransAuth->fContinueAuthSession = TRUE;
883
if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE),
884
(BYTE **)pTransAuth->NonceOdd.nonce))) {
885
LogError("Failed creating random nonce");
886
return TSPERR(TSS_E_INTERNAL_ERROR);
893
do_transport_decryption(TPM_TRANSPORT_PUBLIC *transPub,
894
TPM_AUTH *pTransAuth,
903
UINT32 seedLen, ivLen;
905
BYTE seed[(2 * sizeof(TPM_NONCE)) + strlen("out") + TPM_SHA1_160_HASH_LEN];
907
/* allocate the most data anyone below might need */
908
decLen = inLen;//((inLen / TSS_MAX_SYM_BLOCK_SIZE) + 1) * TSS_MAX_SYM_BLOCK_SIZE;
909
if ((dec = malloc(decLen)) == NULL) {
910
LogError("malloc of %u bytes failed", decLen);
911
return TSPERR(TSS_E_OUTOFMEMORY);
914
/* set the common 3 initial values of 'seed', which is used to generate either the IV or
916
memcpy(seed, pTransAuth->NonceEven.nonce, sizeof(TPM_NONCE));
917
memcpy(&seed[sizeof(TPM_NONCE)], pTransAuth->NonceOdd.nonce, sizeof(TPM_NONCE));
918
memcpy(&seed[2 * sizeof(TPM_NONCE)], "out", strlen("out"));
920
switch (transPub->algId) {
924
seedLen = sizeof(seed);
926
/* add the secret data to the seed for MGF1 */
927
memcpy(&seed[2 * sizeof(TPM_NONCE) + strlen("out")], secret, TPM_SHA1_160_HASH_LEN);
929
if ((result = Trspi_MGF1(TSS_HASH_SHA1, seedLen, seed, decLen, dec))) {
934
for (i = 0; i < inLen; i++)
940
BYTE iv[TSS_MAX_SYM_BLOCK_SIZE];
942
ivLen = TSS_MAX_SYM_BLOCK_SIZE;
943
seedLen = (2 * sizeof(TPM_NONCE)) + strlen("out");
945
if ((result = Trspi_MGF1(TSS_HASH_SHA1, seedLen, seed, ivLen, iv))) {
950
/* use the secret data as the key for AES */
951
if ((result = Trspi_SymEncrypt(transPub->algId, transPub->encScheme, secret, iv, in,
952
inLen, dec, &decLen))) {
960
LogDebug("Unknown algorithm for encrypted transport session: 0x%x",
962
return TSPERR(TSS_E_INTERNAL_ERROR);
972
do_transport_encryption(TPM_TRANSPORT_PUBLIC *transPub,
973
TPM_AUTH *pTransAuth,
982
UINT32 seedLen, ivLen;
984
BYTE seed[(2 * sizeof(TPM_NONCE)) + strlen("in") + TPM_SHA1_160_HASH_LEN];
986
/* allocate the most data anyone below might need */
987
encLen = ((inLen / TSS_MAX_SYM_BLOCK_SIZE) + 1) * TSS_MAX_SYM_BLOCK_SIZE;
988
if ((enc = malloc(encLen)) == NULL) {
989
LogError("malloc of %u bytes failed", encLen);
990
return TSPERR(TSS_E_OUTOFMEMORY);
993
/* set the common 3 initial values of 'seed', which is used to generate either the IV or
995
memcpy(seed, pTransAuth->NonceEven.nonce, sizeof(TPM_NONCE));
996
memcpy(&seed[sizeof(TPM_NONCE)], pTransAuth->NonceOdd.nonce, sizeof(TPM_NONCE));
997
memcpy(&seed[2 * sizeof(TPM_NONCE)], "in", strlen("in"));
999
switch (transPub->algId) {
1003
seedLen = sizeof(seed);
1005
/* add the secret data to the seed for MGF1 */
1006
memcpy(&seed[2 * sizeof(TPM_NONCE) + strlen("in")], secret, TPM_SHA1_160_HASH_LEN);
1008
if ((result = Trspi_MGF1(TSS_HASH_SHA1, seedLen, seed, encLen, enc))) {
1013
for (i = 0; i < inLen; i++)
1017
case TPM_ALG_AES128:
1019
BYTE iv[TSS_MAX_SYM_BLOCK_SIZE];
1021
ivLen = TSS_MAX_SYM_BLOCK_SIZE;
1022
seedLen = (2 * sizeof(TPM_NONCE)) + strlen("in");
1024
if ((result = Trspi_MGF1(TSS_HASH_SHA1, seedLen, seed, ivLen, iv))) {
1029
/* use the secret data as the key for AES */
1030
if ((result = Trspi_SymEncrypt(transPub->algId, transPub->encScheme, secret, iv, in,
1031
inLen, enc, &encLen))) {
1039
LogDebug("Unknown algorithm for encrypted transport session: 0x%x",
1041
return TSPERR(TSS_E_INTERNAL_ERROR);
1051
obj_context_transport_execute(TSS_HCONTEXT tspContext,
1052
TPM_COMMAND_CODE ordinal,
1055
TPM_DIGEST* pubKeyHash,
1057
TCS_HANDLE** handles,
1063
TSS_RESULT result = TSS_SUCCESS;
1064
struct tsp_object *obj;
1065
struct tr_context_obj *context;
1066
UINT32 encLen, ulWrappedDataLen = 0;
1067
BYTE *pEnc = NULL, *rgbWrappedData = NULL;
1068
TPM_RESULT tpmResult;
1069
Trspi_HashCtx hashCtx;
1070
TPM_DIGEST etDigest, wDigest;
1071
TPM_AUTH *pTransAuth;
1072
UINT64 currentTicks;
1073
TSS_BOOL free_enc = FALSE;
1075
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
1076
return TSPERR(TSS_E_INVALID_HANDLE);
1078
context = (struct tr_context_obj *)obj->data;
1080
pTransAuth = &context->transAuth;
1082
/* TPM Commands spec rev106 step 6 */
1083
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
1084
result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
1091
result |= Trspi_HashUpdate(&hashCtx, ulDataLen, rgbData);
1095
if ((result |= Trspi_HashFinal(&hashCtx, wDigest.digest)))
1098
if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC) {
1099
/* TPM Commands spec rev106 step 10.b */
1100
memcpy(context->transLogIn.parameters.digest, wDigest.digest, sizeof(TPM_DIGEST));
1101
/* TPM Commands spec rev106 step 10.c, d or e, calculated by the caller */
1103
memcpy(context->transLogIn.pubKeyHash.digest, pubKeyHash->digest,
1104
sizeof(TPM_DIGEST));
1106
memset(context->transLogIn.pubKeyHash.digest, 0, sizeof(TPM_DIGEST));
1108
/* TPM Commands spec rev106 step 10.f */
1109
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
1110
result |= Trspi_Hash_DIGEST(&hashCtx, context->transLogDigest.digest);
1111
result |= Trspi_Hash_TRANSPORT_LOG_IN(&hashCtx, &context->transLogIn);
1112
if ((result |= Trspi_HashFinal(&hashCtx, context->transLogDigest.digest)))
1116
/* TPM Commands spec rev106 step 7.a */
1117
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
1118
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ExecuteTransport);
1119
result |= Trspi_Hash_UINT32(&hashCtx, ulDataLen + TSS_TPM_TXBLOB_HDR_LEN
1120
+ (*handlesLen * sizeof(UINT32))
1121
+ (pAuth1 ? TPM_AUTH_RQU_SIZE : 0)
1122
+ (pAuth2 ? TPM_AUTH_RQU_SIZE : 0));
1123
result |= Trspi_HashUpdate(&hashCtx, TPM_SHA1_160_HASH_LEN, wDigest.digest);
1124
if ((result |= Trspi_HashFinal(&hashCtx, etDigest.digest)))
1127
/* encrypt the data if necessary */
1128
if (ulDataLen && context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT) {
1138
UINT32 tmpLen, entityValueLen;
1139
BYTE *tmpEnc, *entityValuePtr;
1141
/* DSAP is a special case where only entityValue is encrypted. So, we'll
1142
* parse through rgbData until we get to entityValue, encrypt it, alloc
1143
* new space for rgbData (since it could be up to a block length larger
1144
* than it came in) and copy the unencrypted data and the encrypted
1145
* entityValue to the new block, setting pEnc and encLen to new values. */
1147
offset = (2 * sizeof(UINT32)) + sizeof(TPM_NONCE);
1148
Trspi_UnloadBlob_UINT32(&offset, &entityValueLen, rgbData);
1150
entityValuePtr = &rgbData[offset];
1151
if ((result = do_transport_encryption(&context->transPub, pTransAuth,
1152
context->transSecret.authData.authdata,
1153
entityValueLen, entityValuePtr, &tmpLen,
1157
/* offset is the amount of data before the block we encrypted and tmpLen is
1158
* the size of the encrypted data */
1159
encLen = offset + tmpLen;
1160
if ((pEnc = malloc(encLen)) == NULL) {
1161
LogError("malloc of %u bytes failed.", encLen);
1162
result = TSPERR(TSS_E_OUTOFMEMORY);
1165
memcpy(pEnc, rgbData, offset);
1166
memcpy(&pEnc[offset], tmpEnc, tmpLen);
1173
if ((result = do_transport_encryption(&context->transPub, pTransAuth,
1174
context->transSecret.authData.authdata,
1175
ulDataLen, rgbData, &encLen, &pEnc)))
1186
/* TPM Commands spec rev106 step 7.b */
1187
HMAC_Auth(context->transSecret.authData.authdata, etDigest.digest, pTransAuth);
1189
if ((result = RPC_ExecuteTransport(tspContext, ordinal, encLen, pEnc, handlesLen, handles,
1190
pAuth1, pAuth2, pTransAuth, ¤tTicks,
1191
&context->transMod, &tpmResult, &ulWrappedDataLen,
1192
&rgbWrappedData))) {
1193
LogDebugFn("Execute Transport failed: %s", Trspi_Error_String(result));
1198
LogDebug("Wrapped command ordinal 0x%x failed with result: 0x%x", ordinal,
1204
/* decrypt the returned wrapped data if necessary */
1205
if (ulWrappedDataLen && context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_DEFAULT_ENCRYPT) {
1210
*outLen = ulWrappedDataLen;
1211
*out = rgbWrappedData;
1214
if ((result = do_transport_decryption(&context->transPub, pTransAuth,
1215
context->transSecret.authData.authdata,
1216
ulWrappedDataLen, rgbWrappedData, outLen,
1220
free(rgbWrappedData);
1224
*outLen = ulWrappedDataLen;
1225
*out = rgbWrappedData;
1229
/* TPM Commands spec rev106 step 14 */
1230
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
1231
result |= Trspi_Hash_UINT32(&hashCtx, tpmResult);
1232
result |= Trspi_Hash_UINT32(&hashCtx, ordinal);
1240
result |= Trspi_HashUpdate(&hashCtx, *outLen, *out);
1244
if ((result |= Trspi_HashFinal(&hashCtx, wDigest.digest)))
1247
/* TPM Commands spec rev106 step 15 */
1248
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
1249
result |= Trspi_Hash_UINT32(&hashCtx, result);
1250
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ExecuteTransport);
1251
result |= Trspi_Hash_UINT64(&hashCtx, currentTicks);
1252
result |= Trspi_Hash_UINT32(&hashCtx, context->transMod);
1253
result |= Trspi_Hash_UINT32(&hashCtx, (outLen ? *outLen : 0)
1254
+ TSS_TPM_TXBLOB_HDR_LEN
1255
+ (*handlesLen * sizeof(UINT32))
1256
+ (pAuth1 ? TPM_AUTH_RSP_SIZE : 0)
1257
+ (pAuth2 ? TPM_AUTH_RSP_SIZE : 0));
1258
result |= Trspi_HashUpdate(&hashCtx, TPM_SHA1_160_HASH_LEN, wDigest.digest);
1259
if ((result |= Trspi_HashFinal(&hashCtx, etDigest.digest)))
1262
if (validateReturnAuth(context->transSecret.authData.authdata, etDigest.digest,
1264
result = TSPERR(TSS_E_TSP_TRANS_AUTHFAIL);
1268
if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC) {
1269
context->transLogOut.currentTicks.currentTicks = currentTicks;
1271
/* TPM Commands spec rev106 step 16.b */
1272
memcpy(context->transLogOut.parameters.digest, wDigest.digest, sizeof(TPM_DIGEST));
1273
/* TPM Commands spec rev106 step 16.c done above */
1274
/* TPM Commands spec rev106 step 16.d */
1275
context->transLogOut.locality = context->transMod;
1277
/* TPM Commands spec rev106 step 16.d */
1278
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
1279
result |= Trspi_Hash_DIGEST(&hashCtx, context->transLogDigest.digest);
1280
result |= Trspi_Hash_TRANSPORT_LOG_OUT(&hashCtx, &context->transLogOut);
1281
if ((result |= Trspi_HashFinal(&hashCtx, context->transLogDigest.digest)))
1285
/* Refresh nonceOdd for continued transport auth session */
1286
if ((result = get_local_random(tspContext, FALSE, sizeof(TPM_NONCE),
1287
(BYTE **)pTransAuth->NonceOdd.nonce))) {
1288
LogError("Failed creating random nonce");
1294
obj_list_put(&context_list);
1299
/* called to close a transport session */
1301
obj_context_transport_close(TSS_HCONTEXT tspContext,
1303
TSS_HPOLICY hPolicy,
1305
TPM_SIGN_INFO* signInfo,
1309
TSS_RESULT result = TSS_SUCCESS;
1310
struct tsp_object *obj;
1311
struct tr_context_obj *context;
1312
Trspi_HashCtx hashCtx;
1314
TPM_AUTH auth, *pAuth;
1315
TCS_KEY_HANDLE tcsKey;
1319
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
1320
return TSPERR(TSS_E_INVALID_HANDLE);
1322
context = (struct tr_context_obj *)obj->data;
1324
/* return immediately if we're not in a transport session */
1325
if (!(context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_ENABLED)) {
1326
result = TSPERR(TSS_E_INTERNAL_ERROR);
1330
if ((result = obj_rsakey_get_tcs_handle(hKey, &tcsKey)))
1333
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
1334
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ReleaseTransportSigned);
1335
result |= Trspi_Hash_NONCE(&hashCtx, signInfo->replay.nonce);
1336
if ((result |= Trspi_HashFinal(&hashCtx, (BYTE *)&digest)))
1340
if ((result = secret_PerformAuth_OIAP(hKey, TPM_ORD_ReleaseTransportSigned,
1341
hPolicy, FALSE, &digest, &auth)))
1348
/* continue the auth session established in obj_context_transport_establish */
1349
HMAC_Auth(context->transSecret.authData.authdata, digest.digest, &context->transAuth);
1351
if ((result = RPC_ReleaseTransportSigned(tspContext, tcsKey, &signInfo->replay, pAuth,
1352
&context->transAuth,
1353
&context->transLogOut.locality, &tickLen, &ticks,
1357
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
1358
result |= Trspi_Hash_UINT32(&hashCtx, result);
1359
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ReleaseTransportSigned);
1360
result |= Trspi_Hash_UINT32(&hashCtx, context->transLogOut.locality);
1361
result |= Trspi_HashUpdate(&hashCtx, tickLen, ticks);
1362
result |= Trspi_Hash_UINT32(&hashCtx, *sigLen);
1363
result |= Trspi_HashUpdate(&hashCtx, *sigLen, *sig);
1364
if ((result |= Trspi_HashFinal(&hashCtx, (BYTE *)&digest)))
1367
/* validate the return data using the key's auth */
1369
if ((result = obj_policy_validate_auth_oiap(hPolicy, &digest, pAuth)))
1373
/* validate again using the transport session's auth */
1374
if ((result = validateReturnAuth(context->transSecret.authData.authdata, digest.digest,
1375
&context->transAuth))) {
1376
result = TSPERR(TSS_E_TSP_TRANS_AUTHFAIL);
1380
if (context->flags & TSS_CONTEXT_FLAGS_TRANSPORT_AUTHENTIC) {
1383
/* TPM Commands Spec step 6.b */
1384
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
1385
result |= Trspi_Hash_UINT32(&hashCtx, TPM_ORD_ReleaseTransportSigned);
1386
result |= Trspi_Hash_NONCE(&hashCtx, signInfo->replay.nonce);
1387
if ((result |= Trspi_HashFinal(&hashCtx, context->transLogOut.parameters.digest)))
1390
/* TPM Commands Spec step 6.c */
1392
Trspi_UnloadBlob_CURRENT_TICKS(&offset, ticks, &context->transLogOut.currentTicks);
1395
/* TPM Commands Spec step 6.d was set above */
1396
/* TPM Commands Spec step 6.e */
1397
result = Trspi_HashInit(&hashCtx, TSS_HASH_SHA1);
1398
result |= Trspi_Hash_DIGEST(&hashCtx, context->transLogDigest.digest);
1399
result |= Trspi_Hash_TRANSPORT_LOG_OUT(&hashCtx, &context->transLogOut);
1400
if ((result |= Trspi_HashFinal(&hashCtx, context->transLogDigest.digest)))
1404
if ((signInfo->data = malloc(sizeof(TPM_DIGEST))) == NULL) {
1405
LogError("malloc %zd bytes failed.", sizeof(TPM_DIGEST));
1406
result = TSPERR(TSS_E_OUTOFMEMORY);
1409
memcpy(signInfo->data, context->transLogDigest.digest, sizeof(TPM_DIGEST));
1410
signInfo->dataLen = sizeof(TPM_DIGEST);
1412
/* destroy all transport session info, except the key handle */
1413
memset(&context->transPub, 0, sizeof(TPM_TRANSPORT_PUBLIC));
1414
memset(&context->transMod, 0, sizeof(TPM_MODIFIER_INDICATOR));
1415
memset(&context->transSecret, 0, sizeof(TPM_TRANSPORT_AUTH));
1416
memset(&context->transAuth, 0, sizeof(TPM_AUTH));
1417
memset(&context->transLogIn, 0, sizeof(TPM_TRANSPORT_LOG_IN));
1418
memset(&context->transLogOut, 0, sizeof(TPM_TRANSPORT_LOG_OUT));
1419
memset(&context->transLogDigest, 0, sizeof(TPM_DIGEST));
1422
context->flags &= ~TSS_CONTEXT_FLAGS_TRANSPORT_ESTABLISHED;
1424
obj_list_put(&context_list);
1429
/* XXX change 0,1,2 to #defines */
1431
obj_context_set_tpm_version(TSS_HCONTEXT tspContext, UINT32 ver)
1433
TSS_RESULT result = TSS_SUCCESS;
1434
struct tsp_object *obj;
1435
struct tr_context_obj *context;
1437
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
1438
return TSPERR(TSS_E_INVALID_HANDLE);
1440
context = (struct tr_context_obj *)obj->data;
1444
context->flags &= ~TSS_CONTEXT_FLAGS_TPM_VERSION_MASK;
1445
context->flags |= TSS_CONTEXT_FLAGS_TPM_VERSION_1;
1448
context->flags &= ~TSS_CONTEXT_FLAGS_TPM_VERSION_MASK;
1449
context->flags |= TSS_CONTEXT_FLAGS_TPM_VERSION_2;
1452
LogError("Invalid TPM version set: %u", ver);
1453
result = TSPERR(TSS_E_INTERNAL_ERROR);
1457
obj_list_put(&context_list);
1462
/* XXX change 0,1,2 to #defines */
1464
obj_context_get_tpm_version(TSS_HCONTEXT tspContext, UINT32 *ver)
1466
struct tsp_object *obj;
1467
struct tr_context_obj *context;
1469
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
1470
return TSPERR(TSS_E_INVALID_HANDLE);
1472
context = (struct tr_context_obj *)obj->data;
1474
if (context->flags & TSS_CONTEXT_FLAGS_TPM_VERSION_1)
1476
else if (context->flags & TSS_CONTEXT_FLAGS_TPM_VERSION_2)
1481
obj_list_put(&context_list);
1487
obj_context_get_loadkey_ordinal(TSS_HCONTEXT tspContext, TPM_COMMAND_CODE *ordinal)
1489
struct tsp_object *obj;
1490
struct tr_context_obj *context;
1492
if ((obj = obj_list_get_obj(&context_list, tspContext)) == NULL)
1493
return TSPERR(TSS_E_INVALID_HANDLE);
1495
context = (struct tr_context_obj *)obj->data;
1497
switch (context->flags & TSS_CONTEXT_FLAGS_TPM_VERSION_MASK) {
1498
case TSS_CONTEXT_FLAGS_TPM_VERSION_2:
1499
*ordinal = TPM_ORD_LoadKey2;
1502
LogDebugFn("No TPM version set!");
1504
case TSS_CONTEXT_FLAGS_TPM_VERSION_1:
1505
*ordinal = TPM_ORD_LoadKey;
1509
obj_list_put(&context_list);