Skip to content

Commit

Permalink
[cert] move cert keygen function to otbn_boot_services lib
Browse files Browse the repository at this point in the history
This moves the `cert_ecc_p256_keygen()` function from the `cert` lib to
the `otbn_boot_services` lib to simplify on-host unit testing of the
`cert` lib. The `otbn_boot_services` lib is only tested on-device at the
moment due to the dependencies on specific OpenTitan hardware that is
difficult to mock. In refactoring this, the cert_unittest is now fixed.

Signed-off-by: Tim Trippel <ttrippel@google.com>
  • Loading branch information
timothytrippel committed Aug 29, 2024
1 parent 8149de2 commit c90a625
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 67 deletions.
1 change: 1 addition & 0 deletions sw/device/silicon_creator/lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ cc_library(
"//sw/device/silicon_creator/lib:dbg_print",
"//sw/device/silicon_creator/lib:error",
"//sw/device/silicon_creator/lib/base:sec_mmio",
"//sw/device/silicon_creator/lib/base:util",
"//sw/device/silicon_creator/lib/drivers:flash_ctrl",
"//sw/device/silicon_creator/lib/drivers:hmac",
"//sw/device/silicon_creator/lib/drivers:keymgr",
Expand Down
2 changes: 0 additions & 2 deletions sw/device/silicon_creator/lib/cert/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ cc_library(
"//hw/top_earlgrey/ip_autogen/flash_ctrl:flash_ctrl_c_regs",
"//sw/device/lib/base:hardened",
"//sw/device/silicon_creator/lib:error",
"//sw/device/silicon_creator/lib:otbn_boot_services",
"//sw/device/silicon_creator/lib/base:util",
"//sw/device/silicon_creator/lib/drivers:flash_ctrl",
"//sw/device/silicon_creator/lib/drivers:hmac",
"//sw/device/silicon_creator/lib/drivers:keymgr",
Expand Down
37 changes: 0 additions & 37 deletions sw/device/silicon_creator/lib/cert/cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,16 @@
#include "sw/device/silicon_creator/lib/cert/cert.h"

#include "sw/device/lib/base/hardened.h"
#include "sw/device/silicon_creator/lib/base/util.h"
#include "sw/device/silicon_creator/lib/cert/asn1.h"
#include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
#include "sw/device/silicon_creator/lib/drivers/hmac.h"
#include "sw/device/silicon_creator/lib/drivers/keymgr.h"
#include "sw/device/silicon_creator/lib/error.h"
#include "sw/device/silicon_creator/lib/otbn_boot_services.h"
#include "sw/device/silicon_creator/lib/sigverify/ecdsa_p256_key.h"

#include "flash_ctrl_regs.h" // Generated.

static uint8_t actual_serial_number[kCertX509Asn1SerialNumberSizeInBytes] = {0};

/**
* Helper function to convert an attestation public key from little to big
* endian in place.
*/
static void curr_pubkey_le_to_be_convert(ecdsa_p256_public_key_t *pubkey) {
util_reverse_bytes(pubkey->x, kEcdsaP256PublicKeyCoordBytes);
util_reverse_bytes(pubkey->y, kEcdsaP256PublicKeyCoordBytes);
}

rom_error_t cert_ecc_p256_keygen(sc_keymgr_ecc_key_t key,
hmac_digest_t *pubkey_id,
ecdsa_p256_public_key_t *pubkey) {
HARDENED_RETURN_IF_ERROR(sc_keymgr_state_check(key.required_keymgr_state));

// Generate / sideload key material into OTBN, and generate the ECC keypair.
HARDENED_RETURN_IF_ERROR(otbn_boot_attestation_keygen(
key.keygen_seed_idx, key.type, *key.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.
//
// Note: the certificate generation functions expect the digest to be in big
// endian form, but the HMAC driver returns the digest in little endian, so we
// re-format it.
hmac_sha256(pubkey, sizeof(*pubkey), pubkey_id);
util_reverse_bytes(pubkey_id, sizeof(*pubkey_id));

return kErrorOk;
}

uint32_t cert_x509_asn1_decode_size_header(const uint8_t *header) {
if (header[0] != 0x30 || header[1] != 0x82) {
return 0;
Expand Down
17 changes: 0 additions & 17 deletions sw/device/silicon_creator/lib/cert/cert.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,6 @@ typedef struct cert_key_id_pair {
hmac_digest_t *cert;
} cert_key_id_pair_t;

/**
* Generates an ECC P256 keypair to build a certificate around, using Keymgr
* and OTBN, 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 key The description of the desired key to generate.
* @param[out] pubkey_id The public key ID (for embedding into certificates).
* @param[out] pubkey The public key.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
rom_error_t cert_ecc_p256_keygen(sc_keymgr_ecc_key_t key,
hmac_digest_t *pubkey_id,
ecdsa_p256_public_key_t *pubkey);

/**
* Decodes the ASN1 size header word to extract the number of bytes contained in
* the ASN1 blob.
Expand Down
35 changes: 35 additions & 0 deletions sw/device/silicon_creator/lib/otbn_boot_services.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "sw/device/silicon_creator/lib/attestation.h"
#include "sw/device/silicon_creator/lib/base/sec_mmio.h"
#include "sw/device/silicon_creator/lib/base/util.h"
#include "sw/device/silicon_creator/lib/dbg_print.h"
#include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
#include "sw/device/silicon_creator/lib/drivers/hmac.h"
Expand Down Expand Up @@ -154,6 +155,40 @@ rom_error_t otbn_boot_attestation_keygen(
return kErrorOk;
}

/**
* Helper function to convert an ECC P256 public key from little to big endian
* in place.
*/
static void pubkey_le_to_be_convert(ecdsa_p256_public_key_t *pubkey) {
util_reverse_bytes(pubkey->x, kEcdsaP256PublicKeyCoordBytes);
util_reverse_bytes(pubkey->y, kEcdsaP256PublicKeyCoordBytes);
}

rom_error_t otbn_boot_cert_ecc_p256_keygen(sc_keymgr_ecc_key_t key,
hmac_digest_t *pubkey_id,
ecdsa_p256_public_key_t *pubkey) {
HARDENED_RETURN_IF_ERROR(sc_keymgr_state_check(key.required_keymgr_state));

// Generate / sideload key material into OTBN, and generate the ECC keypair.
HARDENED_RETURN_IF_ERROR(otbn_boot_attestation_keygen(
key.keygen_seed_idx, key.type, *key.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.
pubkey_le_to_be_convert(pubkey);

// Generate the key ID.
//
// Note: the certificate generation functions expect the digest to be in big
// endian form, but the HMAC driver returns the digest in little endian, so we
// re-format it.
hmac_sha256(pubkey, sizeof(*pubkey), pubkey_id);
util_reverse_bytes(pubkey_id, sizeof(*pubkey_id));

return kErrorOk;
}

rom_error_t otbn_boot_attestation_key_save(
uint32_t additional_seed_idx, sc_keymgr_key_type_t key_type,
sc_keymgr_diversification_t diversification) {
Expand Down
29 changes: 28 additions & 1 deletion sw/device/silicon_creator/lib/otbn_boot_services.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,17 @@ rom_error_t otbn_boot_attestation_keygen(
uint32_t additional_seed_idx, sc_keymgr_key_type_t key_type,
sc_keymgr_diversification_t diversification,
ecdsa_p256_public_key_t *public_key);

/**
* Generate an attestation public key from a keymgr-derived secret.
* Generate a deterministic ECC P256 attestation public key from a
* keymgr-derived secret.
*
* This routine may be used to generate DICE attestation keys, TPM identity
* keys, or any other deterministic asymmetric ECC P256 keys required. DICE keys
* should be contructed from the "attestation" keymgr key type, while TPM keys
* should be constructed form the "sealing" key type. The former are bound to
* firmware updates, and change when ROM_EXT or Owner firmware is updated. The
* latter remain stable across the lifetime of an ownership of the chip.
*
* This routine triggers the key manager to sideload key material into OTBN,
* and also loads in an extra seed to XOR with the key material. The final
Expand Down Expand Up @@ -91,6 +100,24 @@ rom_error_t otbn_boot_attestation_keygen(
sc_keymgr_diversification_t diversification,
ecdsa_p256_public_key_t *public_key);

/**
* Wrapper for `otbn_boot_attestation_keygen()` that generates an ECC P256
* keypair to build a certificate around, using Keymgr and OTBN, returning the
* public key (in big endian order for inserting into a cert) 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 key The description of the desired key to generate.
* @param[out] pubkey_id The public key ID (for embedding into certificates).
* @param[out] pubkey The public key.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
rom_error_t otbn_boot_cert_ecc_p256_keygen(sc_keymgr_ecc_key_t key,
hmac_digest_t *pubkey_id,
ecdsa_p256_public_key_t *pubkey);

/**
* Saves an attestation private key to OTBN's scratchpad.
*
Expand Down
1 change: 1 addition & 0 deletions sw/device/silicon_creator/manuf/base/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ cc_library(
"//sw/device/lib/testing/test_framework:status",
"//sw/device/lib/testing/test_framework:ujson_ottf",
"//sw/device/silicon_creator/lib:attestation",
"//sw/device/silicon_creator/lib:otbn_boot_services",
"//sw/device/silicon_creator/lib/cert",
"//sw/device/silicon_creator/lib/cert:tpm",
"//sw/device/silicon_creator/lib/cert:tpm_ek_template_library",
Expand Down
9 changes: 6 additions & 3 deletions sw/device/silicon_creator/manuf/base/ft_personalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,8 @@ static status_t personalize_gen_dice_certificates(ujson_t *uj) {

// Generate UDS keys and (TBS) cert.
curr_cert_size = kUdsMaxTbsSizeBytes;
TRY(cert_ecc_p256_keygen(kDiceKeyUds, &uds_pubkey_id, &curr_pubkey));
TRY(otbn_boot_cert_ecc_p256_keygen(kDiceKeyUds, &uds_pubkey_id,
&curr_pubkey));
TRY(otbn_boot_attestation_key_save(kDiceKeyUds.keygen_seed_idx,
kDiceKeyUds.type,
*kDiceKeyUds.keymgr_diversifier));
Expand All @@ -378,7 +379,8 @@ static status_t personalize_gen_dice_certificates(ujson_t *uj) {
TRY(sc_keymgr_owner_int_advance(&sealing_binding_value,
&attestation_binding_value,
/*max_key_version=*/0));
TRY(cert_ecc_p256_keygen(kDiceKeyCdi0, &cdi_0_pubkey_id, &curr_pubkey));
TRY(otbn_boot_cert_ecc_p256_keygen(kDiceKeyCdi0, &cdi_0_pubkey_id,
&curr_pubkey));
TRY(dice_cdi_0_cert_build((hmac_digest_t *)certgen_inputs.rom_ext_measurement,
certgen_inputs.rom_ext_security_version,
&cdi_0_key_ids, &curr_pubkey, all_certs,
Expand All @@ -393,7 +395,8 @@ static status_t personalize_gen_dice_certificates(ujson_t *uj) {
TRY(sc_keymgr_owner_advance(&sealing_binding_value,
&attestation_binding_value,
/*max_key_version=*/0));
TRY(cert_ecc_p256_keygen(kDiceKeyCdi1, &cdi_1_pubkey_id, &curr_pubkey));
TRY(otbn_boot_cert_ecc_p256_keygen(kDiceKeyCdi1, &cdi_1_pubkey_id,
&curr_pubkey));
TRY(dice_cdi_1_cert_build(
(hmac_digest_t *)certgen_inputs.owner_measurement,
(hmac_digest_t *)certgen_inputs.owner_manifest_measurement,
Expand Down
3 changes: 2 additions & 1 deletion sw/device/silicon_creator/manuf/base/tpm_personalize_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "sw/device/silicon_creator/lib/cert/tpm_ek.h" // Generated.
#include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
#include "sw/device/silicon_creator/lib/drivers/hmac.h"
#include "sw/device/silicon_creator/lib/otbn_boot_services.h"
#include "sw/device/silicon_creator/manuf/base/personalize_ext.h"
#include "sw/device/silicon_creator/manuf/lib/personalize.h"

Expand Down Expand Up @@ -82,7 +83,7 @@ static status_t personalize_gen_tpm_ek_certificate(
kAttestationSeedWords));

// Generate TPM EK keys and (TBS) cert.
TRY(cert_ecc_p256_keygen(kTpmKeyEk, &tpm_pubkey_id, &curr_pubkey));
TRY(otbn_boot_cert_ecc_p256_keygen(kTpmKeyEk, &tpm_pubkey_id, &curr_pubkey));

curr_cert_size = sizeof(cert_buffer);
TRY(tpm_ek_tbs_cert_build(&tpm_key_ids, &curr_pubkey, cert_buffer,
Expand Down
12 changes: 6 additions & 6 deletions sw/device/silicon_creator/rom_ext/rom_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ static rom_error_t rom_ext_attestation_silicon(void) {

// Generate UDS keys.
sc_keymgr_advance_state();
HARDENED_RETURN_IF_ERROR(cert_ecc_p256_keygen(kDiceKeyUds, &uds_pubkey_id,
&curr_attestation_pubkey));
HARDENED_RETURN_IF_ERROR(otbn_boot_cert_ecc_p256_keygen(
kDiceKeyUds, &uds_pubkey_id, &curr_attestation_pubkey));
HARDENED_RETURN_IF_ERROR(otbn_boot_attestation_key_save(
kDiceKeyUds.keygen_seed_idx, kDiceKeyUds.type,
*kDiceKeyUds.keymgr_diversifier));
Expand Down Expand Up @@ -396,8 +396,8 @@ static rom_error_t rom_ext_attestation_creator(
sc_keymgr_owner_int_advance(/*sealing_binding=*/&seal_binding_value,
/*attest_binding=*/&boot_measurements.rom_ext,
rom_ext_manifest->max_key_version));
HARDENED_RETURN_IF_ERROR(cert_ecc_p256_keygen(kDiceKeyCdi0, &cdi_0_pubkey_id,
&curr_attestation_pubkey));
HARDENED_RETURN_IF_ERROR(otbn_boot_cert_ecc_p256_keygen(
kDiceKeyCdi0, &cdi_0_pubkey_id, &curr_attestation_pubkey));
hardened_bool_t cert_valid = kHardenedBoolFalse;
uint32_t cert_size = 0;
HARDENED_RETURN_IF_ERROR(cert_x509_asn1_check_serial_number(
Expand Down Expand Up @@ -438,8 +438,8 @@ static rom_error_t rom_ext_attestation_owner(const manifest_t *owner_manifest) {
sc_keymgr_owner_advance(/*sealing_binding=*/&zero_binding_value,
/*attest_binding=*/&boot_measurements.bl0,
owner_manifest->max_key_version));
HARDENED_RETURN_IF_ERROR(cert_ecc_p256_keygen(kDiceKeyCdi1, &cdi_1_pubkey_id,
&curr_attestation_pubkey));
HARDENED_RETURN_IF_ERROR(otbn_boot_cert_ecc_p256_keygen(
kDiceKeyCdi1, &cdi_1_pubkey_id, &curr_attestation_pubkey));
hardened_bool_t cert_valid = kHardenedBoolFalse;
uint32_t cert_size = 0;
HARDENED_RETURN_IF_ERROR(cert_x509_asn1_check_serial_number(
Expand Down

0 comments on commit c90a625

Please sign in to comment.