コード例 #1
0
ファイル: tpm_transport.c プロジェクト: Aorimn/tpm-emulator
TPM_RESULT TPM_ReleaseTransportSigned(TPM_KEY_HANDLE keyHandle,
                                      TPM_NONCE *antiReplay,
                                      TPM_AUTH *auth1, TPM_AUTH *auth2,
                                      TPM_MODIFIER_INDICATOR *locality,
                                      TPM_CURRENT_TICKS *currentTicks,
                                      UINT32 *sigSize, BYTE **sig)
{
  TPM_RESULT res;
  TPM_KEY_DATA *key;
  TPM_SESSION_DATA *session;
  BYTE buf[30 + 20];
  info("TPM_ReleaseTransportSigned()");
  /* get key */
  key = tpm_get_key(keyHandle);
  if (key == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify authorization */ 
  if (auth2->authHandle != TPM_INVALID_HANDLE
      || key->authDataUsage != TPM_AUTH_NEVER) {
    res = tpm_verify_auth(auth1, key->usageAuth, keyHandle);
    if (res != TPM_SUCCESS) return res;
    session = tpm_get_transport(auth2->authHandle);
    if (session == NULL) return TPM_INVALID_AUTHHANDLE;
    res = tpm_verify_auth(auth2, session->transInternal.authData, TPM_INVALID_HANDLE);
    if (res != TPM_SUCCESS) return (res == TPM_AUTHFAIL) ? TPM_AUTH2FAIL : res;
  } else {
    session = tpm_get_transport(auth1->authHandle);
    if (session == NULL) return TPM_INVALID_AUTHHANDLE;
    res = tpm_verify_auth(auth1, session->transInternal.authData, TPM_INVALID_HANDLE);
    if (res != TPM_SUCCESS) return res;
  }
  /* invalidate transport session */
  auth1->continueAuthSession = FALSE;
  /* logging must be enabled */
  if (!(session->transInternal.transPublic.transAttributes & TPM_TRANSPORT_LOG))
    return TPM_BAD_MODE;
  *locality = tpmData.stany.flags.localityModifier;
  memcpy(currentTicks, &tpmData.stany.data.currentTicks, sizeof(TPM_CURRENT_TICKS));
  transport_log_out(auth1->digest, &session->transInternal.transDigest);
  /* setup a TPM_SIGN_INFO structure */
  memcpy(&buf[0], (uint8_t*)"\x00\x05TRAN", 6);
  memcpy(&buf[6], antiReplay->nonce, 20);
  memcpy(&buf[26], (uint8_t*)"\x00\x00\x00\x14", 4);
  memcpy(&buf[30], session->transInternal.transDigest.digest, 20);
  /* sign info structure */ 
  if (key->sigScheme == TPM_SS_RSASSAPKCS1v15_SHA1) {
    tpm_sha1_ctx_t ctx;
    debug("TPM_SS_RSASSAPKCS1v15_SHA1");
    tpm_sha1_init(&ctx);
    tpm_sha1_update(&ctx, buf, sizeof(buf));
    tpm_sha1_final(&ctx, buf);
    res = tpm_sign(key, auth1, FALSE, buf, SHA1_DIGEST_LENGTH, sig, sigSize);
  } else if (key->sigScheme == TPM_SS_RSASSAPKCS1v15_INFO) {
    debug("TPM_SS_RSASSAPKCS1v15_INFO");
    res = tpm_sign(key, auth1, TRUE, buf, sizeof(buf), sig, sigSize);
  } else {
    debug("unsupported signature scheme: %02x", key->sigScheme);
    res = TPM_INVALID_KEYUSAGE;
  }
  return res;
}
コード例 #2
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) {
コード例 #3
0
TPM_RESULT TPM_KeyControlOwner(TPM_KEY_HANDLE keyHandle, UINT32 bitName,
                               BOOL bitValue, TPM_AUTH *auth1)
{
  TPM_RESULT res;
  TPM_KEY_DATA *key;
  info("TPM_KeyControlOwner()");
  /* get key */
  key = tpm_get_key(keyHandle);
  if (key == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify authorization */
  res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
  if (res != TPM_SUCCESS) return res;
  /* get bit name */
  switch (bitName) {
    case TPM_KEY_CONTROL_OWNER_EVICT:
      if (bitValue) {
        int i, num = 0;
        for (i = 0; i < TPM_MAX_KEYS; i++) {
          if (!tpmData.permanent.data.keys[i].valid ||
              !(tpmData.permanent.data.keys[i].keyControl 
                & TPM_KEY_CONTROL_OWNER_EVICT)) num++;
        }
        if (num < 2) return TPM_NOSPACE;
        if (key->parentPCRStatus || (key->keyFlags & TPM_KEY_FLAG_VOLATILE))
          return TPM_BAD_PARAMETER;
        key->keyControl |= TPM_KEY_CONTROL_OWNER_EVICT;
      } else {
        key->keyControl &= ~TPM_KEY_CONTROL_OWNER_EVICT;
      }
      return TPM_SUCCESS;
    default:
      return TPM_BAD_PARAMETER;
  }
}
コード例 #4
0
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;
}
コード例 #5
0
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;
}
コード例 #6
0
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;
}
コード例 #7
0
ファイル: tpm_context.c プロジェクト: johnxn/rockey-tpm
TPM_RESULT TPM_KeyControlOwner(TPM_KEY_HANDLE keyHandle, TPM_PUBKEY pubKey,
                               UINT32 bitName, BOOL bitValue, TPM_AUTH *auth1)
{
  TPM_RESULT res;
  TPM_KEY_DATA *key;
  TPM_PUBKEY pubKey2;
  TPM_DIGEST keyDigest, keyDigest2;
  info("TPM_KeyControlOwner()");
  /* get key */
  key = tpm_get_key(keyHandle);
  if (key == NULL) return TPM_INVALID_KEYHANDLE;
  /* verify authorization */
  res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
  if (res != TPM_SUCCESS) return res;
  /* verify public key */
  if (tpm_compute_pubkey_digest(&pubKey, &keyDigest)) {
    debug("tpm_compute_pubkey_digest() failed");
    return TPM_FAIL;
  }
  if (tpm_extract_pubkey(key, &pubKey2)) {
    debug("tpm_extraxt_pubkey() failed.");
    return TPM_FAIL;
  }
  if (tpm_compute_pubkey_digest(&pubKey2, &keyDigest2)) {
    debug("tpm_compute_pubkey_digest() failed");
    free_TPM_PUBKEY(pubKey2);
    return TPM_FAIL;
  }
  free_TPM_PUBKEY(pubKey2);
  if (memcmp(&keyDigest, &keyDigest2, sizeof(TPM_DIGEST)) != 0)
    return TPM_BAD_PARAMETER;
  /* get bit name */
  debug("bitName = %d", bitName);
  if (bitName & TPM_KEY_CONTROL_OWNER_EVICT) {
    if (bitValue) {
      int i, num = 0;
      for (i = 0; i < TPM_MAX_KEYS; i++) {
        if (!tpmData.permanent.data.keys[i].payload ||
            !(tpmData.permanent.data.keys[i].keyControl
              & TPM_KEY_CONTROL_OWNER_EVICT)) num++;
      }
      if (num < 2) return TPM_NOSPACE;
      if (key->parentPCRStatus || (key->keyFlags & TPM_KEY_FLAG_VOLATILE))
        return TPM_BAD_PARAMETER;
      key->keyControl |= TPM_KEY_CONTROL_OWNER_EVICT;
    } else {
      key->keyControl &= ~TPM_KEY_CONTROL_OWNER_EVICT;
    }
  } else {
    return TPM_BAD_MODE;
  }
  return TPM_SUCCESS;
}
コード例 #8
0
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;
}
コード例 #9
0
ファイル: tpm_transport.c プロジェクト: Aorimn/tpm-emulator
TPM_RESULT TPM_ExecuteTransport(UINT32 inWrappedCmdSize, BYTE *inWrappedCmd,
                                TPM_AUTH *auth1, UINT64 *currentTicks,
                                TPM_MODIFIER_INDICATOR *locality,
                                UINT32 *outWrappedCmdSize, BYTE **outWrappedCmd)
{
  TPM_RESULT res;
  TPM_SESSION_DATA *session;
  TPM_REQUEST req;
  TPM_RESPONSE rsp;
  BYTE *ptr, buf[4 * 4 + 8 + 20];
  UINT32 len, offset;
  tpm_sha1_ctx_t sha1;
  info("TPM_ExecuteTransport()");
  /* get transport session */
  session = tpm_get_transport(auth1->authHandle);
  if (session == NULL) return TPM_BAD_PARAMETER;
  /* unmarshal wrapped command */
  len = inWrappedCmdSize;
  ptr = inWrappedCmd;
  if (tpm_unmarshal_TPM_REQUEST(&ptr, &len, &req)) return TPM_FAIL;
  /* decrypt wrapped command if needed */
  ptr = tpm_malloc(req.paramSize);
  if (ptr == NULL) return TPM_FAIL;
  memcpy(ptr, req.param, req.paramSize);
  if (session->transInternal.transPublic.transAttributes & TPM_TRANSPORT_ENCRYPT) {
    if (req.ordinal == TPM_ORD_OIAP || req.ordinal == TPM_ORD_OSAP) {
      offset = req.paramSize;
    } else if (req.ordinal == TPM_ORD_DSAP) {
      offset = 30;
    } else {
      offset = tpm_get_in_param_offset(req.ordinal);
    }
    debug("decrypting %d bytes, starting at pos %d", req.paramSize - offset, offset);
    decrypt_wrapped_command(ptr + offset, req.paramSize - offset, auth1, session);
  }
  req.param = ptr;
  /* verify authorization */
  tpm_compute_in_param_digest(&req);
  tpm_sha1_init(&sha1);
  tpm_sha1_update_be32(&sha1, TPM_ORD_ExecuteTransport);
  tpm_sha1_update_be32(&sha1, inWrappedCmdSize);
  tpm_sha1_update(&sha1, req.auth1.digest, sizeof(req.auth1.digest));
  tpm_sha1_final(&sha1, auth1->digest);
  res = tpm_verify_auth(auth1, session->transInternal.authData, TPM_INVALID_HANDLE);
  if (res != TPM_SUCCESS) {
    tpm_free(req.param);
    return res;
  }
  /* nested transport sessions are not allowed */
  if (req.ordinal == TPM_ORD_EstablishTransport
      || req.ordinal == TPM_ORD_ExecuteTransport
      || req.ordinal == TPM_ORD_ReleaseTransportSigned) {
    tpm_free(req.param);
    return TPM_NO_WRAP_TRANSPORT;
  }
  /* log input parameters */
  if (session->transInternal.transPublic.transAttributes & TPM_TRANSPORT_LOG) {
    TPM_DIGEST keyDigest;
    compute_key_digest(&req, &keyDigest);
    transport_log_in(req.auth1.digest, keyDigest.digest,
                     &session->transInternal.transDigest);
  }
  /* execute and audit command*/
  tpm_audit_request(req.ordinal, &req);
  tpm_execute_command(&req, &rsp);
  tpm_audit_response(req.ordinal, &rsp);
  tpm_free(req.param);
  /* get locality and ticks */
  *locality = tpmData.stany.flags.localityModifier;
  *currentTicks = tpmData.stany.data.currentTicks.currentTicks;
  /* if required, compute digest of internal output parameters */
  debug("result = %d", rsp.result);
  if (rsp.result == TPM_SUCCESS) {
    if (rsp.tag == TPM_TAG_RSP_COMMAND) {
      rsp.auth1 = &req.auth1;
      tpm_compute_out_param_digest(req.ordinal, &rsp);
    }
    /* encrypt parameters */
    if (session->transInternal.transPublic.transAttributes & TPM_TRANSPORT_ENCRYPT) {
      if (req.ordinal == TPM_ORD_OIAP || req.ordinal == TPM_ORD_OSAP) {
        offset = rsp.paramSize;
      } else if (req.ordinal == TPM_ORD_DSAP) {
        offset = rsp.paramSize;
      } else {
        offset = tpm_get_out_param_offset(req.ordinal);
      }
      debug("encrypting %d bytes, starting at pos %d", rsp.paramSize - offset, offset);
      encrypt_wrapped_command(rsp.param + offset, rsp.paramSize - offset, auth1, session);
    }
  } else {
    rsp.auth1 = &req.auth1;
    memset(rsp.auth1->digest, 0, sizeof(*rsp.auth1->digest));
  }
  /* marshal response */
  *outWrappedCmdSize = len = rsp.size;
  *outWrappedCmd = ptr = tpm_malloc(len);
  if (ptr == NULL) {
    tpm_free(rsp.param);
    return TPM_FAIL;
  }
  tpm_marshal_TPM_RESPONSE(&ptr, &len, &rsp);
  debug("marshalling done.");
  /* log output parameters */
  if (session->transInternal.transPublic.transAttributes & TPM_TRANSPORT_LOG) {
    transport_log_out(rsp.auth1->digest, &session->transInternal.transDigest);
  }
  tpm_free(rsp.param);
  /* compute digest of output parameters */
  ptr = buf; len = sizeof(buf);
  tpm_marshal_UINT32(&ptr, &len, TPM_SUCCESS);
  tpm_marshal_TPM_COMMAND_CODE(&ptr, &len, TPM_ORD_ExecuteTransport);
  tpm_marshal_UINT64(&ptr, &len, *currentTicks);
  tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len, *locality);
  tpm_marshal_UINT32(&ptr, &len, *outWrappedCmdSize);
  memcpy(ptr, rsp.auth1->digest, sizeof(rsp.auth1->digest));
  tpm_sha1_init(&sha1);
  tpm_sha1_update(&sha1, buf, sizeof(buf));
  tpm_sha1_final(&sha1, auth1->digest);
  return TPM_SUCCESS;
}
コード例 #10
0
ファイル: tpm_transport.c プロジェクト: Aorimn/tpm-emulator
TPM_RESULT TPM_EstablishTransport(TPM_KEY_HANDLE encHandle,
                                  TPM_TRANSPORT_PUBLIC *transPublic,
                                  UINT32 secretSize, BYTE *secret,
                                  TPM_AUTH *auth1,
                                  TPM_TRANSHANDLE *transHandle,
                                  TPM_MODIFIER_INDICATOR *locality,
                                  TPM_CURRENT_TICKS *currentTicks,
                                  TPM_NONCE *transNonceEven)
{
  TPM_RESULT res;
  TPM_KEY_DATA *key;
  TPM_TRANSPORT_AUTH trans_auth;
  TPM_SESSION_DATA *session;

  info("TPM_EstablishTransport()");
  /* setup authorization data */
  if (encHandle == TPM_KH_TRANSPORT) {
    if (auth1->authHandle != TPM_INVALID_HANDLE) return TPM_BADTAG;
    if (transPublic->transAttributes & TPM_TRANSPORT_ENCRYPT) return TPM_BAD_SCHEME;
    if (secretSize != 20) return TPM_BAD_PARAM_SIZE;
    memcpy(trans_auth.authData, secret, 20);
  } else {
    /* get key and verify its usage */
    key = tpm_get_key(encHandle);
    if (key == NULL) return TPM_INVALID_KEYHANDLE;
    if (key->keyUsage != TPM_KEY_STORAGE && key->keyUsage != TPM_KEY_LEGACY)
        return TPM_INVALID_KEYUSAGE;
    /* verify authorization */ 
    if (key->authDataUsage != TPM_AUTH_NEVER) {
      res = tpm_verify_auth(auth1, key->usageAuth, encHandle);
      if (res != TPM_SUCCESS) return res;
      if (decrypt_transport_auth(key, secret, secretSize, &trans_auth))
        return TPM_DECRYPT_ERROR;
    }
  }
  /* check whether the transport has to be encrypted */
  if (transPublic->transAttributes & TPM_TRANSPORT_ENCRYPT) {
    if (tpmData.permanent.flags.FIPS
        && transPublic->algID == TPM_ALG_MGF1) return TPM_INAPPROPRIATE_ENC;
    /* until now, only MGF1 is supported */
    if (transPublic->algID != TPM_ALG_MGF1) return TPM_BAD_KEY_PROPERTY;
  }
  /* initialize transport session */
  tpm_get_random_bytes(transNonceEven->nonce, sizeof(transNonceEven->nonce));
  *transHandle = tpm_get_free_session(TPM_ST_TRANSPORT);
  session = tpm_get_transport(*transHandle);
  if (session == NULL) return TPM_RESOURCES;
  session->transInternal.transHandle = *transHandle;
  memset(&session->transInternal.transDigest, 0, sizeof(TPM_DIGEST));
  memcpy(&session->transInternal.transPublic, transPublic,
    sizeof_TPM_TRANSPORT_PUBLIC((*transPublic)));
  memcpy(&session->transInternal.transNonceEven, transNonceEven, sizeof(TPM_NONCE));
  memcpy(&session->nonceEven, transNonceEven, sizeof(TPM_NONCE));
  memcpy(&session->transInternal.authData, trans_auth.authData, sizeof(TPM_AUTHDATA));
  *locality = tpmData.stany.flags.localityModifier;
  memcpy(currentTicks, &tpmData.stany.data.currentTicks, sizeof(TPM_CURRENT_TICKS));
  /* perform transport logging */
  if (transPublic->transAttributes & TPM_TRANSPORT_LOG) {
    tpm_sha1_ctx_t sha1;
    BYTE *ptr, buf[4 + 4 + 4 + sizeof_TPM_CURRENT_TICKS(x) + 20];
    UINT32 len;
    /* log input */
    memset(buf, 0, sizeof(buf));
    transport_log_in(auth1->digest, buf, &session->transInternal.transDigest);
    /* compute digest of output parameters and log output */
    ptr = buf; len = sizeof(buf);
    tpm_marshal_UINT32(&ptr, &len, TPM_SUCCESS);
    tpm_marshal_TPM_COMMAND_CODE(&ptr, &len, TPM_ORD_EstablishTransport);
    tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len, *locality);
    tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, currentTicks);
    tpm_marshal_TPM_NONCE(&ptr, &len, transNonceEven);
    tpm_sha1_init(&sha1);
    tpm_sha1_update(&sha1, buf, sizeof(buf));
    tpm_sha1_final(&sha1, buf);
    transport_log_out(buf, &session->transInternal.transDigest);
  }
  /* check whether this is a exclusive transport session */
  if (transPublic->transAttributes & TPM_TRANSPORT_EXCLUSIVE) {
    tpmData.stany.flags.transportExclusive = TRUE;
    tpmData.stany.data.transExclusive = *transHandle;
  }
  auth1->continueAuthSession = FALSE;
  return TPM_SUCCESS;
}
コード例 #11
0
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_DECRYPT_ERROR;
  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_DECRYPT_ERROR;
  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.readPubek = FALSE;
  tpmData.permanent.flags.owned = TRUE;
  return TPM_SUCCESS;
}
コード例 #12
0
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) {
コード例 #13
0
TPM_RESULT TPM_GetCapabilityOwner(TPM_VERSION *version, 
                                  UINT32 *non_volatile_flags, 
                                  UINT32 *volatile_flags, 
                                  TPM_AUTH *auth1)
{
  TPM_RESULT res;
  
  info("TPM_GetCapabilityOwner()");
 
  if (!tpmData.permanent.flags.owned) {
    return TPM_NOSRK;
  } 
  /* Verify owner authorization */
  res = tpm_verify_auth(auth1, tpmData.permanent.data.ownerAuth, TPM_KH_OWNER);
  if (res != TPM_SUCCESS) return res;
  
  /* initialize */
  *version = tpmData.permanent.data.version;
  *non_volatile_flags = *volatile_flags = 0;
  
  /* set non-volatile flags */
  if (tpmData.permanent.flags.disable)
    *non_volatile_flags |= (1 <<  0);
  if (tpmData.permanent.flags.ownership)
    *non_volatile_flags |= (1 <<  1);
  if (tpmData.permanent.flags.deactivated)
    *non_volatile_flags |= (1 <<  2);
  if (tpmData.permanent.flags.readPubek)
    *non_volatile_flags |= (1 <<  3);
  if (tpmData.permanent.flags.disableOwnerClear)
    *non_volatile_flags |= (1 <<  4);
  if (tpmData.permanent.flags.allowMaintenance)
    *non_volatile_flags |= (1 <<  5);
  if (tpmData.permanent.flags.physicalPresenceLifetimeLock)
    *non_volatile_flags |= (1 <<  6);
  if (tpmData.permanent.flags.physicalPresenceHWEnable)
    *non_volatile_flags |= (1 <<  7);
  if (tpmData.permanent.flags.physicalPresenceCMDEnable)
    *non_volatile_flags |= (1 <<  8);
  if (tpmData.permanent.flags.CEKPUsed)
    *non_volatile_flags |= (1 <<  9);
  if (tpmData.permanent.flags.TPMpost)
    *non_volatile_flags |= (1 << 10);
  if (tpmData.permanent.flags.TPMpostLock)
    *non_volatile_flags |= (1 << 11);
  if (tpmData.permanent.flags.FIPS)
    *non_volatile_flags |= (1 << 12);
  if (tpmData.permanent.flags.operator)
    *non_volatile_flags |= (1 << 13);
  if (tpmData.permanent.flags.enableRevokeEK)
    *non_volatile_flags |= (1 << 14);
  if (tpmData.permanent.flags.nvLocked)
    *non_volatile_flags |= (1 << 15);
  if (tpmData.permanent.flags.readSRKPub)
    *non_volatile_flags |= (1 << 16);
  if (tpmData.permanent.flags.tpmEstablished)
    *non_volatile_flags |= (1 << 17);
  if (tpmData.permanent.flags.maintenanceDone)
    *non_volatile_flags |= (1 << 18);
  
  /* set volatile flags */
  if (tpmData.stclear.flags.deactivated)
    *volatile_flags |= (1 <<  0);
  if (tpmData.stclear.flags.disableForceClear)
    *volatile_flags |= (1 <<  1);
  if (tpmData.stclear.flags.physicalPresence)
    *volatile_flags |= (1 <<  2);
  if (tpmData.stclear.flags.physicalPresenceLock)
    *volatile_flags |= (1 <<  3);
  if (tpmData.stclear.flags.bGlobalLock)
    *volatile_flags |= (1 <<  4);
  
  return TPM_SUCCESS;
}