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

Implement API for requesting/retrieving Caliptra's IDEVID CSR. #1583

Merged
merged 2 commits into from
Jul 15, 2024
Merged
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
29 changes: 29 additions & 0 deletions libcaliptra/examples/generic/idev_csr_array.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Licensed under the Apache-2.0 license
// Generated from test/tests/caliptra_integration_tests/smoke_testdata/idev_csr.der

#include <stdint.h>
#define IDEV_CSR_LEN 443
uint8_t idev_csr_bytes[IDEV_CSR_LEN] = {
48, 130, 1, 183, 48, 130, 1, 62, 2, 1, 0, 48, 105, 49, 28, 48, 26, 6,
3, 85, 4, 3, 12, 19, 67, 97, 108, 105, 112, 116, 114, 97, 32, 49, 46,
48, 32, 73, 68, 101, 118, 73, 68, 49, 73, 48, 71, 6, 3, 85, 4, 5, 19,
rusty1968 marked this conversation as resolved.
Show resolved Hide resolved
64, 56, 69, 51, 67, 49, 65, 48, 53, 56, 70, 55, 48, 52, 65, 49, 49, 56,
50, 49, 70, 55, 66, 52, 56, 68, 51, 52, 48, 65, 69, 70, 57, 57, 68, 68,
65, 66, 65, 68, 67, 49, 48, 57, 48, 68, 55, 52, 68, 48, 53, 55, 70, 69,
67, 67, 70, 55, 51, 50, 57, 52, 69, 68, 54, 48, 118, 48, 16, 6, 7, 42, 134,
72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 34, 3, 98, 0, 4, 215, 180, 133, 242,
159, 17, 92, 28, 179, 4, 107, 132, 11, 69, 137, 181, 120, 98, 245, 235, 249,
157, 132, 111, 190, 63, 210, 209, 67, 150, 245, 246, 154, 55, 154, 89, 172,
197, 162, 174, 200, 54, 158, 203, 101, 144, 68, 55, 180, 188, 124, 217, 165,
168, 64, 60, 91, 177, 145, 82, 35, 170, 134, 190, 242, 193, 188, 146, 20, 95, 252,
39, 193, 37, 198, 219, 250, 212, 156, 145, 232, 72, 197, 68, 172, 127, 14, 149, 214,
205, 140, 172, 251, 146, 63, 166, 160, 86, 48, 84, 6, 9, 42, 134, 72, 134, 247, 13,
1, 9, 14, 49, 71, 48, 69, 48, 18, 6, 3, 85, 29, 19, 1, 1, 255, 4, 8, 48, 6, 1, 1, 255, 2
, 1, 5, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 2, 4, 48, 31, 6, 6, 103, 129, 5, 5,
4, 4, 4, 21, 48, 19, 4, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 10, 6, 8, 42,
134, 72, 206, 61, 4, 3, 3, 3, 103, 0, 48, 100, 2, 48, 124, 116, 253, 40, 206, 15, 249, 233, 218, 239
,144, 132, 165, 175, 192, 66, 209, 226, 8, 132, 103, 214, 106, 232, 220, 70, 204, 2, 29, 128, 218, 55, 80,
145, 238, 117, 9, 237, 21, 85, 15, 49, 21, 35, 201, 187, 230, 225, 2, 48, 36, 253, 27, 91, 71, 204, 20, 74, 102,
165, 187, 231, 4, 116, 240, 33, 54, 55, 244, 158, 93, 205, 161, 66, 191, 246, 130, 92, 161, 244, 81, 67, 226, 151,
252, 149, 206, 86, 177, 103, 225, 191, 225, 38, 58, 206, 161, 243,
};
123 changes: 114 additions & 9 deletions libcaliptra/examples/generic/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "caliptra_api.h"
#include "caliptra_image.h"
#include "idev_csr_array.h"

// Arbitrary example only - values must be customized/tuned for the SoC
static const uint64_t wdt_timeout = 0xA0000000; // approximately 5s for 500MHz clock
Expand All @@ -23,6 +24,11 @@ static const uint32_t apb_pauser = 0x1;
// Exists for testbench only - not part of interface for actual implementation
extern void testbench_reinit(void);

#ifdef ENABLE_DEBUG
// Exists for testbench only - not part of interface for actual implementation
static int dump_array_to_file(struct caliptra_buffer* buffer, const char *filename);
#endif

struct caliptra_buffer image_bundle;
struct caliptra_fuses fuses = {0};

