Skip to content

Commit 3209ace

Browse files
committed
[ot] hw/opentitan: ot_otp: rework key management
- use Top defined constants - simplify stack of macro calls - remove definitions from ot_otp_engine.h Signed-off-by: Emmanuel Blot <[email protected]>
1 parent e24e611 commit 3209ace

File tree

5 files changed

+136
-111
lines changed

5 files changed

+136
-111
lines changed

hw/opentitan/ot_otp_dj.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#define NUM_PART 22u
4343
#define NUM_PART_BUF 7u
4444
#define NUM_PART_UNBUF 15u
45+
#define NUM_SRAM_KEY_REQ_SLOTS 4u
4546
#define NUM_SW_CFG_WINDOW_WORDS 4096u
4647

4748
#define OTP_BYTE_ADDR_WIDTH 14u
@@ -407,9 +408,6 @@ REG32(LC_STATE, 16344u)
407408
#define REG_NAME(_reg_) \
408409
((((_reg_) <= REGS_COUNT) && REG_NAMES[_reg_]) ? REG_NAMES[_reg_] : "?")
409410

410-
static_assert(SRAM_KEY_SEED_WIDTH == SECRET1_SRAM_DATA_KEY_SEED_SIZE * 8u,
411-
"SRAM key seed size does not match OTP field size");
412-
413411
typedef enum {
414412
OTP_PART_VENDOR_TEST,
415413
OTP_PART_CREATOR_SW_CFG,
@@ -1294,8 +1292,13 @@ static void ot_otp_dj_class_init(ObjectClass *klass, void *data)
12941292
ic->part_descs = OT_OTP_PART_DESCS;
12951293
ic->part_count = (unsigned)OTP_PART_COUNT;
12961294
ic->part_lc_num = (unsigned)OTP_PART_LIFE_CYCLE;
1295+
ic->sram_key_req_slot_count = NUM_SRAM_KEY_REQ_SLOTS;
1296+
12971297
ic->key_seeds = OT_OTP_KEY_SEEDS;
12981298
ic->has_flash_support = false;
1299+
1300+
g_assert(OT_OTP_KEY_SEEDS[OTP_KEY_SRAM].size ==
1301+
SECRET1_SRAM_DATA_KEY_SEED_SIZE);
12991302
}
13001303

