Skip to content

Commit

Permalink
Restore the fuse API to top level (#677)
Browse files Browse the repository at this point in the history
This restores the fuse programming APIs to the top level and
places the fuse structure definition in the generic example.
  • Loading branch information
wmaroneAMD authored Aug 23, 2023
1 parent ded54b1 commit b7348b3
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 121 deletions.
40 changes: 39 additions & 1 deletion libcaliptra/examples/generic/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,44 @@
#include <unistd.h>

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

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

__attribute__((section("VPK_HASH"))) uint8_t vpk_hash[48];
__attribute__((section("OPK_HASH"))) uint8_t opk_hash[48];

static const uint32_t default_uds_seed[] = { 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f,
0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f,
0x20212223, 0x24252627, 0x28292a2b, 0x2c2d2e2f };

static const uint32_t default_field_entropy[] = { 0x80818283, 0x84858687, 0x88898a8b, 0x8c8d8e8f,
0x90919293, 0x94959697, 0x98999a9b, 0x9c9d9e9f };

static int set_fuses()
{
int status;

fuses = (struct caliptra_fuses){0};

memcpy(&fuses.uds_seed, &default_uds_seed, sizeof(default_uds_seed));
memcpy(&fuses.field_entropy, &default_field_entropy, sizeof(default_field_entropy));

for (int x = 0; x < SHA384_DIGEST_WORD_SIZE; x++)
{
fuses.owner_pk_hash[x] = __builtin_bswap32(((uint32_t*)opk_hash)[x]);
}

memcpy(&fuses.key_manifest_pk_hash, &vpk_hash, SHA384_DIGEST_BYTE_SIZE);

if ((status = caliptra_init_fuses(&fuses)) != 0)
{
printf("Failed to init fuses: %d\n", status);
}

return status;
}

int main(int argc, char *argv[])
{
Expand All @@ -17,6 +53,8 @@ int main(int argc, char *argv[])
// Initialize FSM GO
caliptra_bootfsm_go();

set_fuses();

// Wait until ready for FW
caliptra_ready_for_firmware();

Expand Down
121 changes: 1 addition & 120 deletions libcaliptra/examples/hwmodel/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,127 +14,15 @@

#include "caliptra_model.h"
#include "caliptra_api.h"
#include "caliptra_fuses.h"
#include "caliptra_image.h"

#define CALIPTRA_STATUS_OK 0

// Implementation specifics

struct caliptra_model_init_params init_params;
struct caliptra_fuses fuses = {0};

__attribute__((section("VPK_HASH"))) uint8_t vpk_hash[48];
__attribute__((section("OPK_HASH"))) uint8_t opk_hash[48];

struct caliptra_buffer image_bundle;

static bool caliptra_model_init_complete = false;

static const uint32_t default_uds_seed[] = { 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f,
0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f,
0x20212223, 0x24252627, 0x28292a2b, 0x2c2d2e2f };

static const uint32_t default_field_entropy[] = { 0x80818283, 0x84858687, 0x88898a8b, 0x8c8d8e8f,
0x90919293, 0x94959697, 0x98999a9b, 0x9c9d9e9f };
/**
* caliptra_ready_for_fuses
*
* Reports if the Caliptra hardware is ready for fuse data
*
* @return bool True if ready, false otherwise
*/
bool caliptra_ready_for_fuses(void)
{
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_READY_FOR_FUSES_MASK) != 0) {
return true;
}

return false;
}

/**
* caliptra_init_fuses
*
* Initialize fuses based on contents of "fuses" argument
*
* @param[in] fuses Valid caliptra_fuses structure
*
* @return int 0 if successful, -EINVAL if fuses is null, -EPERM if caliptra is not ready for fuses, -EIO if still ready after fuses are written
*/
int caliptra_init_fuses(struct caliptra_fuses *fuses)
{
// Parameter check
if (!fuses)
{
return -EINVAL;
}

// Check whether caliptra is ready for fuses
if (!caliptra_ready_for_fuses())
return -EPERM;

// Write Fuses
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_UDS_SEED_0, fuses->uds_seed, ARRAY_SIZE(fuses->uds_seed));
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_FIELD_ENTROPY_0, fuses->field_entropy, ARRAY_SIZE(fuses->field_entropy));
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_KEY_MANIFEST_PK_HASH_0, fuses->key_manifest_pk_hash, ARRAY_SIZE(fuses->key_manifest_pk_hash));
caliptra_fuse_write(GENERIC_AND_FUSE_REG_FUSE_KEY_MANIFEST_PK_HASH_MASK, fuses->key_manifest_pk_hash_mask);
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_OWNER_PK_HASH_0, fuses->owner_pk_hash, ARRAY_SIZE(fuses->owner_pk_hash));
caliptra_fuse_write(GENERIC_AND_FUSE_REG_FUSE_FMC_KEY_MANIFEST_SVN, fuses->fmc_key_manifest_svn);
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_RUNTIME_SVN_0, fuses->runtime_svn, ARRAY_SIZE(fuses->runtime_svn));
caliptra_fuse_write(GENERIC_AND_FUSE_REG_FUSE_ANTI_ROLLBACK_DISABLE, (uint32_t)fuses->anti_rollback_disable);
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_IDEVID_CERT_ATTR_0, fuses->idevid_cert_attr, ARRAY_SIZE(fuses->idevid_cert_attr));
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_IDEVID_MANUF_HSM_ID_0, fuses->idevid_manuf_hsm_id, ARRAY_SIZE(fuses->idevid_manuf_hsm_id));
caliptra_fuse_write(GENERIC_AND_FUSE_REG_FUSE_LIFE_CYCLE, (uint32_t)fuses->life_cycle);

