/* Software-based Trusted Platform Module (TPM) Emulator
 * Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net>
 *
 * This module is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 *
 * This module is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * $Id: tpm_owner.c 374 2010-02-16 14:00:35Z mast $
 */

#include "tpm_emulator.h"
#include "tpm_commands.h"
#include "tpm_data.h"
#include "tpm_handles.h"
#include "crypto/rsa.h"

/*
 * Admin Opt-in ([TPM_Part3], Section 5)
 * [tpm_owner.c]
 */

TPM_RESULT TPM_SetOwnerInstall(BOOL state)
{
  info("TPM_SetOwnerInstall()");
  if (tpmData.permanent.flags.owned) return TPM_SUCCESS;
  if (!tpm_get_physical_presence()) return TPM_BAD_PRESENCE;
  tpmData.permanent.flags.ownership = state;
  return TPM_SUCCESS;
}

TPM_RESULT TPM_OwnerSetDisable(BOOL disableState, TPM_AUTH *auth1)
{
  TPM_RESULT res;
  info("TPM_OwnerSetDisable()");
  res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
  if (res != TPM_SUCCESS) return res;
  tpmData.permanent.flags.disable = disableState;
  return TPM_SUCCESS;
}

TPM_RESULT TPM_PhysicalEnable()
{
  info("TPM_PhysicalEnable()");
  if (!tpm_get_physical_presence()) return TPM_BAD_PRESENCE;
  tpmData.permanent.flags.disable = FALSE;
  return TPM_SUCCESS;
}

TPM_RESULT TPM_PhysicalDisable()
{
  info("TPM_PhysicalDisable()");
  if (!tpm_get_physical_presence()) return TPM_BAD_PRESENCE;
  tpmData.permanent.flags.disable = TRUE;
  return TPM_SUCCESS;
}

TPM_RESULT TPM_PhysicalSetDeactivated(BOOL state)
{
  info("TPM_PhysicalSetDeactivated()");
  if (!tpm_get_physical_presence()) return TPM_BAD_PRESENCE;
  tpmData.permanent.flags.deactivated = state;
  return TPM_SUCCESS;
}

TPM_RESULT TPM_SetTempDeactivated(TPM_AUTH *auth1)
{
  TPM_RESULT res;
  info("TPM_SetTempDeactivated()");
  if (auth1->authHandle == TPM_INVALID_HANDLE) {
    if (!tpm_get_physical_presence()) return TPM_BAD_PRESENCE;
  } else {
    if (!tpmData.permanent.flags.operator) return TPM_NOOPERATOR;
    res = tpm_verify_auth(auth1, tpmData.permanent.data.operatorAuth, TPM_KH_OPERATOR);
    if (res != TPM_SUCCESS) return res;
  }
  tpmData.stclear.flags.deactivated = TRUE;
  return TPM_SUCCESS;
}

TPM_RESULT TPM_SetOperatorAuth(TPM_SECRET *operatorAuth)
{
  info("TPM_SetOperatorAuth()");
  if (!tpm_get_physical_presence()) return TPM_BAD_PRESENCE;
  memcpy(&tpmData.permanent.data.operatorAuth, 
    operatorAuth, sizeof(TPM_SECRET));
  tpmData.permanent.flags.operator = TRUE;
  return TPM_SUCCESS;
}

/*
 * Admin Ownership ([TPM_Part3], Section 6)
 */