Expand All @@ -36,7 +42,25 @@ static const uint32_t default_uds_seed[] = { 0x00010203, 0x04050607, 0x08090a0b,
static const uint32_t default_field_entropy[] = { 0x80818283, 0x84858687, 0x88898a8b, 0x8c8d8e8f,
0x90919293, 0x94959697, 0x98999a9b, 0x9c9d9e9f };

static int set_fuses()
/*
* caliptra_csr_is_ready
*
* Waits forever for the CSR to be ready
*
* @return bool True if ready, false otherwise
*/
static void caliptra_wait_for_csr_ready(void)
{
while (true)
{
if (caliptra_is_idevid_csr_ready()) {
break;
}
caliptra_wait();
}
}

static int set_fuses(bool manuf_req_csr)
{
int status;

Expand Down Expand Up @@ -66,13 +90,18 @@ void dump_caliptra_error_codes()
printf("Caliptra FW error fatal code is 0x%x\n", caliptra_read_fw_fatal_error());
}

int boot_to_ready_for_fw()
int boot_to_ready_for_fw(bool req_idev_csr)
{
int status;

// Initialize FSM GO
caliptra_bootfsm_go();

// Request CSR if needed
if (req_idev_csr)
{
caliptra_req_idev_csr_start();
}
caliptra_set_wdt_timeout(wdt_timeout);

caliptra_configure_itrng_entropy(itrng_entropy_low_threshold,
Expand All @@ -93,18 +122,22 @@ int boot_to_ready_for_fw()
return status;
}

set_fuses();

// Wait until ready for FW
caliptra_ready_for_firmware();
set_fuses(req_idev_csr);

if (req_idev_csr == false)
{
// Wait until ready for FW
caliptra_ready_for_firmware();
}


return status;
}

int legacy_boot_test()
{
int failure = 0;
int status = boot_to_ready_for_fw();
int status = boot_to_ready_for_fw(false);

if (status){
failure = 1;
Expand Down Expand Up @@ -173,7 +206,7 @@ int legacy_boot_test()
int rom_test_all_commands()
{
int failure = 0;
int status = boot_to_ready_for_fw();
int status = boot_to_ready_for_fw(false);

if (status){
dump_caliptra_error_codes();
Expand Down Expand Up @@ -263,7 +296,7 @@ int rt_test_all_commands()
{
int failure = 0;
uint32_t non_fatal_error;
int status = boot_to_ready_for_fw();
int status = boot_to_ready_for_fw(false);

if (status){
rusty1968 marked this conversation as resolved.
Show resolved Hide resolved
failure = 1;
Expand Down Expand Up @@ -609,6 +642,55 @@ int rt_test_all_commands()
return failure;
}

int rom_test_devid_csr()
{
int failure = 0;

struct caliptra_buffer caliptra_idevid_csr_buf = {0};
caliptra_idevid_csr_buf.len = IDEV_CSR_LEN;
// Allocte a buffer to hold the IDEV CSR using malloc
caliptra_idevid_csr_buf.data = malloc(caliptra_idevid_csr_buf.len);

// Check if the buffer was allocated successfully
if (caliptra_idevid_csr_buf.data == NULL) {
printf("Failed to allocate memory for IDEV CSR\n");
return 1;
}

bool request_csr = true;
int status = boot_to_ready_for_fw(request_csr);

fdamato marked this conversation as resolved.
Show resolved Hide resolved
if (status){
dump_caliptra_error_codes();
failure = 1;
}

caliptra_wait_for_csr_ready();


int ret;
// Retrieve the IDEV CSR
if ((ret = caliptra_retrieve_idevid_csr(&caliptra_idevid_csr_buf)) != NO_ERROR) {
printf("Failed to retrieve IDEV CSR\n");
printf("Error is 0x%x\n", ret);
failure = 1;
} else {
printf("IDEV CSR retrieved\n");
}

// Compare the retrieved IDEV CSR with the expected IDEV CSR
if (memcmp(caliptra_idevid_csr_buf.data, idev_csr_bytes, caliptra_idevid_csr_buf.len) != 0) {
printf("IDEV CSR does not match\n");
#ifdef ENABLE_DEBUG
dump_array_to_file(&caliptra_idevid_csr_buf, "retrieved.bin");
nquarton marked this conversation as resolved.
Show resolved Hide resolved
#endif
failure = 1;
} else {
printf("IDEV CSR matches\n");
}

return failure;
}

// Test infrastructure

Expand All @@ -630,13 +712,35 @@ void run_test( int func(void), char* test_name)
global_test_result |= result;
}

#ifdef ENABLE_DEBUG
static int dump_array_to_file(struct caliptra_buffer* buffer, const char *filename) {
FILE *file = fopen(filename, "wb"); // Open the file in binary write mode
if (!file) {
perror("Failed to open file");
return -1; // Return an error code if file opening fails
}

// Write the array to the file
size_t written = fwrite(buffer->data, sizeof(uint8_t), buffer->len, file);
if (written < IDEV_CSR_LEN) {
perror("Failed to write the full array to file");
fclose(file);
return -2; // Return an error code if writing fails
}

fclose(file); // Close the file
return 0; // Success
}
#endif

int main(int argc, char *argv[])
{
global_test_result = 0;

run_test(legacy_boot_test, "Legacy boot test");
run_test(rom_test_all_commands, "Test all ROM commands");
run_test(rt_test_all_commands, "Test all Runtime commmands");
run_test(rom_test_devid_csr, "Test IDEV CSR GEN");

if (global_test_result) {
printf("\t\tlibcaliptra test failures reported\n");
Expand All @@ -646,3 +750,4 @@ int main(int argc, char *argv[])

return global_test_result;
}

9 changes: 9 additions & 0 deletions libcaliptra/inc/caliptra_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,13 @@ int caliptra_shutdown(bool async);
// Capabilities
int caliptra_capabilities(struct caliptra_capabilities_resp *resp, bool async);

// Query if IDevID CSR is ready.
bool caliptra_is_idevid_csr_ready();
nquarton marked this conversation as resolved.
Show resolved Hide resolved

int caliptra_retrieve_idevid_csr(struct caliptra_buffer* caliptra_idevid_csr);

void caliptra_req_idev_csr_start();

// Clear IDEV CSR request.
void caliptra_req_idev_csr_complete();

3 changes: 3 additions & 0 deletions libcaliptra/inc/caliptra_enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ enum libcaliptra_error {
MBX_RESP_NO_HEADER = 0x306,
MBX_RESP_CHKSUM_INVALID = 0x307,
MBX_RESP_FIPS_NOT_APPROVED = 0x308,

// MFG
IDEV_CSR_NOT_READY = 0x400,
};

/**
Expand Down
1 change: 0 additions & 1 deletion libcaliptra/inc/caliptra_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,4 +390,3 @@ struct caliptra_invoke_dpe_resp {
uint8_t data[sizeof(struct dpe_certify_key_response)];
};
};

74 changes: 73 additions & 1 deletion libcaliptra/src/caliptra_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ int caliptra_bootfsm_go()
return 0;
}


/**
* caliptra_set_wdt_timeout
*
Expand Down Expand Up @@ -269,6 +270,8 @@ int caliptra_init_fuses(struct caliptra_fuses *fuses)
if (!caliptra_ready_for_fuses())
return NOT_READY_FOR_FUSES;



// Write Fuses
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_UDS_SEED_0, fuses->uds_seed, CALIPTRA_ARRAY_SIZE(fuses->uds_seed));
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_FIELD_ENTROPY_0, fuses->field_entropy, CALIPTRA_ARRAY_SIZE(fuses->field_entropy));
Expand Down Expand Up @@ -348,6 +351,28 @@ bool caliptra_ready_for_firmware(void)
return true;
}

/*
* caliptra_is_csr_ready
*
* Reports if the IDEVID CSR is ready
*
* @return bool True if ready, false otherwise
*/
bool caliptra_is_csr_ready(void)
{
uint32_t status;

status = caliptra_read_status();

if ((status & GENERIC_AND_FUSE_REG_CPTRA_FLOW_STATUS_IDEVID_CSR_READY_MASK) == GENERIC_AND_FUSE_REG_CPTRA_FLOW_STATUS_IDEVID_CSR_READY_MASK)
{
return true;
}

return false;
}


/**
* caliptra_mailbox_write_fifo
*
Expand Down Expand Up @@ -1060,4 +1085,51 @@ int caliptra_capabilities(struct caliptra_capabilities_resp *resp, bool async)
CREATE_PARCEL(p, OP_CAPABILITIES, &checksum, resp);

return pack_and_execute_command(&p, async);
}
}

int caliptra_retrieve_idevid_csr(struct caliptra_buffer* caliptra_idevid_csr)
{
if (!caliptra_idevid_csr) {
return INVALID_PARAMS;
}

fdamato marked this conversation as resolved.
Show resolved Hide resolved
if (!caliptra_is_idevid_csr_ready()) {
return IDEV_CSR_NOT_READY;
}

return caliptra_mailbox_read_fifo(caliptra_idevid_csr);
}

void caliptra_req_idev_csr_start()
{
uint32_t dbg_manuf_serv_req;

caliptra_read_u32(CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_DBG_MANUF_SERVICE_REG, &dbg_manuf_serv_req);

// Write to Caliptra Fuse Done
caliptra_write_u32(CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_DBG_MANUF_SERVICE_REG, dbg_manuf_serv_req | 0x01);
}

void caliptra_req_idev_csr_complete()
{
uint32_t dbg_manuf_serv_req;

caliptra_read_u32(CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_DBG_MANUF_SERVICE_REG, &dbg_manuf_serv_req);

// Write to Caliptra Fuse Done
caliptra_write_u32(CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_DBG_MANUF_SERVICE_REG, dbg_manuf_serv_req & ~0x01);
}


// Check if IDEV CSR is ready.
bool caliptra_is_idevid_csr_ready() {
uint32_t status;

caliptra_read_u32(CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_FLOW_STATUS, &status);

if ((status & GENERIC_AND_FUSE_REG_CPTRA_FLOW_STATUS_IDEVID_CSR_READY_MASK) != 0) {
return true;
}

return false;
}
Loading
Loading