Skip to content
Open
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
16 changes: 16 additions & 0 deletions libcaliptra/examples/generic/test.c
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -320,19 +320,35 @@ int boot_to_ready_for_fw(const test_info* info, bool req_idev_csr)
itrng_entropy_repetition_count);

// Set up our PAUSER value for the mailbox regs
if (caliptra_mbox_pauser_is_valid(info->apb_pauser)) {
printf("MBOX pauser should not be valid before being set\n");
return -1;
}
status = caliptra_mbox_pauser_set_and_lock(info->apb_pauser);
if (status) {
printf("Set MBOX pauser Failed: 0x%x\n", status);
return status;
}
if (!caliptra_mbox_pauser_is_valid(info->apb_pauser)) {
printf("MBOX pauser should be valid after being set\n");
return -1;
}

// Set up our PAUSER value for the fuse regs
if (caliptra_fuse_pauser_is_valid(info->apb_pauser)) {
printf("Fuse pauser should not be valid before being set\n");
return -1;
}
status = caliptra_fuse_pauser_set_and_lock(info->apb_pauser);
if (status)
{
printf("Set FUSE pauser Failed: 0x%x\n", status);
return status;
}
if (!caliptra_fuse_pauser_is_valid(info->apb_pauser)) {
printf("Fuse pauser should be valid after being set\n");
return -1;
}

