コード例 #1
0
ファイル: hmac.c プロジェクト: Aorimn/tpm-emulator
void tpm_hmac_init(tpm_hmac_ctx_t *ctx, const uint8_t *key, size_t key_len)
{
    uint8_t tk[SHA1_DIGEST_LENGTH];
    uint8_t k_ipad[HMAC_PAD_LENGTH];
    int i;

    /* if the key is longer than 64 bytes reset it to key := hash(key) */
    if (key_len > HMAC_PAD_LENGTH) {
        tpm_sha1_init(&ctx->ctx);
        tpm_sha1_update(&ctx->ctx, key, key_len);
        tpm_sha1_final(&ctx->ctx, tk);
        key = tk;
        key_len = SHA1_DIGEST_LENGTH;
    }
    /* start out by storing key in pads */
    memset(k_ipad, 0, HMAC_PAD_LENGTH);
    memset(ctx->k_opad, 0, HMAC_PAD_LENGTH);
    memcpy(k_ipad, key, key_len);
    memcpy(ctx->k_opad, key, key_len);
    /* xor key with ipad and opad values */
    for (i = 0; i < HMAC_PAD_LENGTH; i++) {
        k_ipad[i] ^= 0x36;
        ctx->k_opad[i] ^= 0x5C;
    }
    /* start inner hash */
    tpm_sha1_init(&ctx->ctx);
    tpm_sha1_update(&ctx->ctx, k_ipad, HMAC_PAD_LENGTH);
}
コード例 #2
0
ファイル: tpm_transport.c プロジェクト: Aorimn/tpm-emulator
static void compute_key_digest(TPM_REQUEST *req, TPM_DIGEST *digest)
{
  tpm_sha1_ctx_t ctx;
  TPM_HANDLE h1, h2;
  TPM_KEY_DATA *k1, *k2;
  BYTE *ptr;
  UINT32 len, offset = tpm_get_in_param_offset(req->ordinal);
  /* handle some exceptions */
  if (req->ordinal == TPM_ORD_FlushSpecific) offset = 0;
  else if (req->ordinal == TPM_ORD_OwnerReadInternalPub) offset = 4;
  /* compute public key digests */
  if (offset == 0) {
    debug("no handles");
    memset(digest, 0, sizeof(TPM_DIGEST));
  } else if (offset == 4) {
    debug("one handle");
    ptr = req->param; len = 4;
    tpm_unmarshal_TPM_HANDLE(&ptr, &len, &h1);
    k1 = tpm_get_key(h1);
    if (k1 != NULL && tpm_compute_key_data_digest(k1, digest) == 0) {
      debug("key found");
      /* compute outer hash */
      tpm_sha1_init(&ctx);
      tpm_sha1_update(&ctx, digest->digest, sizeof(digest->digest));
      tpm_sha1_final(&ctx, digest->digest);
    } else {
      memset(digest, 0, sizeof(TPM_DIGEST));
    }
  } else if (offset == 8) {
    TPM_DIGEST digest2;
    debug("two handles");
    ptr = req->param; len = 8;
    tpm_unmarshal_TPM_HANDLE(&ptr, &len, &h1);
    tpm_unmarshal_TPM_HANDLE(&ptr, &len, &h2);
    k1 = tpm_get_key(h1);
    k2 = tpm_get_key(h2);
    if (k1 != NULL && tpm_compute_key_data_digest(k1, digest) == 0
        && k2 != NULL && tpm_compute_key_data_digest(k2, &digest2) == 0) {
      debug("two keys found");
      /* compute outer hash */
      tpm_sha1_init(&ctx);
      tpm_sha1_update(&ctx, digest->digest, sizeof(digest->digest));
      tpm_sha1_update(&ctx, digest2.digest, sizeof(digest2.digest));
      tpm_sha1_final(&ctx, digest->digest);
    } else {
      memset(digest, 0, sizeof(TPM_DIGEST));
    }
  } else {
    memset(digest, 0, sizeof(TPM_DIGEST));
  }
}
コード例 #3
0
ファイル: tpm_transport.c プロジェクト: Aorimn/tpm-emulator
TPM_RESULT TPM_ReleaseTransportSigned(TPM_KEY_HANDLE keyHandle,
                                      TPM_NONCE *antiReplay,
                                      TPM_AUTH *auth1, TPM_AUTH *auth2,
                                      TPM_MODIFIER_INDICATOR *locality,
                                      TPM_CURRENT_TICKS *currentTicks,
                                      UINT32 *sigSize, BYTE **sig)
{
  TPM_RESULT res;
  TPM_KEY_DATA *key;
  TPM_SESSION_DATA *session;
  BYTE buf[30 + 20];
  info("TPM_ReleaseTransportSigned()");
  /* get key */
  key = tpm_get_key(keyHandle);
  if (key == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify authorization */ 
  if (auth2->authHandle != TPM_INVALID_HANDLE
      || key->authDataUsage != TPM_AUTH_NEVER) {
    res = tpm_verify_auth(auth1, key->usageAuth, keyHandle);
    if (res != TPM_SUCCESS) return res;
    session = tpm_get_transport(auth2->authHandle);
    if (session == NULL) return TPM_INVALID_AUTHHANDLE;
    res = tpm_verify_auth(auth2, session->transInternal.authData, TPM_INVALID_HANDLE);
    if (res != TPM_SUCCESS) return (res == TPM_AUTHFAIL) ? TPM_AUTH2FAIL : res;
  } else {
    session = tpm_get_transport(auth1->authHandle);
    if (session == NULL) return TPM_INVALID_AUTHHANDLE;
    res = tpm_verify_auth(auth1, session->transInternal.authData, TPM_INVALID_HANDLE);
    if (res != TPM_SUCCESS) return res;
  }
  /* invalidate transport session */
  auth1->continueAuthSession = FALSE;
  /* logging must be enabled */
  if (!(session->transInternal.transPublic.transAttributes & TPM_TRANSPORT_LOG))
    return TPM_BAD_MODE;
  *locality = tpmData.stany.flags.localityModifier;
  memcpy(currentTicks, &tpmData.stany.data.currentTicks, sizeof(TPM_CURRENT_TICKS));
  transport_log_out(auth1->digest, &session->transInternal.transDigest);
  /* setup a TPM_SIGN_INFO structure */
  memcpy(&buf[0], (uint8_t*)"\x00\x05TRAN", 6);
  memcpy(&buf[6], antiReplay->nonce, 20);
  memcpy(&buf[26], (uint8_t*)"\x00\x00\x00\x14", 4);
  memcpy(&buf[30], session->transInternal.transDigest.digest, 20);
  /* sign info structure */ 
  if (key->sigScheme == TPM_SS_RSASSAPKCS1v15_SHA1) {
    tpm_sha1_ctx_t ctx;
    debug("TPM_SS_RSASSAPKCS1v15_SHA1");
    tpm_sha1_init(&ctx);
    tpm_sha1_update(&ctx, buf, sizeof(buf));
    tpm_sha1_final(&ctx, buf);
    res = tpm_sign(key, auth1, FALSE, buf, SHA1_DIGEST_LENGTH, sig, sigSize);
  } else if (key->sigScheme == TPM_SS_RSASSAPKCS1v15_INFO) {
    debug("TPM_SS_RSASSAPKCS1v15_INFO");
    res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), sig, sigSize);
  } else {
    debug("unsupported signature scheme: %02x", key->sigScheme);
    res = TPM_INVALID_KEYUSAGE;
  }
  return res;
}
コード例 #4
0
ファイル: hmac.c プロジェクト: Aorimn/tpm-emulator
void tpm_hmac_final(tpm_hmac_ctx_t *ctx, uint8_t *digest)
{
    /* complete inner hash */
    tpm_sha1_final(&ctx->ctx, digest);
    /* perform outer hash */
    tpm_sha1_init(&ctx->ctx);
    tpm_sha1_update(&ctx->ctx, ctx->k_opad, HMAC_PAD_LENGTH);
    tpm_sha1_update(&ctx->ctx, digest, SHA1_DIGEST_LENGTH);
    tpm_sha1_final(&ctx->ctx, digest);
}
コード例 #5
0
ファイル: tpm_cmd_handler.c プロジェクト: johnxn/rockey-tpm
void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
{
  tpm_sha1_ctx_t sha1;
  UINT32 offset = tpm_get_out_param_offset(ordinal);

  /* compute SHA1 hash */
  tpm_sha1_init(&sha1);
  tpm_sha1_update_be32(&sha1, rsp->result);
  tpm_sha1_update_be32(&sha1, ordinal);

  tpm_sha1_update(&sha1, rsp->param + offset, rsp->paramSize - offset);
  tpm_sha1_final(&sha1, rsp->auth1->digest);
  if (rsp->auth2 != NULL) memcpy(rsp->auth2->digest, 
    rsp->auth1->digest, sizeof(rsp->auth1->digest));
}
コード例 #6
0
ファイル: tpm_cmd_handler.c プロジェクト: johnxn/rockey-tpm
void tpm_compute_in_param_digest(TPM_REQUEST *req)
{
  tpm_sha1_ctx_t sha1;
  UINT32 offset = tpm_get_in_param_offset(req->ordinal);

  /* compute SHA1 hash */
  if (offset <= req->paramSize) {
    tpm_sha1_init(&sha1);
    tpm_sha1_update_be32(&sha1, req->ordinal);
    /* skip all handles at the beginning */
    tpm_sha1_update(&sha1, req->param + offset, req->paramSize - offset);
    tpm_sha1_final(&sha1, req->auth1.digest);
    memcpy(req->auth2.digest, req->auth1.digest, sizeof(req->auth1.digest));
  }
}
コード例 #7
0
ファイル: tpm_transport.c プロジェクト: Aorimn/tpm-emulator
static void transport_log_out(BYTE *params, TPM_DIGEST *transDigest)
{
  BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_OUT(x)];
  UINT32 len;
  tpm_sha1_ctx_t sha1;

  ptr = buf; len = sizeof(buf);
  tpm_marshal_TPM_TAG(&ptr, &len, TPM_TAG_TRANSPORT_LOG_OUT);
  tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, &tpmData.stany.data.currentTicks);
  tpm_marshal_BLOB(&ptr, &len, params, SHA1_DIGEST_LENGTH);
  tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len, tpmData.stany.flags.localityModifier);
  tpm_sha1_init(&sha1);
  tpm_sha1_update(&sha1, transDigest->digest, sizeof(transDigest->digest));
  tpm_sha1_update(&sha1, buf, sizeof(buf));
  tpm_sha1_final(&sha1, transDigest->digest);
  debug_buf("LogOut: transDigest: ", transDigest->digest, sizeof(transDigest->digest));
}
コード例 #8
0
ファイル: tpm_transport.c プロジェクト: Aorimn/tpm-emulator
static void transport_log_in(BYTE *params, BYTE *pubKeyHash,
                             TPM_DIGEST *transDigest)
{
  BYTE *ptr, buf[sizeof_TPM_TRANSPORT_LOG_IN(x)];
  UINT32 len;
  tpm_sha1_ctx_t sha1;

  ptr = buf; len = sizeof(buf);
  tpm_marshal_TPM_TAG(&ptr, &len, TPM_TAG_TRANSPORT_LOG_IN);
  tpm_marshal_BLOB(&ptr, &len, params, SHA1_DIGEST_LENGTH);
  tpm_marshal_BLOB(&ptr, &len, pubKeyHash, SHA1_DIGEST_LENGTH);
  tpm_sha1_init(&sha1);
  tpm_sha1_update(&sha1, transDigest->digest, sizeof(transDigest->digest));
  tpm_sha1_update(&sha1, buf, sizeof(buf));
  tpm_sha1_final(&sha1, transDigest->digest);
  debug_buf("LogIn: transDigest: ", transDigest->digest, sizeof(transDigest->digest));
}
コード例 #9
0
ファイル: tpm_transport.c プロジェクト: Aorimn/tpm-emulator
static void encrypt_wrapped_command(BYTE *buf, UINT32 buf_len, TPM_AUTH *auth,
                                    TPM_SESSION_DATA *session)
{
  UINT32 i, j;
  BYTE mask[SHA1_DIGEST_LENGTH];
  tpm_sha1_ctx_t sha1;
  for (i = 0; buf_len > 0; i++) {
    tpm_sha1_init(&sha1);
    tpm_sha1_update(&sha1, session->nonceEven.nonce, sizeof(session->nonceEven.nonce));
    tpm_sha1_update(&sha1, auth->nonceOdd.nonce, sizeof(auth->nonceOdd.nonce));
    tpm_sha1_update(&sha1, (uint8_t*)"out", 3);
    tpm_sha1_update(&sha1, session->transInternal.authData, sizeof(TPM_SECRET));
    tpm_sha1_update_be32(&sha1, i);
    tpm_sha1_final(&sha1, mask);
    for (j = 0; j < sizeof(mask) && buf_len > 0; j++) { 
      *buf++ ^= mask[j];
      buf_len--;
    }
  }
}
コード例 #10
0
static int tpm_compute_migration_digest(TPM_PUBKEY *migrationKey,
                                        TPM_MIGRATE_SCHEME migrationScheme,
                                        TPM_NONCE *tpmProof, TPM_DIGEST *digest)
{
  tpm_sha1_ctx_t sha1;
  UINT32 len = sizeof_TPM_PUBKEY((*migrationKey));
  BYTE *buf, *ptr, buf2[2];
  buf = ptr = tpm_malloc(len);
  if (buf == NULL
      || tpm_marshal_TPM_PUBKEY(&ptr, &len, migrationKey)) {
    tpm_free(buf);
    return -1;
  }
  /* compute SHA1 hash */
  tpm_sha1_init(&sha1);
  tpm_sha1_update(&sha1, buf, sizeof_TPM_PUBKEY((*migrationKey)));
  ptr = buf2; len = 2;
  tpm_marshal_UINT16(&ptr, &len, migrationScheme);
  tpm_sha1_update(&sha1, buf2, 2);
  tpm_sha1_update(&sha1, tpmProof->nonce, sizeof(TPM_NONCE));
  tpm_sha1_final(&sha1, digest->digest);
  tpm_free(buf);
  return 0;
}
コード例 #11
0
ファイル: tpm_transport.c プロジェクト: Aorimn/tpm-emulator
TPM_RESULT TPM_ExecuteTransport(UINT32 inWrappedCmdSize, BYTE *inWrappedCmd,
                                TPM_AUTH *auth1, UINT64 *currentTicks,
                                TPM_MODIFIER_INDICATOR *locality,
                                UINT32 *outWrappedCmdSize, BYTE **outWrappedCmd)
{
  TPM_RESULT res;
  TPM_SESSION_DATA *session;
  TPM_REQUEST req;
  TPM_RESPONSE rsp;
  BYTE *ptr, buf[4 * 4 + 8 + 20];
  UINT32 len, offset;
  tpm_sha1_ctx_t sha1;
  info("TPM_ExecuteTransport()");
  /* get transport session */
  session = tpm_get_transport(auth1->authHandle);
  if (session == NULL) return TPM_BAD_PARAMETER;
  /* unmarshal wrapped command */
  len = inWrappedCmdSize;
  ptr = inWrappedCmd;
  if (tpm_unmarshal_TPM_REQUEST(&ptr, &len, &req)) return TPM_FAIL;
  /* decrypt wrapped command if needed */
  ptr = tpm_malloc(req.paramSize);
  if (ptr == NULL) return TPM_FAIL;
  memcpy(ptr, req.param, req.paramSize);
  if (session->transInternal.transPublic.transAttributes & TPM_TRANSPORT_ENCRYPT) {
    if (req.ordinal == TPM_ORD_OIAP || req.ordinal == TPM_ORD_OSAP) {
      offset = req.paramSize;
    } else if (req.ordinal == TPM_ORD_DSAP) {
      offset = 30;
    } else {
      offset = tpm_get_in_param_offset(req.ordinal);
    }
    debug("decrypting %d bytes, starting at pos %d", req.paramSize - offset, offset);
    decrypt_wrapped_command(ptr + offset, req.paramSize - offset, auth1, session);
  }
  req.param = ptr;
  /* verify authorization */
  tpm_compute_in_param_digest(&req);
  tpm_sha1_init(&sha1);
  tpm_sha1_update_be32(&sha1, TPM_ORD_ExecuteTransport);
  tpm_sha1_update_be32(&sha1, inWrappedCmdSize);
  tpm_sha1_update(&sha1, req.auth1.digest, sizeof(req.auth1.digest));
  tpm_sha1_final(&sha1, auth1->digest);
  res = tpm_verify_auth(auth1, session->transInternal.authData, TPM_INVALID_HANDLE);
  if (res != TPM_SUCCESS) {
    tpm_free(req.param);
    return res;
  }
  /* nested transport sessions are not allowed */
  if (req.ordinal == TPM_ORD_EstablishTransport
      || req.ordinal == TPM_ORD_ExecuteTransport
      || req.ordinal == TPM_ORD_ReleaseTransportSigned) {
    tpm_free(req.param);
    return TPM_NO_WRAP_TRANSPORT;
  }
  /* log input parameters */
  if (session->transInternal.transPublic.transAttributes & TPM_TRANSPORT_LOG) {
    TPM_DIGEST keyDigest;
    compute_key_digest(&req, &keyDigest);
    transport_log_in(req.auth1.digest, keyDigest.digest,
                     &session->transInternal.transDigest);
  }
  /* execute and audit command*/
  tpm_audit_request(req.ordinal, &req);
  tpm_execute_command(&req, &rsp);
  tpm_audit_response(req.ordinal, &rsp);
  tpm_free(req.param);
  /* get locality and ticks */
  *locality = tpmData.stany.flags.localityModifier;
  *currentTicks = tpmData.stany.data.currentTicks.currentTicks;
  /* if required, compute digest of internal output parameters */
  debug("result = %d", rsp.result);
  if (rsp.result == TPM_SUCCESS) {
    if (rsp.tag == TPM_TAG_RSP_COMMAND) {
      rsp.auth1 = &req.auth1;
      tpm_compute_out_param_digest(req.ordinal, &rsp);
    }
    /* encrypt parameters */
    if (session->transInternal.transPublic.transAttributes & TPM_TRANSPORT_ENCRYPT) {
      if (req.ordinal == TPM_ORD_OIAP || req.ordinal == TPM_ORD_OSAP) {
        offset = rsp.paramSize;
      } else if (req.ordinal == TPM_ORD_DSAP) {
        offset = rsp.paramSize;
      } else {
        offset = tpm_get_out_param_offset(req.ordinal);
      }
      debug("encrypting %d bytes, starting at pos %d", rsp.paramSize - offset, offset);
      encrypt_wrapped_command(rsp.param + offset, rsp.paramSize - offset, auth1, session);
    }
  } else {
    rsp.auth1 = &req.auth1;
    memset(rsp.auth1->digest, 0, sizeof(*rsp.auth1->digest));
  }
  /* marshal response */
  *outWrappedCmdSize = len = rsp.size;
  *outWrappedCmd = ptr = tpm_malloc(len);
  if (ptr == NULL) {
    tpm_free(rsp.param);
    return TPM_FAIL;
  }
  tpm_marshal_TPM_RESPONSE(&ptr, &len, &rsp);
  debug("marshalling done.");
  /* log output parameters */
  if (session->transInternal.transPublic.transAttributes & TPM_TRANSPORT_LOG) {
    transport_log_out(rsp.auth1->digest, &session->transInternal.transDigest);
  }
  tpm_free(rsp.param);
  /* compute digest of output parameters */
  ptr = buf; len = sizeof(buf);
  tpm_marshal_UINT32(&ptr, &len, TPM_SUCCESS);
  tpm_marshal_TPM_COMMAND_CODE(&ptr, &len, TPM_ORD_ExecuteTransport);
  tpm_marshal_UINT64(&ptr, &len, *currentTicks);
  tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len, *locality);
  tpm_marshal_UINT32(&ptr, &len, *outWrappedCmdSize);
  memcpy(ptr, rsp.auth1->digest, sizeof(rsp.auth1->digest));
  tpm_sha1_init(&sha1);
  tpm_sha1_update(&sha1, buf, sizeof(buf));
  tpm_sha1_final(&sha1, auth1->digest);
  return TPM_SUCCESS;
}
コード例 #12
0
ファイル: tpm_transport.c プロジェクト: Aorimn/tpm-emulator
TPM_RESULT TPM_EstablishTransport(TPM_KEY_HANDLE encHandle,
                                  TPM_TRANSPORT_PUBLIC *transPublic,
                                  UINT32 secretSize, BYTE *secret,
                                  TPM_AUTH *auth1,
                                  TPM_TRANSHANDLE *transHandle,
                                  TPM_MODIFIER_INDICATOR *locality,
                                  TPM_CURRENT_TICKS *currentTicks,
                                  TPM_NONCE *transNonceEven)
{
  TPM_RESULT res;
  TPM_KEY_DATA *key;
  TPM_TRANSPORT_AUTH trans_auth;
  TPM_SESSION_DATA *session;

  info("TPM_EstablishTransport()");
  /* setup authorization data */
  if (encHandle == TPM_KH_TRANSPORT) {
    if (auth1->authHandle != TPM_INVALID_HANDLE) return TPM_BADTAG;
    if (transPublic->transAttributes & TPM_TRANSPORT_ENCRYPT) return TPM_BAD_SCHEME;
    if (secretSize != 20) return TPM_BAD_PARAM_SIZE;
    memcpy(trans_auth.authData, secret, 20);
  } else {
    /* get key and verify its usage */
    key = tpm_get_key(encHandle);
    if (key == NULL) return TPM_INVALID_KEYHANDLE;
    if (key->keyUsage != TPM_KEY_STORAGE && key->keyUsage != TPM_KEY_LEGACY)
        return TPM_INVALID_KEYUSAGE;
    /* verify authorization */ 
    if (key->authDataUsage != TPM_AUTH_NEVER) {
      res = tpm_verify_auth(auth1, key->usageAuth, encHandle);
      if (res != TPM_SUCCESS) return res;
      if (decrypt_transport_auth(key, secret, secretSize, &trans_auth))
        return TPM_DECRYPT_ERROR;
    }
  }
  /* check whether the transport has to be encrypted */
  if (transPublic->transAttributes & TPM_TRANSPORT_ENCRYPT) {
    if (tpmData.permanent.flags.FIPS
        && transPublic->algID == TPM_ALG_MGF1) return TPM_INAPPROPRIATE_ENC;
    /* until now, only MGF1 is supported */
    if (transPublic->algID != TPM_ALG_MGF1) return TPM_BAD_KEY_PROPERTY;
  }
  /* initialize transport session */
  tpm_get_random_bytes(transNonceEven->nonce, sizeof(transNonceEven->nonce));
  *transHandle = tpm_get_free_session(TPM_ST_TRANSPORT);
  session = tpm_get_transport(*transHandle);
  if (session == NULL) return TPM_RESOURCES;
  session->transInternal.transHandle = *transHandle;
  memset(&session->transInternal.transDigest, 0, sizeof(TPM_DIGEST));
  memcpy(&session->transInternal.transPublic, transPublic,
    sizeof_TPM_TRANSPORT_PUBLIC((*transPublic)));
  memcpy(&session->transInternal.transNonceEven, transNonceEven, sizeof(TPM_NONCE));
  memcpy(&session->nonceEven, transNonceEven, sizeof(TPM_NONCE));
  memcpy(&session->transInternal.authData, trans_auth.authData, sizeof(TPM_AUTHDATA));
  *locality = tpmData.stany.flags.localityModifier;
  memcpy(currentTicks, &tpmData.stany.data.currentTicks, sizeof(TPM_CURRENT_TICKS));
  /* perform transport logging */
  if (transPublic->transAttributes & TPM_TRANSPORT_LOG) {
    tpm_sha1_ctx_t sha1;
    BYTE *ptr, buf[4 + 4 + 4 + sizeof_TPM_CURRENT_TICKS(x) + 20];
    UINT32 len;
    /* log input */
    memset(buf, 0, sizeof(buf));
    transport_log_in(auth1->digest, buf, &session->transInternal.transDigest);
    /* compute digest of output parameters and log output */
    ptr = buf; len = sizeof(buf);
    tpm_marshal_UINT32(&ptr, &len, TPM_SUCCESS);
    tpm_marshal_TPM_COMMAND_CODE(&ptr, &len, TPM_ORD_EstablishTransport);
    tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len, *locality);
    tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, currentTicks);
    tpm_marshal_TPM_NONCE(&ptr, &len, transNonceEven);
    tpm_sha1_init(&sha1);
    tpm_sha1_update(&sha1, buf, sizeof(buf));
    tpm_sha1_final(&sha1, buf);
    transport_log_out(buf, &session->transInternal.transDigest);
  }
  /* check whether this is a exclusive transport session */
  if (transPublic->transAttributes & TPM_TRANSPORT_EXCLUSIVE) {
    tpmData.stany.flags.transportExclusive = TRUE;
    tpmData.stany.data.transExclusive = *transHandle;
  }
  auth1->continueAuthSession = FALSE;
  return TPM_SUCCESS;
}