Skip to content

Commit

Permalink
xtest: sdp_basic: use TEE_IOC_RSTMEM_ALLOC
Browse files Browse the repository at this point in the history
Use the new TEE IOCTL TEE_IOC_RSTMEM_ALLOC to allocate restricted
buffers for Secure Data Path tests.

Signed-off-by: Jens Wiklander <[email protected]>
  • Loading branch information
jenswi-linaro committed Nov 28, 2024
1 parent f75bb37 commit e3ff5f4
Showing 1 changed file with 137 additions and 76 deletions.
213 changes: 137 additions & 76 deletions host/xtest/sdp_basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <pta_invoke_tests.h>
#include <stdio.h>
Expand All @@ -15,6 +16,7 @@
#include <tee_client_api.h>
#include <tee_client_api_extensions.h>
#include <unistd.h>
#include <linux/tee.h>

#include "crypto_common.h"
#include "sdp_basic.h"
Expand Down Expand Up @@ -56,6 +58,44 @@ struct tee_ctx {
TEEC_Session sess;
};

#ifndef TEE_IOC_RSTMEM_ALLOC

#define TEE_IOC_UC_RESERVED 0
#define TEE_IOC_UC_SECURE_VIDEO_PLAY 1
#define TEE_IOC_UC_TRUSTED_UI 2
#define TEE_IOC_UC_SECURE_VIDEO_RECORD 3


/**
* struct tee_ioctl_rstmem_alloc_data - Restricted memory allocate argument
* @size: [in/out] Size of restricted memory to allocate
* @flags: [in/out] Flags to/from allocate
* @use_case [in] Restricted memroy use case, TEE_IOC_UC_*
* @id: [out] Identifier of the restricted memory
*/
struct tee_ioctl_rstmem_alloc_data {
__u64 size;
__u32 flags;
__u32 use_case;
__s32 id;
};

/**
* TEE_IOC_RSTMEM_ALLOC - allocate restricted memory
*
* Allocates restricted physically memory normally not accessible by the
* kernel.
*
* Returns a file descriptor on success or < 0 on failure
*
* The returned file descriptor is a dma-buf that can be attached and
* mapped for device with permission to access the physical memory.
*/
#define TEE_IOC_RSTMEM_ALLOC _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 10, \
struct tee_ioctl_rstmem_alloc_data)
#endif


int allocate_dma_buffer(size_t size, const char *heap_name, int verbosity)
{
const char *default_dev = DEFAULT_HEAP_NAME;
Expand Down Expand Up @@ -90,6 +130,53 @@ int allocate_dma_buffer(size_t size, const char *heap_name, int verbosity)
return fd;
}

static int rmem_alloc(int fd, size_t size, int *id)
{
struct tee_ioctl_rstmem_alloc_data data = {
.size = size,
.use_case = TEE_IOC_UC_SECURE_VIDEO_PLAY,
};
int rmem_fd = 0;

rmem_fd = ioctl(fd, TEE_IOC_RSTMEM_ALLOC, &data);
if (rmem_fd >= 0)
*id = data.id;
return rmem_fd;
}

static TEEC_Result TEEC_AllocateRestrictedMemory(TEEC_Context *ctx, TEEC_SharedMemory *shm)
{
size_t s = 0;
int fd = 0;

warn("%s: hej 1\n", __func__);
if (!ctx || !shm)
return TEEC_ERROR_BAD_PARAMETERS;

warn("%s: hej 2\n", __func__);
if (!shm->flags || (shm->flags & ~(TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)))
return TEEC_ERROR_BAD_PARAMETERS;

warn("%s: hej 3\n", __func__);
s = shm->size;
if (!s)
s = 8;

fd = rmem_alloc(ctx->imp.fd, s, &shm->imp.id);
if (fd < 0) {
warn("%s: hej 4\n", __func__);
if (errno == ENOMEM)
return TEEC_ERROR_OUT_OF_MEMORY;
warn("%s: hej 6\n", __func__);
return TEEC_ERROR_NOT_SUPPORTED;
}

shm->imp.registered_fd = fd;
warn("%s: hej 7\n", __func__);

return TEEC_SUCCESS;
}

