Skip to content

Commit f2dd196

Browse files
AlexJones0luismarques
authored andcommitted
[ot] hw/opentitan: ot_otp_eg: Load OTP scrambling keys
Load the OTP scrambling keys from hex-string configured properties. These keys are used for decoding the scrambled data stored in secret partitions (`SECRET0`, `SECRET1`, etc.) Signed-off-by: Alex Jones <[email protected]>
1 parent 508a0ea commit f2dd196

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

hw/opentitan/ot_otp_eg.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,11 @@ REG32(LC_STATE, 2008u)
418418
#define DAI_DIGEST_DELAY_NS 50000u /* 50us */
419419
#define LCI_PROG_SCHED_NS 1000u /* 1us*/
420420

421+
/* The size of keys used for OTP scrambling */
422+
#define OTP_SCRAMBLING_KEY_WIDTH 128u
423+
#define OTP_SCRAMBLING_KEY_BYTES ((OTP_SCRAMBLING_KEY_WIDTH) / 8u)
424+
425+
/* Sizes of constants used for deriving scrambling keys (e.g. flash, SRAM) */
421426
#define FLASH_KEY_SEED_WIDTH 256u
422427
#define SRAM_KEY_SEED_WIDTH 128u
423428
#define KEY_MGR_KEY_WIDTH 256u
@@ -682,6 +687,8 @@ struct OtOTPEgState {
682687
uint8_t flash_data_const[16u];
683688
uint64_t flash_addr_iv;
684689
uint8_t flash_addr_const[16u];
690+
/* OTP scrambling key constants, not constants for deriving other keys */
691+
uint8_t *otp_scramble_keys[ARRAY_SIZE(OtOTPPartDescs)]; /* may be NULL */
685692
uint8_t *inv_default_parts[ARRAY_SIZE(OtOTPPartDescs)]; /* may be NULL */
686693

687694
OtOTPStorage *otp;
@@ -703,6 +710,7 @@ struct OtOTPEgState {
703710
char *flash_data_const_xstr;
704711
char *flash_addr_iv_xstr;
705712
char *flash_addr_const_xstr;
713+
char *otp_scramble_key_xstrs[ARRAY_SIZE(OtOTPPartDescs)]; /* may be NULL */
706714
char *inv_default_part_xstrs[ARRAY_SIZE(OtOTPPartDescs)]; /* may be NULL */
707715
uint8_t edn_ep;
708716
bool fatal_escalate;
@@ -3724,6 +3732,65 @@ static void ot_otp_eg_configure_sram(OtOTPEgState *s)
37243732
s->sram_iv = ldq_le_p(sram_iv);
37253733
}
37263734

3735+
static void ot_otp_eg_configure_part_scramble_keys(OtOTPEgState *s)
3736+
{
3737+
for (unsigned ix = 0u; ix < ARRAY_SIZE(OtOTPPartDescs); ix++) {
3738+
if (!s->otp_scramble_key_xstrs[ix]) {
3739+
continue;
3740+
}
3741+
3742+
size_t len = strlen(s->otp_scramble_key_xstrs[ix]);
3743+
if (len != OTP_SCRAMBLING_KEY_BYTES * 2u) {
3744+
error_setg(
3745+
&error_fatal,
3746+
"%s: %s Invalid OTP scrambling key length %zu for partition %u",
3747+
__func__, s->ot_id, len, ix);
3748+
return;
3749+
}
3750+
3751+
g_assert(!s->otp_scramble_keys[ix]);
3752+
3753+
s->otp_scramble_keys[ix] = g_new0(uint8_t, OTP_SCRAMBLING_KEY_BYTES);
3754+
if (ot_common_parse_hexa_str(s->otp_scramble_keys[ix],
3755+
s->otp_scramble_key_xstrs[ix],
3756+
OTP_SCRAMBLING_KEY_BYTES, true, true)) {
3757+
error_setg(&error_fatal,
3758+
"%s: %s unable to parse otp_scramble_keys[%u]", __func__,
3759+
s->ot_id, ix);
3760+
return;
3761+
}
3762+
3763+
TRACE_OTP("otp_scramble_keys[%s] %s", PART_NAME(ix),
3764+
ot_otp_hexdump(s, s->otp_scramble_keys[ix],
3765+
OTP_SCRAMBLING_KEY_BYTES));
3766+
}
3767+
}
3768+
3769+
static void ot_otp_eg_class_add_scramble_key_props(OtOTPClass *odc)
3770+
{
3771+
unsigned secret_ix = 0u;
3772+
for (unsigned ix = 0u; ix < ARRAY_SIZE(OtOTPPartDescs); ix++) {
3773+
if (!OtOTPPartDescs[ix].secret) {
3774+
continue;
3775+
}
3776+
3777+
Property *prop = g_new0(Property, 1u);
3778+
3779+
/*
3780+
* Assumes secret partitions are sequentially ordered and named
3781+
* SECRET0, SECRET1, SECRET2, etc.
3782+
*/
3783+
prop->name = g_strdup_printf("secret%u_scramble_key", secret_ix++);
3784+
prop->info = &qdev_prop_string;
3785+
prop->offset = offsetof(OtOTPEgState, otp_scramble_key_xstrs) +
3786+
sizeof(char *) * ix;
3787+
3788+
object_class_property_add(OBJECT_CLASS(odc), prop->name,
3789+
prop->info->name, prop->info->get,
3790+
prop->info->set, prop->info->release, prop);
3791+
}
3792+
}
3793+
37273794
static void ot_otp_eg_configure_inv_default_parts(OtOTPEgState *s)
37283795
{
37293796
for (unsigned ix = 0; ix < ARRAY_SIZE(OtOTPPartDescs); ix++) {
@@ -3943,6 +4010,7 @@ static void ot_otp_eg_realize(DeviceState *dev, Error **errp)
39434010
ot_otp_eg_configure_digest(s);
39444011
ot_otp_eg_configure_sram(s);
39454012
ot_otp_eg_configure_flash(s);
4013+
ot_otp_eg_configure_part_scramble_keys(s);
39464014
ot_otp_eg_configure_inv_default_parts(s);
39474015
}
39484016

@@ -4050,6 +4118,7 @@ static void ot_otp_eg_class_init(ObjectClass *klass, void *data)
40504118
oc->get_keymgr_secret = &ot_otp_eg_get_keymgr_secret;
40514119
oc->program_req = &ot_otp_eg_program_req;
40524120

4121+
ot_otp_eg_class_add_scramble_key_props(oc);
40534122
ot_otp_eg_class_add_inv_def_props(oc);
40544123
}
40554124

0 commit comments

Comments
 (0)