Пример #1
0
TPM_RESULT TPM_ChangeAuth(TPM_KEY_HANDLE parentHandle,
                          TPM_PROTOCOL_ID protocolID, TPM_ENCAUTH *newAuth,
                          TPM_ENTITY_TYPE entityType, UINT32 encDataSize,
                          BYTE *encData, TPM_AUTH *auth1, TPM_AUTH *auth2,
                          UINT32 *outDataSize, BYTE **outData)
{
  TPM_RESULT res;
  TPM_KEY_DATA *parent;
  TPM_SESSION_DATA *session;
  TPM_SECRET plainAuth;
  info("TPM_ChangeAuth()");
  /* get parent key */
  parent = tpm_get_key(parentHandle);
  if (parent == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify entity authorization */ 
  auth2->continueAuthSession = FALSE;
  session = tpm_get_auth(auth2->authHandle);
  if (session->type != TPM_ST_OIAP) return TPM_BAD_MODE; 
  /* verify parent 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_BAD_MODE;  
  /* decrypt auth */
  tpm_decrypt_auth_secret(*newAuth, session->sharedSecret,
                          &session->lastNonceEven, plainAuth);
  /* decrypt the entity, replace authData, and encrypt it again */
  if (entityType == TPM_ET_DATA) {
    TPM_SEALED_DATA seal;
    BYTE *seal_buf;
    /* decrypt entity */
    if (decrypt_sealed_data(parent, encData, encDataSize,
        &seal, &seal_buf)) return TPM_DECRYPT_ERROR;
    /* verify auth2 */
    res = tpm_verify_auth(auth2, seal.authData, TPM_INVALID_HANDLE);
    if (res != TPM_SUCCESS) return (res == TPM_AUTHFAIL) ? TPM_AUTH2FAIL : res;
    /* change authData and use it also for auth2 */
    memcpy(seal.authData, plainAuth, sizeof(TPM_SECRET));    
    /* encrypt entity */
    *outDataSize = parent->key.size >> 3;
    *outData = tpm_malloc(*outDataSize);
    if (encrypt_sealed_data(parent, &seal, *outData, outDataSize)) {
      tpm_free(encData);
      tpm_free(seal_buf);      
      return TPM_ENCRYPT_ERROR;
    }                    
    tpm_free(seal_buf); 
  } else if (entityType == TPM_ET_KEY) {
Пример #2
0
static int handle_emuldev_command(int devfd)
{
    ssize_t in_len;
    uint32_t out_len;
    uint8_t in[TPM_CMD_BUF_SIZE], *out;
    int res;

    debug("waiting for commands...");
    in_len = read(devfd, in, sizeof(in));
    debug("received %d bytes", in_len);
    if (in_len <= 0)
	return errno == -EAGAIN ? 0 : in_len;
	
    out = NULL;
    res = tpm_handle_command(in, in_len, &out, &out_len);
    if (res < 0) {
	error("tpm_handle_command() failed");
	if (ioctl(devfd, 0, 0) < 0)
	    return -1;
    } else {
	debug("sending %d bytes", out_len);
	res = write(devfd, out, out_len);
	if (res < 0) {
	    error("write(%d) failed: %s", out_len, strerror(errno));
	    if (errno != ECANCELED)
		return -1;
	}
    }
    tpm_free(out);
    return 0;
}
static TPM_RESULT execute_MTM_InstallRIM(TPM_REQUEST *req, TPM_RESPONSE *rsp)
{
  BYTE *ptr;
  UINT32 len;
  UINT32 rimCertSize;
  TPM_RIM_CERTIFICATE rimCertIn;
  TPM_RIM_CERTIFICATE rimCertOut;
  TPM_RESULT res;
  /* compute parameter digest */
  tpm_compute_in_param_digest(req);
  /* unmarshal input */
  ptr = req->param;
  len = req->paramSize;
  if (tpm_unmarshal_UINT32(&ptr, &len, &rimCertSize)
      || tpm_unmarshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCertIn)
      || len != 0) return TPM_BAD_PARAMETER;
  /* execute command */
  res = MTM_InstallRIM(&rimCertIn, &req->auth1, &rimCertOut);
  if (res != TPM_SUCCESS) return res;
  /* marshal output */
  rsp->paramSize = len = 4 + sizeof_TPM_RIM_CERTIFICATE(rimCertOut);
  rsp->param = ptr = tpm_malloc(len);
  if (ptr == NULL
      || tpm_marshal_UINT32(&ptr, &len, sizeof_TPM_RIM_CERTIFICATE(rimCertOut))
      || tpm_marshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCertOut)) {
    tpm_free(rsp->param);
    res = TPM_FAIL;
  }
  free_TPM_RIM_CERTIFICATE(rimCertOut);
  return res;
}
static TPM_RESULT execute_MTM_LoadVerificationKey(TPM_REQUEST *req, TPM_RESPONSE *rsp)
{
  BYTE *ptr;
  UINT32 len;
  TPM_VERIFICATION_KEY_HANDLE parentKey;
  UINT32 verificationKeySize;
  TPM_VERIFICATION_KEY verificationKey;
  TPM_VERIFICATION_KEY_HANDLE verificationKeyHandle;
  BYTE loadMethod;
  TPM_RESULT res;
  /* compute parameter digest */
  tpm_compute_in_param_digest(req);
  /* unmarshal input */
  ptr = req->param;
  len = req->paramSize;
  if (tpm_unmarshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, &parentKey)
      || tpm_unmarshal_UINT32(&ptr, &len, &verificationKeySize)
      || tpm_unmarshal_TPM_VERIFICATION_KEY(&ptr, &len, &verificationKey)
      || len != 0) return TPM_BAD_PARAMETER;
  /* execute command  */
  res = MTM_LoadVerificationKey(parentKey, &verificationKey, &req->auth1,
    &verificationKeyHandle, &loadMethod);
  if (res != TPM_SUCCESS) return res;
  /* marshal output */
  rsp->paramSize = len = 4 + 1;
  rsp->param = ptr = tpm_malloc(len);
  if (ptr == NULL
      || tpm_marshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, verificationKeyHandle)
      || tpm_marshal_BYTE(&ptr, &len, loadMethod)) {
    tpm_free(rsp->param);
    res = TPM_FAIL;
  }
  return res;
}
static int _tpm_read_from_storage(uint8_t **data, size_t *data_length)
{
  int fh;
  ssize_t res;
  size_t total_length;

#if defined(_WIN32) || defined(_WIN64)
  fh = open(tpm_storage_file, O_RDONLY | O_BINARY); 
#else
  fh = open(tpm_storage_file, O_RDONLY);
#endif
  if (fh < 0) return -1;
  total_length = lseek(fh, 0, SEEK_END);
  lseek(fh, 0, SEEK_SET);
  *data = tpm_malloc(total_length);
  if (*data == NULL) {
    close(fh);
    return -1;
  }
  *data_length = 0;
  while (total_length > 0) {
    res = read(fh, &(*data)[*data_length], total_length);
    if (res < 0) {
      close(fh);
      tpm_free(*data);
      return -1;
    }
    if (res == 0) break;
    *data_length += res;
    total_length -= res;
  }
  close(fh);
  return 0;
}
static TPM_RESULT execute_MTM_VerifyRIMCertAndExtend(TPM_REQUEST *req, TPM_RESPONSE *rsp)
{
  BYTE *ptr;
  UINT32 len;
  UINT32 rimCertSize;
  TPM_RIM_CERTIFICATE rimCert;
  TPM_VERIFICATION_KEY_HANDLE rimKey;
  TPM_PCRVALUE outDigest;
  TPM_RESULT res;
  /* compute parameter digest */
  tpm_compute_in_param_digest(req);
  /* unmarshal input */
  ptr = req->param;
  len = req->paramSize;
  if (tpm_unmarshal_UINT32(&ptr, &len, &rimCertSize)
      || tpm_unmarshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCert)
      || tpm_unmarshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, &rimKey)
      || len != 0) return TPM_BAD_PARAMETER;
  /* execute command */
  res = MTM_VerifyRIMCertAndExtend(&rimCert, rimKey, &outDigest);
  /* marshal output */
  rsp->paramSize = len = 20;
  rsp->param = ptr = tpm_malloc(len);
  if (ptr == NULL
      || tpm_marshal_TPM_PCRVALUE(&ptr, &len, &outDigest)) {
    tpm_free(rsp->param);
    res = TPM_FAIL;
  }
  return res;
}
Пример #7
0
inline TPM_RESULT return_BOOL(UINT32 *respSize, BYTE **resp, BOOL value)
{
  UINT32 len = *respSize = 1;
  BYTE *ptr = *resp = tpm_malloc(*respSize);
  if (ptr == NULL || tpm_marshal_BOOL(&ptr, &len, value)) {
    tpm_free(*resp);
    return TPM_FAIL;
  }
  return TPM_SUCCESS;
}
Пример #8
0
/* manufacturer specific */
static TPM_RESULT cap_mfr(UINT32 *respSize, BYTE **resp)
{
  UINT32 len = *respSize = 4;
  BYTE *ptr = *resp = tpm_malloc(*respSize);
  if (ptr == NULL || tpm_marshal_TPM_VERSION(&ptr, &len, 
      &tpmData.permanent.data.version)) {
    tpm_free(*resp);
    return TPM_FAIL;
  }
  return TPM_SUCCESS;
}
Пример #9
0
static int compute_context_digest(TPM_CONTEXT_BLOB *contextBlob, TPM_DIGEST *digest)
{
  BYTE *buf, *ptr;
  UINT32 len;
  tpm_hmac_ctx_t hmac_ctx;
  len = sizeof_TPM_CONTEXT_BLOB((*contextBlob));
  buf = ptr = tpm_malloc(len);
  if (buf == NULL) return -1;
  if (tpm_marshal_TPM_CONTEXT_BLOB(&ptr, &len, contextBlob)) {
    tpm_free(buf);
    return -1;
  }
  memset(&buf[30], 0, 20);
  tpm_hmac_init(&hmac_ctx, tpmData.permanent.data.tpmProof.nonce, 
    sizeof(tpmData.permanent.data.tpmProof.nonce));
  tpm_hmac_update(&hmac_ctx, buf, sizeof_TPM_CONTEXT_BLOB((*contextBlob)));
  tpm_hmac_final(&hmac_ctx, digest->digest);
  tpm_free(buf);
  return 0;
}
Пример #10
0
TPM_RESULT cap_flag(UINT32 subCapSize, BYTE *subCap,
                    UINT32 *respSize, BYTE **resp)
{
  UINT32 type, len;
  BYTE *ptr;
  if (tpm_unmarshal_UINT32(&subCap, &subCapSize, &type)) return TPM_BAD_MODE;
  switch (type) {
    case TPM_CAP_FLAG_PERMANENT:
      debug("[TPM_CAP_FLAG_PERMANENT");
      *respSize = len = sizeof_TPM_PERMANENT_FLAGS(tpmData.permanent.flags);
      *resp = ptr = tpm_malloc(len);
      if (tpm_marshal_TPM_PERMANENT_FLAGS(&ptr, &len, &tpmData.permanent.flags)) {
        tpm_free(*resp);
        return TPM_FAIL;
      }
      return TPM_SUCCESS;
    case TPM_CAP_FLAG_VOLATILE:
      debug("[TPM_CAP_FLAG_VOLATILE]");
      *respSize = len = sizeof_TPM_STCLEAR_FLAGS(tpmData.stclear.flags);
      *resp = ptr = tpm_malloc(len);
      if (tpm_marshal_TPM_STCLEAR_FLAGS(&ptr, &len, &tpmData.stclear.flags)) {
        tpm_free(*resp);
        return TPM_FAIL;
      }
      return TPM_SUCCESS;
/* removed since v1.2 rev 94
    case TPM_CAP_FLAG_STANY:
      debug("[TPM_CAP_FLAG_STANY]");
      *respSize = len = sizeof_TPM_STANY_FLAGS(tpmData.stany.flags);
      *resp = ptr = tpm_malloc(len);
      if (tpm_marshal_TPM_STANY_FLAGS(&ptr, &len, &tpmData.stany.flags)) {
        tpm_free(*resp);
        return TPM_FAIL;
      }
*/
      return TPM_SUCCESS;
    default:
      return TPM_BAD_MODE;
  }
}
Пример #11
0
/* changed since rev 94: returned version MUST BE 1.1.0.0 */
static TPM_RESULT cap_version(UINT32 *respSize, BYTE **resp)
{
  UINT32 len = *respSize = 4;
  BYTE *ptr = *resp = tpm_malloc(*respSize);
  TPM_STRUCT_VER version;
  version.major = version.minor = 1;
  version.revMajor = version.revMinor = 0;
  if (ptr == NULL || tpm_marshal_TPM_STRUCT_VER(&ptr, &len, &version)) {
    tpm_free(*resp);
    return TPM_FAIL;
  }
  return TPM_SUCCESS;
}
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;
}
Пример #13
0
static int decrypt_transport_auth(TPM_KEY_DATA *key, BYTE *enc, UINT32 enc_size,
                                  TPM_TRANSPORT_AUTH *trans_auth) 
{
  BYTE *buf;
  size_t buf_size;
  int scheme;
  switch (key->encScheme) {
    case TPM_ES_RSAESOAEP_SHA1_MGF1: scheme = RSA_ES_OAEP_SHA1; break;
    case TPM_ES_RSAESPKCSv15: scheme = RSA_ES_PKCSV15; break;
    default: return -1;
  }
  buf = tpm_malloc(key->key.size);
  if (buf == NULL
      || tpm_rsa_decrypt(&key->key, scheme, enc, enc_size, buf, &buf_size)
      || buf_size != sizeof_TPM_TRANSPORT_AUTH(x)
      || (((UINT16)buf[0] << 8) | buf[1]) != TPM_TAG_TRANSPORT_AUTH) {
    tpm_free(buf);
    return -1;
  }
  trans_auth->tag = TPM_TAG_TRANSPORT_AUTH;
  memcpy(trans_auth->authData, &buf[2], sizeof(TPM_AUTHDATA));
  tpm_free(buf);
  return 0;
}
Пример #14
0
static int decrypt_context(BYTE *iv, UINT32 iv_size, BYTE *enc, UINT32 enc_size, 
                           TPM_CONTEXT_SENSITIVE *context, BYTE **buf) 
{
  UINT32 len;
  BYTE *ptr;
  tpm_rc4_ctx_t rc4_ctx;
  BYTE key[TPM_SYM_KEY_SIZE + iv_size];
  len = enc_size;
  *buf = ptr = tpm_malloc(len);
  if (*buf == NULL) return -1;
  /* decrypt context */
  memcpy(key, tpmData.permanent.data.contextKey, TPM_SYM_KEY_SIZE);
  memcpy(&key[TPM_SYM_KEY_SIZE], iv, iv_size);
  tpm_rc4_init(&rc4_ctx, key, sizeof(key));  
  tpm_rc4_crypt(&rc4_ctx, enc, *buf, enc_size);
  /* unmarshal context */
  if (tpm_unmarshal_TPM_CONTEXT_SENSITIVE(&ptr, &len, context)) {
    tpm_free(*buf);
    return -1;
  }
  return 0;
}
Пример #15
0
static int encrypt_context(BYTE *iv, UINT32 iv_size, TPM_CONTEXT_SENSITIVE *context, 
                           BYTE **enc, UINT32 *enc_size)
{
  UINT32 len;
  BYTE *ptr;
  tpm_rc4_ctx_t rc4_ctx;
  BYTE key[TPM_SYM_KEY_SIZE + iv_size];
  /* marshal context */
  *enc_size = len = sizeof_TPM_CONTEXT_SENSITIVE((*context));
  *enc = ptr = tpm_malloc(len);
  if (*enc == NULL) return -1;
  if (tpm_marshal_TPM_CONTEXT_SENSITIVE(&ptr, &len, context)) {
    tpm_free(*enc);
    return -1;
  }
  /* encrypt context */
  memcpy(key, tpmData.permanent.data.contextKey, TPM_SYM_KEY_SIZE);
  memcpy(&key[TPM_SYM_KEY_SIZE], iv, iv_size);
  tpm_rc4_init(&rc4_ctx, key, sizeof(key));
  tpm_rc4_crypt(&rc4_ctx, *enc, *enc, *enc_size);
  return 0;
}
Пример #16
0
/* TODO: added since rev 94 */
TPM_RESULT cap_version_val(UINT32 *respSize, BYTE **resp)
{
  UINT32 len;
  BYTE *ptr;
  TPM_CAP_VERSION_INFO version;
  
  version.tag = TPM_TAG_CAP_VERSION_INFO;
  version.version = tpmData.permanent.data.version;
  version.specLevel = 2;
  version.errataRev = 94;
  memset(version.tpmVendorID, 0, sizeof(version.tpmVendorID));
  version.vendorSpecificSize = 0;
  version.vendorSpecific = NULL;
  
  len = *respSize = sizeof_TPM_CAP_VERSION_INFO(version);
  ptr = *resp = tpm_malloc(*respSize);
  
  if (ptr == NULL || tpm_marshal_TPM_CAP_VERSION_INFO(&ptr, &len, &version)) {
    tpm_free(*resp);
    return TPM_FAIL;
  }
  return TPM_SUCCESS;
}
Пример #17
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;
}
Пример #18
0
int tpm_store_permanent_data(void)
{
  uint8_t *buf, *ptr;
  size_t buf_length;
  uint32_t len;

  /* marshal data */
  buf_length = len = sizeof_TPM_VERSION(tpmData.permanent.data.version)
#ifdef MTM_EMULATOR
                     + sizeof_TPM_DATA(tpmData) + sizeof_MTM_DATA(mtmData);
#else
                     + sizeof_TPM_DATA(tpmData);
#endif
  debug("size of permanent data: %d", buf_length);
  buf = ptr = tpm_malloc(buf_length);
  if (buf == NULL
      || tpm_marshal_TPM_VERSION(&ptr, &len, &tpmData.permanent.data.version)
#ifdef MTM_EMULATOR
      || tpm_marshal_TPM_DATA(&ptr, &len, &tpmData)
      || tpm_marshal_MTM_DATA(&ptr, &len, &mtmData)) {
#else
      || tpm_marshal_TPM_DATA(&ptr, &len, &tpmData)) {
#endif
    tpm_free(buf);
    return -1;
  }
  if (len != 0) debug("warning: buffer was too large, %d bytes left", len);
  if (tpm_write_to_storage(buf, buf_length - len)) {
    tpm_free(buf);
    return -1; 
  }
  tpm_free(buf);
  return 0;
}

