Skip to content

Commit 56b1a5e

Browse files
committed
[ot] hw/opentitan: ot_otp_engine: rework partition "readconfig" properties
- secret_scrambling_keys: the exact number of such properties is created. this avoid allocated useless memory, and ensure QEMU property subsystem may report any attempt to define values for keys that do not exist - secret_scrambling_key and inv_default_data values are now tied to the partition controller, rather than to be allocated as separate arrays Signed-off-by: Emmanuel Blot <[email protected]>
1 parent fd09294 commit 56b1a5e

File tree

4 files changed

+45
-36
lines changed

4 files changed

+45
-36
lines changed

hw/opentitan/ot_otp_dj.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,8 @@ static void ot_otp_dj_get_keymgr_secret(
10731073
data_ptr = (const uint8_t *)s->part_ctrls[part_ix].buffer.data;
10741074
} else {
10751075
/* source data from PartInvDefault instead of real buffer */
1076-
data_ptr = s->inv_default_parts[part_ix];
1076+
OtOTPPartController *pctrl = &s->part_ctrls[part_ix];
1077+
data_ptr = pctrl->inv_default_data;
10771078
}
10781079

10791080
secret->valid = s->part_ctrls[part_ix].digest != 0;

hw/opentitan/ot_otp_eg.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,8 @@ static void ot_otp_eg_get_keymgr_secret(
963963
data_ptr = (const uint8_t *)s->part_ctrls[part_ix].buffer.data;
964964
} else {
965965
/* source data from PartInvDefault instead of real buffer */
966-
data_ptr = s->inv_default_parts[part_ix];
966+
OtOTPPartController *pctrl = &s->part_ctrls[part_ix];
967+
data_ptr = pctrl->inv_default_data;
967968
}
968969

969970
secret->valid = s->part_ctrls[part_ix].digest != 0;

hw/opentitan/ot_otp_engine.c

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -861,11 +861,10 @@ ot_otp_engine_unscramble_partition(OtOTPEngineState *s, unsigned part_ix)
861861
g_assert(pctrl->buffer.data != NULL);
862862
uint64_t *clear = (uint64_t *)pctrl->buffer.data;
863863

864-
const uint8_t *scrambling_key = s->otp_scramble_keys[part_ix];
865-
g_assert(scrambling_key);
864+
g_assert(pctrl->otp_scramble_key);
866865

867866
OtPresentState *ps = ot_present_new();
868-
ot_present_init(ps, scrambling_key);
867+
ot_present_init(ps, pctrl->otp_scramble_key);
869868