// Write to Caliptra Fuse Done
caliptra_write_u32(CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_FUSE_WR_DONE, 1);

// No longer ready for fuses
if (caliptra_ready_for_fuses())
return -EIO;

return 0;
}

/**
* set_fuses
*
* This function exists to account for the fact that the simulator and
* FPGA do not have true OTP fuses and, as such, need to be set during
* early startup.
*
* The expectation at actual time of use is that the SOC will have OTP
* fuses (and the associated key digests) programmed during manufacturing
* and as such users will not perform these digests and writes.
*/
static int set_fuses(struct caliptra_image_manifest *image)
{
int status;

fuses = (struct caliptra_fuses){0};

memcpy(&fuses.uds_seed, &default_uds_seed, sizeof(default_uds_seed));
memcpy(&fuses.field_entropy, &default_field_entropy, sizeof(default_field_entropy));

for (int x = 0; x < SHA384_DIGEST_WORD_SIZE; x++)
{
fuses.owner_pk_hash[x] = __builtin_bswap32(((uint32_t*)opk_hash)[x]);
}

memcpy(&fuses.key_manifest_pk_hash, &vpk_hash, SHA384_DIGEST_BYTE_SIZE);

if ((status = caliptra_init_fuses(&fuses)) != 0)
{
printf("Failed to init fuses: %d\n", status);
}

return status;
}
extern struct caliptra_buffer image_bundle;

static struct caliptra_buffer read_file_or_exit(const char* path)
{
Expand Down Expand Up @@ -191,13 +79,6 @@ struct caliptra_model* hwmod_get_or_init(void)
{
return NULL;
}

struct caliptra_image_manifest *image = (struct caliptra_image_manifest *)image_bundle.data;

if (status = set_fuses(image))
{
return NULL;
}
}

return model;
Expand Down
6 changes: 6 additions & 0 deletions libcaliptra/inc/caliptra_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
// Write into Caliptra BootFSM Go Register
int caliptra_bootfsm_go();

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

// Program calpitra_fuse object contents to caliptra fuses
int caliptra_init_fuses(struct caliptra_fuses *fuses);

// Query if ROM is ready for firmware
bool caliptra_ready_for_firmware(void);

Expand Down
66 changes: 66 additions & 0 deletions libcaliptra/src/caliptra_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <caliptra_top_reg.h>
#include "caliptra_if.h"
#include "caliptra_api.h"
#include "caliptra_fuses.h"
#include "caliptra_mbox.h"

#define CALIPTRA_STATUS_NOT_READY 0
Expand Down Expand Up @@ -75,6 +76,71 @@ int caliptra_bootfsm_go()
return 0;
}

/**
* caliptra_ready_for_fuses
*
* Reports if the Caliptra hardware is ready for fuse data
*
* @return bool True if ready, false otherwise
*/
bool caliptra_ready_for_fuses(void)
{
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_READY_FOR_FUSES_MASK) != 0) {
return true;
}

return false;
}

/**
* caliptra_init_fuses
*
* Initialize fuses based on contents of "fuses" argument
*
* @param[in] fuses Valid caliptra_fuses structure
*
* @return int 0 if successful, -EINVAL if fuses is null, -EPERM if caliptra is not ready for fuses, -EIO if still ready after fuses are written
*/
int caliptra_init_fuses(struct caliptra_fuses *fuses)
{
// Parameter check
if (!fuses)
{
return -EINVAL;
}

// Check whether caliptra is ready for fuses
if (!caliptra_ready_for_fuses())
return -EPERM;

// Write Fuses
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_UDS_SEED_0, fuses->uds_seed, ARRAY_SIZE(fuses->uds_seed));
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_FIELD_ENTROPY_0, fuses->field_entropy, ARRAY_SIZE(fuses->field_entropy));
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_KEY_MANIFEST_PK_HASH_0, fuses->key_manifest_pk_hash, ARRAY_SIZE(fuses->key_manifest_pk_hash));
caliptra_fuse_write(GENERIC_AND_FUSE_REG_FUSE_KEY_MANIFEST_PK_HASH_MASK, fuses->key_manifest_pk_hash_mask);
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_OWNER_PK_HASH_0, fuses->owner_pk_hash, ARRAY_SIZE(fuses->owner_pk_hash));
caliptra_fuse_write(GENERIC_AND_FUSE_REG_FUSE_FMC_KEY_MANIFEST_SVN, fuses->fmc_key_manifest_svn);
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_RUNTIME_SVN_0, fuses->runtime_svn, ARRAY_SIZE(fuses->runtime_svn));
caliptra_fuse_write(GENERIC_AND_FUSE_REG_FUSE_ANTI_ROLLBACK_DISABLE, (uint32_t)fuses->anti_rollback_disable);
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_IDEVID_CERT_ATTR_0, fuses->idevid_cert_attr, ARRAY_SIZE(fuses->idevid_cert_attr));
caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_IDEVID_MANUF_HSM_ID_0, fuses->idevid_manuf_hsm_id, ARRAY_SIZE(fuses->idevid_manuf_hsm_id));
caliptra_fuse_write(GENERIC_AND_FUSE_REG_FUSE_LIFE_CYCLE, (uint32_t)fuses->life_cycle);

// Write to Caliptra Fuse Done
caliptra_write_u32(CALIPTRA_TOP_REG_GENERIC_AND_FUSE_REG_CPTRA_FUSE_WR_DONE, 1);

// No longer ready for fuses
if (caliptra_ready_for_fuses())
return -EIO;

return 0;
}


/**
* caliptra_mailbox_write_fifo
*
Expand Down
File renamed without changes.

0 comments on commit b7348b3

Please sign in to comment.