TPM_RESULT TPM_TakeOwnership(TPM_PROTOCOL_ID protocolID, 
                             UINT32 encOwnerAuthSize, BYTE *encOwnerAuth, 
                             UINT32 encSrkAuthSize, BYTE *encSrkAuth, 
                             TPM_KEY *srkParams, TPM_AUTH *auth1,  
                             TPM_KEY *srkPub)
{
  TPM_RESULT res;
  tpm_rsa_private_key_t *ek = &tpmData.permanent.data.endorsementKey;
  TPM_KEY_DATA *srk = &tpmData.permanent.data.srk;
  size_t buf_size = ek->size >> 3;
  BYTE buf[buf_size];

  info("TPM_TakeOwnership()");
  if (!ek->size) return TPM_NO_ENDORSEMENT;
  if (protocolID != TPM_PID_OWNER) return TPM_BAD_PARAMETER;
  if (tpmData.permanent.flags.owned) return TPM_OWNER_SET;
  if (!tpmData.permanent.flags.ownership) return TPM_INSTALL_DISABLED;
  /* decrypt ownerAuth */
  if (tpm_rsa_decrypt(ek, RSA_ES_OAEP_SHA1, encOwnerAuth, encOwnerAuthSize, 
      buf, &buf_size) != 0) return TPM_FAIL;
  if (buf_size != sizeof(TPM_SECRET)) return TPM_BAD_KEY_PROPERTY;
  memcpy(tpmData.permanent.data.ownerAuth, buf, buf_size);
  /* verify authorization */
  res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
  if (res != TPM_SUCCESS) return res;
  if (tpm_get_auth(auth1->authHandle)->type != TPM_ST_OIAP)
    return TPM_AUTHFAIL;
  /* reset srk and decrypt srkAuth */
  memset(srk, 0, sizeof(*srk));
  if (tpm_rsa_decrypt(ek, RSA_ES_OAEP_SHA1, encSrkAuth, encSrkAuthSize,
      buf, &buf_size) != 0) return TPM_FAIL;
  if (buf_size != sizeof(TPM_SECRET)) return TPM_BAD_KEY_PROPERTY;
  memcpy(srk->usageAuth, buf, buf_size);
  /* validate SRK parameters */
  if (srkParams->keyFlags & TPM_KEY_FLAG_MIGRATABLE
      || srkParams->keyUsage != TPM_KEY_STORAGE) return TPM_INVALID_KEYUSAGE;
  if (srkParams->algorithmParms.algorithmID != TPM_ALG_RSA
      || srkParams->algorithmParms.encScheme != TPM_ES_RSAESOAEP_SHA1_MGF1
      || srkParams->algorithmParms.sigScheme != TPM_SS_NONE
      || srkParams->algorithmParms.parmSize == 0
      || srkParams->algorithmParms.parms.rsa.keyLength != 2048
      || srkParams->algorithmParms.parms.rsa.numPrimes != 2
      || srkParams->algorithmParms.parms.rsa.exponentSize != 0
      || srkParams->PCRInfoSize != 0) return TPM_BAD_KEY_PROPERTY;
  /* setup and generate SRK */
  srk->keyFlags = srkParams->keyFlags;
  srk->keyFlags |= TPM_KEY_FLAG_PCR_IGNORE;
  srk->keyFlags &= ~TPM_KEY_FLAG_HAS_PCR;
  srk->keyUsage = srkParams->keyUsage;
  srk->encScheme = srkParams->algorithmParms.encScheme;
  srk->sigScheme = srkParams->algorithmParms.sigScheme;
  srk->authDataUsage = srkParams->authDataUsage;
  debug("srk->authDataUsage = %02x", srk->authDataUsage);
  srk->parentPCRStatus = FALSE;
  srkParams->algorithmParms.parms.rsa.keyLength = 2048;
  if (tpm_rsa_generate_key(&srk->key, 
      srkParams->algorithmParms.parms.rsa.keyLength)) return TPM_FAIL;
  srk->payload = TPM_PT_ASYM;
  /* generate context, delegate, and DAA key */
  tpm_get_random_bytes(tpmData.permanent.data.contextKey,
    sizeof(tpmData.permanent.data.contextKey));
  tpm_get_random_bytes(tpmData.permanent.data.delegateKey,
      sizeof(tpmData.permanent.data.delegateKey));
  tpm_get_random_bytes(tpmData.permanent.data.daaKey,
      sizeof(tpmData.permanent.data.daaKey));
  /* export SRK */
  memcpy(srkPub, srkParams, sizeof(TPM_KEY));
  srkPub->pubKey.keyLength = srk->key.size >> 3;
  srkPub->pubKey.key = tpm_malloc(srkPub->pubKey.keyLength);
  if (srkPub->pubKey.key == NULL) {
    tpm_rsa_release_private_key(&srk->key);
    srk->payload = TPM_PT_NONE;
    return TPM_FAIL;
  }
  tpm_rsa_export_modulus(&srk->key, srkPub->pubKey.key, NULL);
  /* setup tpmProof/daaProof and set state to owned */
  tpm_get_random_bytes(tpmData.permanent.data.tpmProof.nonce, 
    sizeof(tpmData.permanent.data.tpmProof.nonce));
  tpm_get_random_bytes(tpmData.permanent.data.daaProof.nonce,
    sizeof(tpmData.permanent.data.daaProof.nonce));
  tpmData.permanent.flags.owned = TRUE;
  return TPM_SUCCESS;
}

