예제 #1
0
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));
}
예제 #2
0
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));
  }
}
예제 #3
0
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--;
    }
  }
}
예제 #4
0
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;
}