void check_pcr_locks()

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);
    }
}