13011304
static const TypeInfo ot_otp_dj_info = {

hw/opentitan/ot_otp_eg.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#define NUM_PART 11u
4141
#define NUM_PART_BUF 6u
4242
#define NUM_PART_UNBUF 5u
43+
#define NUM_SRAM_KEY_REQ_SLOTS 4u
4344
#define NUM_SW_CFG_WINDOW_WORDS 512u
4445

4546
#define OTP_BYTE_ADDR_WIDTH 11u
@@ -356,13 +357,6 @@ REG32(LC_STATE, 2008u)
356357
#define REG_NAME(_reg_) \
357358
((((_reg_) <= REGS_COUNT) && REG_NAMES[_reg_]) ? REG_NAMES[_reg_] : "?")
358359

359-
static_assert(FLASH_KEY_SEED_WIDTH == SECRET1_FLASH_ADDR_KEY_SEED_SIZE * 8u,
360-
"Flash key seed size does not match flash address field size");
361-
static_assert(FLASH_KEY_SEED_WIDTH == SECRET1_FLASH_DATA_KEY_SEED_SIZE * 8u,
362-
"Flash key seed size does not match flash data field size");
363-
static_assert(SRAM_KEY_SEED_WIDTH == SECRET1_SRAM_DATA_KEY_SEED_SIZE * 8u,
364-
"SRAM key seed size does not match OTP field size");
365-
366360
typedef enum {
367361
OTP_PART_VENDOR_TEST,
368362
OTP_PART_CREATOR_SW_CFG,
@@ -1177,8 +1171,17 @@ static void ot_otp_eg_class_init(ObjectClass *klass, void *data)
11771171
ic->part_descs = OT_OTP_PART_DESCS;
11781172
ic->part_count = (unsigned)OTP_PART_COUNT;
11791173
ic->part_lc_num = (unsigned)OTP_PART_LIFE_CYCLE;
1174+
ic->sram_key_req_slot_count = NUM_SRAM_KEY_REQ_SLOTS;
1175+
11801176
ic->key_seeds = OT_OTP_KEY_SEEDS;
11811177
ic->has_flash_support = true;
1178+
1179+
g_assert(OT_OTP_KEY_SEEDS[OTP_KEY_FLASH_ADDR].size ==
1180+
SECRET1_FLASH_ADDR_KEY_SEED_SIZE);
1181+
g_assert(OT_OTP_KEY_SEEDS[OTP_KEY_FLASH_DATA].size ==
1182+
SECRET1_FLASH_DATA_KEY_SEED_SIZE);
1183+
g_assert(OT_OTP_KEY_SEEDS[OTP_KEY_SRAM].size ==
1184+
SECRET1_SRAM_DATA_KEY_SEED_SIZE);
11821185
}
11831186

11841187
static const TypeInfo ot_otp_eg_info = {

hw/opentitan/ot_otp_engine.c

Lines changed: 109 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,41 @@
3232
#include "qemu/bswap.h"
3333
#include "qemu/log.h"
3434
#include "qapi/error.h"
35-
#include "hw/opentitan/ot_fifo32.h"
3635
#include "hw/opentitan/ot_alert.h"
36+
#include "hw/opentitan/ot_fifo32.h"
3737
#include "hw/opentitan/ot_lc_ctrl.h"
3838
#include "hw/opentitan/ot_otp_impl_if.h"
39-
#include "hw/opentitan/ot_pwrmgr.h"
4039
#include "hw/opentitan/ot_present.h"
41-
#include "hw/qdev-properties-system.h"
4240
#include "hw/opentitan/ot_prng.h"
41+
#include "hw/opentitan/ot_pwrmgr.h"
42+
#include "hw/qdev-properties-system.h"
4343
#include "hw/qdev-properties.h"
4444
#include "ot_otp_engine.h"
4545
#include "sysemu/block-backend.h"
4646
#include "trace.h"
4747

48+
/*
49+
* The OTP may be used before any CPU is started, This may cause the default
50+
* virtual clock to stall, as the hart does not execute. OTP nevertheless may
51+
* be active, updating the OTP content where write delays are still needed.
52+
* Use the alternative clock source which counts even when the CPU is stalled.
53+
*/
54+
#define OT_OTP_HW_CLOCK QEMU_CLOCK_VIRTUAL_RT
55+
56+
/* the following delays are arbitrary for now */
57+
#define DAI_DIGEST_DELAY_NS 50000u /* 50us */
58+
#define LCI_PROG_SCHED_NS 1000u /* 1us*/
59+
60+
/* The size of keys used for OTP scrambling */
61+
#define OTP_SCRAMBLING_KEY_WIDTH 128u
62+
#define OTP_SCRAMBLING_KEY_BYTES ((OTP_SCRAMBLING_KEY_WIDTH) / 8u)
63+
64+
#define LC_TRANSITION_CNT_SIZE 48u
65+
#define LC_STATE_SIZE 40u
66+
67+
/* Sizes of constants used for deriving scrambling keys */
68+
#define KEY_MGR_KEY_WIDTH 256u
69+
4870
static const char *DAI_STATE_NAMES[] = {
4971
/* clang-format off */
5072
OTP_NAME_ENTRY(OTP_DAI_RESET),
@@ -124,6 +146,25 @@ static const char *ERR_CODE_NAMES[] = {
124146
#define ERR_CODE_PART_REG(_s_, _pix_) \
125147
((_s_)->regs[(_s_)->reg_offset.err_code_base + (_pix_)])
126148

149+
#define SRAM_KEY_BYTES(_ic_) ((_ic_)->key_seeds[OTP_KEY_SRAM].size)
150+
#define SRAM_NONCE_BYTES(_ic_) ((_ic_)->key_seeds[OTP_KEY_SRAM].size)
151+
#define OTBN_KEY_BYTES(_ic_) ((_ic_)->key_seeds[OTP_KEY_OTBN].size)
152+
#define OTBN_NONCE_BYTES(_ic_) (((_ic_)->key_seeds[OTP_KEY_OTBN].size) / 2u)
153+
154+
#define OT_OTP_SCRMBL_KEY_SIZE 16u
155+
#define OT_OTP_SCRMBL_NONE_SIZE (OT_OTP_SCRMBL_KEY_SIZE)
156+
157+
/* Need 128 bits of entropy to compute each 64-bit key part */
158+
#define OTP_ENTROPY_PRESENT_BYTES(_ic_) \
159+
(((((_ic_)->sram_key_req_slot_count) * SRAM_KEY_BYTES(_ic_)) + \
160+
(OTBN_KEY_BYTES(_ic_))) * \
161+
2u)
162+
#define OTP_ENTROPY_NONCE_BYTES(_ic_) \
163+
(((_ic_)->sram_key_req_slot_count) * SRAM_NONCE_BYTES(_ic_) + \
164+
OTBN_NONCE_BYTES(_ic_))
165+
#define OTP_ENTROPY_BUF_COUNT(_ic_) \
166+
((OTP_ENTROPY_PRESENT_BYTES(_ic_) + OTP_ENTROPY_NONCE_BYTES(_ic_)) / 4u)
167+
127168
#ifdef OT_OTP_DEBUG
128169
#define OT_OTP_HEXSTR_SIZE 256u
129170
#define TRACE_OTP(msg, ...) qemu_log("%s: " msg "\n", __func__, ##__VA_ARGS__);
@@ -146,6 +187,19 @@ static void ot_otp_engine_dai_change_state_line(OtOTPEngineState *s,
146187
static void ot_otp_engine_lci_change_state_line(OtOTPEngineState *s,
147188
OtOTPLCIState state, int line);
148189

190+
struct OtOTPScrmblKeyInit_ {
191+
uint8_t key[OT_OTP_SCRMBL_KEY_SIZE];
192+
uint8_t nonce[OT_OTP_SCRMBL_NONE_SIZE];
193+
};
194+
195+
struct OtOTPKeyGen_ {
196+
QEMUBH *entropy_bh;
197+
OtPresentState *present;
198+
OtPrngState *prng;
199+
OtFifo32 entropy_buf;
200+
bool edn_sched;
201+
};
202+
149203
static void ot_otp_engine_update_irqs(OtOTPEngineState *s)
150204
{
151205
uint32_t levels = s->regs[R_INTR_STATE] & s->regs[R_INTR_ENABLE];
@@ -1762,54 +1816,67 @@ static void ot_otp_engine_get_otp_key(OtOTPIf *dev, OtOTPKeyType type,
17621816
trace_ot_otp_get_otp_key(s->ot_id, type);
17631817

17641818
/* reference: req_bundles in OpenTitan rtl/otp_ctrl_kdi.sv */
1819+
const uint64_t *iv;
1820+
const uint8_t *constant;
1821+
bool ingest_entropy;
17651822
switch (type) {
17661823
case OTP_KEY_FLASH_DATA:
17671824
if (!ic->has_flash_support) {
1825+
iv = NULL;
17681826
break;
17691827
}
1770-
memcpy(key->seed, s->scrmbl_key_init->key, FLASH_KEY_BYTES);
1771-
memcpy(key->nonce, s->scrmbl_key_init->nonce, FLASH_NONCE_BYTES);
1772-
key->seed_size = FLASH_KEY_BYTES;
1773-
key->nonce_size = FLASH_NONCE_BYTES;
1774-
key->seed_valid = false;
1775-
ot_otp_engine_generate_scrambling_key(s, key, type, s->flash_data_iv,
1776-
s->flash_data_const, true, false);
1828+
key->seed_size = (uint8_t)ic->key_seeds[type].size;
1829+
key->nonce_size = key->seed_size;
1830+
iv = &s->flash_data_iv;
1831+
constant = s->flash_data_const;
1832+
ingest_entropy = false;
17771833
return;
17781834
case OTP_KEY_FLASH_ADDR:
17791835
if (!ic->has_flash_support) {
1836+
iv = NULL;
17801837
break;
17811838
}
1782-
memcpy(key->seed, s->scrmbl_key_init->key, FLASH_KEY_BYTES);
1783-
key->seed_size = FLASH_KEY_BYTES;
1784-
key->nonce_size = 0u; /* FLASH_ADDR_KEY has nonce_size = 0 */
1785-
key->seed_valid = false;
1786-
ot_otp_engine_generate_scrambling_key(s, key, type, s->flash_addr_iv,
1787-
s->flash_addr_const, true, false);
1839+
key->seed_size = (uint8_t)ic->key_seeds[type].size;
1840+
key->nonce_size = 0u;
1841+
iv = &s->flash_addr_iv;
1842+
constant = s->flash_addr_const;
1843+
ingest_entropy = false;
17881844
return;
17891845
case OTP_KEY_OTBN:
1790-
memcpy(key->seed, s->scrmbl_key_init->key, OTBN_KEY_BYTES);
1791-
memcpy(key->nonce, s->scrmbl_key_init->nonce, OTBN_NONCE_BYTES);
1792-
key->seed_size = OTBN_KEY_BYTES;
1793-
key->nonce_size = OTBN_NONCE_BYTES;
1794-
key->seed_valid = false;
1795-
ot_otp_engine_generate_scrambling_key(s, key, type, s->sram_iv,
1796-
s->sram_const, true, true);
1846+
key->seed_size = (uint8_t)ic->key_seeds[type].size;
1847+
key->nonce_size = key->seed_size / 2u;
1848+
iv = &s->sram_iv;
1849+
constant = s->sram_const;
1850+
ingest_entropy = true;
17971851
return;
17981852
case OTP_KEY_SRAM:
1799-
memcpy(key->seed, s->scrmbl_key_init->key, SRAM_KEY_BYTES);
1800-
memcpy(key->nonce, s->scrmbl_key_init->nonce, SRAM_NONCE_BYTES);
1801-
key->seed_size = SRAM_KEY_BYTES;
1802-
key->nonce_size = SRAM_NONCE_BYTES;
1803-
key->seed_valid = false;
1804-
ot_otp_engine_generate_scrambling_key(s, key, type, s->sram_iv,
1805-
s->sram_const, true, true);
1853+
key->seed_size = (uint8_t)ic->key_seeds[type].size;
1854+
key->nonce_size = key->seed_size;
1855+
iv = &s->sram_iv;
1856+
constant = s->sram_const;
1857+
ingest_entropy = true;
18061858
return;
18071859
default:
1808-
return;
1860+
iv = NULL;
1861+
ingest_entropy = false;
1862+
break;
18091863
}
18101864

1811-
error_report("%s: %s: invalid OTP key type: %d", __func__, s->ot_id, type);
1865+
if (!iv) {
1866+
error_report("%s: %s: invalid OTP key type: %d", __func__, s->ot_id,
1867+
type);
1868+
g_assert_not_reached();
1869+
}
1870+
1871+
g_assert(key->seed_size <= sizeof(s->scrmbl_key_init->key));
1872+
g_assert(key->nonce_size <= sizeof(s->scrmbl_key_init->nonce));
1873+
memcpy(key->seed, s->scrmbl_key_init->key, key->seed_size);
1874+
memcpy(key->nonce, s->scrmbl_key_init->nonce, key->nonce_size);
1875+
key->seed_valid = false;
1876+
ot_otp_engine_generate_scrambling_key(s, key, type, *iv, constant, true,
1877+
ingest_entropy);
18121878
}
1879+
18131880
static bool ot_otp_engine_program_req(OtOTPIf *dev, const uint16_t *lc_tcount,
18141881
const uint16_t *lc_state,
18151882
ot_otp_program_ack_fn ack, void *opaque)
@@ -2221,29 +2288,33 @@ static void ot_otp_engine_pwr_otp_bh(void *opaque)
22212288

22222289
static void ot_otp_engine_configure_scrmbl_key(OtOTPEngineState *s)
22232290
{
2291+
OtOTPImplIfClass *ic = OT_OTP_IMPL_IF_GET_CLASS(s);
2292+
22242293
if (!s->scrmbl_key_xstr) {
22252294
trace_ot_otp_configure_missing(s->ot_id, "scrmbl_key");
22262295
return;
22272296
}
22282297

2298+
size_t sram_key_bytes = SRAM_KEY_BYTES(ic);
2299+
size_t sram_nonce_bytes = SRAM_NONCE_BYTES(ic);
22292300
size_t len = strlen(s->scrmbl_key_xstr);
2230-
if (len != (size_t)(SRAM_KEY_BYTES + SRAM_NONCE_BYTES) * 2u) {
2301+
if (len != (size_t)(sram_key_bytes + sram_nonce_bytes) * 2u) {
22312302
error_setg(&error_fatal, "%s: %s invalid scrmbl_key length\n", __func__,
22322303
s->ot_id);
22332304
return;
22342305
}
22352306

22362307
if (ot_common_parse_hexa_str(s->scrmbl_key_init->key,
2237-
&s->scrmbl_key_xstr[0], SRAM_KEY_BYTES, false,
2308+
&s->scrmbl_key_xstr[0], sram_key_bytes, false,
22382309
false)) {
22392310
error_setg(&error_fatal, "%s: %s unable to parse scrmbl_key\n",
22402311
__func__, s->ot_id);
22412312
return;
22422313
}
22432314

22442315
if (ot_common_parse_hexa_str(s->scrmbl_key_init->nonce,
2245-
&s->scrmbl_key_xstr[SRAM_KEY_BYTES * 2u],
2246-
SRAM_NONCE_BYTES, false, true)) {
2316+
&s->scrmbl_key_xstr[sram_key_bytes * 2u],
2317+
sram_nonce_bytes, false, true)) {
22472318
error_setg(&error_fatal, "%s: %s unable to parse scrmbl_key\n",
22482319
__func__, s->ot_id);
22492320
return;
@@ -2769,6 +2840,7 @@ static void ot_otp_engine_init(Object *obj)
27692840
g_assert(ic->part_descs != NULL);
27702841
g_assert(ic->part_count > 1u);
27712842
g_assert(ic->part_lc_num > 0u && ic->part_lc_num < ic->part_count);
2843+
g_assert(ic->sram_key_req_slot_count > 0u);
27722844

27732845
/*
27742846
* The following members are constant values, and are used very often in
@@ -2805,7 +2877,7 @@ static void ot_otp_engine_init(Object *obj)
28052877
s->lci->data =
28062878
g_new0(uint16_t, s->part_descs[s->part_lc_num].size / sizeof(uint16_t));
28072879

2808-
ot_fifo32_create(&s->keygen->entropy_buf, OTP_ENTROPY_BUF_COUNT);
2880+
ot_fifo32_create(&s->keygen->entropy_buf, OTP_ENTROPY_BUF_COUNT(ic));
28092881
s->keygen->present = ot_present_new();
28102882
s->keygen->prng = ot_prng_allocate();
28112883

0 commit comments

Comments
 (0)