From 21bad5b6faeb0d1ccaabd93266e91ef5c26ac7e1 Mon Sep 17 00:00:00 2001 From: Liming Sun Date: Mon, 21 Aug 2023 18:13:11 -0400 Subject: [PATCH] tee-supplicant: Enable command line support for RPMB_EMU The current eMMC RPMB support is enabled with RPMB_EMU=1 by default at compiling time and needs re-compiling to access real eMMC RPMB. It's inconvenient especially when this package is provided by known Linux distributions like Ubuntu. This commit enhances it by adding command line option for RPMB_EMU. It still uses RPMB emulation by default to be backwoard compatible, but could use '--rpmb-emu-disable' to access the actual eMMC RPMB. Signed-off-by: Liming Sun --- tee-supplicant/CMakeLists.txt | 6 -- tee-supplicant/Makefile | 9 +-- tee-supplicant/src/rpmb.c | 88 ++++++++++++++---------- tee-supplicant/src/rpmb.h | 2 + tee-supplicant/src/tee_supplicant.c | 9 ++- tee-supplicant/src/tee_supplicant.h | 1 + tee-supplicant/tee_supplicant_android.mk | 4 -- 7 files changed, 64 insertions(+), 55 deletions(-) diff --git a/tee-supplicant/CMakeLists.txt b/tee-supplicant/CMakeLists.txt index 57a3326d..7a9e6db5 100644 --- a/tee-supplicant/CMakeLists.txt +++ b/tee-supplicant/CMakeLists.txt @@ -4,7 +4,6 @@ project (tee-supplicant C) # Configuration flags always included ################################################################################ option (CFG_TA_TEST_PATH "Enable tee-supplicant to load from test/debug path" OFF) -option (RPMB_EMU "Enable tee-supplicant to emulate RPMB" ON) option (CFG_TA_GPROF_SUPPORT "Enable tee-supplicant support for TAs instrumented with gprof" ON) option (CFG_FTRACE_SUPPORT "Enable tee-supplicant support for TAs instrumented with ftrace" ON) option (CFG_TEE_SUPP_PLUGINS "Enable tee-supplicant plugin support" ON) @@ -74,11 +73,6 @@ if (CFG_TA_TEST_PATH) PRIVATE -DCFG_TA_TEST_PATH=${CFG_TA_TEST_PATH}) endif() -if (RPMB_EMU) - target_compile_definitions (${PROJECT_NAME} - PRIVATE -DRPMB_EMU=1) -endif() - if (CFG_TA_GPROF_SUPPORT) target_compile_definitions (${PROJECT_NAME} PRIVATE -DCFG_TA_GPROF_SUPPORT) diff --git a/tee-supplicant/Makefile b/tee-supplicant/Makefile index b862a7ef..ba7b43a0 100644 --- a/tee-supplicant/Makefile +++ b/tee-supplicant/Makefile @@ -3,9 +3,6 @@ include ../config.mk OUT_DIR := $(OO)/tee-supplicant -# Emulate RPMB ioctl's by default -RPMB_EMU ?= 1 - .PHONY: all tee-supplicant clean all: tee-supplicant @@ -24,9 +21,8 @@ ifeq ($(CFG_GP_SOCKETS),y) TEES_SRCS += tee_socket.c endif -ifeq ($(RPMB_EMU),1) TEES_SRCS += sha2.c hmac_sha2.c -endif + ifneq (,$(filter y,$(CFG_TA_GPROF_SUPPORT) $(CFG_FTRACE_SUPPORT))) TEES_SRCS += prof.c endif @@ -51,9 +47,6 @@ TEES_CFLAGS := $(addprefix -I, $(TEES_INCLUDES)) $(CFLAGS) \ ifeq ($(CFG_GP_SOCKETS),y) TEES_CFLAGS += -DCFG_GP_SOCKETS=1 endif -ifeq ($(RPMB_EMU),1) -TEES_CFLAGS += -DRPMB_EMU=1 -endif ifeq ($(CFG_TA_TEST_PATH),y) TEES_CFLAGS += -DCFG_TA_TEST_PATH=1 endif diff --git a/tee-supplicant/src/rpmb.c b/tee-supplicant/src/rpmb.c index 7643ed64..e21d10a7 100644 --- a/tee-supplicant/src/rpmb.c +++ b/tee-supplicant/src/rpmb.c @@ -26,12 +26,14 @@ */ #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -43,12 +45,7 @@ #include #include -#ifdef RPMB_EMU -#include #include "hmac_sha2.h" -#else -#include -#endif /* * Request and response definitions must be in sync with the secure side @@ -139,17 +136,16 @@ 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; \ - }) +typedef struct { + int (*ioctl)(int d, long unsigned int request, ...); + int (*get_fd)(uint16_t dev_id); + TEEC_Result (*read_cid)(uint16_t dev_id, uint8_t *cid); + TEEC_Result (*read_size_mult)(uint16_t dev_id, uint8_t *value); + TEEC_Result (*read_rel_wr_sec_c)(uint16_t dev_id, uint8_t *value); + bool (*remap_dev_id)(uint16_t dev_id, uint16_t *ndev_id); +} rpmb_ops_t; +static rpmb_ops_t rpmb_ops; /* Open and/or return file descriptor to RPMB partition of device dev_id */ static int mmc_rpmb_fd(uint16_t dev_id) @@ -389,10 +385,6 @@ static bool remap_rpmb_dev_id(uint16_t dev_id, uint16_t *ndev_id) return found; } -#else /* RPMB_EMU */ - -#define IOCTL(fd, request, ...) ioctl_emu((fd), (request), ##__VA_ARGS__) - /* Emulated rel_wr_sec_c value (reliable write size, *256 bytes) */ #define EMU_RPMB_REL_WR_SEC_C 1 /* Emulated rpmb_size_mult value (RPMB size, *128 kB) */ @@ -414,9 +406,7 @@ struct rpmb_emu { uint16_t address; } last_op; }; -static struct rpmb_emu rpmb_emu = { - .size = EMU_RPMB_SIZE_BYTES -}; +static struct rpmb_emu *rpmb_emu; static struct rpmb_emu *mem_for_fd(int fd) { @@ -429,7 +419,7 @@ static struct rpmb_emu *mem_for_fd(int fd) return NULL; } - return &rpmb_emu; + return rpmb_emu; } #if (DEBUGLEVEL >= TRACE_FLOW) @@ -609,7 +599,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[] = { @@ -747,7 +737,7 @@ 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; @@ -755,7 +745,7 @@ static int mmc_rpmb_fd(uint16_t dev_id) 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; @@ -763,7 +753,7 @@ static TEEC_Result read_size_mult(uint16_t dev_id, uint8_t *value) 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; @@ -771,14 +761,12 @@ static TEEC_Result read_rel_wr_sec_c(uint16_t dev_id, uint8_t *value) 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; } -#endif /* RPMB_EMU */ - static inline void set_mmc_io_cmd(struct mmc_ioc_cmd *cmd, unsigned int blocks, __u32 opcode, int write_flag) { @@ -890,7 +878,7 @@ static uint32_t rpmb_data_req(int fd, struct rpmb_data_frame *req_frm, goto out; } - st = IOCTL(fd, MMC_IOC_MULTI_CMD, mcmd); + st = rpmb_ops.ioctl(fd, MMC_IOC_MULTI_CMD, mcmd); if (st < 0) res = TEEC_ERROR_GENERIC; @@ -906,16 +894,16 @@ 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); + res = rpmb_ops.read_cid(dev_id, info->cid); if (res != TEEC_SUCCESS) return res; - res = read_size_mult(dev_id, &rpmb_size_mult); + res = rpmb_ops.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); + res = rpmb_ops.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; @@ -943,14 +931,14 @@ static uint32_t rpmb_process_request_unlocked(void *req, size_t req_size, if (req_size < sizeof(*sreq)) return TEEC_ERROR_BAD_PARAMETERS; - if (!remap_rpmb_dev_id(sreq->dev_id, &dev_id)) + if (!rpmb_ops.remap_dev_id(sreq->dev_id, &dev_id)) 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); + fd = rpmb_ops.get_fd(dev_id); if (fd < 0) return TEEC_ERROR_BAD_PARAMETERS; res = rpmb_data_req(fd, RPMB_REQ_DATA(req), req_nfrm, rsp, @@ -987,3 +975,31 @@ uint32_t rpmb_process_request(void *req, size_t req_size, void *rsp, return res; } + + +int rpmb_init() +{ + if (!supplicant_params.rpmb_emu_disable) { + rpmb_emu = calloc(1, sizeof(*rpmb_emu)); + if (!rpmb_emu) { + EMSG("Failed to allocate buffer for RPMBi emulation"); + return -ENOMEM; + } + rpmb_emu->size = EMU_RPMB_SIZE_BYTES; + rpmb_ops.ioctl = ioctl_emu; + rpmb_ops.get_fd = mmc_rpmb_fd_emu; + rpmb_ops.read_cid = read_cid_emu; + rpmb_ops.read_size_mult = read_size_mult_emu; + rpmb_ops.read_rel_wr_sec_c = read_rel_wr_sec_c_emu; + rpmb_ops.remap_dev_id = remap_rpmb_dev_id_emu; + } else { + rpmb_ops.ioctl = ioctl; + rpmb_ops.get_fd = mmc_rpmb_fd; + rpmb_ops.read_cid = read_cid; + rpmb_ops.read_size_mult = read_size_mult; + rpmb_ops.read_rel_wr_sec_c = read_rel_wr_sec_c; + rpmb_ops.remap_dev_id = remap_rpmb_dev_id; + } + + return 0; +} diff --git a/tee-supplicant/src/rpmb.h b/tee-supplicant/src/rpmb.h index feeed5b8..7075eee3 100644 --- a/tee-supplicant/src/rpmb.h +++ b/tee-supplicant/src/rpmb.h @@ -34,4 +34,6 @@ uint32_t rpmb_process_request(void *req, size_t req_size, void *rsp, size_t rsp_size); +int rpmb_init(void); + #endif /* RPMB_H */ diff --git a/tee-supplicant/src/tee_supplicant.c b/tee-supplicant/src/tee_supplicant.c index 850ab6f4..85218165 100644 --- a/tee-supplicant/src/tee_supplicant.c +++ b/tee-supplicant/src/tee_supplicant.c @@ -493,6 +493,7 @@ 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"); + fprintf(stderr, "\t-e, --rpmb-emu-disable: RPMB emunation disable\n"); 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, @@ -808,6 +809,7 @@ int main(int argc, char *argv[]) /* long name | has argument | flag | short value */ { "help", no_argument, 0, 'h' }, { "daemonize", no_argument, 0, 'd' }, + { "rpmb-emu-disable", no_argument, 0, 'e' }, { "fs-parent-path", required_argument, 0, 'f' }, { "ta-dir", required_argument, 0, 't' }, { "plugin-path", required_argument, 0, 'p' }, @@ -815,7 +817,7 @@ int main(int argc, char *argv[]) { 0, 0, 0, 0 } }; - while ((opt = getopt_long(argc, argv, "hdf:t:p:r:", + while ((opt = getopt_long(argc, argv, "hde:f:t:p:r:", long_options, &long_index )) != -1) { switch (opt) { case 'h' : @@ -824,6 +826,9 @@ int main(int argc, char *argv[]) case 'd': daemonize = true; break; + case 'e': + supplicant_params.rpmb_emu_disable = true; + break; case 'f': supplicant_params.fs_parent_path = optarg; break; @@ -895,6 +900,8 @@ int main(int argc, char *argv[]) close(pipefd[1]); } + rpmb_init(); + while (!arg.abort) { if (!process_one_request(&arg)) arg.abort = true; diff --git a/tee-supplicant/src/tee_supplicant.h b/tee-supplicant/src/tee_supplicant.h index cf98ac83..e79c5d2e 100644 --- a/tee-supplicant/src/tee_supplicant.h +++ b/tee-supplicant/src/tee_supplicant.h @@ -44,6 +44,7 @@ struct tee_supplicant_params { const char *plugin_load_path; const char *fs_parent_path; const char *rpmb_cid; + bool rpmb_emu_disable; }; extern struct tee_supplicant_params supplicant_params; diff --git a/tee-supplicant/tee_supplicant_android.mk b/tee-supplicant/tee_supplicant_android.mk index 49bc388a..397b11f6 100644 --- a/tee-supplicant/tee_supplicant_android.mk +++ b/tee-supplicant/tee_supplicant_android.mk @@ -30,11 +30,7 @@ LOCAL_SRC_FILES += src/tee_socket.c LOCAL_CFLAGS += -DCFG_GP_SOCKETS=1 endif -RPMB_EMU ?= 1 -ifeq ($(RPMB_EMU),1) LOCAL_SRC_FILES += src/sha2.c src/hmac_sha2.c -LOCAL_CFLAGS += -DRPMB_EMU=1 -endif ifneq (,$(filter y,$(CFG_TA_GPROF_SUPPORT) $(CFG_FTRACE_SUPPORT))) LOCAL_SRC_FILES += src/prof.c