Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tee-supplicant: Allow to control RPMB emulation during runtime #354

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tee-supplicant/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ include ../config.mk

OUT_DIR := $(OO)/tee-supplicant

# Emulate RPMB ioctl's by default
# Support RPMB emulation by default (--rpmb-emu command line argument)
RPMB_EMU ?= 1

.PHONY: all tee-supplicant clean
Expand Down
74 changes: 47 additions & 27 deletions tee-supplicant/src/rpmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
*/

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/types.h>
#include <linux/mmc/ioctl.h>
Expand All @@ -46,8 +47,6 @@
#ifdef RPMB_EMU
#include <stdarg.h>
#include "hmac_sha2.h"
#else
#include <errno.h>
#endif

/*
Expand Down Expand Up @@ -139,18 +138,6 @@ static pthread_mutex_t rpmb_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Maximum number of commands used in a multiple ioc command request */
#define RPMB_MAX_IOC_MULTI_CMDS 3

#ifndef RPMB_EMU

#define IOCTL(fd, request, ...) \
({ \
int ret; \
ret = ioctl((fd), (request), ##__VA_ARGS__); \
if (ret < 0) \
EMSG("ioctl ret=%d errno=%d", ret, errno); \
ret; \
})


/* Open and/or return file descriptor to RPMB partition of device dev_id */
static int mmc_rpmb_fd(uint16_t dev_id)
{
Expand Down Expand Up @@ -389,9 +376,9 @@ static bool remap_rpmb_dev_id(uint16_t dev_id, uint16_t *ndev_id)
return found;
}

#else /* RPMB_EMU */
#ifdef RPMB_EMU

#define IOCTL(fd, request, ...) ioctl_emu((fd), (request), ##__VA_ARGS__)
#define use_rpmb_emu() supplicant_params.rpmb_emu

/* Emulated rel_wr_sec_c value (reliable write size, *256 bytes) */
#define EMU_RPMB_REL_WR_SEC_C 1
Expand Down Expand Up @@ -609,7 +596,7 @@ static void ioctl_emu_read_ctr(struct rpmb_emu *mem,
frm->op_result = compute_hmac(mem, frm, 1);
}

static uint32_t read_cid(uint16_t dev_id, uint8_t *cid)
static uint32_t read_cid_emu(uint16_t dev_id, uint8_t *cid)
{
/* Taken from an actual eMMC chip */
static const uint8_t test_cid[] = {
Expand Down Expand Up @@ -747,36 +734,46 @@ static int ioctl_emu(int fd, unsigned long request, ...)
return res;
}

static int mmc_rpmb_fd(uint16_t dev_id)
static int mmc_rpmb_fd_emu(uint16_t dev_id)
{
(void)dev_id;

/* Any value != -1 will do in test mode */
return 0;
}

static TEEC_Result read_size_mult(uint16_t dev_id, uint8_t *value)
static TEEC_Result read_size_mult_emu(uint16_t dev_id, uint8_t *value)
{
(void)dev_id;

*value = EMU_RPMB_SIZE_MULT;
return TEEC_SUCCESS;
}

static TEEC_Result read_rel_wr_sec_c(uint16_t dev_id, uint8_t *value)
static TEEC_Result read_rel_wr_sec_c_emu(uint16_t dev_id, uint8_t *value)
{
(void)dev_id;

*value = EMU_RPMB_REL_WR_SEC_C;
return TEEC_SUCCESS;
}

static bool remap_rpmb_dev_id(uint16_t dev_id, uint16_t *ndev_id)
static bool remap_rpmb_dev_id_emu(uint16_t dev_id, uint16_t *ndev_id)
{
*ndev_id = dev_id;
return true;
}

#else /* !RPMB_EMU */

#define use_rpmb_emu() (0)
#define read_cid_emu(dev_id, cid) (TEEC_ERROR_GENERIC)
#define ioctl_emu(fd, request, ...) (-1)
#define mmc_rpmb_fd_emu(dev_id) (-1)
#define read_size_mult_emu(dev_id, value) (TEEC_ERROR_GENERIC)
#define read_rel_wr_sec_c_emu(dev_id, value) (TEEC_ERROR_GENERIC)
#define remap_rpmb_dev_id_emu(dev_id, ndev_id) (false)

#endif /* RPMB_EMU */

static inline void set_mmc_io_cmd(struct mmc_ioc_cmd *cmd, unsigned int blocks,
Expand Down Expand Up @@ -890,7 +887,13 @@ static uint32_t rpmb_data_req(int fd, struct rpmb_data_frame *req_frm,
goto out;
}

st = IOCTL(fd, MMC_IOC_MULTI_CMD, mcmd);
if (use_rpmb_emu()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure it is very helpful to modify all the call sites to test for emu enabled. In this particular case we could define a ioctl wrapper for example do_ioctl() which would call either ioctl() or ioctl_emu().

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have multiple call sites for those, that's why I left the if-else there and didn't add another level of wrappers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, I see what you mean. Please disregard my comment then.

st = ioctl_emu(fd, MMC_IOC_MULTI_CMD, mcmd);
} else {
st = ioctl(fd, MMC_IOC_MULTI_CMD, mcmd);
if (st < 0)
EMSG("ioctl ret=%d errno=%d", st, errno);
}
if (st < 0)
res = TEEC_ERROR_GENERIC;

Expand All @@ -906,16 +909,25 @@ static uint32_t rpmb_get_dev_info(uint16_t dev_id, struct rpmb_dev_info *info)
uint8_t rpmb_size_mult = 0;
uint8_t rel_wr_sec_c = 0;

res = read_cid(dev_id, info->cid);
if (use_rpmb_emu())
res = read_cid_emu(dev_id, info->cid);
else
res = read_cid(dev_id, info->cid);
if (res != TEEC_SUCCESS)
return res;

res = read_size_mult(dev_id, &rpmb_size_mult);
if (use_rpmb_emu())
res = read_size_mult_emu(dev_id, &rpmb_size_mult);
else
res = read_size_mult(dev_id, &rpmb_size_mult);
if (res != TEEC_SUCCESS)
return res;
info->rpmb_size_mult = rpmb_size_mult;

res = read_rel_wr_sec_c(dev_id, &rel_wr_sec_c);
if (use_rpmb_emu())
res = read_rel_wr_sec_c_emu(dev_id, &rel_wr_sec_c);
else
res = read_rel_wr_sec_c(dev_id, &rel_wr_sec_c);
if (res != TEEC_SUCCESS)
return res;
info->rel_wr_sec_c = rel_wr_sec_c;
Expand All @@ -938,19 +950,27 @@ static uint32_t rpmb_process_request_unlocked(void *req, size_t req_size,
size_t rsp_nfrm = 0;
uint16_t dev_id = 0;
uint32_t res = 0;
bool success;
int fd = 0;

if (req_size < sizeof(*sreq))
return TEEC_ERROR_BAD_PARAMETERS;

if (!remap_rpmb_dev_id(sreq->dev_id, &dev_id))
if (use_rpmb_emu())
success = remap_rpmb_dev_id_emu(sreq->dev_id, &dev_id);
else
success = remap_rpmb_dev_id(sreq->dev_id, &dev_id);
if (!success)
return TEEC_ERROR_ITEM_NOT_FOUND;

switch (sreq->cmd) {
case RPMB_CMD_DATA_REQ:
req_nfrm = (req_size - sizeof(struct rpmb_req)) / 512;
rsp_nfrm = rsp_size / 512;
fd = mmc_rpmb_fd(dev_id);
if (use_rpmb_emu())
fd = mmc_rpmb_fd_emu(dev_id);
else
fd = mmc_rpmb_fd(dev_id);
if (fd < 0)
return TEEC_ERROR_BAD_PARAMETERS;
res = rpmb_data_req(fd, RPMB_REQ_DATA(req), req_nfrm, rsp,
Expand Down
13 changes: 12 additions & 1 deletion tee-supplicant/src/tee_supplicant.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,9 @@ static int usage(int status)
fprintf(stderr, "\t-h, --help: this help\n");
fprintf(stderr, "\t-d, --daemonize: run as a daemon (fork and return "
"after child has opened the TEE device or on error)\n");
#ifdef RPMB_EMU
fprintf(stderr, "\t-e, --rpmb-emu: use emulated RPMB\n");
#endif
fprintf(stderr, "\t-f, --fs-parent-path: secure fs parent path [%s]\n",
supplicant_params.fs_parent_path);
fprintf(stderr, "\t-t, --ta-dir: TAs dirname under %s [%s]\n", TEEC_LOAD_PATH,
Expand Down Expand Up @@ -808,14 +811,17 @@ int main(int argc, char *argv[])
/* long name | has argument | flag | short value */
{ "help", no_argument, 0, 'h' },
{ "daemonize", no_argument, 0, 'd' },
#ifdef RPMB_EMU
{ "rpmb-emu", no_argument, 0, 'e' },
#endif
{ "fs-parent-path", required_argument, 0, 'f' },
{ "ta-dir", required_argument, 0, 't' },
{ "plugin-path", required_argument, 0, 'p' },
{ "rpmb-cid", required_argument, 0, 'r' },
{ 0, 0, 0, 0 }
};

while ((opt = getopt_long(argc, argv, "hdf:t:p:r:",
while ((opt = getopt_long(argc, argv, "hdef:t:p:r:",
long_options, &long_index )) != -1) {
switch (opt) {
case 'h' :
Expand All @@ -824,6 +830,11 @@ int main(int argc, char *argv[])
case 'd':
daemonize = true;
break;
#ifdef RPMB_EMU
case 'e':
supplicant_params.rpmb_emu = true;
break;
#endif
case 'f':
supplicant_params.fs_parent_path = optarg;
break;
Expand Down
3 changes: 3 additions & 0 deletions tee-supplicant/src/tee_supplicant.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ struct tee_supplicant_params {
const char *plugin_load_path;
const char *fs_parent_path;
const char *rpmb_cid;
#ifdef RPMB_EMU
bool rpmb_emu;
#endif
};

extern struct tee_supplicant_params supplicant_params;
Expand Down