int tpm_restore_permanent_data(void)
{
  uint8_t *buf, *ptr;
  size_t buf_length;
  uint32_t len;
  TPM_VERSION ver;

  /* read data */
  if (tpm_read_from_storage(&buf, &buf_length)) return -1;
  ptr = buf;
  len = buf_length;
  /* unmarshal data */
  if (tpm_unmarshal_TPM_VERSION(&ptr, &len, &ver)
      || memcmp(&ver, &tpm_version, sizeof(TPM_VERSION))
      || tpm_unmarshal_TPM_DATA(&ptr, &len, &tpmData)
#ifdef MTM_EMULATOR
      || tpm_unmarshal_MTM_DATA(&ptr, &len, &mtmData)
#endif
      || len > 0) {
    tpm_free(buf);
    return -1;
  }
  tpm_free(buf);
  tpmData.permanent.flags.dataRestored = TRUE;
  return 0;
}
Пример #19
0
TPM_RESULT TPM_LoadContext(TPM_HANDLE entityHandle, BOOL keepHandle,
                           UINT32 contextSize, TPM_CONTEXT_BLOB *contextBlob,
                           TPM_HANDLE *handle)
{
  TPM_CONTEXT_SENSITIVE context;
  BYTE *context_buf;
  TPM_SESSION_DATA *session;
  TPM_DAA_SESSION_DATA *sessionDAA;
  TPM_KEY_DATA *key;
  TPM_DIGEST digest;
  int i = 0;
  info("TPM_LoadContext()");
  if (decrypt_context(contextBlob->additionalData, contextBlob->additionalSize,
      contextBlob->sensitiveData, contextBlob->sensitiveSize, 
      &context, &context_buf)) return TPM_DECRYPT_ERROR;
  /* validate structure */
  if (compute_context_digest(contextBlob, &digest)
      || memcmp(&digest, &contextBlob->integrityDigest, sizeof(TPM_DIGEST))) {
    tpm_free(context_buf);
    return TPM_BADCONTEXT;
  }
  if (contextBlob->resourceType == TPM_RT_KEY) {
   /* check contextNonce */
    if (context.internalData.key.parentPCRStatus 
        || (context.internalData.key.keyFlags & TPM_KEY_FLAG_VOLATILE)) {
      if (memcmp(&context.contextNonce, &tpmData.stclear.data.contextNonceKey,
          sizeof(TPM_NONCE)) != 0) {
        tpm_free(context_buf);
        return TPM_BADCONTEXT;
      }
    }
    /* check handle */
    key = tpm_get_key_slot(entityHandle);
    if (key == NULL || !key->payload) {
      if (keepHandle) {
        tpm_free(context_buf);
        return TPM_BAD_HANDLE;
      }    
      *handle = tpm_get_free_key();
      if (*handle == TPM_INVALID_HANDLE) {
        tpm_free(context_buf);
        return TPM_RESOURCES;
      }
      key = &tpmData.permanent.data.keys[HANDLE_TO_INDEX(*handle)];
    } else {
      *handle = entityHandle;
    }
    /* reload resource */
    memcpy(key, &context.internalData.key, sizeof(TPM_KEY_DATA));
    tpm_rsa_copy_key(&key->key, &context.internalData.key.key);
  } else if (contextBlob->resourceType == TPM_RT_DAA_TPM) {
    /* check contextNonce */
    if (memcmp(&context.contextNonce, &tpmData.stany.data.contextNonceSession, 
        sizeof(TPM_NONCE)) != 0) {
      tpm_free(context_buf);
      return TPM_BADCONTEXT;
    }
    /* check context list */
    for (i = 0; i < TPM_MAX_SESSION_LIST; i++)
      if (tpmData.stany.data.contextList[i] == contextBlob->contextCount) break;
    if (i >= TPM_MAX_SESSION_LIST) {
      tpm_free(context_buf);
      return TPM_BADCONTEXT;
    }
    tpmData.stany.data.contextList[i] = 0;
    /* check handle */
    info("entityHandle = %08x, keepHandle = %d", entityHandle, keepHandle);
    sessionDAA = tpm_get_daa_slot(entityHandle);
    if (sessionDAA == NULL) {
      if (keepHandle) {
        tpm_free(context_buf);
        return TPM_BAD_HANDLE;
      }
      *handle = tpm_get_free_daa_session();
      if (*handle == TPM_INVALID_HANDLE) {
        tpm_free(context_buf);
        return TPM_RESOURCES;
      }
      sessionDAA = &tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(*handle)];
    } else if (sessionDAA->type != TPM_ST_INVALID) {
      if (keepHandle) {
        tpm_free(context_buf);
        return TPM_BAD_HANDLE;
      }
      *handle = tpm_get_free_daa_session();
      if (*handle == TPM_INVALID_HANDLE) {
        tpm_free(context_buf);
        return TPM_RESOURCES;
      }
      sessionDAA = &tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(*handle)];
    } else {
      if (HANDLE_TO_RT(entityHandle) != TPM_RT_DAA_TPM) {
        if (keepHandle) {
          tpm_free(context_buf);
          return TPM_BAD_HANDLE;
        }
        *handle = tpm_get_free_daa_session();
        if (*handle == TPM_INVALID_HANDLE) {
          tpm_free(context_buf);
          return TPM_RESOURCES;
        }
        sessionDAA = &tpmData.stany.data.sessionsDAA[HANDLE_TO_INDEX(*handle)];
      } else
        *handle = entityHandle;
    }
    /* reload resource */
    tpmData.stany.data.currentDAA = *handle;
    info("stany.data.currentDAA := %.8x", *handle);
    memset(sessionDAA, 0, sizeof(TPM_DAA_SESSION_DATA));
    memcpy(sessionDAA, &context.internalData.sessionDAA, context.internalSize);
  } else {
    /* check contextNonce */
    if (memcmp(&context.contextNonce, &tpmData.stany.data.contextNonceSession, 
        sizeof(TPM_NONCE)) != 0) {
      tpm_free(context_buf);
      return TPM_BADCONTEXT;
    }
    if (context.internalData.session.type == TPM_ST_OSAP
        && tpm_get_key(context.internalData.session.handle) == NULL) {
      tpm_free(context_buf);
      return TPM_RESOURCEMISSING;
    }
    /* check context list */
    for (i = 0; i < TPM_MAX_SESSION_LIST; i++)
      if (tpmData.stany.data.contextList[i] == contextBlob->contextCount) break;
    if (i >= TPM_MAX_SESSION_LIST) {
      tpm_free(context_buf);
      return TPM_BADCONTEXT;
    }
    tpmData.stany.data.contextList[i] = 0;
    /* check handle */
    session = tpm_get_session_slot(entityHandle);
    if (session == NULL || session->type != TPM_ST_INVALID) {
      if (keepHandle) {
        tpm_free(context_buf);
        return TPM_BAD_HANDLE;
      }
      *handle = tpm_get_free_session(context.internalData.session.type);
      if (*handle == TPM_INVALID_HANDLE) {
        tpm_free(context_buf);
        return TPM_RESOURCES;
      }
      session = &tpmData.stany.data.sessions[HANDLE_TO_INDEX(*handle)];
    } else {
      *handle = entityHandle;
    }
    /* reload resource */
    memcpy(session, &context.internalData.session, sizeof(TPM_SESSION_DATA));
  }
  tpm_free(context_buf);
  return TPM_SUCCESS;
}
Пример #20
0
TPM_RESULT TPM_SaveContext(TPM_HANDLE handle, TPM_RESOURCE_TYPE resourceType,
                           const BYTE label[16], UINT32 *contextSize,
                           TPM_CONTEXT_BLOB *contextBlob)
{
  TPM_CONTEXT_SENSITIVE context;
  TPM_SESSION_DATA *session = NULL;
  TPM_DAA_SESSION_DATA *sessionDAA = NULL;
  TPM_KEY_DATA *key = NULL;
  int i = 0;
  info("TPM_SaveContext() resourceType = %08x", resourceType);
  /* setup context data */
  context.tag = TPM_TAG_CONTEXT_SENSITIVE;
  context.resourceType = resourceType;
  if (resourceType == TPM_RT_AUTH || resourceType == TPM_RT_TRANS) {
    session = (resourceType == TPM_RT_AUTH) ? tpm_get_auth(handle) : 
               tpm_get_transport(handle);
    if (session == NULL) return TPM_INVALID_RESOURCE;
    /* store session data */
    memcpy(&context.internalData.session, session, sizeof(TPM_SESSION_DATA));
    context.internalSize = sizeof_TPM_SESSION_DATA((*session));
    /* set context nonce */
    memcpy(&context.contextNonce, &tpmData.stany.data.contextNonceSession, 
           sizeof(TPM_NONCE));
  } else if (resourceType == TPM_RT_KEY) {
    key = tpm_get_key(handle);
    debug("resourceType = TPM_RT_KEY, handle = %08x, key = %p", handle, key);
    if (key == NULL) return TPM_INVALID_RESOURCE;
    if (key->keyControl & TPM_KEY_CONTROL_OWNER_EVICT) return TPM_OWNER_CONTROL;
    /* store key data (shallow copy is ok) */
    memcpy(&context.internalData.key, key, sizeof(TPM_KEY_DATA));
    context.internalSize = sizeof_TPM_KEY_DATA((*key));
    /* set context nonce */
    memcpy(&context.contextNonce, &tpmData.stclear.data.contextNonceKey, 
           sizeof(TPM_NONCE));
  } else if (resourceType == TPM_RT_DAA_TPM) {
    sessionDAA = tpm_get_daa(handle);
    if (sessionDAA == NULL) return TPM_INVALID_RESOURCE;
    /* store sessionDAA data */
    memcpy(&context.internalData.sessionDAA, sessionDAA,
           sizeof(TPM_DAA_SESSION_DATA));
    context.internalSize = sizeof(TPM_DAA_SESSION_DATA);
    /* set context nonce */
    memcpy(&context.contextNonce, &tpmData.stany.data.contextNonceSession, 
           sizeof(TPM_NONCE));
  } else {
    return TPM_INVALID_RESOURCE;
  }
  /* setup context blob */
  contextBlob->tag = TPM_TAG_CONTEXTBLOB;
  contextBlob->resourceType = resourceType;
  contextBlob->handle = handle;
  memset(&contextBlob->integrityDigest, 0, sizeof(TPM_DIGEST));
  memcpy(contextBlob->label, label, sizeof(contextBlob->label));
  contextBlob->additionalSize = TPM_SYM_KEY_SIZE;
  contextBlob->additionalData = tpm_malloc(contextBlob->additionalSize);
  if (contextBlob->additionalData == NULL) return TPM_FAIL;
  tpm_get_random_bytes(contextBlob->additionalData, 
                       contextBlob->additionalSize);
  /* increment context counter */
  if (resourceType == TPM_RT_KEY) {
    contextBlob->contextCount = 0;
  } else {
    if (tpmData.stany.data.contextCount >= 0xfffffffc) {
      tpm_free(contextBlob->additionalData);
      return TPM_TOOMANYCONTEXTS;
    }
    contextBlob->contextCount = ++tpmData.stany.data.contextCount;
    for (i = 0; i < TPM_MAX_SESSION_LIST; i++) {
      if (tpmData.stany.data.contextList[i] == 0) break;
    }
    if (i >= TPM_MAX_SESSION_LIST) {
      tpm_free(contextBlob->additionalData);
      return TPM_NOCONTEXTSPACE;
    }
    tpmData.stany.data.contextCount++;
    tpmData.stany.data.contextList[i] = tpmData.stany.data.contextCount;
    contextBlob->contextCount = tpmData.stany.data.contextCount;
  }
  debug("context counter = %d", tpmData.stany.data.contextCount);
  /* encrypt sensitive data */
  if (encrypt_context(contextBlob->additionalData, contextBlob->additionalSize,
      &context, &contextBlob->sensitiveData, &contextBlob->sensitiveSize)) {
        tpm_free(contextBlob->additionalData);
        return TPM_ENCRYPT_ERROR;
  }
  /* compute context digest */
  if (compute_context_digest(contextBlob, &contextBlob->integrityDigest)) {
    tpm_free(contextBlob->additionalData);
    return TPM_FAIL;
  }
  *contextSize = sizeof_TPM_CONTEXT_BLOB((*contextBlob));
  if (resourceType != TPM_RT_KEY) {
    /* The TPM MUST invalidate all information regarding the resource 
     * except for information needed for reloading. */
    if (resourceType != TPM_RT_DAA_TPM)
      session->type = TPM_ST_INVALID;
    else {
      memset(sessionDAA, 0, sizeof(TPM_DAA_SESSION_DATA));
      sessionDAA->type = TPM_ST_INVALID;
      tpmData.stany.data.currentDAA = 0;
    }
  }
  return TPM_SUCCESS;
}
Пример #21
0
static TPM_RESULT cap_handle(UINT32 subCapSize, BYTE *subCap,
                               UINT32 *respSize, BYTE **resp)
{
  UINT32 i, len, type;
  BYTE *ptr; 
  /* maximum of { TPM_MAX_KEYS, TPM_MAX_SESSIONS } */
  UINT32 list_size =
    (TPM_MAX_KEYS > TPM_MAX_SESSIONS) ? TPM_MAX_KEYS : TPM_MAX_SESSIONS;
  UINT32 handles[list_size];
  TPM_KEY_HANDLE_LIST list = { 0, handles };

  if (tpm_unmarshal_UINT32(&subCap, &subCapSize, &type))
    return TPM_BAD_MODE;
  switch (type) {
    case TPM_RT_KEY:
      debug("[TPM_RT_KEY]");
      for (i = 0; i < TPM_MAX_KEYS; i++)
        if (tpmData.permanent.data.keys[i].valid) {
          list.loaded++;
          list.handle[i] = INDEX_TO_KEY_HANDLE(i);
        }
      break;
    case TPM_RT_AUTH:
      debug("[TPM_RT_AUTH]");
      for (i = 0; i < TPM_MAX_SESSIONS; i++)
        if (tpmData.stany.data.sessions[i].type == TPM_ST_OIAP
            || tpmData.stany.data.sessions[i].type == TPM_ST_OSAP) {
          list.loaded++;
          list.handle[i] = INDEX_TO_AUTH_HANDLE(i);
        }
      break;
    case TPM_RT_TRANS:
      debug("[TPM_RT_TRANS]");
      for (i = 0; i < TPM_MAX_SESSIONS; i++)
        if (tpmData.stany.data.sessions[i].type == TPM_ST_TRANSPORT) {
          list.loaded++;
          list.handle[i] = INDEX_TO_TRANS_HANDLE(i);
        }
      break;
/* removed since v1.2 rev 94
    case TPM_RT_DELEGATE:
      debug("[TPM_RT_DELEGATE]");
      break;
*/
    case TPM_RT_COUNTER:
      debug("[TPM_RT_COUNTER]");
      for (i = 0; i < TPM_MAX_COUNTERS; i++)
        if (tpmData.permanent.data.counters[i].valid) {
          list.loaded++;
          list.handle[i] = INDEX_TO_COUNTER_HANDLE(i);
        }
      break;
    case TPM_RT_CONTEXT:
      /* TODO: implement TPM_CAP_HANDLE for TPM_RT_CONTEXT */
    default:
      return TPM_BAD_MODE;
  }
  /* marshal handle list */
  len = *respSize = 2 + list.loaded * 4;
  ptr = *resp = tpm_malloc(len);
  if (ptr == NULL || tpm_marshal_TPM_KEY_HANDLE_LIST(&ptr, &len, &list)) {
    tpm_free(*resp);
    return TPM_FAIL;
  }
  return TPM_SUCCESS;
}
Пример #22
0
static TPM_RESULT cap_property(UINT32 subCapSize, BYTE *subCap, 
                               UINT32 *respSize, BYTE **resp)
{
  UINT32 i, j, property;

  if (tpm_unmarshal_UINT32(&subCap, &subCapSize, &property))
    return TPM_BAD_MODE;
  switch (property) {
    case TPM_CAP_PROP_PCR:
      debug("[TPM_CAP_PROP_PCR]");
      return return_UINT32(respSize, resp, TPM_NUM_PCR);

    case TPM_CAP_PROP_DIR:
      debug("[TPM_CAP_PROP_DIR]");
      return return_UINT32(respSize, resp, 1);

    case TPM_CAP_PROP_MANUFACTURER:
      debug("[TPM_CAP_PROP_MANUFACTURER]");
      return return_UINT32(respSize, resp, TPM_MANUFACTURER);

    case TPM_CAP_PROP_KEYS:
      debug("[TPM_CAP_PROP_KEYS]");
      for (i = 0, j = TPM_MAX_KEYS; i < TPM_MAX_KEYS; i++)
        if (tpmData.permanent.data.keys[i].valid) j--;
      return return_UINT32(respSize, resp, j); 

    case TPM_CAP_PROP_MIN_COUNTER:
      debug("[TPM_CAP_PROP_MIN_COUNTER]");
      return return_UINT32(respSize, resp, 1);

    case TPM_CAP_PROP_AUTHSESS:
      debug("[TPM_CAP_PROP_AUTHSESS]");
      for (i = 0, j = TPM_MAX_SESSIONS; i < TPM_MAX_SESSIONS; i++)
        if (tpmData.stany.data.sessions[i].type != TPM_ST_INVALID) j--;
      return return_UINT32(respSize, resp, j);

    case TPM_CAP_PROP_TRANSESS:
      debug("[TPM_CAP_PROP_TRANSESS]");
      for (i = 0, j = TPM_MAX_SESSIONS; i < TPM_MAX_SESSIONS; i++)
        if (tpmData.stany.data.sessions[i].type != TPM_ST_INVALID) j--;
      return return_UINT32(respSize, resp, j);

    case TPM_CAP_PROP_COUNTERS:
      debug("[TPM_CAP_PROP_COUNTERS]");
      for (i = 0, j = TPM_MAX_COUNTERS; i < TPM_MAX_COUNTERS; i++)
        if (tpmData.permanent.data.counters[i].valid) j--;
      return return_UINT32(respSize, resp, j);

    case TPM_CAP_PROP_MAX_AUTHSESS:
      debug("[TPM_CAP_PROP_MAX_AUTHSESS]");
      return return_UINT32(respSize, resp, TPM_MAX_SESSIONS);

    case TPM_CAP_PROP_MAX_TRANSESS:
      debug("[TPM_CAP_PROP_MAX_TRANSESS]");
      return return_UINT32(respSize, resp, TPM_MAX_SESSIONS);

    case TPM_CAP_PROP_MAX_COUNTERS:
      debug("[TPM_CAP_PROP_MAX_COUNTERS]");
      return return_UINT32(respSize, resp, TPM_MAX_COUNTERS);

    case TPM_CAP_PROP_MAX_KEYS:
      debug("[TPM_CAP_PROP_MAX_KEYS]");
      return return_UINT32(respSize, resp, TPM_MAX_KEYS);

    case TPM_CAP_PROP_OWNER:
      debug("[TPM_CAP_PROP_OWNER]");
      return return_BOOL(respSize, resp, tpmData.permanent.flags.owned);

    case TPM_CAP_PROP_CONTEXT:
      debug("[TPM_CAP_PROP_CONTEXT]");
      for (i = 0, j = 0; i < TPM_MAX_SESSION_LIST; i++)
        if (tpmData.stany.data.contextList[i] == 0) j++;
      return return_UINT32(respSize, resp, j);

    case TPM_CAP_PROP_MAX_CONTEXT:
      debug("[TPM_CAP_PROP_MAX_CONTEXT]");
      return return_UINT32(respSize, resp, TPM_MAX_SESSION_LIST);

    case TPM_CAP_PROP_FAMILYROWS:
      debug("[TPM_CAP_PROP_FAMILYROWS]");
      /* TODO: TPM_CAP_PROP_FAMILYROWS */
      return TPM_FAIL;

    case TPM_CAP_PROP_TIS_TIMEOUT:
      debug("[TPM_CAP_PROP_TIS_TIMEOUT]");
      /* TODO: TPM_CAP_PROP_TIS_TIMEOUT: Measure these values and determine correct ones */
      UINT32 len = *respSize = 16;
      BYTE *ptr = *resp = tpm_malloc(*respSize);
      if (ptr == NULL || 
          tpm_marshal_UINT32(&ptr, &len, 200000) ||
          tpm_marshal_UINT32(&ptr, &len, 200000) ||
          tpm_marshal_UINT32(&ptr, &len, 200000) ||
          tpm_marshal_UINT32(&ptr, &len, 200000)) {
        tpm_free(*resp);
        return TPM_FAIL;
      }
      return TPM_SUCCESS;

    case TPM_CAP_PROP_STARTUP_EFFECT:
      debug("[TPM_CAP_PROP_STARTUP_EFFECT]");
      /* TODO: TPM_CAP_PROP_STARTUP_EFFECT */
      return TPM_FAIL;

    case TPM_CAP_PROP_DELEGATE_ROW:
      debug("[TPM_CAP_PROP_DELEGATE_ROW]");
      /* TODO: TPM_CAP_PROP_DELEGATE_ROW */
      return TPM_FAIL;

    case TPM_CAP_PROP_DAA_MAX:
      debug("[TPM_CAP_PROP_DAA_MAX]");
      return return_UINT32(respSize, resp, TPM_MAX_SESSIONS_DAA);

    case TPM_CAP_PROP_SESSION_DAA:
      debug("[TPM_CAP_PROP_SESSION_DAA]");
      for (i = 0, j = TPM_MAX_SESSIONS_DAA; i < TPM_MAX_SESSIONS_DAA; i++)
        if (tpmData.stany.data.sessionsDAA[i].type != TPM_ST_INVALID) j--;
      return return_UINT32(respSize, resp, j);

    case TPM_CAP_PROP_CONTEXT_DIST:
      debug("[TPM_CAP_PROP_CONTEXT_DIST]");
      /* TODO: TPM_CAP_PROP_CONTEXT_DIST */
      return TPM_FAIL;

    case TPM_CAP_PROP_DAA_INTERRUPT:
      debug("[TPM_CAP_PROP_DAA_INTERRUPT]");
      /* A value of TRUE indicates that the TPM will accept ANY command 
       * while executing a DAA Join or Sign. A value of FALSE indicates 
       * that the TPM will invalidate the DAA Join or Sign upon the 
       * receipt of any command other than the next join/sign in the 
       * session or a TPM_SaveContext. */
      return return_BOOL(respSize, resp, TRUE);

    case TPM_CAP_PROP_SESSIONS:
      debug("[TPM_CAP_PROP_SESSIONS]");
      for (i = 0, j = TPM_MAX_SESSIONS; i < TPM_MAX_SESSIONS; i++)
        if (tpmData.stany.data.sessions[i].type != TPM_ST_INVALID) j--;
      return return_UINT32(respSize, resp, j);

    case TPM_CAP_PROP_MAX_SESSIONS:
      debug("[TPM_CAP_PROP_MAX_SESSIONS]");
      return return_UINT32(respSize, resp, TPM_MAX_SESSIONS);

    case TPM_CAP_PROP_CMK_RESTRICTION:
      debug("[TPM_CAP_PROP_CMK_RESTRICTION]");
      /* TODO: TPM_CAP_PROP_CMK_RESTRICTION */
      return TPM_FAIL;

    case TPM_CAP_PROP_DURATION:
      debug("[TPM_CAP_PROP_DURATION]");
      /* TODO: TPM_CAP_PROP_DURATION: Measure these values and return accurate ones */
      BYTE dur[]= {0x0,0x0,0x0,0xc,0x0,0x7,0xa1,0x20,0x0,0x1e,0x84,0x80,0x11,0xe1,0xa3,0x0}; 
      *respSize = 16;
      *resp = tpm_malloc(*respSize);
      memcpy(*resp,dur,16); 
      return TPM_FAIL;

    case TPM_CAP_PROP_ACTIVE_COUNTER:
      debug("[TPM_CAP_PROP_ACTIVE_COUNTER]");
      /* TODO: TPM_CAP_PROP_ACTIVE_COUNTER */
      return TPM_FAIL;

    case TPM_CAP_PROP_MAX_NV_AVAILABLE:
      debug("[TPM_CAP_PROP_MAX_NV_AVAILABLE]");
      /* TODO: TPM_CAP_PROP_MAX_NV_AVAILABLE */
      return TPM_FAIL;

    case TPM_CAP_PROP_INPUT_BUFFER:
      debug("[TPM_CAP_PROP_INPUT_BUFFER]");
      /* TODO: TPM_CAP_PROP_INPUT_BUFFER */
      return TPM_FAIL;

    default:
      return TPM_BAD_MODE;
  }
}
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) != 0) {
    return TPM_DECRYPT_ERROR;
  }
  if (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) {
Пример #24
0
static void main_loop(void)
{
    int sock = -1, devfd = -1, fh, res, npoll;
    int32_t in_len;
    uint32_t out_len;
    uint8_t in[TPM_CMD_BUF_SIZE], *out;
    struct sockaddr_un addr;
    socklen_t addr_len;
    struct pollfd poll_table[2];

    info("staring main loop");
    /* open UNIX socket */
    if (opt_socket_name) {
	sock = init_socket(opt_socket_name);
	if (sock < 0) exit(EXIT_FAILURE);
    }

    if (opt_dev_name) {
	devfd = init_device(opt_dev_name);
	if (devfd < 0)
	    exit(EXIT_FAILURE);
    }

    /* init tpm emulator */
    debug("initializing TPM emulator");
    if (tpm_emulator_init(tpm_startup, tpm_config) != 0) {
        error("tpm_emulator_init() failed");
        close(sock);
        unlink(opt_socket_name);
        exit(EXIT_FAILURE);
    }

    /* start command processing */
    while (!stopflag) {
        /* wait for incomming connections */
        debug("waiting for connections...");
	npoll = 0;
	if (sock != -1) {
	    poll_table[npoll].fd = sock;
	    poll_table[npoll].events = POLLIN;
	    poll_table[npoll++].revents = 0;
	}
	if (devfd != -1) {
	    poll_table[npoll].fd = devfd;
	    poll_table[npoll].events = POLLIN | POLLERR;
	    poll_table[npoll++].revents = 0;
	}
	res = poll(poll_table, npoll, -1);
        if (res < 0) {
            error("poll(sock,dev) failed: %s", strerror(errno));
            break;
        }

	if (devfd != -1 && poll_table[npoll - 1].revents) {
	    /* if POLLERR was set, let read() handle it */
	    if (handle_emuldev_command(devfd) < 0)
		break;
	}
	if (sock == -1 || !poll_table[0].revents)
	    continue;

	/* Beyond this point, npoll will always be 1 if the emulator device is
	 * not open and 2 if it is, so we can just fill in the second slot of
	 * the poll table unconditionally and rely on passing npoll to poll().
	 */

        addr_len = sizeof(addr);
        fh = accept(sock, (struct sockaddr*)&addr, &addr_len);
        if (fh < 0) {
            error("accept() failed: %s", strerror(errno));
            continue;
        }
        /* receive and handle commands */
        in_len = 0;
        do {
            debug("waiting for commands...");
	    poll_table[0].fd = fh;
	    poll_table[0].events = POLLIN;
	    poll_table[0].revents = 0;
	    poll_table[1].fd = devfd;
	    poll_table[1].events = POLLIN | POLLERR;
	    poll_table[1].revents = 0;

	    res = poll(poll_table, npoll, TPM_COMMAND_TIMEOUT);
            if (res < 0) {
                error("poll(fh) failed: %s", strerror(errno));
                close(fh);
                break;
            } else if (res == 0) {
#ifdef TPMD_DISCONNECT_IDLE_CLIENTS	    
                info("connection closed due to inactivity");
                close(fh);
                break;
#else		
                continue;
#endif		
            }

	    if (poll_table[1].revents) {
		/* if POLLERR was set, let read() handle it */
		if (handle_emuldev_command(devfd) < 0)
		    break;
	    }
	    if (!poll_table[0].revents)
		continue;

            in_len = read(fh, in, sizeof(in));
            if (in_len > 0) {
                debug("received %d bytes", in_len);
                out = NULL;
                res = tpm_handle_command(in, in_len, &out, &out_len);
                if (res < 0) {
                    error("tpm_handle_command() failed");
                } else {
                    debug("sending %d bytes", out_len);
                    uint32_t len = 0;
                    while (len < out_len) {
                        res = write(fh, &out[len], out_len - len);
                        if (res < 0) {
                            error("write(%d) failed: %s", 
                                  out_len - len, strerror(errno));
                            break;
                        }
                        len += res;
                    }
                    tpm_free(out);
                }
            }
        } while (in_len > 0);
        close(fh);
    }
    /* shutdown tpm emulator */
    tpm_emulator_shutdown();
    /* close socket */
    close(sock);
    unlink(opt_socket_name);
    info("main loop stopped");
}