870869
trace_ot_otp_unscramble_partition(s->ot_id,
871870
ot_otp_engine_part_name(s, part_ix),
@@ -1130,11 +1129,10 @@ static void ot_otp_engine_dai_read(OtOTPEngineState *s)
11301129
* if the partition is a secret partition, OTP storage is scrambled
11311130
* except the digest and the zeroification fields
11321131
*/
1133-
const uint8_t *scrambling_key = s->otp_scramble_keys[part_ix];
1134-
g_assert(scrambling_key);
1132+
g_assert(pctrl->otp_scramble_key);
11351133
uint64_t tmp_data = ((uint64_t)data_hi << 32u) | data_lo;
11361134
OtPresentState *ps = ot_present_new();
1137-
ot_present_init(ps, scrambling_key);
1135+
ot_present_init(ps, pctrl->otp_scramble_key);
11381136
ot_present_decrypt(ps, tmp_data, &tmp_data);
11391137
ot_present_free(ps);
11401138
data_lo = (uint32_t)tmp_data;
@@ -1179,11 +1177,12 @@ static int ot_otp_engine_dai_write_u64(OtOTPEngineState *s, unsigned address)
11791177
bool is_zer = ot_otp_engine_is_part_zer_offset(s, part_ix, address);
11801178

11811179
if (is_secret && !is_zer) {
1182-
const uint8_t *scrambling_key = s->otp_scramble_keys[part_ix];
1180+
OtOTPPartController *pctrl = &s->part_ctrls[part_ix];
1181+
g_assert(pctrl->otp_scramble_key);
1182+
11831183
uint64_t data = ((uint64_t)hi << 32u) | lo;
1184-
g_assert(scrambling_key);
11851184
OtPresentState *ps = ot_present_new();
1186-
ot_present_init(ps, scrambling_key);
1185+
ot_present_init(ps, pctrl->otp_scramble_key);
11871186
ot_present_encrypt(ps, data, &data);
11881187
lo = (uint32_t)data;
11891188
hi = (uint32_t)(data >> 32u);
@@ -2522,12 +2521,17 @@ static void ot_otp_engine_configure_part_scramble_keys(OtOTPEngineState *s)
25222521
{
25232522
g_assert(s->part_count);
25242523

2524+
unsigned secret_ix = 0;
25252525
for (unsigned part_ix = 0u; part_ix < s->part_count; part_ix++) {
25262526
if (!s->part_descs[part_ix].secret) {
25272527
continue;
25282528
}
25292529

2530-
if (!s->otp_scramble_key_xstrs[part_ix]) {
2530+
/*
2531+
* the property exists, but QEMU only assigns a value when the property
2532+
* is given a value.
2533+
*/
2534+
if (!s->otp_scramble_key_xstrs[secret_ix]) {
25312535
/* if OTP data is loaded, unscrambling keys are mandatory */
25322536
if (s->blk) {
25332537
error_setg(&error_fatal,
@@ -2536,10 +2540,11 @@ static void ot_otp_engine_configure_part_scramble_keys(OtOTPEngineState *s)
25362540
ot_otp_engine_part_name(s, part_ix), part_ix);
25372541
return;
25382542
}
2543+
secret_ix += 1u;
25392544
continue;
25402545
}
25412546

2542-
size_t len = strlen(s->otp_scramble_key_xstrs[part_ix]);
2547+
size_t len = strlen(s->otp_scramble_key_xstrs[secret_ix]);
25432548
if (len != OTP_SCRAMBLING_KEY_BYTES * 2u) {
25442549
error_setg(
25452550
&error_fatal,
@@ -2549,12 +2554,11 @@ static void ot_otp_engine_configure_part_scramble_keys(OtOTPEngineState *s)
25492554
return;
25502555
}
25512556

2552-
g_assert(!s->otp_scramble_keys[part_ix]);
2557+
OtOTPPartController *pctrl = &s->part_ctrls[part_ix];
2558+
pctrl->otp_scramble_key = g_new0(uint8_t, OTP_SCRAMBLING_KEY_BYTES);
25532559

2554-
s->otp_scramble_keys[part_ix] =
2555-
g_new0(uint8_t, OTP_SCRAMBLING_KEY_BYTES);
2556-
if (ot_common_parse_hexa_str(s->otp_scramble_keys[part_ix],
2557-
s->otp_scramble_key_xstrs[part_ix],
2560+
if (ot_common_parse_hexa_str(pctrl->otp_scramble_key,
2561+
s->otp_scramble_key_xstrs[secret_ix],
25582562
OTP_SCRAMBLING_KEY_BYTES, true, true)) {
25592563
error_setg(&error_fatal,
25602564
"%s: %s unable to parse otp_scramble_keys[%u] for %s",
@@ -2565,22 +2569,25 @@ static void ot_otp_engine_configure_part_scramble_keys(OtOTPEngineState *s)
25652569

25662570
TRACE_OTP("otp_scramble_keys[%s] %s",
25672571
ot_otp_engine_part_name(s, part_ix),
2568-
ot_otp_hexdump(s, s->otp_scramble_keys[part_ix],
2572+
ot_otp_hexdump(s, pctrl->otp_scramble_key,
25692573
OTP_SCRAMBLING_KEY_BYTES));
2574+
2575+
secret_ix += 1u;
25702576
}
25712577
}
25722578

25732579
static void ot_otp_engine_add_scramble_key_props(OtOTPEngineState *s)
25742580
{
25752581
g_assert(s->part_count);
25762582

2577-
/*
2578-
* @todo we know the number of secret partitions, so use it rather than
2579-
* whole partition count
2580-
*/
2581-
s->otp_scramble_keys = g_new0(uint8_t *, s->part_count);
2582-
s->otp_scramble_key_xstrs = g_new0(char *, s->part_count);
2583+
unsigned secret_part_count = 0;
2584+
for (unsigned part_ix = 0u; part_ix < s->part_count; part_ix++) {
2585+
if (s->part_descs[part_ix].secret) {
2586+
secret_part_count++;
2587+
}
2588+
}
25832589

2590+
s->otp_scramble_key_xstrs = g_new0(char *, secret_part_count);
25842591
unsigned secret_ix = 0u;
25852592
for (unsigned part_ix = 0u; part_ix < s->part_count; part_ix++) {
25862593
if (!s->part_descs[part_ix].secret) {
@@ -2593,18 +2600,20 @@ static void ot_otp_engine_add_scramble_key_props(OtOTPEngineState *s)
25932600
* Assumes secret partitions are sequentially ordered and named
25942601
* SECRET0, SECRET1, SECRET2, ...
25952602
*/
2596-
prop->name = g_strdup_printf("secret%u_scramble_key", secret_ix++);
2603+
prop->name = g_strdup_printf("secret%u_scramble_key", secret_ix);
25972604
prop->info = &qdev_prop_string;
25982605
/*
25992606
* Property stores the address of the stored string as a relative offset
26002607
* from the parent address
26012608
*/
26022609
prop->offset =
2603-
(intptr_t)&s->otp_scramble_key_xstrs[part_ix] - (intptr_t)s;
2610+
(intptr_t)&s->otp_scramble_key_xstrs[secret_ix] - (intptr_t)s;
26042611

26052612
object_property_add(OBJECT(s), prop->name, prop->info->name,
26062613
prop->info->get, prop->info->set,
26072614
prop->info->release, prop);
2615+
2616+
secret_ix++;
26082617
}
26092618
}
26102619

@@ -2629,10 +2638,9 @@ static void ot_otp_engine_configure_inv_default_parts(OtOTPEngineState *s)
26292638
return;
26302639
}
26312640

2632-
g_assert(!s->inv_default_parts[part_ix]);
2633-
2634-
s->inv_default_parts[part_ix] = g_new0(uint8_t, part->size + 1u);
2635-
if (ot_common_parse_hexa_str(s->inv_default_parts[part_ix],
2641+
OtOTPPartController *pctrl = &s->part_ctrls[part_ix];
2642+
pctrl->inv_default_data = g_new0(uint8_t, part->size + 1u);
2643+
if (ot_common_parse_hexa_str(pctrl->inv_default_data,
26362644
s->inv_default_part_xstrs[part_ix],
26372645
part->size, false, true)) {
26382646
error_setg(&error_fatal,
@@ -2643,15 +2651,14 @@ static void ot_otp_engine_configure_inv_default_parts(OtOTPEngineState *s)
26432651

26442652
TRACE_OTP("inv_default_part[%s] %s",
26452653
ot_otp_engine_part_name(s, part_ix),
2646-
ot_otp_hexdump(s, s->inv_default_parts[part_ix], part->size));
2654+
ot_otp_hexdump(s, pctrl->inv_default_data, part->size));
26472655
}
26482656
}
26492657

26502658
static void ot_otp_engine_add_inv_def_props(OtOTPEngineState *s)
26512659
{
26522660
g_assert(s->part_count);
26532661

2654-
s->inv_default_parts = g_new0(uint8_t *, s->part_count);
26552662
s->inv_default_part_xstrs = g_new0(char *, s->part_count);
26562663

26572664
for (unsigned part_ix = 0; part_ix < s->part_count; part_ix++) {

include/hw/opentitan/ot_otp_engine.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ typedef struct {
156156
bool failed;
157157
bool read_lock;
158158
bool write_lock;
159+
/* OTP scrambling key constant, not constant for deriving other keys */
160+
uint8_t *otp_scramble_key; /* may be NULL */
161+
uint8_t *inv_default_data; /* may be NULL */
159162
} OtOTPPartController;
160163

161164
typedef struct OtOTPDAIController {
@@ -236,9 +239,6 @@ struct OtOTPEngineState {
236239
uint8_t flash_data_const[16u];
237240
uint64_t flash_addr_iv;
238241
uint8_t flash_addr_const[16u];
239-
/* OTP scrambling key constants, not constants for deriving other keys */
240-
uint8_t **otp_scramble_keys; /* some entries may be NULL */
241-
uint8_t **inv_default_parts; /* some entries may be NULL */
242242

243243
OtOTPStorage *otp;
244244
OtOTPHWCfg *hw_cfg;

0 commit comments

Comments
 (0)