void tpm_owner_clear()
{
  int i;
  /* unload all keys */
  for (i = 0; i < TPM_MAX_KEYS; i++) {
    if (tpmData.permanent.data.keys[i].payload)
      TPM_FlushSpecific(INDEX_TO_KEY_HANDLE(i), TPM_RT_KEY);
  }
  /* invalidate stany and stclear data */
  memset(&tpmData.stany.data, 0 , sizeof(tpmData.stany.data));
  memset(&tpmData.stclear.data, 0 , sizeof(tpmData.stclear.data));
  /* release SRK */
  tpm_rsa_release_private_key(&tpmData.permanent.data.srk.key);
  /* invalidate permanent data */
  memset(&tpmData.permanent.data.ownerAuth, 0, 
    sizeof(tpmData.permanent.data.ownerAuth));
  memset(&tpmData.permanent.data.srk, 0, 
    sizeof(tpmData.permanent.data.srk));
  memset(&tpmData.permanent.data.tpmProof, 0,
    sizeof(tpmData.permanent.data.tpmProof));
  memset(&tpmData.permanent.data.operatorAuth, 0,
    sizeof(tpmData.permanent.data.operatorAuth));
  /* invalidate delegate, context, and DAA key */
  memset(&tpmData.permanent.data.contextKey, 0,
    sizeof(tpmData.permanent.data.contextKey));
  memset(&tpmData.permanent.data.delegateKey, 0,
    sizeof(tpmData.permanent.data.delegateKey));
  /* set permanent data */
  tpmData.permanent.data.noOwnerNVWrite = 0;
  tpmData.permanent.data.restrictDelegate = 0;
  memset (tpmData.permanent.data.ordinalAuditStatus, 0,
          sizeof(tpmData.permanent.data.ordinalAuditStatus));
  /* set permanent flags */
  tpmData.permanent.flags.owned = FALSE;
  tpmData.permanent.flags.operator = FALSE;
  tpmData.permanent.flags.disableOwnerClear = FALSE;
  tpmData.permanent.flags.ownership = TRUE;
  tpmData.permanent.flags.disable = FALSE;
  tpmData.permanent.flags.deactivated = FALSE;
  tpmData.permanent.flags.maintenanceDone = FALSE;
  tpmData.permanent.flags.allowMaintenance = TRUE;
  tpmData.permanent.flags.disableFullDALogicInfo = FALSE;
  if (tpmConf & TPM_CONF_KEEP_PUBEK_READABLE) {
    tpmData.permanent.flags.readPubek = TRUE;
  } else {
    tpmData.permanent.flags.readPubek = FALSE;
  }
  /* release all counters */
  for (i = 0; i < TPM_MAX_COUNTERS; i++)
    memset(&tpmData.permanent.data.counters[i], 0, sizeof(TPM_COUNTER_VALUE));
  /* invalidate family and delegates table */
  for (i = 0; i < TPM_NUM_FAMILY_TABLE_ENTRY; i++) {
    memset(&tpmData.permanent.data.familyTable.famRow[i], 0,
           sizeof(TPM_FAMILY_TABLE_ENTRY));
  }
  for (i = 0; i < TPM_NUM_DELEGATE_TABLE_ENTRY; i++) {
    memset(&tpmData.permanent.data.delegateTable.delRow[i], 0,
           sizeof(TPM_DELEGATE_TABLE_ROW));
  }
  /* release NV storage */
  for (i = 0; i < TPM_MAX_NVS; i++) {
    if (tpmData.permanent.data.nvStorage[i].valid
        && (tpmData.permanent.data.nvStorage[i].pubInfo.permission.attributes
            & (TPM_NV_PER_OWNERWRITE | TPM_NV_PER_OWNERREAD))) {
      tpm_nv_remove_data(&tpmData.permanent.data.nvStorage[i]);
    }
  }
}

