int blob_pubkey(char *out, unsigned int olen, char *in, unsigned int ilen, char *p, unsigned int psize) { unsigned int offset, size; if (olen < ilen) { printf("\t\tblob_pubkey failed: olen < ilen\n"); return; } if (psize == 0) { printf("\t\tblob_pubkey failed: psize == 0\n"); return; } memcpy(out, in, ilen); /* Keep all the keyparms the same, overwrite the public key at end. * Check sizes to make sure we get the right offset. They are * big-endian. */ offset = 4 + 2 + 2; /* Key parms length */ size = Decode_UINT32(in + offset); offset += 4; offset += size; /* Key length */ UINT32ToArray(psize, out + offset); offset += 4; /* out + offset should now be pointing to the public key */ memcpy(out + offset, p, psize); offset += psize; return offset; }
TSS_RESULT get_max_auths(UINT32 *auths) { TCS_AUTHHANDLE handles[TSS_MAX_AUTHS_CAP]; TCPA_NONCE nonce; UINT32 subCap; TSS_RESULT result; int i; if (TPM_VERSION_IS(1,2)) { UINT32ToArray(TPM_CAP_PROP_MAX_AUTHSESS, (BYTE *)(&subCap)); result = get_cap_uint32(TPM_CAP_PROPERTY, (BYTE *)&subCap, sizeof(subCap), auths); } else if (TPM_VERSION_IS(1,1)) { /* open auth sessions until we get a failure */ for (i = 0; i < TSS_MAX_AUTHS_CAP; i++) { result = TCSP_OIAP_Internal(InternalContext, &(handles[i]), &nonce); if (result != TSS_SUCCESS) { /* this is not off by one since we're 0 indexed */ *auths = i; break; } } if (i == TSS_MAX_AUTHS_CAP) *auths = TSS_MAX_AUTHS_CAP; /* close the auth sessions */ for (i = 0; (UINT32)i < *auths; i++) { internal_TerminateHandle(handles[i]); } } else { result = TCSERR(TSS_E_INTERNAL_ERROR); *auths = 0; } if (*auths < 2) { LogError("%s reported only %u auth available!", __FUNCTION__, *auths); LogError("Your TPM must be reset before the TCSD can be started."); } else { LogDebug("get_max_auths reports %u auth contexts found", *auths); result = TSS_SUCCESS; } return result; }
/* This is only called from init paths, so printing an error message is * appropriate if something goes wrong */ TSS_RESULT get_tpm_metrics(struct tpm_properties *p) { TSS_RESULT result; UINT32 subCap, rv = 0; if ((result = get_current_version(&p->version))) goto err; UINT32ToArray(TPM_ORD_SaveKeyContext, (BYTE *)&subCap); if ((result = get_cap_uint32(TCPA_CAP_ORD, (BYTE *)&subCap, sizeof(UINT32), &rv))) goto err; p->keyctx_swap = rv ? TRUE : FALSE; rv = 0; UINT32ToArray(TPM_ORD_SaveAuthContext, (BYTE *)&subCap); if ((result = get_cap_uint32(TCPA_CAP_ORD, (BYTE *)&subCap, sizeof(UINT32), &rv))) goto err; p->authctx_swap = rv ? TRUE : FALSE; UINT32ToArray(TPM_CAP_PROP_PCR, (BYTE *)&subCap); if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32), &p->num_pcrs))) goto err; UINT32ToArray(TPM_CAP_PROP_DIR, (BYTE *)&subCap); if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32), &p->num_dirs))) goto err; UINT32ToArray(TPM_CAP_PROP_SLOTS, (BYTE *)&subCap); if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32), &p->num_keys))) goto err; UINT32ToArray(TPM_CAP_PROP_MANUFACTURER, (BYTE *)&subCap); if ((result = get_cap_uint32(TCPA_CAP_PROPERTY, (BYTE *)&subCap, sizeof(UINT32), (UINT32 *)&p->manufacturer))) goto err; result = get_max_auths(&(p->num_auths)); err: if (result) LogError("TCS GetCapability failed with result = 0x%x", result); return result; }
TSS_RESULT pcrs_calc_composite(TPM_PCR_SELECTION *select, TPM_PCRVALUE *arrayOfPcrs, TPM_DIGEST *digestOut) { UINT32 size, index; BYTE mask; BYTE hashBlob[1024]; UINT32 numPCRs = 0; UINT64 offset = 0; UINT64 sizeOffset = 0; if (select->sizeOfSelect > 0) { sizeOffset = 0; Trspi_LoadBlob_PCR_SELECTION(&sizeOffset, hashBlob, select); offset = sizeOffset + 4; for (size = 0; size < select->sizeOfSelect; size++) { for (index = 0, mask = 1; index < 8; index++, mask = mask << 1) { if (select->pcrSelect[size] & mask) { memcpy(&hashBlob[(numPCRs * TPM_SHA1_160_HASH_LEN) + offset], arrayOfPcrs[index + (size << 3)].digest, TPM_SHA1_160_HASH_LEN); numPCRs++; } } } if (numPCRs > 0) { offset += (numPCRs * TPM_SHA1_160_HASH_LEN); UINT32ToArray(numPCRs * TPM_SHA1_160_HASH_LEN, &hashBlob[sizeOffset]); return Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, digestOut->digest); } } return TSPERR(TSS_E_INTERNAL_ERROR); }
TSS_RESULT LIBTPMCALL TCS_Seal( UINT32 locality, TPM_KEY_HANDLE hParent, TPM_AUTHDATA * parentAuth, TPM_ENCAUTH * encDataAuth, UINT32 pcrInfoSize, BYTE * pcrInfo, UINT32 dataSize, BYTE * data, TPM_AUTH * auth, UINT32 * sealedDataSize, BYTE ** sealedData) { UINT64 offset = 0; TSS_RESULT result; UINT32 paramSize; BYTE txBlob[TSS_TPM_TXBLOB_SIZE]; TPM_COMMAND_CODE ordinal = TPM_ORD_Seal; BYTE bigendian_ordinal[sizeof(ordinal)]; BYTE bigendian_pcrInfoSize[sizeof(pcrInfoSize)]; BYTE bigendian_dataSize[sizeof(dataSize)]; TPM_NONCE h1; TPM_NONCE h1Check; struct USHAContext ctx_sha1; if(LIBTPM_IsInit() == false) { LOGERROR("libtpm not initialized"); return TCSERR(TSS_E_INTERNAL_ERROR); } LOGDEBUG("Entering TCS_Seal"); // Generate H1 USHAReset(&ctx_sha1, SHA1); UINT32ToArray(ordinal, bigendian_ordinal); UINT32ToArray(pcrInfoSize, bigendian_pcrInfoSize); UINT32ToArray(dataSize, bigendian_dataSize); USHAInput(&ctx_sha1, bigendian_ordinal, sizeof(bigendian_ordinal)); USHAInput(&ctx_sha1, encDataAuth->authdata, sizeof(encDataAuth->authdata)); USHAInput(&ctx_sha1, bigendian_pcrInfoSize, sizeof(bigendian_pcrInfoSize)); USHAInput(&ctx_sha1, pcrInfo, pcrInfoSize); USHAInput(&ctx_sha1, bigendian_dataSize, sizeof(bigendian_dataSize)); USHAInput(&ctx_sha1, data, dataSize); USHAResult(&ctx_sha1, (uint8_t *) &h1); memset(&ctx_sha1, 0, sizeof(ctx_sha1)); // Compute AUTH result = tcs_compute_auth(locality, auth, &h1, parentAuth); if(result) { return result; } // Communication with TPM result = tpm_rqu_build(TPM_ORD_Seal, &offset, txBlob, hParent, encDataAuth->authdata, pcrInfoSize, pcrInfo, dataSize, data, auth); if(result) { LOGDEBUG("tpm_rqu_build returns %x", result); return result; } UnloadBlob_Header(txBlob, ¶mSize); result = tpm_io(locality, txBlob, paramSize, txBlob, sizeof(txBlob)); if(result) { result = TDDLERR(result); LOGERROR("tpm_io returns %x", result); return result; } result = UnloadBlob_Header(txBlob, ¶mSize); if (! result) { result = tpm_rsp_parse(TPM_ORD_Seal, txBlob, paramSize, sealedDataSize, sealedData, auth); } if(! result) { // Check auth value USHAReset(&ctx_sha1, SHA1); USHAInput(&ctx_sha1, (uint8_t *) &result, sizeof(TPM_RESULT)); USHAInput(&ctx_sha1, bigendian_ordinal, sizeof(bigendian_ordinal)); USHAInput(&ctx_sha1, *sealedData, *sealedDataSize); USHAResult(&ctx_sha1, (uint8_t *) &h1Check); memset(&ctx_sha1, 0, sizeof(ctx_sha1)); result = tcs_check_auth(auth, &h1Check, parentAuth); if(result) { free(*sealedData); *sealedData = 0; } } LOGDEBUG("Exiting TCS_Seal : %x", result); return result; }