Skip to content

Commit e7c4c54

Browse files
committed
core: rpmb: select the provisioning target by CID
When several RPMB-capable devices are present, key provisioning must not land on an arbitrary one: writing the key to the wrong device is hard to undo and leaves the intended device unprovisioned. CFG_RPMB_WRITE_KEY_CID lets a controlled (factory) setup pin provisioning to a known device so the outcome is deterministic. Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez@oss.qualcomm.com>
1 parent f6cae9a commit e7c4c54

2 files changed

Lines changed: 35 additions & 2 deletions

File tree

core/tee/tee_rpmb_fs.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,28 @@ static TEE_Result rpmb_set_dev_info(const struct rpmb_dev_info *dev_info)
11861186
return TEE_SUCCESS;
11871187
}
11881188

1189+
#ifdef CFG_RPMB_WRITE_KEY_CID
1190+
static bool rpmb_cid_match(const uint8_t *cid)
1191+
{
1192+
char *hs = (char *)TO_STR(CFG_RPMB_WRITE_KEY_CID);
1193+
uint8_t want[RPMB_CID_SIZE] = { };
1194+
uint32_t n = 0;
1195+
1196+
n = tee_hs2b((uint8_t *)hs, want, strlen(hs), sizeof(want));
1197+
if (n != RPMB_CID_SIZE) {
1198+
EMSG("Invalid CFG_RPMB_WRITE_KEY_CID");
1199+
return false;
1200+
}
1201+
1202+
return !memcmp(cid, want, RPMB_CID_SIZE);
1203+
}
1204+
#else
1205+
static bool rpmb_cid_match(const uint8_t *cid __unused)
1206+
{
1207+
return true;
1208+
}
1209+
#endif
1210+
11891211
static TEE_Result legacy_rpmb_init(void)
11901212
{
11911213
TEE_Result res = TEE_SUCCESS;
@@ -1240,7 +1262,10 @@ static TEE_Result legacy_rpmb_init(void)
12401262
* Need to write the key here and verify it.
12411263
*/
12421264
DMSG("RPMB INIT: Auth key not yet written");
1243-
res = tee_rpmb_write_and_verify_key();
1265+
if (rpmb_cid_match(rpmb_ctx->cid))
1266+
res = tee_rpmb_write_and_verify_key();
1267+
else
1268+
EMSG("CID mismatch, CFG_RPMB_WRITE_KEY_CID");
12441269
} else {
12451270
EMSG("Verify key failed! %#"PRIx32, res);
12461271
EMSG("Make sure key here matches device key");
@@ -1257,8 +1282,12 @@ static bool rpmb_ctx_list_empty(void)
12571282

12581283
static TEE_Result add_rpmb_ctx_to_list(void)
12591284
{
1260-
struct rpmb_ctx_candidate *cand = calloc(1, sizeof(*cand));
1285+
struct rpmb_ctx_candidate *cand = NULL;
1286+
1287+
if (!rpmb_cid_match(rpmb_ctx->cid))
1288+
return TEE_SUCCESS;
12611289

1290+
cand = calloc(1, sizeof(*cand));
12621291
if (!cand)
12631292
return TEE_ERROR_OUT_OF_MEMORY;
12641293

mk/config.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ CFG_RPMB_TESTKEY ?= n
231231
# - RPMB key provisioning in a controlled environment (factory setup)
232232
CFG_RPMB_WRITE_KEY ?= n
233233

234+
# Restricts RPMB key provisioning to the device whose CID matches this
235+
# upper-case hex string (2 * RPMB_CID_SIZE chars). Unset: provision the first.
236+
# CFG_RPMB_WRITE_KEY_CID ?= 112233445566778899AABBCCDDEEFF00
237+
234238
# For the kernel driver to enable in-kernel RPMB routing it must know in
235239
# advance that OP-TEE supports it. Setting CFG_RPMB_ANNOUNCE_PROBE_CAP=y
236240
# will announce OP-TEE's capability for RPMB probing to the kernel and it

0 commit comments

Comments
 (0)