Skip to content

Commit d0405da

Browse files
committed
[ot] hw/opentitan: ot_lc_ctrl: Fix HW_CFG load memcpy size calculation
These `memcpy`s were accidentally using the size of the dereferenced byte array (i.e., always just 1 byte), and so were only copying the first byte of the HW_CFG device ID and manufacturing state that were being loaded from the OTP. Also add some local calculations and static assertions to check that the HW_CFG value sizes that are given do not become out of sync with the size of the registers. Signed-off-by: Alex Jones <alex.jones@lowrisc.org>
1 parent 7b28086 commit d0405da

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

hw/opentitan/ot_lc_ctrl.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,15 @@ REG32(MANUF_STATE_7, 0x88u)
146146
#define LC_TOKEN_WIDTH 16u /* 128 bits */
147147
#define LC_TOKEN_DWORDS (LC_TOKEN_WIDTH / sizeof(uint64_t))
148148

149+
#define LC_LAST_DEV_ID_REG (R_DEVICE_ID_7)
150+
#define LC_DEV_ID_REGS_COUNT (LC_LAST_DEV_ID_REG - R_DEVICE_ID_0 + 1u)
151+
#define LC_DEV_ID_WIDTH (LC_DEV_ID_REGS_COUNT * sizeof(uint32_t))
152+
153+
#define LC_LAST_MANUF_STATE_REG (R_MANUF_STATE_7)
154+
#define LC_MANUF_STATE_REG_COUNT \
155+
(LC_LAST_MANUF_STATE_REG - R_MANUF_STATE_0 + 1u)
156+
#define LC_MANUF_STATE_WIDTH (LC_MANUF_STATE_REG_COUNT * sizeof(uint32_t))
157+
149158
#define REG_NAME_ENTRY(_reg_) [R_##_reg_] = stringify(_reg_)
150159
static const char *REG_NAMES[REGS_COUNT] = {
151160
REG_NAME_ENTRY(ALERT_TEST),
@@ -435,7 +444,11 @@ typedef struct {
435444
} OtLcCtrlTransitionDesc;
436445

437446
static_assert(sizeof(OtOTPTokenValue) == LC_TOKEN_WIDTH,
438-
"Unexpected LC TOLEN WIDTH");
447+
"Unexpected LC Token width");
448+
static_assert(OT_OTP_HWCFG_DEVICE_ID_BYTES == LC_DEV_ID_WIDTH,
449+
"Unexpected LC Device ID width");
450+
static_assert(OT_OTP_HWCFG_MANUF_STATE_BYTES == LC_MANUF_STATE_WIDTH,
451+
"Unexpected LC Manufacturing State width");
439452

440453
#define KECCAK_STATE_BITS 1600u
441454
#define KECCAK_STATE_BYTES (KECCAK_STATE_BITS / 8u)
@@ -1211,10 +1224,14 @@ static void ot_lc_ctrl_load_otp_hw_cfg(OtLcCtrlState *s)
12111224
OtOTPClass *oc = OBJECT_GET_CLASS(OtOTPClass, s->otp_ctrl, TYPE_OT_OTP);
12121225
const OtOTPHWCfg *hw_cfg = oc->get_hw_cfg(s->otp_ctrl);
12131226

1214-
memcpy(&s->regs[R_DEVICE_ID_0], &hw_cfg->device_id[0],
1215-
sizeof(*hw_cfg->device_id));
1227+
static_assert(sizeof(hw_cfg->device_id) == LC_DEV_ID_WIDTH,
1228+
"HW_CFG Device ID size does not match size in registers");
1229+
memcpy(&s->regs[R_DEVICE_ID_0], &hw_cfg->device_id[0], LC_DEV_ID_WIDTH);
1230+
1231+
static_assert(sizeof(hw_cfg->manuf_state) == LC_MANUF_STATE_WIDTH,
1232+
"HW_CFG Manuf State size does not match size in reigsters");
12161233
memcpy(&s->regs[R_MANUF_STATE_0], &hw_cfg->manuf_state[0],
1217-
sizeof(*hw_cfg->manuf_state));
1234+
LC_MANUF_STATE_WIDTH);
12181235

12191236
if (!s->socdbg) {
12201237
return;

0 commit comments

Comments
 (0)