TPM_RESULT TPM_OwnerClear(TPM_AUTH *auth1)
{
  TPM_RESULT res;
  info("TPM_OwnerClear()");
  res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
  if (res != TPM_SUCCESS) return res;
  if (tpmData.permanent.flags.disableOwnerClear) return TPM_CLEAR_DISABLED;
  tpm_owner_clear();
  return TPM_SUCCESS;
}

TPM_RESULT TPM_ForceClear()
{
  info("TPM_ForceClear()");
  if (!tpm_get_physical_presence()) return TPM_BAD_PRESENCE;
  if (tpmData.stclear.flags.disableForceClear) return TPM_CLEAR_DISABLED;
  tpm_owner_clear();
  return TPM_SUCCESS;
}

TPM_RESULT TPM_DisableOwnerClear(TPM_AUTH *auth1)
{
  TPM_RESULT res;
  info("TPM_DisableOwnerClear()");
  res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
  if (res != TPM_SUCCESS) return res;
  tpmData.permanent.flags.disableOwnerClear = TRUE;
  return TPM_SUCCESS;
}

TPM_RESULT TPM_DisableForceClear()
{
  info("TPM_DisableForceClear()");
  tpmData.stclear.flags.disableForceClear = TRUE;
  return TPM_SUCCESS;
}

TPM_RESULT TSC_PhysicalPresence(TPM_PHYSICAL_PRESENCE physicalPresence)
{
  info("TSC_PhysicalPresence()");
  if (!tpmData.permanent.flags.physicalPresenceLifetimeLock) {
    /* enable physicalPresenceHW or physicalPresenceCMD */
    if (physicalPresence & TPM_PHYSICAL_PRESENCE_HW_ENABLE)
      tpmData.permanent.flags.physicalPresenceHWEnable = TRUE;
    if (physicalPresence & TPM_PHYSICAL_PRESENCE_CMD_ENABLE)
      tpmData.permanent.flags.physicalPresenceCMDEnable = TRUE;
  } else if (physicalPresence & TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK) {
    /* set physicalPresenceLifetimeLock */
    tpmData.permanent.flags.physicalPresenceLifetimeLock = TRUE;
  } else if (tpmData.permanent.flags.physicalPresenceCMDEnable &&
             !tpmData.stclear.flags.physicalPresenceLock) {
    /* set physicalPresence or physicalPresenceLock */
    if (physicalPresence & TPM_PHYSICAL_PRESENCE_PRESENT)
      tpmData.stclear.flags.physicalPresence = TRUE;
    if (physicalPresence & TPM_PHYSICAL_PRESENCE_NOTPRESENT)
      tpmData.stclear.flags.physicalPresence = FALSE;
    if (physicalPresence & TPM_PHYSICAL_PRESENCE_LOCK)
      tpmData.stclear.flags.physicalPresenceLock = TRUE;
  } else {
    return TPM_BAD_PARAMETER;
  }
  return TPM_SUCCESS;
}

TPM_RESULT TSC_ResetEstablishmentBit()
{
  info("TSC_ResetEstablishmentBit()");
  /* locality must be three or four */
  if (tpmData.stany.flags.localityModifier != 3
      && tpmData.stany.flags.localityModifier != 4) return TPM_BAD_LOCALITY;
  /* as we do not have such a bit we do nothing and just return true */
  return TPM_SUCCESS;
}
