in nsm-test/src/main.cc [263:391]
void check_pcr_locks(int32_t ctx, NsmDescription &description)
{
size_t expected_pcr_len = get_pcr_len(description);
std::vector<uint8_t> zeroed_pcr(expected_pcr_len, 0);
std::vector<uint8_t> dummy_data{1, 2, 3};
uint16_t range = description.max_pcrs;
ErrorCode status;
// Test that PCRs [0..16) cannot be locked.
for (uint16_t index = 0; index < 16; ++index) {
status = nsm_lock_pcr(ctx, index);
if (status == ERROR_CODE_SUCCESS) {
fprintf(stderr, "[Error] PCR %u expected to not be lockable, but got: %s\n",
index, get_status_string(status));
exit(-1);
}
}
printf("Checked Request::LockPCR for PCRs [0..16).\n");
// Extend all unlocked PCRs multiple times with the same input.
for (uint16_t loop_idx = 0; loop_idx < 10; ++loop_idx) {
for (uint16_t index = 16; index < description.max_pcrs; ++index) {
std::vector<uint8_t> pcr_data(expected_pcr_len, 0);
uint32_t pcr_data_len = expected_pcr_len;
// Perform PCR extension.
status = nsm_extend_pcr(ctx, index, dummy_data.data(), dummy_data.size(),
pcr_data.data(), &pcr_data_len);
if (status != ERROR_CODE_SUCCESS) {
fprintf(stderr, "[Error] Request::ExtendPCR got invalid response: %s\n",
get_status_string(status));
exit(-1);
}
if (pcr_data_len != expected_pcr_len) {
fprintf(stderr, "[Error] Request::ExtendPCR got invalid response.\n");
exit(-1);
}
// The extended PCR's data should not be empty.
if (pcr_data == zeroed_pcr) {
fprintf(stderr, "[Error] PCR %u must not be empty.\n", index);
exit(-1);
}
}
printf("[Loop: %u] Checked Request::ExtendedPCR for PCRs [16 ..%u).\n",
loop_idx, description.max_pcrs);
}
// Lock all remaining PCRs.
for (uint16_t index = 16; index < description.max_pcrs; ++index) {
status = nsm_lock_pcr(ctx, index);
if (status != ERROR_CODE_SUCCESS) {
fprintf(stderr, "[Error] Request::LockPCR got invalid response: %s\n",
get_status_string(status));
exit(-1);
}
}
printf("Checked Request::LockPCR for PCRs [16 ..%u).\n", description.max_pcrs);
// Lock PCRs in a valid range.
status = nsm_lock_pcrs(ctx, range);
if (status != ERROR_CODE_SUCCESS) {
fprintf(stderr, "[Error] Request::LockPCRs expected to succeed for [0..%u), but got: %s\n",
range, get_status_string(status));
exit(-1);
}
// Lock PCRs in an invalid range.
++range;
status = nsm_lock_pcrs(ctx, range);
if (status == ERROR_CODE_SUCCESS) {
fprintf(stderr, "[Error] Request::LockPCRs expected to fail for [0..%u), but got: %s\n",
range, get_status_string(status));
exit(-1);
}
printf("Checked Request::LockPCRs for ranges %u and %u.\n", range - 1, range);
// Attempt to extend the locked PCRs, which must fail.
for (uint16_t index = 0; index < description.max_pcrs; ++index) {
std::vector<uint8_t> pcr_data(expected_pcr_len, 0);
uint32_t pcr_data_len = expected_pcr_len;
status = nsm_extend_pcr(ctx, index, dummy_data.data(), dummy_data.size(),
pcr_data.data(), &pcr_data_len);
if (status == ERROR_CODE_SUCCESS) {
fprintf(stderr, "[Error] Request::ExtendPCR expected to fail, but got: %s\n",
get_status_string(status));
exit(-1);
}
}
printf("Checked Request::ExtendPCR for locked PCRs [0..%u).\n", description.max_pcrs);
// Get the description of all PCRs multiple times.
for (uint16_t loop_idx = 0; loop_idx < 10; ++loop_idx) {
for (uint16_t index = 0; index < description.max_pcrs; ++index) {
PcrData single_data;
get_pcr_description(ctx, index, expected_pcr_len, single_data);
// At this point, all PCRs should be locked.
if (!single_data.lock) {
fprintf(stderr, "[Error] PCR %u must be locked.\n", index);
exit(-1);
}
// PCRs [3..16) / {4} should be empty.
if (((index > 4) && (index < 16)) || index == 3) {
if (single_data.data != zeroed_pcr) {
fprintf(stderr, "[Error] PCR %u must be empty.\n", index);
exit(-1);
}
} else {
// All other PCRs should not be empty.
if (single_data.data == zeroed_pcr) {
fprintf(stderr, "[Error] PCR %u must not be empty.\n", index);
exit(-1);
}
}
}
printf("[Loop: %u] Checked Request::DescribePCR for PCRs [0..%u).\n", loop_idx, description.max_pcrs);
}
}