Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic Measurement #436

Draft
wants to merge 2 commits into
base: feature/structured-msr
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions examples/attestation/host/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,7 @@ Host::dispatch_ocall(RunData& run_data) {

Report
Host::run(const std::string& nonce) {
Keystone::Enclave enclave;
enclave.finalize(eapp_file_.c_str(), rt_file_.c_str(), ld_file_.c_str(), params_);

enclave.finalize();
RunData run_data{
SharedBuffer{enclave.getSharedBuffer(), enclave.getSharedBufferSize()},
nonce, nullptr};
Expand Down
44 changes: 22 additions & 22 deletions examples/attestation/host/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,31 +56,31 @@ class SharedBuffer {
// and the remote verifier.
class Host {
public:
Host(
Host(
const Keystone::Params& params, const std::string& eapp_file,
const std::string& rt_file, const std::string& ld_file)
: params_(params), eapp_file_(eapp_file), rt_file_(rt_file),
ld_file_(ld_file) {}
// Given a random nonce from the remote verifier, this method leaves
// it for the enclave to fetch, and returns the attestation report
// from the enclave to the verifier.
Report run(const std::string& nonce);
const std::string& rt_file, const std::string& ld_file) {
enclave = Keystone::Enclave(params);
enclave.addStandard(
eapp_file.c_str(), rt_file.c_str(), ld_file.c_str());
}
// Given a random nonce from the remote verifier, this method leaves
// it for the enclave to fetch, and returns the attestation report
// from the enclave to the verifier.
Report run(const std::string& nonce);
Keystone::Enclave& getEnclave() { return enclave; }

private:
struct RunData {
SharedBuffer shared_buffer;
const std::string& nonce;
std::unique_ptr<Report> report;
};
static void dispatch_ocall(RunData& run_data);
static void print_buffer_wrapper(RunData& run_data);
static void print_value_wrapper(RunData& run_data);
static void copy_report_wrapper(RunData& run_data);
static void get_host_string_wrapper(RunData& run_data);
const Keystone::Params params_;
const std::string eapp_file_;
const std::string rt_file_;
const std::string ld_file_;
struct RunData {
SharedBuffer shared_buffer;
const std::string& nonce;
std::unique_ptr<Report> report;
};
static void dispatch_ocall(RunData& run_data);
static void print_buffer_wrapper(RunData& run_data);
static void print_value_wrapper(RunData& run_data);
static void copy_report_wrapper(RunData& run_data);
static void get_host_string_wrapper(RunData& run_data);
Keystone::Enclave enclave;
};

#endif /* _ATTESTATION_HOST_H_ */
59 changes: 50 additions & 9 deletions examples/attestation/host/verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,49 @@
void
Verifier::run() {
const std::string nonce = std::to_string(random() % 0x100000000);
Host host(params_, eapp_file_, rt_file_, ld_file_);
Host host(params, eapp_file, rt_file, ld_file);
Keystone::Enclave::Checkpoint checkpoint_additions;
{
// create a random file, not used by enclave
const std::string extra_filename = "extra_file.txt";
// random contents
std::string extra_contents;
int extra_contents_length = 10;
extra_contents.reserve(extra_contents_length);
for (int i = 0; i < extra_contents_length; i++) {
extra_contents += (char) (random() % 128);
}
// write to file
FILE* extra_file = fopen(extra_filename.c_str(), "w");
if (!extra_file)
throw std::runtime_error(
"Error opening extra_file: " + extra_filename + ", " +
std::strerror(errno));
if (fwrite(extra_contents.data(), 1, extra_contents.size(), extra_file)
!= extra_contents.size()) {
throw std::runtime_error(
"Error writing extra_file: " + extra_filename + ", " +
std::strerror(errno));
}
fclose(extra_file);
// use Keystone::Enclave to create the delta, and add to existing enclave
Keystone::Enclave& enclave = host.getEnclave();
enclave.startDelta();
enclave.addResidentResource(extra_filename.c_str(), 0,
extra_filename.c_str(), 1);
checkpoint_additions = enclave.makeDeltaCheckpoint();
}
Report report = host.run(nonce);
verify_report(report, nonce);
verify_report(report, nonce, checkpoint_additions);
}

void
Verifier::verify_report(Report& report, const std::string& nonce) {
Verifier::verify_report(Report& report, const std::string& nonce,
Keystone::Enclave::Checkpoint checkpoint_additions) {
debug_verify(report, _sanctum_dev_public_key);

byte expected_enclave_hash[MDSIZE];
compute_expected_enclave_hash(expected_enclave_hash);
compute_expected_enclave_hash(expected_enclave_hash, checkpoint_additions);

byte expected_sm_hash[MDSIZE];
compute_expected_sm_hash(expected_sm_hash);
Expand Down Expand Up @@ -77,8 +109,17 @@ Verifier::verify_data(Report& report, const std::string& nonce) {
}

void
Verifier::compute_expected_enclave_hash(byte* expected_enclave_hash) {
Keystone::Enclave::measure((char*) expected_enclave_hash, eapp_file_.c_str(), rt_file_.c_str(), ld_file_.c_str(), params_);
Verifier::compute_expected_enclave_hash(byte* expected_enclave_hash,
Keystone::Enclave::Checkpoint checkpoint_additions) {
// create base
Keystone::Enclave enclave(params);
enclave.addStandard(
eapp_file.c_str(), rt_file.c_str(), ld_file.c_str());
Keystone::Enclave::Checkpoint checkpoint = enclave.makeCheckpoint();
// add additions & calculate hash
// in reality, would also validate checkpoint_additions is allowed
checkpoint.addFromCheckpoint(checkpoint_additions);
checkpoint.measurement((char *) expected_enclave_hash);
}

void
Expand All @@ -92,14 +133,14 @@ Verifier::compute_expected_sm_hash(byte* expected_sm_hash) {

{
// Reading SM content from file.
FILE* sm_bin = fopen(sm_bin_file_.c_str(), "rb");
FILE* sm_bin = fopen(sm_bin_file.c_str(), "rb");
if (!sm_bin)
throw std::runtime_error(
"Error opening sm_bin_file_: " + sm_bin_file_ + ", " +
"Error opening sm_bin_file: " + sm_bin_file + ", " +
std::strerror(errno));
if (fread(sm_content.data(), 1, sm_content.size(), sm_bin) <= 0)
throw std::runtime_error(
"Error reading sm_bin_file_: " + sm_bin_file_ + ", " +
"Error reading sm_bin_file: " + sm_bin_file + ", " +
std::strerror(errno));
fclose(sm_bin);
}
Expand Down
29 changes: 16 additions & 13 deletions examples/attestation/host/verifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ class Verifier {
public:
Verifier(
const Keystone::Params& params, const std::string& eapp_file,
const std::string& rt_file, const std::string& ld_file, const std::string& sm_bin_file)
: params_(params),
eapp_file_(eapp_file),
rt_file_(rt_file),
ld_file_(ld_file),
sm_bin_file_(sm_bin_file) {}
const std::string& rt_file, const std::string& ld_file,
const std::string& sm_bin_file)
: params(params),
eapp_file(eapp_file),
rt_file(rt_file),
ld_file(ld_file),
sm_bin_file(sm_bin_file) {}
// This method generates a random nonce, invokes the run() method
// of the Host, and verifies that the returned attestation report
// is valid.
Expand All @@ -49,17 +50,19 @@ class Verifier {
static void verify_data(Report& report, const std::string& nonce);

// Verifies the hashes and the nonce in the attestation report.
void verify_report(Report& report, const std::string& nonce);
void verify_report(Report& report, const std::string& nonce,
Keystone::Enclave::Checkpoint checkpoint_additions);

// Computes the hash of the expected EApp running in the enclave.
void compute_expected_enclave_hash(byte* expected_enclave_hash);
void compute_expected_enclave_hash(byte* expected_enclave_hash,
Keystone::Enclave::Checkpoint checkpoint_additions);

// Computes the hash of the expected Security Monitor (SM).
void compute_expected_sm_hash(byte* expected_sm_hash);

const Keystone::Params params_;
const std::string eapp_file_;
const std::string rt_file_;
const std::string ld_file_;
const std::string sm_bin_file_;
const Keystone::Params params;
const std::string eapp_file;
const std::string rt_file;
const std::string ld_file;
const std::string sm_bin_file;
};
24 changes: 23 additions & 1 deletion sdk/include/host/Enclave.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Enclave {
Params params;
KeystoneDevice pDevice;
OcallFunc oFuncDispatch;
Enclave* deltaEnclave = nullptr;

// track added resources
typedef struct {
Expand All @@ -59,7 +60,6 @@ class Enclave {
and their pointers into the enclave bundle in epm. */
Error materializeResourceInfo(resource_ptr_t residentResPtrs[],
ElfFile* allElfFiles[], std::vector<resource_info_t> resInfos);
static Error measureResidentArr(hash_ctx_t& hash_ctx, std::vector<resource_info_t> resident);
static bool resourceInfoCompare(const resource_info_t& a, const resource_info_t& b);
static bool resourceHashCompare(const resource_hash_t& a, const resource_hash_t& b);
void sortAllResources();
Expand All @@ -83,6 +83,28 @@ class Enclave {
// Call after adding all needed resources to fully create the enclave.
Error finalize();
Error finalize(const char* filepath, const char* runtime, const char* loaderpath, Params _params);

class Checkpoint {
public:
Checkpoint() {}
Checkpoint(Params& params, std::vector<resource_hash_t>& identityResident,
std::vector<resource_hash_t>& identityAbsent, std::vector<resource_hash_t>& resident,
std::vector<resource_hash_t>& absent) : params(params), identityResident(identityResident),
resident(resident), absent(absent) {}
Params params;
std::vector<resource_hash_t> identityResident;
std::vector<resource_hash_t> identityAbsent;
std::vector<resource_hash_t> resident;
std::vector<resource_hash_t> absent;
void measurement(char* hash);
void sortAllResources();
void addFromCheckpoint(Checkpoint other);
private:
void assertSorted();
};
void startDelta();
Checkpoint makeDeltaCheckpoint();
Checkpoint makeCheckpoint();
};

} // namespace Keystone
Loading
Loading