in client-library/src/Attestation/LinuxTpm/lib/Tss2Wrapper.cpp [631:685]
attest::Buffer Tss2Wrapper::DecryptWithEphemeralKey(const attest::PcrSet& pcrSet,
const attest::Buffer& encryptedBlob,
const attest::RsaScheme rsaWrapAlgId,
const attest::RsaHashAlg rsaHashAlgId) {
// Create an ephemeral key here and then use that key to decrypted the encrypted blob.
TPM2B_PUBLIC *outPublic = NULL;
ESYS_TR primaryHandle = Tss2Util::CreateEphemeralKey(*ctx, pcrSet, &outPublic);
// Store the object in a unique_c_ptr<> to manage clean up after use.
unique_c_ptr<TPM2B_PUBLIC> outPubPtr(outPublic);
Tss2Session session(this->ctx->Get());
try {
auto pcrDigest = Tss2Util::GeneratePcrDigest(pcrSet, pcrSet.hashAlg);
auto pcrSelection = Tss2Util::GetTssPcrSelection(*ctx, pcrSet, pcrSet.hashAlg);
session.Start(TPM2_SE_POLICY);
session.PolicyPcr(*pcrDigest, *pcrSelection);
}
catch(...) {
Tss2Util::FlushObjectContext(*ctx, primaryHandle);
throw;
}
if(encryptedBlob.size() > TPM2_MAX_RSA_KEY_BYTES) {
Tss2Util::FlushObjectContext(*ctx, primaryHandle);
throw std::runtime_error("Encrypted data size larger than Max RSA key size");
}
TPM2B_PUBLIC_KEY_RSA cipher_msg;
memcpy((void*)cipher_msg.buffer, (void*)encryptedBlob.data(), encryptedBlob.size());
cipher_msg.size = static_cast<UINT16>(encryptedBlob.size());
TPMT_RSA_DECRYPT scheme;
scheme.scheme = rsaWrapAlgId;
scheme.details.oaep.hashAlg = rsaHashAlgId;
TPM2B_PUBLIC_KEY_RSA* decrypted = NULL;
TSS2_RC ret = Esys_RSA_Decrypt(this->ctx->Get(), primaryHandle,
session.GetHandle(), ESYS_TR_NONE, ESYS_TR_NONE,
&cipher_msg, &scheme, nullptr, &decrypted);
if (ret != TSS2_RC_SUCCESS) {
// Flush the key object from the tpm to make sure we are not consuming tpm memory.
Tss2Util::FlushObjectContext(*ctx, primaryHandle);
throw Tss2Exception("Failed to decrypt message", ret);
}
// Flush the key object from the tpm to make sure we are not consuming tpm memory.
Tss2Util::FlushObjectContext(*ctx, primaryHandle);
attest::Buffer decryptedBlob(decrypted->buffer, decrypted->buffer + decrypted->size);
free(decrypted);
return decryptedBlob;
}