libteec 是OP-TEE 提供给用户在linux userspace层面调用的接口实现,从makefile中可以看到libtees是被build成libteec.so,其源文件有两个tee_client_api.c,teec_trace.c.其中主要的接口在tee_client_api.c中,而teec_trace.c 中只是提供用于打印log的_dprintf的实现
MAJOR_VERSION := 1
MINOR_VERSION := 0
LIB_NAME := libteec.so
LIB_MAJOR := $(LIB_NAME).$(MAJOR_VERSION)
LIB_MAJ_MIN := $(LIB_NAME).$(MAJOR_VERSION).$(MINOR_VERSION)
TEEC_SRCS := tee_client_api.c \
teec_trace.c
TEEC_InitializeContext 主要是通过devname打开/dev/teeX 则个文件后得到这个设备的fd,并赋值给ctx->fd,这里的name代表secure os的name,例如optee-tz,ctx代表TA和CA 之间的通信
TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *ctx)
{
char devname[PATH_MAX];
int fd;
size_t n;
if (!ctx)
return TEEC_ERROR_BAD_PARAMETERS;
for (n = 0; n < TEEC_MAX_DEV_SEQ; n++) {
snprintf(devname, sizeof(devname), "/dev/tee%zu", n);
fd = teec_open_dev(devname, name);
if (fd >= 0) {
ctx->fd = fd;
return TEEC_SUCCESS;
}
}
return TEEC_ERROR_ITEM_NOT_FOUND;
}
与TEEC_InitializeContext 对应的就是TEEC_FinalizeContext。可见就是直接close打开的fd
void TEEC_FinalizeContext(TEEC_Context *ctx)
{
if (ctx)
close(ctx->fd);
}
具体的open是通过
static int teec_open_dev(const char *devname, const char *capabilities)
{
struct tee_ioctl_version_data vers;
int fd;
//打开/dev/teeX
fd = open(devname, O_RDWR);
if (fd < 0)
return -1;
//通过ioctl 得到当前tee的version,如果得不到revison的话,直接退出
if (ioctl(fd, TEE_IOC_VERSION, &vers)) {
EMSG("TEE_IOC_VERSION failed");
goto err;
}
/* We can only handle GP TEEs */
if (!(vers.gen_caps & TEE_GEN_CAP_GP))
goto err;
//看TEEC_InitializeContext调用teec_open_dev的时候是否传递capabilities,如果传递且capabilities 中包含optee-tz 这个字符串的话,则判断通过ioctl得到的version中是否包含TEE_IMPL_ID_OPTEE和TEE_OPTEE_CAP_TZ
if (capabilities) {
if (strcmp(capabilities, "optee-tz") == 0) {
if (vers.impl_id != TEE_IMPL_ID_OPTEE)
goto err;
if (!(vers.impl_caps & TEE_OPTEE_CAP_TZ))
goto err;
} else {
/* Unrecognized capability requested */
goto err;
}
}
return fd;
err:
close(fd);
return -1;
}
MAJOR_VERSION := 1
MINOR_VERSION := 0
LIB_NAME := libteec.so
LIB_MAJOR := $(LIB_NAME).$(MAJOR_VERSION)
LIB_MAJ_MIN := $(LIB_NAME).$(MAJOR_VERSION).$(MINOR_VERSION)
TEEC_SRCS := tee_client_api.c \
teec_trace.c
TEEC_InitializeContext 主要是通过devname打开/dev/teeX 则个文件后得到这个设备的fd,并赋值给ctx->fd,这里的name代表secure os的name,例如optee-tz,ctx代表TA和CA 之间的通信
TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *ctx)
{
char devname[PATH_MAX];
int fd;
size_t n;
if (!ctx)
return TEEC_ERROR_BAD_PARAMETERS;
for (n = 0; n < TEEC_MAX_DEV_SEQ; n++) {
snprintf(devname, sizeof(devname), "/dev/tee%zu", n);
fd = teec_open_dev(devname, name);
if (fd >= 0) {
ctx->fd = fd;
return TEEC_SUCCESS;
}
}
return TEEC_ERROR_ITEM_NOT_FOUND;
}
与TEEC_InitializeContext 对应的就是TEEC_FinalizeContext。可见就是直接close打开的fd
void TEEC_FinalizeContext(TEEC_Context *ctx)
{
if (ctx)
close(ctx->fd);
}
具体的open是通过
static int teec_open_dev(const char *devname, const char *capabilities)
{
struct tee_ioctl_version_data vers;
int fd;
//打开/dev/teeX
fd = open(devname, O_RDWR);
if (fd < 0)
return -1;
//通过ioctl 得到当前tee的version,如果得不到revison的话,直接退出
if (ioctl(fd, TEE_IOC_VERSION, &vers)) {
EMSG("TEE_IOC_VERSION failed");
goto err;
}
/* We can only handle GP TEEs */
if (!(vers.gen_caps & TEE_GEN_CAP_GP))
goto err;
//看TEEC_InitializeContext调用teec_open_dev的时候是否传递capabilities,如果传递且capabilities 中包含optee-tz 这个字符串的话,则判断通过ioctl得到的version中是否包含TEE_IMPL_ID_OPTEE和TEE_OPTEE_CAP_TZ
if (capabilities) {
if (strcmp(capabilities, "optee-tz") == 0) {
if (vers.impl_id != TEE_IMPL_ID_OPTEE)
goto err;
if (!(vers.impl_caps & TEE_OPTEE_CAP_TZ))
goto err;
} else {
/* Unrecognized capability requested */
goto err;
}
}
return fd;
err:
close(fd);
return -1;
}