static void finalize_tee_ctx(struct tee_ctx *ctx)
{
if (!ctx)
Expand Down Expand Up @@ -134,37 +221,6 @@ static int create_tee_ctx(struct tee_ctx *ctx, enum test_target_ta target_ta)
return (teerc == TEEC_SUCCESS) ? 0 : -1;
}

static int tee_register_buffer(struct tee_ctx *ctx, void **shm_ref, int fd)
{
TEEC_Result teerc = TEEC_ERROR_GENERIC;
TEEC_SharedMemory *shm = malloc(sizeof(*shm));

if (!shm)
return 1;

shm->flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
teerc = TEEC_RegisterSharedMemoryFileDescriptor(&ctx->ctx, shm, fd);
if (teerc != TEEC_SUCCESS) {
fprintf(stderr, "Error: TEEC_RegisterMemoryFileDescriptor() failed %x\n",
teerc);
return 1;
}

*shm_ref = shm;
return 0;
}

static void tee_deregister_buffer(struct tee_ctx *ctx, void *shm_ref)
{
(void)ctx;

if (!shm_ref)
return;

TEEC_ReleaseSharedMemory((TEEC_SharedMemory *)shm_ref);
free(shm_ref);
}

static int inject_sdp_data(struct tee_ctx *ctx,
void *in, size_t offset, size_t len, void *shm_ref, int ind)
{
Expand Down Expand Up @@ -371,12 +427,12 @@ static int get_random_bytes(char *out, size_t len)
int sdp_basic_test(enum test_target_ta ta, size_t size, size_t loop,
const char *heap_name, int rnd_offset, int verbosity)
{
TEEC_Result res;
struct tee_ctx *ctx = NULL;
unsigned char *test_buf = NULL;
unsigned char *ref_buf = NULL;
void *shm_ref = NULL;
TEEC_SharedMemory shm = { };
unsigned int err = 1;
int fd = -1;
size_t sdp_size = size;
size_t offset = 0;
size_t loop_cnt = 0;
Expand All @@ -394,65 +450,63 @@ int sdp_basic_test(enum test_target_ta ta, size_t size, size_t loop,
ref_buf = malloc(size);
if (!test_buf || !ref_buf) {
verbose("failed to allocate memory\n");
goto bail1;
goto out_free;
}

fd = allocate_buffer(sdp_size, heap_name, verbosity);
if (fd < 0) {
verbose("Failed to allocate SDP buffer (%zu bytes) in %s: %d\n",
sdp_size, heap_name, fd);
goto bail1;
}

/* register secure buffer to TEE */
ctx = malloc(sizeof(*ctx));
if (!ctx)
goto bail1;
goto out_free;
if (create_tee_ctx(ctx, ta))
goto bail1;
if (tee_register_buffer(ctx, &shm_ref, fd))
goto bail2;

/* release registered fd: tee should still hold refcount on resource */
close(fd);
fd = -1;
goto out_free;
shm.size = sdp_size;
shm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
res = TEEC_AllocateRestrictedMemory(&ctx->ctx, &shm);
if (res) {
verbose("Failed to allocate SDP buffer (%zu bytes)\n",
sdp_size);
goto out_finalize_ctx;
}

/* invoke trusted application with secure buffer as memref parameter */
for (loop_cnt = loop; loop_cnt; loop_cnt--) {
/* get an buffer of random-like values */
if (get_random_bytes((char *)ref_buf, size))
goto bail2;
goto out_rel_shm;
memcpy(test_buf, ref_buf, size);
/* random offset [0 255] */
offset = (unsigned int)*ref_buf;

/* TA writes into SDP buffer */
if (inject_sdp_data(ctx, test_buf, offset, size, shm_ref, ta))
goto bail2;
if (inject_sdp_data(ctx, test_buf, offset, size, &shm, ta)) {
fprintf(stderr, "err1\n");
goto out_rel_shm;
}

/* TA reads/writes into SDP buffer */
if (transform_sdp_data(ctx, offset, size, shm_ref, ta))
goto bail2;
if (transform_sdp_data(ctx, offset, size, &shm, ta)) {
fprintf(stderr, "err2\n");
goto out_rel_shm;
}

/* TA reads into SDP buffer */
if (dump_sdp_data(ctx, test_buf, offset, size, shm_ref, ta))
goto bail2;
if (dump_sdp_data(ctx, test_buf, offset, size, &shm, ta)) {
fprintf(stderr, "err3\n");
goto out_rel_shm;
}

/* check dumped data are the expected ones */
if (check_sdp_dumped(ctx, ref_buf, size, test_buf)) {
fprintf(stderr, "check SDP data: %d errors\n", err);
goto bail2;
goto out_rel_shm;
}
}

err = 0;
bail2:
if (fd >= 0)
close(fd);
if (shm_ref)
tee_deregister_buffer(ctx, shm_ref);
out_rel_shm:
TEEC_ReleaseSharedMemory(&shm);
out_finalize_ctx:
finalize_tee_ctx(ctx);
bail1:
out_free:
free(ctx);
free(ref_buf);
free(test_buf);
Expand Down Expand Up @@ -517,14 +571,14 @@ int sdp_out_of_bounds_memref_test(size_t size, const char *heap_name,
{
struct tee_ctx ctx = { };
int err = 0;
int fd = -1;
TEEC_Result teerc = TEEC_ERROR_GENERIC;
TEEC_SharedMemory in = { };
TEEC_SharedMemory *out = NULL;
TEEC_SharedMemory out = { };

if (create_tee_ctx(&ctx, TEST_NS_TO_TA))
return -1;

#if 0
fd = allocate_buffer(size, heap_name, verbosity);
if (fd < 0) {
verbose("SDP alloc failed (%zu bytes) in %s: %d\n",
Expand All @@ -536,12 +590,21 @@ int sdp_out_of_bounds_memref_test(size_t size, const char *heap_name,
err = 1;
goto bail;
}
#else
out.size = size;
out.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
teerc = TEEC_AllocateRestrictedMemory(&ctx.ctx, &out);
if (teerc) {
verbose("failed to allocate memory\n");
goto bail;
}
#endif

/*
* The ION driver will decide how much SDP memory is being allocated.
* Rely on this size to test out of bounds reference cases.
*/
size = out->size;
size = out.size;

in.size = size;
in.flags = TEEC_MEM_INPUT;
Expand All @@ -553,35 +616,33 @@ int sdp_out_of_bounds_memref_test(size_t size, const char *heap_name,

if (verbosity) {
/* Valid case: reference inside allocated buffer: last byte */
err += invoke_out_of_bounds(&ctx, &in, out, size - 1, 1,
err += invoke_out_of_bounds(&ctx, &in, &out, size - 1, 1,
true, verbosity);
}

/* Reference overflows allocated buffer by 1 byte */
err += invoke_out_of_bounds(&ctx, &in, out, size - 1, 2,
err += invoke_out_of_bounds(&ctx, &in, &out, size - 1, 2,
false, verbosity);

/* Reference oveflows allocated buffer by more than 4kB byte */
err += invoke_out_of_bounds(&ctx, &in, out, size - 1, 5000,
err += invoke_out_of_bounds(&ctx, &in, &out, size - 1, 5000,
false, verbosity);

/* Offset exceeds allocated buffer size value by 1 byte */
err += invoke_out_of_bounds(&ctx, &in, out, size, 1,
err += invoke_out_of_bounds(&ctx, &in, &out, size, 1,
false, verbosity);

/* Offset exceeds allocated size value by 4kByte */
err += invoke_out_of_bounds(&ctx, &in, out, size, 4096,
err += invoke_out_of_bounds(&ctx, &in, &out, size, 4096,
false, verbosity);

/* Offset + size overflows offset value */
err += invoke_out_of_bounds(&ctx, &in, out, 2, ~0,
err += invoke_out_of_bounds(&ctx, &in, &out, 2, ~0,
false, verbosity);

TEEC_ReleaseSharedMemory(&in);
bail:
tee_deregister_buffer(&ctx, out);
if (fd >= 0)
close(fd);
TEEC_ReleaseSharedMemory(&out);
finalize_tee_ctx(&ctx);

return err;
Expand Down

0 comments on commit e3ff5f4

Please sign in to comment.