if ((status = caliptra_init_fuses(&info->fuses)) != 0)
{
Expand Down
6 changes: 6 additions & 0 deletions libcaliptra/inc/caliptra_api.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@ void caliptra_configure_itrng_entropy(uint16_t low_threshold, uint16_t high_thre
// If all slots are locked, returns PAUSER_LOCKED error
int caliptra_mbox_pauser_set_and_lock(uint32_t pauser);

// Returns true if pauser matches any locked PAUSER slot, false otherwise
bool caliptra_mbox_pauser_is_valid(uint32_t pauser);

// Sets the provided pauser value in the fuse_pauser_valid reg and sets the lock bit
// Returns PAUSER_LOCKED error if already locked
int caliptra_fuse_pauser_set_and_lock(uint32_t pauser);

// Returns true if the fuse PAUSER slot is locked and matches pauser, false otherwise
bool caliptra_fuse_pauser_is_valid(uint32_t pauser);

// Determine if Caliptra is ready to program fuses
bool caliptra_ready_for_fuses(void);

Expand Down
2 changes: 1 addition & 1 deletion libcaliptra/inc/caliptra_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ typedef uint32_t caliptra_checksum;
#if !defined(HWMODEL)
typedef struct caliptra_buffer
{
const uint8_t *data; //< Pointer to a buffer with data to send/space to receive
uint8_t *data; //< Pointer to a buffer with data to send/space to receive
uintptr_t len; //< Size of the buffer
} caliptra_buffer;
#endif
Expand Down
112 changes: 68 additions & 44 deletions libcaliptra/src/caliptra_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
// Globals should be uninitialized to maximize environment compatibility
static struct caliptra_buffer g_caliptra_mbox_pending_rx_buffer CALIPTRA_API_GLOBAL_SECTION_ATTRIBUTE;
static uint8_t g_caliptra_fw_load_piecewise_in_progress CALIPTRA_API_GLOBAL_SECTION_ATTRIBUTE;
// Shared rx buffer for commands that have no meaningful response beyond the standard header.
// Safe to share because only one mailbox command can be in-flight at a time.
static struct caliptra_resp_header g_resp_hdr CALIPTRA_API_GLOBAL_SECTION_ATTRIBUTE;

#define CREATE_PARCEL(name, op, req, resp) \
struct parcel name = { \
Expand Down Expand Up @@ -210,6 +213,27 @@ int caliptra_mbox_pauser_set_and_lock(uint32_t pauser)
return PAUSER_LOCKED;
}

/**
* caliptra_mbox_pauser_is_valid
*
* Checks whether the provided pauser value matches any locked PAUSER slot
*
* @param[in] pauser pauser value to check
*
* @return true if pauser matches a locked slot, false otherwise
*/
bool caliptra_mbox_pauser_is_valid(uint32_t pauser)
{
for (int i = 0; i < MBOX_PAUSER_SLOTS; i++) {
if (caliptra_read_mbox_pauser_lock(i) &&
caliptra_read_mbox_valid_pauser(i) == pauser) {
return true;
}
}

return false;
}

/**
* caliptra_fuse_pauser_set_and_lock
*
Expand All @@ -232,6 +256,21 @@ int caliptra_fuse_pauser_set_and_lock(uint32_t pauser)
return PAUSER_LOCKED;
}

/**
* caliptra_fuse_pauser_is_valid
*
* Checks whether the provided pauser value matches the locked fuse PAUSER slot
*
* @param[in] pauser pauser value to check
*
* @return true if the fuse pauser slot is locked and matches pauser, false otherwise
*/
bool caliptra_fuse_pauser_is_valid(uint32_t pauser)
{
return caliptra_read_fuse_pauser_lock() &&
caliptra_read_fuse_valid_pauser() == pauser;
}

/**
* caliptra_ready_for_fuses
*
Expand Down Expand Up @@ -478,20 +517,24 @@ static int caliptra_mailbox_write_fifo(const struct caliptra_buffer *buffer)
}

uint32_t remaining_len = buffer->len;
uint32_t *data_dw = (uint32_t *)buffer->data;
const uint8_t *data_p = buffer->data;

// Copy DWord multiples
while (remaining_len > sizeof(uint32_t))
{
caliptra_mbox_write(MBOX_CSR_MBOX_DATAIN, *data_dw++);
uint32_t data;
// memcpy to a temp dword to guarantee no issues with any misaligned reads on certain architectures
memcpy(&data, data_p, sizeof(uint32_t));
caliptra_mbox_write(MBOX_CSR_MBOX_DATAIN, data);
data_p += sizeof(uint32_t);
remaining_len -= sizeof(uint32_t);
}

// if un-aligned dword remainder...
if (remaining_len)
{
uint32_t data = 0;
memcpy(&data, data_dw, remaining_len);
memcpy(&data, data_p, remaining_len);
caliptra_mbox_write(MBOX_CSR_MBOX_DATAIN, data);
}

Expand Down Expand Up @@ -526,12 +569,14 @@ static int caliptra_mailbox_read_fifo(struct caliptra_buffer *buffer, uint32_t *
return INVALID_PARAMS;
}

uint32_t *data_dw = (uint32_t *)buffer->data;
uint8_t *data_p = (uint8_t *)buffer->data;

// Copy DWord multiples
while (remaining_len >= sizeof(uint32_t))
{
*data_dw++ = caliptra_mbox_read(MBOX_CSR_MBOX_DATAOUT);
uint32_t data = caliptra_mbox_read(MBOX_CSR_MBOX_DATAOUT);
memcpy(data_p, &data, sizeof(uint32_t));
data_p += sizeof(uint32_t);
remaining_len -= sizeof(uint32_t);
if (bytes_read) {
*bytes_read += 4;
Expand All @@ -542,7 +587,7 @@ static int caliptra_mailbox_read_fifo(struct caliptra_buffer *buffer, uint32_t *
if (remaining_len)
{
uint32_t data = caliptra_mbox_read(MBOX_CSR_MBOX_DATAOUT);
memcpy(data_dw, &data, remaining_len);
memcpy(data_p, &data, remaining_len);
if (bytes_read) {
*bytes_read += remaining_len;
}
Expand Down Expand Up @@ -781,6 +826,9 @@ static int pack_and_execute_command(struct parcel *parcel, bool async)
.len = parcel->rx_bytes,
};

// Clear the rx buffer before use to avoid stale data in the response
memset(rx_buf.data, 0, rx_buf.len);

// Calculate and populate the checksum field
// Clear the checksum field before calculating
*((caliptra_checksum*)tx_buf.data) = 0x0;
Expand Down Expand Up @@ -983,9 +1031,7 @@ int caliptra_populate_idev_ecc384_cert(struct caliptra_populate_idev_ecc384_cert
return INVALID_PARAMS;
}

struct caliptra_resp_header resp_hdr = {};

CREATE_PARCEL(p, OP_POPULATE_IDEV_ECC384_CERT, req, &resp_hdr);
CREATE_PARCEL(p,OP_POPULATE_IDEV_ECC384_CERT, req, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}
Expand Down Expand Up @@ -1071,9 +1117,7 @@ int caliptra_populate_idev_mldsa87_cert(struct caliptra_populate_idev_mldsa87_ce
return INVALID_PARAMS;
}

struct caliptra_resp_header resp_hdr = {};

CREATE_PARCEL(p, OP_POPULATE_IDEV_MLDSA87_CERT, req, &resp_hdr);
CREATE_PARCEL(p,OP_POPULATE_IDEV_MLDSA87_CERT, req, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}
Expand Down Expand Up @@ -1131,9 +1175,7 @@ int caliptra_ecdsa384_verify(struct caliptra_ecdsa_verify_v2_req *req, bool asyn
return INVALID_PARAMS;
}

struct caliptra_resp_header resp_hdr = {};

CREATE_PARCEL(p, OP_ECDSA384_VERIFY, req, &resp_hdr);
CREATE_PARCEL(p,OP_ECDSA384_VERIFY, req, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}
Expand All @@ -1146,9 +1188,7 @@ int caliptra_lms_verify(struct caliptra_lms_verify_v2_req *req, bool async)
return INVALID_PARAMS;
}

struct caliptra_resp_header resp_hdr = {};

CREATE_PARCEL(p, OP_LMS_VERIFY, req, &resp_hdr);
CREATE_PARCEL(p,OP_LMS_VERIFY, req, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}
Expand Down Expand Up @@ -1214,10 +1254,9 @@ int caliptra_invoke_dpe_mldsa87_command(struct caliptra_invoke_dpe_mldsa87_req *
// Disable attestation
int caliptra_disable_attestation(bool async)
{
struct caliptra_resp_header resp_hdr = {};
caliptra_checksum checksum = 0;

CREATE_PARCEL(p, OP_DISABLE_ATTESTATION, &checksum, &resp_hdr);
CREATE_PARCEL(p, OP_DISABLE_ATTESTATION, &checksum, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}
Expand Down Expand Up @@ -1245,9 +1284,7 @@ int caliptra_dpe_tag_tci(struct caliptra_dpe_tag_tci_req *req, bool async)
return INVALID_PARAMS;
}

struct caliptra_resp_header resp_hdr = {};

CREATE_PARCEL(p, OP_DPE_TAG_TCI, req, &resp_hdr);
CREATE_PARCEL(p,OP_DPE_TAG_TCI, req, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}
Expand All @@ -1273,9 +1310,7 @@ int caliptra_increment_pcr_reset_counter(struct caliptra_increment_pcr_reset_cou
return INVALID_PARAMS;
}

struct caliptra_resp_header resp_hdr = {};

CREATE_PARCEL(p, OP_INCREMENT_PCR_RESET_COUNTER, req, &resp_hdr);
CREATE_PARCEL(p,OP_INCREMENT_PCR_RESET_COUNTER, req, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}
Expand Down Expand Up @@ -1314,9 +1349,7 @@ int caliptra_extend_pcr(struct caliptra_extend_pcr_req *req, bool async)
return INVALID_PARAMS;
}

struct caliptra_resp_header resp_hdr = {};

CREATE_PARCEL(p, OP_EXTEND_PCR, req, &resp_hdr);
CREATE_PARCEL(p,OP_EXTEND_PCR, req, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}
Expand All @@ -1329,9 +1362,7 @@ int caliptra_add_subject_alt_name(struct caliptra_add_subject_alt_name_req *req,
return INVALID_PARAMS;
}

struct caliptra_resp_header resp_hdr = {};

CREATE_PARCEL(p, OP_ADD_SUBJECT_ALT_NAME, req, &resp_hdr);
CREATE_PARCEL(p,OP_ADD_SUBJECT_ALT_NAME, req, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}
Expand Down Expand Up @@ -1445,42 +1476,37 @@ int caliptra_revoke_exported_cdi_handle(struct caliptra_revoke_exported_cdi_hand
return INVALID_PARAMS;
}

struct caliptra_resp_header resp_hdr = {};

CREATE_PARCEL(p, OP_REVOKE_EXPORTED_CDI_HANDLE, req, &resp_hdr);
CREATE_PARCEL(p,OP_REVOKE_EXPORTED_CDI_HANDLE, req, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}

// Self test start
int caliptra_self_test_start(bool async)
{
struct caliptra_resp_header resp_hdr = {};
caliptra_checksum checksum = 0;

CREATE_PARCEL(p, OP_SELF_TEST_START, &checksum, &resp_hdr);
CREATE_PARCEL(p, OP_SELF_TEST_START, &checksum, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}

// Self test get results
int caliptra_self_test_get_results(bool async)
{
struct caliptra_resp_header resp_hdr = {};
caliptra_checksum checksum = 0;

CREATE_PARCEL(p, OP_SELF_TEST_GET_RESULTS, &checksum, &resp_hdr);
CREATE_PARCEL(p, OP_SELF_TEST_GET_RESULTS, &checksum, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}

// Shutdown
int caliptra_shutdown(bool async)
{
struct caliptra_resp_header resp_hdr = {};
caliptra_checksum checksum = 0;

CREATE_PARCEL(p, OP_SHUTDOWN, &checksum, &resp_hdr);
CREATE_PARCEL(p, OP_SHUTDOWN, &checksum, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}
Expand Down Expand Up @@ -1508,9 +1534,7 @@ int caliptra_set_auth_manifest(struct caliptra_set_auth_manifest_req *req, bool
return INVALID_PARAMS;
}

struct caliptra_resp_header resp_hdr = {};

CREATE_PARCEL(p, OP_SET_AUTH_MANIFEST, req, &resp_hdr);
CREATE_PARCEL(p,OP_SET_AUTH_MANIFEST, req, &g_resp_hdr);

return pack_and_execute_command(&p, async);
}
Expand Down
11 changes: 11 additions & 0 deletions libcaliptra/src/caliptra_fuses.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ static inline void caliptra_set_mbox_pauser_lock(uint8_t idx)
caliptra_generic_and_fuse_write(GENERIC_AND_FUSE_REG_CPTRA_MBOX_AXI_USER_LOCK_0 + (sizeof(uint32_t) * idx), 0x1);
}

// NOTE: Is the responsibility of the caller to ensure the index does not exceed MBOX_AXI_USER_SLOTS
static inline uint32_t caliptra_read_mbox_valid_pauser(uint8_t idx)
{
return caliptra_generic_and_fuse_read(GENERIC_AND_FUSE_REG_CPTRA_MBOX_VALID_AXI_USER_0 + (sizeof(uint32_t) * idx));
}

// NOTE: Is the responsibility of the caller to ensure the index does not exceed MBOX_AXI_USER_SLOTS
static inline void caliptra_write_mbox_valid_pauser(uint8_t idx, uint32_t data)
{
Expand All @@ -115,6 +121,11 @@ static inline void caliptra_set_fuse_pauser_lock()
caliptra_generic_and_fuse_write(GENERIC_AND_FUSE_REG_CPTRA_FUSE_AXI_USER_LOCK, 0x1);
}

static inline uint32_t caliptra_read_fuse_valid_pauser()
{
return caliptra_generic_and_fuse_read(GENERIC_AND_FUSE_REG_CPTRA_FUSE_VALID_AXI_USER);
}

static inline void caliptra_write_fuse_valid_pauser(uint32_t data)
{
caliptra_generic_and_fuse_write(GENERIC_AND_FUSE_REG_CPTRA_FUSE_VALID_AXI_USER, data);
Expand Down
2 changes: 1 addition & 1 deletion libcaliptra/src/caliptra_mbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ static inline bool caliptra_mbox_is_busy(void)

static inline uint8_t caliptra_mbox_read_status_fsm(void)
{
return (uint8_t)(caliptra_mbox_read(MBOX_CSR_MBOX_STATUS) & MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK) >> MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_LOW;
return (uint8_t)((caliptra_mbox_read(MBOX_CSR_MBOX_STATUS) & MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_MASK) >> MBOX_CSR_MBOX_STATUS_MBOX_FSM_PS_LOW);
}

static inline uint32_t caliptra_mbox_read_dlen(void)
Expand Down
Loading