Skip to content

Commit

Permalink
[dice] refactor dice lib to reduce code size
Browse files Browse the repository at this point in the history
This refactors the dice lib to optimize code reuse and follow lib asset
naming conventions.

Signed-off-by: Tim Trippel <[email protected]>
(cherry picked from commit b217f41)
  • Loading branch information
timothytrippel committed Apr 30, 2024
1 parent ecb45f6 commit 2d6ed3b
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 94 deletions.
11 changes: 5 additions & 6 deletions sw/device/silicon_creator/lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -489,12 +489,11 @@ cc_library(
opentitan_test(
name = "otbn_boot_services_functest",
srcs = ["otbn_boot_services_functest.c"],
exec_env = dicts.add(
EARLGREY_TEST_ENVS,
{
"//hw/top_earlgrey:fpga_cw310_sival": None,
},
),
exec_env = {
"//hw/top_earlgrey:fpga_cw310_sival": None,
"//hw/top_earlgrey:sim_dv": None,
"//hw/top_earlgrey:sim_verilator": None,
},
# This target uses OTBN pointers internally, so it cannot work host-side.
deps = [
":otbn_boot_services",
Expand Down
106 changes: 43 additions & 63 deletions sw/device/silicon_creator/lib/dice.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,93 +95,70 @@ static void curr_pubkey_le_to_be_convert(attestation_public_key_t *pubkey) {
le_be_buf_format((unsigned char *)pubkey->y, kAttestationPublicKeyCoordBytes);
}

/**
* Function generating a DICE or TPM certificate key pair. If successful, the
* generated public key is saved at pubkey.
*/
static rom_error_t common_attestation_keygen(
otbn_boot_attestation_key_type_t key_type,
const keymgr_diversification_t *diversifier, attestation_key_seed_t seed,
keymgr_state_t desired_keymgr_state, hmac_digest_t *pubkey_id,
attestation_public_key_t *pubkey) {
HARDENED_RETURN_IF_ERROR(keymgr_state_check(desired_keymgr_state));

// Generate / sideload key material into OTBN, and generate the ECC keypair.
HARDENED_RETURN_IF_ERROR(
otbn_boot_attestation_keygen(seed, key_type, *diversifier, pubkey));

// Keys are represented in certificates in big endian format, but the key is
// output from OTBN in little endian format, so we convert the key to
// big endian format.
curr_pubkey_le_to_be_convert(pubkey);

// Generate the key ID.
hmac_sha256(pubkey, kAttestationPublicKeyCoordBytes * 2, pubkey_id);

return kErrorOk;
}

/**
* Function preparing parameters for generating DICE attestation keys.
*/
rom_error_t dice_attestation_keygen(dice_key_t desired_key,
hmac_digest_t *pubkey_id,
attestation_public_key_t *pubkey) {
otbn_boot_attestation_key_type_t key_type;
attestation_key_seed_t otbn_ecc_keygen_seed;
const keymgr_diversification_t *keymgr_diversifier;
keymgr_state_t desired_state;
keymgr_state_t desired_keymgr_state;

switch (desired_key) {
case kDiceKeyUds:
desired_state = kKeymgrStateCreatorRootKey;
desired_keymgr_state = kKeymgrStateCreatorRootKey;
key_type = kOtbnBootAttestationKeyTypeDice;
keymgr_diversifier = &kUdsKeymgrDiversifier;
otbn_ecc_keygen_seed = kUdsAttestationKeySeed;
break;
case kDiceKeyCdi0:
desired_state = kKeymgrStateOwnerIntermediateKey;
desired_keymgr_state = kKeymgrStateOwnerIntermediateKey;
key_type = kOtbnBootAttestationKeyTypeDice;
keymgr_diversifier = &kCdi0KeymgrDiversifier;
otbn_ecc_keygen_seed = kCdi0AttestationKeySeed;
break;
case kDiceKeyCdi1:
desired_state = kKeymgrStateOwnerKey;
desired_keymgr_state = kKeymgrStateOwnerKey;
key_type = kOtbnBootAttestationKeyTypeDice;
keymgr_diversifier = &kCdi1KeymgrDiversifier;
otbn_ecc_keygen_seed = kCdi1AttestationKeySeed;
break;
default:
return kErrorDiceInvalidArgument;
};
return common_attestation_keygen(kOtbnBootAttestationKeyTypeDice,
keymgr_diversifier, otbn_ecc_keygen_seed,
desired_state, pubkey_id, pubkey);
}

/**
* Function preparing parameters for generating TPM keys.
*/
rom_error_t tpm_cert_keygen(tpm_key_t desired_key, hmac_digest_t *pubkey_id,
attestation_public_key_t *pubkey) {
attestation_key_seed_t otbn_ecc_keygen_seed;
const keymgr_diversification_t *keymgr_diversifier;

switch (desired_key) {
case kTpmKeyEk:
case kDiceKeyTpmEk:
desired_keymgr_state = kKeymgrStateOwnerKey;
key_type = kOtbnBootAttestationKeyTypeTpm;
keymgr_diversifier = &kTpmEkKeymgrDiversifier;
otbn_ecc_keygen_seed = kTpmEkAttestationKeySeed;
break;
case kTpmKeyCek:
case kDiceKeyTpmCek:
desired_keymgr_state = kKeymgrStateOwnerKey;
key_type = kOtbnBootAttestationKeyTypeTpm;
keymgr_diversifier = &kTpmCekKeymgrDiversifier;
otbn_ecc_keygen_seed = kTpmCekAttestationKeySeed;
break;
case kTpmKeyCik:
case kDiceKeyTpmCik:
desired_keymgr_state = kKeymgrStateOwnerKey;
key_type = kOtbnBootAttestationKeyTypeTpm;
keymgr_diversifier = &kTpmCikKeymgrDiversifier;
otbn_ecc_keygen_seed = kTpmCikAttestationKeySeed;
break;
default:
return kErrorDiceInvalidArgument;
return kErrorDiceInvalidKeyType;
};
return common_attestation_keygen(kOtbnBootAttestationKeyTypeTpm,
keymgr_diversifier, otbn_ecc_keygen_seed,
kKeymgrStateOwnerKey, pubkey_id, pubkey);

HARDENED_RETURN_IF_ERROR(keymgr_state_check(desired_keymgr_state));

// Generate / sideload key material into OTBN, and generate the ECC keypair.
HARDENED_RETURN_IF_ERROR(otbn_boot_attestation_keygen(
otbn_ecc_keygen_seed, key_type, *keymgr_diversifier, pubkey));

// Keys are represented in certificates in big endian format, but the key is
// output from OTBN in little endian format, so we convert the key to
// big endian format.
curr_pubkey_le_to_be_convert(pubkey);

// Generate the key ID.
hmac_sha256(pubkey, kAttestationPublicKeyCoordBytes * 2, pubkey_id);

return kErrorOk;
}

/**
Expand Down Expand Up @@ -351,7 +328,8 @@ rom_error_t dice_cdi_1_cert_build(hmac_digest_t *owner_measurement,

rom_error_t dice_tpm_ek_cert_build(manuf_certgen_inputs_t *inputs,
attestation_public_key_t *tpm_ek_pubkey,
hmac_digest_t *digest, uint8_t *tpm_ek_tbs,
hmac_digest_t *pubkey_id,
uint8_t *tpm_ek_tbs,
size_t *tpm_ek_tbs_size) {
tpm_ek_tbs_values_t tpm_ek_tbs_params = {
.auth_key_key_id = inputs->auth_key_key_id,
Expand All @@ -360,7 +338,7 @@ rom_error_t dice_tpm_ek_cert_build(manuf_certgen_inputs_t *inputs,
.tpm_ek_pub_key_ec_x_size = kAttestationPublicKeyCoordBytes,
.tpm_ek_pub_key_ec_y = (unsigned char *)tpm_ek_pubkey->y,
.tpm_ek_pub_key_ec_y_size = kAttestationPublicKeyCoordBytes,
.tpm_ek_pub_key_id = (unsigned char *)digest->digest, // Nobody cares.
.tpm_ek_pub_key_id = (unsigned char *)pubkey_id->digest,
.tpm_ek_pub_key_id_size = kDiceCertKeyIdSizeInBytes,
.tpm_version = "0.0.1",
.tpm_version_len = 5,
Expand All @@ -378,7 +356,8 @@ rom_error_t dice_tpm_ek_cert_build(manuf_certgen_inputs_t *inputs,

rom_error_t dice_tpm_cek_cert_build(manuf_certgen_inputs_t *inputs,
attestation_public_key_t *tpm_cek_pubkey,
hmac_digest_t *digest, uint8_t *tpm_cek_tbs,
hmac_digest_t *pubkey_id,
uint8_t *tpm_cek_tbs,
size_t *tpm_cek_tbs_size) {
tpm_cek_tbs_values_t tpm_cek_tbs_params = {
.auth_key_key_id = inputs->auth_key_key_id,
Expand All @@ -387,7 +366,7 @@ rom_error_t dice_tpm_cek_cert_build(manuf_certgen_inputs_t *inputs,
.tpm_cek_pub_key_ec_x_size = kAttestationPublicKeyCoordBytes,
.tpm_cek_pub_key_ec_y = (unsigned char *)tpm_cek_pubkey->y,
.tpm_cek_pub_key_ec_y_size = kAttestationPublicKeyCoordBytes,
.tpm_cek_pub_key_id = (unsigned char *)digest->digest,
.tpm_cek_pub_key_id = (unsigned char *)pubkey_id->digest,
.tpm_cek_pub_key_id_size = kDiceCertKeyIdSizeInBytes,
};

Expand All @@ -399,7 +378,8 @@ rom_error_t dice_tpm_cek_cert_build(manuf_certgen_inputs_t *inputs,

rom_error_t dice_tpm_cik_cert_build(manuf_certgen_inputs_t *inputs,
attestation_public_key_t *tpm_cik_pubkey,
hmac_digest_t *digest, uint8_t *tpm_cik_tbs,
hmac_digest_t *pubkey_id,
uint8_t *tpm_cik_tbs,
size_t *tpm_cik_tbs_size) {
tpm_cik_tbs_values_t tpm_cik_tbs_params = {
.auth_key_key_id = inputs->auth_key_key_id,
Expand All @@ -408,7 +388,7 @@ rom_error_t dice_tpm_cik_cert_build(manuf_certgen_inputs_t *inputs,
.tpm_cik_pub_key_ec_x_size = kAttestationPublicKeyCoordBytes,
.tpm_cik_pub_key_ec_y = (unsigned char *)tpm_cik_pubkey->y,
.tpm_cik_pub_key_ec_y_size = kAttestationPublicKeyCoordBytes,
.tpm_cik_pub_key_id = (unsigned char *)digest->digest,
.tpm_cik_pub_key_id = (unsigned char *)pubkey_id->digest,
.tpm_cik_pub_key_id_size = kDiceCertKeyIdSizeInBytes,
};

Expand Down
46 changes: 22 additions & 24 deletions sw/device/silicon_creator/lib/dice.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,35 @@ enum {
};

/**
* Supported DICE attestation keys.
* Supported DICE/TPM attestation keys.
*/
typedef enum dice_key {
/**
* DICE UDS key.
*/
kDiceKeyUds = 0,
/**
* DICE CDI0 key.
*/
kDiceKeyCdi0 = 1,
/**
* DICE CDI1 key.
*/
kDiceKeyCdi1 = 2,
/**
* TPM EK key.
*/
kDiceKeyTpmEk = 3,
/**
* TPM CEK key.
*/
kDiceKeyTpmCek = 4,
/**
* TPM CIK key.
*/
kDiceKeyTpmCik = 5,
} dice_key_t;

/**
* Supported TPM attestation keys.
*/
typedef enum tpm_key {
kTpmKeyEk = 0,
kTpmKeyCek = 1,
kTpmKeyCik = 2,
} tpm_key_t;

/**
* A set of public key IDs required to generate an X.509 certificate.
*/
Expand Down Expand Up @@ -131,20 +143,6 @@ rom_error_t dice_cdi_1_cert_build(hmac_digest_t *owner_measurement,
attestation_public_key_t *cdi_1_pubkey,
uint8_t *cert, size_t *cert_size);

/**
* Generates the requested TPM ECC keypair, returning the public key and
* a key ID (which is a SHA256 digest of the public key).
*
* Preconditions: keymgr has been initialized and cranked to the desired stage.
*
* @param desired_key The desired attestation key to generate.
* @param[out] pubkey_id The public key ID (for embedding into certificates).
* @param[out] pubkey The public key.
*/
OT_WARN_UNUSED_RESULT
rom_error_t tpm_cert_keygen(tpm_key_t desired_key, hmac_digest_t *pubkey_id,
attestation_public_key_t *pubkey);

/**
* Generates an X.509 TBS section of a TPM EK certificate.
*
Expand Down
2 changes: 1 addition & 1 deletion sw/device/silicon_creator/lib/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ enum module_ {
X(kErrorRescueBadMode, ERROR_(1, kModuleRescue, kInvalidArgument)), \
X(kErrorRescueImageTooBig, ERROR_(2, kModuleRescue, kFailedPrecondition)), \
\
X(kErrorDiceInvalidArgument, ERROR_(0, kModuleDice, kInvalidArgument)), \
X(kErrorDiceInvalidKeyType, ERROR_(0, kModuleDice, kInvalidArgument)), \
\
X(kErrorCertInternal, ERROR_(0, kModuleCert, kInternal)), \
X(kErrorCertInvalidArgument, ERROR_(1, kModuleCert, kInvalidArgument)), \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ static status_t personalize(ujson_t *uj) {
keymgr_advance_state();
TRY(dice_attestation_keygen(kDiceKeyUds, &uds_pubkey_id, &curr_pubkey));
TRY(otbn_boot_attestation_key_save(kUdsAttestationKeySeed,
kOtbnBootAttestationKeyTypeDice,
kUdsKeymgrDiversifier));
// We copy over the UDS endorsement key ID to an SHA256 digest type, since
// this is the format of key IDs generated on-dice.
Expand Down

0 comments on commit 2d6ed3b

Please sign in to comment.