/* 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_migration.c 367 2010-02-13 15:52:18Z mast $
 */

#include "tpm_emulator.h"
#include "tpm_commands.h"
#include "tpm_handles.h"
#include "tpm_data.h"
#include "tpm_marshalling.h"
#include "crypto/sha1.h"
#include "crypto/hmac.h"

/*
 * Migration ([TPM_Part3], Section 11)
 */

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;
}

static int tpm_verify_migration_digest(TPM_MIGRATIONKEYAUTH *migrationKeyAuth,
                                       TPM_NONCE *tpmProof)
{
  TPM_DIGEST digest;
  if (tpm_compute_migration_digest(&migrationKeyAuth->migrationKey,
      migrationKeyAuth->migrationScheme, tpmProof, &digest)) return -1;
  return memcmp(digest.digest, migrationKeyAuth->digest.digest, sizeof(TPM_DIGEST));
}

TPM_RESULT TPM_CreateMigrationBlob(TPM_KEY_HANDLE parentHandle,
                                   TPM_MIGRATE_SCHEME migrationType,
                                   TPM_MIGRATIONKEYAUTH *migrationKeyAuth,
                                   UINT32 encDataSize, BYTE *encData,
                                   TPM_AUTH *auth1, TPM_AUTH *auth2,
                                   UINT32 *randomSize, BYTE **random,
                                   UINT32 *outDataSize, BYTE **outData)
{
  TPM_RESULT res;
  TPM_KEY_DATA *parent;
  TPM_SESSION_DATA *session;
  BYTE *key_buf;
  UINT32 key_buf_size;
  TPM_STORE_ASYMKEY store;
  TPM_PUBKEY_DATA key;

  info("TPM_CreateMigrationBlob()");
  /* get parent key */
  parent = tpm_get_key(parentHandle);
  if (parent == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify parent authorization */
  res = tpm_verify_auth(auth1, parent->usageAuth, parentHandle);
  if (res != TPM_SUCCESS) return res;
  session = tpm_get_auth(auth2->authHandle);
  if (session == NULL || session->type != TPM_ST_OIAP) return TPM_AUTHFAIL;
  /* verify key properties */
  if (parent->keyUsage != TPM_KEY_STORAGE) return TPM_INVALID_KEYUSAGE;
  /* decrypt private key */
  if (tpm_decrypt_private_key(parent, encData, encDataSize,
                              &store, &key_buf, &key_buf_size)
      || store.payload != TPM_PT_ASYM) {
    tpm_free(key_buf);
    return TPM_DECRYPT_ERROR;
  }
  debug("key size: %d / %d", store.privKey.keyLength, key_buf_size);
  /* verify migration authorization */
  res = tpm_verify_auth(auth2, store.migrationAuth, TPM_INVALID_HANDLE);
  if (res != TPM_SUCCESS) {
    tpm_free(key_buf);
    return TPM_MIGRATEFAIL;
  }
  if (tpm_verify_migration_digest(migrationKeyAuth,
      &tpmData.permanent.data.tpmProof)) {
    debug("tpm_verify_migration_digest() failed");
    tpm_free(key_buf);
    return TPM_MIGRATEFAIL;
  }
  debug("migration authorization is valid.");
  /* set public key */
  if (tpm_setup_pubkey_data(&migrationKeyAuth->migrationKey, &key) != 0) {
      debug("tpm_setup_pubkey() failed");
      tpm_free(key_buf);
      return TPM_FAIL;
  }
  /* perform migration */
  if (migrationType == TPM_MS_REWRAP) {
    /* re-encrypt raw key data */
    debug("migrationType = TPM_MS_REWRAP");
    *random = NULL;
    *randomSize = 0;
    *outDataSize = key.key.size >> 3;
    *outData = tpm_malloc(*outDataSize);
    if (*outData == NULL) {
      free_TPM_PUBKEY_DATA(key);
      tpm_free(*outData);
      tpm_free(key_buf);
      return TPM_FAIL;
    }
    if (tpm_encrypt_public(&key, key_buf, key_buf_size,
                           *outData, outDataSize) != 0) {
        free_TPM_PUBKEY_DATA(key);
        tpm_free(*outData);
        tpm_free(key_buf);
        return TPM_ENCRYPT_ERROR;
    }
  } else if (migrationType == TPM_MS_MIGRATE) {
    BYTE *ptr, *buf;
    UINT32 len;
    size_t buf_len;
    /* generate an OAEP encoding of the TPM_MIGRATE_ASYMKEY structure:
       0x00|seed|K1|0x00-pad|0x01|TPM_MIGRATE_ASYMKEY */
    debug("migrationType = TPM_MS_MIGRATE");
    buf_len = key.key.size >> 3;
    ptr = buf = tpm_malloc(buf_len);
    *randomSize = buf_len;
    *random = tpm_malloc(*randomSize);
    if (buf == NULL || *random == NULL) {
      free_TPM_PUBKEY_DATA(key);
      tpm_free(buf);
      tpm_free(*random);
      tpm_free(key_buf);
      return TPM_NOSPACE;
    }
    buf[0] = 0x00;
    memcpy(&buf[1], store.migrationAuth, sizeof(TPM_SECRET));
    ptr = &buf[1 + sizeof(TPM_SECRET)];
    len = 4;
    tpm_marshal_UINT32(&ptr, &len, store.privKey.keyLength);
    memcpy(ptr, store.privKey.key, 16);
    memset(ptr + 16, 0, buf_len - 41);
    len = 46 + store.privKey.keyLength - 16;
    ptr = &buf[buf_len - len];
    tpm_marshal_BYTE(&ptr, &len, 0x01);
    tpm_marshal_TPM_PAYLOAD_TYPE(&ptr, &len, TPM_PT_MIGRATE);
    tpm_marshal_TPM_SECRET(&ptr, &len, &store.usageAuth);
    tpm_marshal_TPM_DIGEST(&ptr, &len, &store.pubDataDigest);
    tpm_marshal_UINT32(&ptr, &len, store.privKey.keyLength - 16);
    memcpy(ptr, &store.privKey.key[16], store.privKey.keyLength - 16);
    tpm_rsa_mask_generation(&buf[1], SHA1_DIGEST_LENGTH,
      &buf[1 + SHA1_DIGEST_LENGTH], buf_len - SHA1_DIGEST_LENGTH - 1);
    tpm_rsa_mask_generation(&buf[1 + SHA1_DIGEST_LENGTH],
      buf_len - SHA1_DIGEST_LENGTH - 1, &buf[1], SHA1_DIGEST_LENGTH);
    /* XOR encrypt OAEP encoding */
    tpm_get_random_bytes(*random, *randomSize);
    for (len = 0; len < buf_len; len++) buf[len] ^= (*random)[len];
    /* RSA encrypt OAEP encoding */
    if (tpm_rsa_encrypt(&key.key, RSA_ES_PLAIN, buf, buf_len, buf, &buf_len)) {
      debug("tpm_rsa_encrypt() failed");
      free_TPM_PUBKEY_DATA(key);
      tpm_free(buf);
      tpm_free(*random);
      tpm_free(key_buf);
      return TPM_ENCRYPT_ERROR;
    }
    *outDataSize = buf_len;
    *outData = buf;
  } else {
    debug("invalid migration type: %d", migrationType);
    free_TPM_PUBKEY_DATA(key);
    tpm_free(key_buf);
    return TPM_BAD_PARAMETER;
  }
  free_TPM_PUBKEY_DATA(key);
  tpm_free(key_buf);
  return TPM_SUCCESS;
}

TPM_RESULT TPM_ConvertMigrationBlob(TPM_KEY_HANDLE parentHandle,
                                    UINT32 inDataSize, BYTE *inData,
                                    UINT32 randomSize, BYTE *random,
                                    TPM_AUTH *auth1,
                                    UINT32 *outDataSize,BYTE **outData)
{
  TPM_RESULT res;
  TPM_KEY_DATA *parent;
  BYTE *ptr, *buf;
  UINT32 len;
  size_t buf_len;
  TPM_STORE_ASYMKEY store;

  info("TPM_ConvertMigrationBlob()");
  /* get parent key */
  parent = tpm_get_key(parentHandle);
  if (parent == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify parent authorization */
  if (auth1->authHandle != TPM_INVALID_HANDLE
      || parent->authDataUsage != TPM_AUTH_NEVER) {
    res = tpm_verify_auth(auth1, parent->usageAuth, parentHandle);
    if (res != TPM_SUCCESS) return res;
  }
  /* verify key properties */
  if (parent->keyUsage != TPM_KEY_STORAGE) return TPM_INVALID_KEYUSAGE;
  /* decrypt private key */
  buf_len = parent->key.size >> 3;
  buf = tpm_malloc(buf_len);
  if (buf == NULL) return TPM_NOSPACE;
  /* RSA decrypt OAEP encoding */
  if (tpm_rsa_decrypt(&parent->key, RSA_ES_PLAIN, inData, inDataSize, buf, &buf_len)
      || buf_len != randomSize) {
    debug("tpm_rsa_decrypt() failed");
    tpm_free(buf);
    return TPM_DECRYPT_ERROR;
  }
  /* XOR decrypt OAEP encoding */
  for (len = 0; len < buf_len; len++) buf[len] ^= random[len];
  /* unmask OAEP encoding */
  tpm_rsa_mask_generation(&buf[1 + SHA1_DIGEST_LENGTH],
    buf_len - SHA1_DIGEST_LENGTH - 1, &buf[1], SHA1_DIGEST_LENGTH);
  tpm_rsa_mask_generation(&buf[1], SHA1_DIGEST_LENGTH,
    &buf[1 + SHA1_DIGEST_LENGTH], buf_len - SHA1_DIGEST_LENGTH - 1);
  /* create a TPM_STORE_ASYMKEY structure */
  memcpy(store.migrationAuth, &buf[1], sizeof(TPM_SECRET));
  for (ptr = &buf[1 + sizeof(TPM_SECRET) + 20]; *ptr == 0x00; ptr++);
  if (ptr[0] != 0x01 || ptr[1] != TPM_PT_MIGRATE) {
      tpm_free(buf);
      return TPM_DECRYPT_ERROR;
  }
  ptr += 2;
  len = buf_len - (ptr - buf);
  store.payload = TPM_PT_ASYM;
  tpm_unmarshal_TPM_SECRET(&ptr, &len, &store.usageAuth);
  tpm_unmarshal_TPM_DIGEST(&ptr, &len, &store.pubDataDigest);
  tpm_unmarshal_UINT32(&ptr, &len, &store.privKey.keyLength);
  store.privKey.keyLength += 16;
  memmove(&buf[1 + sizeof(TPM_SECRET) + 20], ptr, len);
  store.privKey.key = &buf[1 + sizeof(TPM_SECRET) + 4];
  /* encrypt private key */
  *outDataSize = parent->key.size >> 3;
  *outData = tpm_malloc(*outDataSize);
  if (*outData == NULL) {
    tpm_free(buf);
    return TPM_NOSPACE;
  }
  if (tpm_encrypt_private_key(parent, &store, *outData, outDataSize)) {
    debug("tpm_encrypt_private_key() failed");
    tpm_free(*outData);
    tpm_free(buf);
    return TPM_ENCRYPT_ERROR;
  }
  tpm_free(buf);
  return TPM_SUCCESS;
}

static int tpm_copy_pubkey(TPM_PUBKEY *in, TPM_PUBKEY *out)
{
  memcpy(out, in, sizeof(TPM_PUBKEY));
  out->pubKey.key = tpm_malloc(out->pubKey.keyLength);
  if (out->pubKey.key == NULL) return -1;
  memcpy(out->pubKey.key, in->pubKey.key, out->pubKey.keyLength);
  out->algorithmParms.parms.rsa.exponent =
    tpm_malloc(out->algorithmParms.parms.rsa.exponentSize);
  if (out->algorithmParms.parms.rsa.exponent == NULL) {
    tpm_free(out->pubKey.key);
    return -1;
  }
  memcpy(out->algorithmParms.parms.rsa.exponent,
    in->algorithmParms.parms.rsa.exponent,
    out->algorithmParms.parms.rsa.exponentSize);
  return 0;
}

TPM_RESULT TPM_AuthorizeMigrationKey(TPM_MIGRATE_SCHEME migrateScheme,
                                     TPM_PUBKEY *migrationKey, TPM_AUTH *auth1,
                                     TPM_MIGRATIONKEYAUTH *outData)
{
  TPM_RESULT res;

  info("TPM_AuthorizeMigrationKey()");
  /* verify authorization */
  res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
  if (res != TPM_SUCCESS) return res;
  /* verify the key size and encryption scheme */
  if (migrationKey->algorithmParms.encScheme != TPM_ES_RSAESOAEP_SHA1_MGF1
      || migrationKey->algorithmParms.algorithmID != TPM_ALG_RSA)
    return TPM_INAPPROPRIATE_ENC;
  if (migrationKey->algorithmParms.parms.rsa.keyLength  < 2048)
    return TPM_BAD_KEY_PROPERTY;
  /* create migration key authorization */
  if (tpm_compute_migration_digest(migrationKey, migrateScheme,
      &tpmData.permanent.data.tpmProof, &outData->digest) != 0) {
      debug("tpm_compute_migration_digest() failed");
      return TPM_FAIL;
  }
  outData->migrationScheme = migrateScheme;
  if (tpm_copy_pubkey(migrationKey, &outData->migrationKey) != 0) {
      debug("tpm_copy_pubkey() failed");
      return TPM_FAIL;
  }
  return TPM_SUCCESS;
}

TPM_RESULT TPM_MigrateKey(TPM_KEY_HANDLE maKeyHandle, TPM_PUBKEY *pubKey,
                          UINT32 inDataSize, BYTE *inData, TPM_AUTH *auth1,
                          UINT32 *outDataSize, BYTE **outData)
{
  TPM_RESULT res;
  TPM_KEY_DATA *key;
  TPM_PUBKEY_DATA key2;
  UINT32 size;

  info("TPM_MigrateKey()");
  key = tpm_get_key(maKeyHandle);
  if (key == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify key authorization */
  res = tpm_verify_auth(auth1, key->usageAuth, maKeyHandle);
  if (res != TPM_SUCCESS) return res;
  /* verify key usage */
  if (key->keyUsage != TPM_KEY_MIGRATE) return TPM_BAD_KEY_PROPERTY;
  if (key->encScheme != TPM_ES_RSAESOAEP_SHA1_MGF1) return TPM_INAPPROPRIATE_ENC;
  /* verify public key  */
  if (pubKey->algorithmParms.algorithmID != TPM_ALG_RSA
      || pubKey->algorithmParms.parms.rsa.keyLength < (inDataSize << 3))
    return TPM_BAD_KEY_PROPERTY;
  if (tpm_setup_pubkey_data(pubKey, &key2) != 0) return TPM_FAIL;
  /* decrypt inData and re-encrypt it with the public key */
  *outDataSize = size = pubKey->algorithmParms.parms.rsa.keyLength >> 3;
  *outData = tpm_malloc(*outDataSize);
  if (*outData == NULL) {
    free_TPM_PUBKEY_DATA(key2);
    return TPM_FAIL;
  }
  if (tpm_decrypt(key, inData, inDataSize, *outData, &size) != 0) {
    free_TPM_PUBKEY_DATA(key2);
    tpm_free(*outData);
    return TPM_DECRYPT_ERROR;
  }
  if (tpm_encrypt_public(&key2, *outData, size, *outData, outDataSize) != 0) {
    free_TPM_PUBKEY_DATA(key2);
    tpm_free(*outData);
    return TPM_ENCRYPT_ERROR;
  }
  free_TPM_PUBKEY_DATA(key2);
  return TPM_SUCCESS;
}

TPM_RESULT TPM_CMK_SetRestrictions(TPM_CMK_DELEGATE restriction,
                                   TPM_AUTH *auth1)
{
  TPM_RESULT res;

  info("TPM_CMK_SetRestrictions()");
  /* verify authorization */
  res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
  if (res != TPM_SUCCESS) return res;
  /* update delegation restriction */
  tpmData.permanent.data.restrictDelegate = restriction;
  return TPM_SUCCESS;
}

TPM_RESULT TPM_CMK_ApproveMA(TPM_DIGEST *migrationAuthorityDigest,
                             TPM_AUTH *auth1, TPM_HMAC *outData)
{
  TPM_RESULT res;
  BYTE buf[2];
  tpm_hmac_ctx_t ctx;

  info("TPM_CMK_ApproveMA()");
  /* verify authorization */
  res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
  if (res != TPM_SUCCESS) return res;
  /* create hmac of a TPM_CMK_MA_APPROVAL structure */
  buf[0] = (TPM_TAG_CMK_MA_APPROVAL >> 8) & 0xff;
  buf[1] = TPM_TAG_CMK_MA_APPROVAL & 0xff;
  tpm_hmac_init(&ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
  tpm_hmac_update(&ctx, buf, 2);
  tpm_hmac_update(&ctx, migrationAuthorityDigest->digest, sizeof(TPM_DIGEST));
  tpm_hmac_final(&ctx, outData->digest);
  return TPM_SUCCESS;
}

TPM_RESULT TPM_CMK_CreateKey(TPM_KEY_HANDLE parentHandle,
                             TPM_ENCAUTH *dataUsageAuth,
                             TPM_KEY *keyInfo,
                             TPM_HMAC *migrationAuthorityApproval,
                             TPM_DIGEST *migrationAuthorityDigest,
                             TPM_AUTH *auth1, TPM_AUTH *auth2,
                             TPM_KEY *wrappedKey)
{
  TPM_RESULT res;
  TPM_KEY_DATA *parent;
  TPM_SESSION_DATA *session;
  tpm_hmac_ctx_t ctx;
  BYTE buf[SHA1_DIGEST_LENGTH];
  TPM_STORE_ASYMKEY store;
  tpm_rsa_private_key_t rsa;
  UINT32 key_length;
  TPM_PUBKEY pubKey;
  TPM_DIGEST keyDigest;

  info("TPM_CMK_CreateKey()");
  /* get parent key */
  parent = tpm_get_key(parentHandle);
  if (parent == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify authorization */
  res = tpm_verify_auth(auth1, parent->usageAuth, parentHandle);
  if (res != TPM_SUCCESS) return res;
  auth1->continueAuthSession = FALSE;
  session = tpm_get_auth(auth1->authHandle);
  if (session->type != TPM_ST_OSAP) return TPM_AUTHFAIL;
  /* must be TPM_KEY12 */
  if (keyInfo->tag != TPM_TAG_KEY12) return TPM_INVALID_STRUCTURE;
  /* verify key parameters */
  if (parent->keyUsage != TPM_KEY_STORAGE
      || parent->encScheme == TPM_ES_NONE
      || parent->keyFlags & TPM_KEY_FLAG_MIGRATABLE
      || !(keyInfo->keyFlags & TPM_KEY_FLAG_MIGRATABLE)
      || !(keyInfo->keyFlags & TPM_KEY_FLAG_AUTHORITY)
      || keyInfo->keyUsage == TPM_KEY_IDENTITY
      || keyInfo->keyUsage == TPM_KEY_AUTHCHANGE) return TPM_INVALID_KEYUSAGE;
  if (keyInfo->algorithmParms.algorithmID != TPM_ALG_RSA
      || keyInfo->algorithmParms.parmSize == 0
      || keyInfo->algorithmParms.parms.rsa.keyLength < 512
      || keyInfo->algorithmParms.parms.rsa.numPrimes != 2
      || keyInfo->algorithmParms.parms.rsa.exponentSize != 0)
    return TPM_BAD_KEY_PROPERTY;
  if (tpmData.permanent.flags.FIPS
      && (keyInfo->algorithmParms.parms.rsa.keyLength < 1024
          || keyInfo->authDataUsage == TPM_AUTH_NEVER
          || keyInfo->keyUsage == TPM_KEY_LEGACY)) return TPM_NOTFIPS;
  if ((keyInfo->keyUsage == TPM_KEY_STORAGE
       || keyInfo->keyUsage == TPM_KEY_MIGRATE)
      && (keyInfo->algorithmParms.algorithmID != TPM_ALG_RSA
          || keyInfo->algorithmParms.parms.rsa.keyLength != 2048
          || keyInfo->algorithmParms.sigScheme != TPM_SS_NONE
          || keyInfo->algorithmParms.encScheme != TPM_ES_RSAESOAEP_SHA1_MGF1))
    return TPM_BAD_KEY_PROPERTY;
  /* verify migration authority */
  buf[0] = (TPM_TAG_CMK_MA_APPROVAL >> 8) & 0xff;
  buf[1] = TPM_TAG_CMK_MA_APPROVAL & 0xff;
  tpm_hmac_init(&ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
  tpm_hmac_update(&ctx, buf, 2);
  tpm_hmac_update(&ctx, migrationAuthorityDigest->digest, sizeof(TPM_DIGEST));
  tpm_hmac_final(&ctx, buf);
  if (memcmp(migrationAuthorityApproval->digest, buf, sizeof(TPM_HMAC)) != 0)
    return TPM_MA_AUTHORITY;
  /* setup the wrapped key */
  memcpy(wrappedKey, keyInfo, sizeof(TPM_KEY));
  /* setup key store */
  store.payload = TPM_PT_MIGRATE_RESTRICTED;
  tpm_decrypt_auth_secret(*dataUsageAuth, session->sharedSecret,
    &session->lastNonceEven, store.usageAuth);
  /* compute PCR digest */
  if (keyInfo->PCRInfoSize > 0) {
    tpm_compute_pcr_digest(&keyInfo->PCRInfo.creationPCRSelection,
      &keyInfo->PCRInfo.digestAtCreation, NULL);
    keyInfo->PCRInfo.localityAtCreation =
      tpmData.stany.flags.localityModifier;
  }
  /* generate key and store it */
  key_length = keyInfo->algorithmParms.parms.rsa.keyLength;
  if (tpm_rsa_generate_key(&rsa, key_length)) {
    debug("TPM_CreateWrapKey(): tpm_rsa_generate_key() failed.");
    return TPM_FAIL;
  }
  wrappedKey->pubKey.keyLength = key_length >> 3;
  wrappedKey->pubKey.key = tpm_malloc(wrappedKey->pubKey.keyLength);
  store.privKey.keyLength = key_length >> 4;
  store.privKey.key = tpm_malloc(store.privKey.keyLength);
  wrappedKey->encDataSize = parent->key.size >> 3;
  wrappedKey->encData = tpm_malloc(wrappedKey->encDataSize);
  if (wrappedKey->pubKey.key == NULL || store.privKey.key == NULL
      || wrappedKey->encData == NULL) {
    tpm_rsa_release_private_key(&rsa);
    tpm_free(wrappedKey->pubKey.key);
    tpm_free(store.privKey.key);
    tpm_free(wrappedKey->encData);
    return TPM_NOSPACE;
  }
  tpm_rsa_export_modulus(&rsa, wrappedKey->pubKey.key, NULL);
  tpm_rsa_export_prime1(&rsa, store.privKey.key, NULL);
  tpm_rsa_release_private_key(&rsa);
  /* create hmac of TPM_CMK_MIGAUTH  */
  buf[0] = (TPM_TAG_CMK_MIGAUTH >> 8) & 0xff;
  buf[1] = TPM_TAG_CMK_MIGAUTH & 0xff;
  memcpy(&pubKey.algorithmParms, &wrappedKey->algorithmParms,
         sizeof(TPM_KEY_PARMS));
  memcpy(&pubKey.pubKey, &wrappedKey->pubKey, sizeof(TPM_STORE_PUBKEY));
  if (tpm_compute_pubkey_digest(&pubKey, &keyDigest) !=0 ) {
    debug("tpm_compute_pubkey_digest() failed");
    return TPM_FAIL;
  }
  tpm_hmac_init(&ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
  tpm_hmac_update(&ctx, buf, 2);
  tpm_hmac_update(&ctx, migrationAuthorityDigest->digest, sizeof(TPM_DIGEST));
  tpm_hmac_update(&ctx, keyDigest.digest, sizeof(TPM_DIGEST));
  tpm_hmac_final(&ctx, store.migrationAuth);
  /* compute the digest of the wrapped key (without encData) */
  if (tpm_compute_key_digest(wrappedKey, &store.pubDataDigest)) {
    debug("TPM_CreateWrapKey(): tpm_compute_key_digest() failed.");
    return TPM_FAIL;
  }
  /* encrypt private key data */
  if (tpm_encrypt_private_key(parent, &store, wrappedKey->encData,
      &wrappedKey->encDataSize)) {
    tpm_free(wrappedKey->pubKey.key);
    tpm_free(store.privKey.key);
    tpm_free(wrappedKey->encData);
    return TPM_ENCRYPT_ERROR;
  }
  tpm_free(store.privKey.key);
  return TPM_SUCCESS;
}

TPM_RESULT TPM_CMK_CreateTicket(TPM_PUBKEY *verificationKey,
                                TPM_DIGEST *signedData,
                                UINT32 signatureValueSize,
                                BYTE *signatureValue, TPM_AUTH *auth1,
                                TPM_DIGEST *sigTicket)
{
  TPM_RESULT res;
  TPM_PUBKEY_DATA key;
  BYTE buf[2];
  TPM_DIGEST keyDigest;
  tpm_hmac_ctx_t ctx;

  info("TPM_CMK_CreateTicket()");
  /* verify authorization */
  res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
  /* verify key type and algorithm */
  if (verificationKey->algorithmParms.algorithmID != TPM_ALG_RSA
      || verificationKey->algorithmParms.encScheme != TPM_ES_NONE)
    return TPM_BAD_KEY_PROPERTY;
  if (verificationKey->algorithmParms.sigScheme != TPM_SS_RSASSAPKCS1v15_SHA1
      && verificationKey->algorithmParms.sigScheme != TPM_SS_RSASSAPKCS1v15_INFO)
    return TPM_BAD_KEY_PROPERTY;
  /* verify signature */
  if (tpm_setup_pubkey_data(verificationKey, &key) != 0) return TPM_FAIL;
  res = tpm_verify(&key, auth1, FALSE, signedData->digest, sizeof(TPM_DIGEST),
                   signatureValue, signatureValueSize);
  free_TPM_PUBKEY_DATA(key);
  if (res != TPM_SUCCESS) return res;
  /* create hmac on TPM_CMK_SIGTICKET */
  buf[0] = (TPM_TAG_CMK_SIGTICKET >> 8) & 0xff;
  buf[1] = TPM_TAG_CMK_SIGTICKET & 0xff;
  if (tpm_compute_pubkey_digest(verificationKey, &keyDigest) !=0 ) {
    debug("tpm_compute_pubkey_digest() failed");
    return TPM_FAIL;
  }
  tpm_hmac_init(&ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
  tpm_hmac_update(&ctx, buf, 2);
  tpm_hmac_update(&ctx, keyDigest.digest, sizeof(TPM_DIGEST));
  tpm_hmac_update(&ctx, signedData->digest, sizeof(TPM_DIGEST));
  tpm_hmac_final(&ctx, sigTicket->digest);
  return TPM_SUCCESS;
}

TPM_RESULT TPM_CMK_CreateBlob(TPM_KEY_HANDLE parentHandle,
                              TPM_MIGRATE_SCHEME migrationType,
                              TPM_MIGRATIONKEYAUTH *migrationKeyAuth,
                              TPM_DIGEST *pubSourceKeyDigest,
                              TPM_MSA_COMPOSITE *msaList,
                              TPM_CMK_AUTH *restrictTicket,
                              TPM_HMAC *sigTicket,
                              UINT32 encDataSize, BYTE *encData,
                              TPM_AUTH *auth1,
                              UINT32 *randomSize, BYTE **random,
                              UINT32 *outDataSize, BYTE **outData)
{
  TPM_RESULT res;
  TPM_KEY_DATA *parent;
  TPM_STORE_ASYMKEY store;
  BYTE *key_buf;
  UINT32 key_buf_size;
  tpm_hmac_ctx_t hmac_ctx;
  tpm_sha1_ctx_t sha1_ctx;
  BYTE tag[2], hmac[SHA1_DIGEST_LENGTH];
  BYTE *ptr, *buf;
  UINT32 i, len;
  size_t buf_len;
  TPM_DIGEST migKeyDigest;
  TPM_DIGEST msaListDigest;
  TPM_DIGEST ticketDigest;
  TPM_PUBKEY_DATA key;

  info("TPM_CMK_CreateBlob()");
  /* get parent key */
  parent = tpm_get_key(parentHandle);
  if (parent == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify authorization */
  res = tpm_verify_auth(auth1, parent->usageAuth, parentHandle);
  if (res != TPM_SUCCESS) return res;
  /* migrationType must match */
  if (migrationType != migrationKeyAuth->migrationScheme) return TPM_BAD_MODE;
  if (parent->keyFlags & TPM_KEY_FLAG_MIGRATABLE) return TPM_BAD_KEY_PROPERTY;
  /* decrypt private key */
  if (tpm_decrypt_private_key(parent, encData, encDataSize,
                              &store, &key_buf, &key_buf_size)
      || (store.payload != TPM_PT_MIGRATE_RESTRICTED
          && store.payload != TPM_PT_MIGRATE_EXTERNAL)) {
    tpm_free(key_buf);
    return TPM_DECRYPT_ERROR;
  }
  if (tpm_verify_migration_digest(migrationKeyAuth,
      &tpmData.permanent.data.tpmProof)) {
    debug("tpm_verify_migration_digest() failed");
    tpm_free(key_buf);
    return TPM_MIGRATEFAIL;
  }
  /* verify the migration authority list */
  len = sizeof_TPM_MSA_COMPOSITE((*msaList));
  ptr = buf = tpm_malloc(len);
  if (buf == NULL || tpm_marshal_TPM_MSA_COMPOSITE(&ptr, &len, msaList)) {
    debug("tpm_marshal_TPM_MSA_COMPOSITE() failed");
    tpm_free(buf);
    tpm_free(key_buf);
    return TPM_FAIL;
  }
  tpm_sha1_init(&sha1_ctx);
  tpm_sha1_update(&sha1_ctx, buf, sizeof_TPM_MSA_COMPOSITE((*msaList)));
  tpm_sha1_final(&sha1_ctx, msaListDigest.digest);
  tpm_free(buf);
  tag[0] = (TPM_TAG_CMK_MIGAUTH >> 8) & 0xff;
  tag[1] = TPM_TAG_CMK_MIGAUTH & 0xff;
  tpm_hmac_init(&hmac_ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
  tpm_hmac_update(&hmac_ctx, tag, 2);
  tpm_hmac_update(&hmac_ctx, msaListDigest.digest, sizeof(TPM_DIGEST));
  tpm_hmac_update(&hmac_ctx, pubSourceKeyDigest->digest, sizeof(TPM_DIGEST));
  tpm_hmac_final(&hmac_ctx, hmac);
  if (memcmp(hmac, store.migrationAuth, sizeof(TPM_SECRET)) != 0) {
    tpm_free(key_buf);
    return TPM_MA_AUTHORITY;
  }
  if (tpm_compute_pubkey_digest(&migrationKeyAuth->migrationKey, &migKeyDigest) !=0 ) {
    debug("tpm_compute_pubkey_digest() failed");
    tpm_free(key_buf);
    return TPM_FAIL;
  }
  len = sizeof_TPM_CMK_AUTH((*restrictTicket));
  ptr = buf = tpm_malloc(len);
  if (buf == NULL || tpm_marshal_TPM_CMK_AUTH(&ptr, &len, restrictTicket)) {
    debug("tpm_marshal_TPM_CMK_AUTH() failed");
    tpm_free(buf);
    tpm_free(key_buf);
    return TPM_FAIL;
  }
  tpm_sha1_init(&sha1_ctx);
  tpm_sha1_update(&sha1_ctx, buf, sizeof_TPM_CMK_AUTH((*restrictTicket)));
  tpm_sha1_final(&sha1_ctx, ticketDigest.digest);
  tpm_free(buf);
  /* verify the migration destination */
  if (migrationKeyAuth->migrationScheme == TPM_MS_RESTRICT_MIGRATE) {
    for (i = 0; i < msaList->MSAlist; i++) {
        if (memcmp(msaList->migAuthDigest[i].digest, migKeyDigest.digest,
                   sizeof(TPM_DIGEST)) == 0) break;
    }
    if (i >= msaList->MSAlist) {
      tpm_free(key_buf);
      return TPM_MA_AUTHORITY;
    }
    /* verify the key type and algorithm */
    if (migrationKeyAuth->migrationKey.algorithmParms.algorithmID != TPM_ALG_RSA
        || migrationKeyAuth->migrationKey.algorithmParms.encScheme != TPM_ES_RSAESOAEP_SHA1_MGF1
        || migrationKeyAuth->migrationKey.algorithmParms.sigScheme != TPM_SS_NONE) {
      tpm_free(key_buf);
      return TPM_BAD_KEY_PROPERTY;
    }
  } else if (migrationKeyAuth->migrationScheme == TPM_MS_RESTRICT_APPROVE) {
    if (restrictTicket == NULL || sigTicket == NULL) {
      tpm_free(key_buf);
      return TPM_BAD_PARAMETER;
    }
    for (i = 0; i < msaList->MSAlist; i++) {
      /* create hmac of TPM_CMK_SIGTICKET */
      tag[0] = (TPM_TAG_CMK_SIGTICKET >> 8) & 0xff;
      tag[1] = TPM_TAG_CMK_SIGTICKET & 0xff;
      tpm_hmac_init(&hmac_ctx, tpmData.permanent.data.tpmProof.nonce,
                    sizeof(TPM_NONCE));
      tpm_hmac_update(&hmac_ctx, tag, 2);
      tpm_hmac_update(&hmac_ctx, msaList->migAuthDigest[i].digest,
                      sizeof(TPM_DIGEST));
      tpm_hmac_update(&hmac_ctx, ticketDigest.digest, sizeof(TPM_DIGEST));
      tpm_hmac_final(&hmac_ctx, hmac);
      if (memcmp(hmac, sigTicket->digest, sizeof(TPM_DIGEST)) == 0) break;
    }
    if (i >= msaList->MSAlist) {
      tpm_free(key_buf);
      return TPM_MA_AUTHORITY;
    }
    if (memcmp(&restrictTicket->destinationKeyDigest, &migKeyDigest,
               sizeof(TPM_DIGEST)) != 0) {
      tpm_free(key_buf);
      return TPM_MA_DESTINATION;
    }
    if (memcmp(&restrictTicket->sourceKeyDigest, pubSourceKeyDigest,
               sizeof(TPM_DIGEST)) != 0) {
      tpm_free(key_buf);
      return TPM_MA_SOURCE;
    }
  } else {
    tpm_free(key_buf);
    return TPM_BAD_PARAMETER;
  }
  /* set public key */
  if (tpm_setup_pubkey_data(&migrationKeyAuth->migrationKey, &key) != 0) {
    debug("tpm_setup_pubkey() failed");
    tpm_free(key_buf);
    return TPM_FAIL;
  }
  /* generate an OAEP encoding of the TPM_MIGRATE_ASYMKEY structure:
     0x00|seed|K1|0x00-pad|0x01|TPM_MIGRATE_ASYMKEY */
  buf_len = key.key.size >> 3;
  ptr = buf = tpm_malloc(buf_len);
  *randomSize = buf_len;
  *random = tpm_malloc(*randomSize);
  if (buf == NULL || *random == NULL) {
    free_TPM_PUBKEY_DATA(key);
    tpm_free(buf);
    tpm_free(*random);
    tpm_free(key_buf);
    return TPM_NOSPACE;
  }
  buf[0] = 0x00;
  tpm_sha1_init(&sha1_ctx);
  tpm_sha1_update(&sha1_ctx, msaListDigest.digest, sizeof(TPM_DIGEST));
  tpm_sha1_update(&sha1_ctx, pubSourceKeyDigest->digest, sizeof(TPM_DIGEST));
  tpm_sha1_final(&sha1_ctx, &buf[1]);
  ptr = &buf[1 + sizeof(TPM_DIGEST)];
  len = 4;
  tpm_marshal_UINT32(&ptr, &len, store.privKey.keyLength);
  memcpy(ptr, store.privKey.key, 16);
  memset(ptr + 16, 0, buf_len - 41);
  len = 46 + store.privKey.keyLength - 16;
  ptr = &buf[buf_len - len];
  tpm_marshal_BYTE(&ptr, &len, 0x01);
  tpm_marshal_TPM_PAYLOAD_TYPE(&ptr, &len, TPM_PT_CMK_MIGRATE);
  tpm_marshal_TPM_SECRET(&ptr, &len, &store.usageAuth);
  tpm_marshal_TPM_DIGEST(&ptr, &len, &store.pubDataDigest);
  tpm_marshal_UINT32(&ptr, &len, store.privKey.keyLength - 16);
  memcpy(ptr, &store.privKey.key[16], store.privKey.keyLength - 16);
  tpm_rsa_mask_generation(&buf[1], SHA1_DIGEST_LENGTH,
    &buf[1 + SHA1_DIGEST_LENGTH], buf_len - SHA1_DIGEST_LENGTH - 1);
  tpm_rsa_mask_generation(&buf[1 + SHA1_DIGEST_LENGTH],
    buf_len - SHA1_DIGEST_LENGTH - 1, &buf[1], SHA1_DIGEST_LENGTH);
  /* XOR encrypt OAEP encoding */
  tpm_get_random_bytes(*random, *randomSize);
  for (len = 0; len < buf_len; len++) buf[len] ^= (*random)[len];
  /* RSA encrypt OAEP encoding */
  if (tpm_rsa_encrypt(&key.key, RSA_ES_PLAIN, buf, buf_len, buf, &buf_len)) {
    debug("tpm_rsa_encrypt() failed");
    free_TPM_PUBKEY_DATA(key);
    tpm_free(buf);
    tpm_free(*random);
    tpm_free(key_buf);
    return TPM_ENCRYPT_ERROR;
  }
  *outDataSize = buf_len;
  *outData = buf;
  free_TPM_PUBKEY_DATA(key);
  tpm_free(key_buf);
  return TPM_SUCCESS;
}

TPM_RESULT TPM_CMK_ConvertMigration(TPM_KEY_HANDLE parentHandle,
                                    TPM_CMK_AUTH *restrictTicket,
                                    TPM_HMAC *sigTicket, TPM_KEY *migratedKey,
                                    TPM_MSA_COMPOSITE *msaList,
                                    UINT32 randomSize, BYTE *random,
                                    TPM_AUTH *auth1,
                                    UINT32 *outDataSize, BYTE **outData)
{
  TPM_RESULT res;
  TPM_KEY_DATA *parent;
  BYTE *ptr, *buf, *buf2;
  UINT32 i, len;
  size_t buf_len;
  BYTE tag[2], hmac[SHA1_DIGEST_LENGTH];
  TPM_STORE_ASYMKEY store;
  tpm_sha1_ctx_t sha1_ctx;
  tpm_hmac_ctx_t hmac_ctx;
  TPM_PUBKEY migratedPubKey;
  TPM_PUBKEY parentPubKey;
  TPM_DIGEST migKeyDigest;
  TPM_DIGEST msaListDigest;
  TPM_DIGEST ticketDigest;
  TPM_DIGEST parentDigest;

  info("TPM_CMK_ConvertMigration()");
  /* get parent key */
  parent = tpm_get_key(parentHandle);
  if (parent == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify authorization */
  if (auth1->authHandle != TPM_INVALID_HANDLE
      || parent->authDataUsage != TPM_AUTH_NEVER) {
    res = tpm_verify_auth(auth1, parent->usageAuth, parentHandle);
    if (res != TPM_SUCCESS) return res;
  }
  /* verify key properties */
  if (parent->keyUsage != TPM_KEY_STORAGE
      || parent->keyFlags & TPM_KEY_FLAG_MIGRATABLE) return TPM_INVALID_KEYUSAGE;
  if (!(migratedKey->keyFlags & TPM_KEY_FLAG_MIGRATABLE)
      && (!(migratedKey->keyFlags & TPM_KEY_FLAG_AUTHORITY))) return TPM_INVALID_KEYUSAGE;
  /* decrypt private key */
  buf_len = parent->key.size >> 3;
  buf = tpm_malloc(buf_len);
  if (buf == NULL) return TPM_NOSPACE;
  /* RSA decrypt OAEP encoding */
  if (tpm_rsa_decrypt(&parent->key, RSA_ES_PLAIN, migratedKey->encData,
      migratedKey->encDataSize, buf, &buf_len)
      || buf_len != randomSize) {
    debug("tpm_rsa_decrypt() failed");
    tpm_free(buf);
    return TPM_DECRYPT_ERROR;
  }
  /* XOR decrypt OAEP encoding */
  for (len = 0; len < buf_len; len++) buf[len] ^= random[len];
  /* unmask OAEP encoding */
  tpm_rsa_mask_generation(&buf[1 + SHA1_DIGEST_LENGTH],
    buf_len - SHA1_DIGEST_LENGTH - 1, &buf[1], SHA1_DIGEST_LENGTH);
  tpm_rsa_mask_generation(&buf[1], SHA1_DIGEST_LENGTH,
    &buf[1 + SHA1_DIGEST_LENGTH], buf_len - SHA1_DIGEST_LENGTH - 1);
  /* compute digest of migrated public key */
  memcpy(&migratedPubKey.algorithmParms, &migratedKey->algorithmParms,
         sizeof(TPM_KEY_PARMS));
  memcpy(&migratedPubKey.pubKey, &migratedKey->pubKey, sizeof(TPM_STORE_PUBKEY));
  if (tpm_compute_pubkey_digest(&migratedPubKey, &migKeyDigest) != 0) {
    debug("tpm_compute_pubkey_digest() failed");
    tpm_free(buf);
    return TPM_FAIL;
  }
  /* compute digest of parent key */
  parentPubKey.pubKey.keyLength = parent->key.size >> 3;
  parentPubKey.pubKey.key = tpm_malloc(parentPubKey.pubKey.keyLength);
  if (parentPubKey.pubKey.key == NULL) {
    tpm_free(buf);
    return TPM_NOSPACE;
  }
  tpm_rsa_export_modulus(&parent->key, parentPubKey.pubKey.key, NULL);
  if (tpm_setup_key_parms(parent, &parentPubKey.algorithmParms) != 0) {
    debug("tpm_setup_key_parms() failed.");
    tpm_free(parentPubKey.pubKey.key);
    tpm_free(buf);
    return TPM_FAIL;
  }
  if (tpm_compute_pubkey_digest(&parentPubKey, &parentDigest) != 0) {
    debug("tpm_compute_pubkey_digest() failed.");
    free_TPM_PUBKEY(parentPubKey);
    tpm_free(buf);
    return TPM_FAIL;
  }
  free_TPM_PUBKEY(parentPubKey);
  /* compute digest of msaList */
  len = sizeof_TPM_MSA_COMPOSITE((*msaList));
  ptr = buf2 = tpm_malloc(len);
  if (buf2 == NULL || tpm_marshal_TPM_MSA_COMPOSITE(&ptr, &len, msaList)) {
    debug("tpm_marshal_TPM_MSA_COMPOSITE() failed");
    tpm_free(buf2);
    tpm_free(buf);
    return TPM_FAIL;
  }
  tpm_sha1_init(&sha1_ctx);
  tpm_sha1_update(&sha1_ctx, buf2, sizeof_TPM_MSA_COMPOSITE((*msaList)));
  tpm_sha1_final(&sha1_ctx, msaListDigest.digest);
  tpm_free(buf2);
  /* compute digest of restrictedTicket */
  len = sizeof_TPM_CMK_AUTH((*restrictTicket));
  ptr = buf2 = tpm_malloc(len);
  if (buf2 == NULL || tpm_marshal_TPM_CMK_AUTH(&ptr, &len, restrictTicket)) {
    debug("tpm_marshal_TPM_CMK_AUTH() failed");
    tpm_free(buf2);
    tpm_free(buf);
    return TPM_FAIL;
  }
  tpm_sha1_init(&sha1_ctx);
  tpm_sha1_update(&sha1_ctx, buf2, sizeof_TPM_CMK_AUTH((*restrictTicket)));
  tpm_sha1_final(&sha1_ctx, ticketDigest.digest);
  tpm_free(buf2);
  /* verify decoded data */
  tpm_sha1_init(&sha1_ctx);
  tpm_sha1_update(&sha1_ctx, msaListDigest.digest, sizeof(TPM_DIGEST));
  tpm_sha1_update(&sha1_ctx, migKeyDigest.digest, sizeof(TPM_DIGEST));
  tpm_sha1_final(&sha1_ctx, hmac);
  if (memcmp(&buf[1], hmac, sizeof(TPM_DIGEST)) != 0) {
    tpm_free(buf);
    return TPM_INVALID_STRUCTURE;
  }
  /* create a TPM_STORE_ASYMKEY structure */
  for (ptr = &buf[1 + sizeof(TPM_SECRET) + 20]; *ptr == 0x00; ptr++);
  if (ptr[0] != 0x01 || ptr[1] != TPM_PT_CMK_MIGRATE) {
    tpm_free(buf);
    return TPM_DECRYPT_ERROR;
  }
  ptr += 2;
  len = buf_len - (ptr - buf);
  store.payload = TPM_PT_MIGRATE_EXTERNAL;
  tpm_unmarshal_TPM_SECRET(&ptr, &len, &store.usageAuth);
  tpm_unmarshal_TPM_DIGEST(&ptr, &len, &store.pubDataDigest);
  tpm_unmarshal_UINT32(&ptr, &len, &store.privKey.keyLength);
  store.privKey.keyLength += 16;
  memmove(&buf[1 + sizeof(TPM_SECRET) + 20], ptr, len);
  store.privKey.key = &buf[1 + sizeof(TPM_SECRET) + 4];
  tag[0] = (TPM_TAG_CMK_MIGAUTH >> 8) & 0xff;
  tag[1] = TPM_TAG_CMK_MIGAUTH & 0xff;
  tpm_hmac_init(&hmac_ctx, tpmData.permanent.data.tpmProof.nonce, sizeof(TPM_NONCE));
  tpm_hmac_update(&hmac_ctx, tag, 2);
  tpm_hmac_update(&hmac_ctx, msaListDigest.digest, sizeof(TPM_DIGEST));
  tpm_hmac_update(&hmac_ctx, migKeyDigest.digest, sizeof(TPM_DIGEST));
  tpm_hmac_final(&hmac_ctx, store.migrationAuth);
  /* verify the migration destination */
  for (i = 0; i < msaList->MSAlist; i++) {
    /* create hmac of TPM_CMK_SIGTICKET */
    tag[0] = (TPM_TAG_CMK_SIGTICKET >> 8) & 0xff;
    tag[1] = TPM_TAG_CMK_SIGTICKET & 0xff;
    tpm_hmac_init(&hmac_ctx, tpmData.permanent.data.tpmProof.nonce,
                  sizeof(TPM_NONCE));
    tpm_hmac_update(&hmac_ctx, tag, 2);
    tpm_hmac_update(&hmac_ctx, msaList->migAuthDigest[i].digest,
                    sizeof(TPM_DIGEST));
    tpm_hmac_update(&hmac_ctx, ticketDigest.digest, sizeof(TPM_DIGEST));
    tpm_hmac_final(&hmac_ctx, hmac);
    if (memcmp(hmac, sigTicket->digest, sizeof(TPM_DIGEST)) == 0) break;
  }
  if (i >= msaList->MSAlist) {
    tpm_free(buf);
    return TPM_MA_AUTHORITY;
  }
  if (memcmp(&restrictTicket->destinationKeyDigest, &parentDigest,
             sizeof(TPM_DIGEST)) != 0) {
    tpm_free(buf);
    return TPM_MA_DESTINATION;
  }
  if (memcmp(&restrictTicket->sourceKeyDigest, &migKeyDigest,
             sizeof(TPM_DIGEST)) != 0) {
    tpm_free(buf);
    return TPM_MA_SOURCE;
  }
  /* encrypt private key */
  *outDataSize = parent->key.size >> 3;
  *outData = tpm_malloc(*outDataSize);
  if (*outData == NULL) {
    tpm_free(buf);
    return TPM_NOSPACE;
  }
  if (tpm_encrypt_private_key(parent, &store, *outData, outDataSize)) {
    debug("tpm_encrypt_private_key() failed");
    tpm_free(*outData);
    tpm_free(buf);
    return TPM_ENCRYPT_ERROR;
  }
  tpm_free(buf);
  return TPM_SUCCESS;
}
