/*
|
* Copyright (c) 2017, Linaro Limited
|
*
|
* SPDX-License-Identifier: BSD-2-Clause
|
*/
|
|
#include <dirent.h>
|
#include <err.h>
|
#include <errno.h>
|
#include <fnmatch.h>
|
#include <inttypes.h>
|
#include <pta_secstor_ta_mgmt.h>
|
#include <stdbool.h>
|
#include <stdint.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <sys/stat.h>
|
#include <sys/types.h>
|
#include <tee_client_api.h>
|
#include <unistd.h>
|
|
#include "install_ta.h"
|
#include "xtest_helpers.h"
|
#include "xtest_test.h"
|
|
static void *read_ta(const char *dname, const char *fname, size_t *size)
|
{
|
char nbuf[PATH_MAX];
|
FILE *f = NULL;
|
void *buf = NULL;
|
size_t s = 0;
|
|
if (dname)
|
snprintf(nbuf, sizeof(nbuf), "%s/%s", dname, fname);
|
else
|
snprintf(nbuf, sizeof(nbuf), "%s", fname);
|
|
f = fopen(nbuf, "rb");
|
if (!f)
|
err(1, "fopen(\"%s\")", nbuf);
|
|
if (fseek(f, 0, SEEK_END))
|
err(1, "fseek");
|
|
s = ftell(f);
|
rewind(f);
|
|
buf = malloc(s);
|
if (!buf)
|
err(1, "malloc(%zu)", s);
|
|
if (fread(buf, 1, s, f) != s)
|
err(1, "fread");
|
|
*size = s;
|
return buf;
|
}
|
|
static void install_ta(TEEC_Session *sess, void *buf, size_t blen)
|
{
|
TEEC_Result res = TEEC_ERROR_GENERIC;
|
uint32_t err_origin = 0;
|
TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
|
|
op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
|
TEEC_NONE, TEEC_NONE);
|
op.params[0].tmpref.buffer = buf;
|
op.params[0].tmpref.size = blen;
|
|
res = TEEC_InvokeCommand(sess, PTA_SECSTOR_TA_MGMT_BOOTSTRAP, &op,
|
&err_origin);
|
if (res)
|
errx(1, "install_ta: TEEC_InvokeCommand: %#" PRIx32
|
" err_origin %#" PRIx32, res, err_origin);
|
}
|
|
static void install_file(TEEC_Session *sess, const char *dirname,
|
const char *filename)
|
{
|
void *ta = NULL;
|
size_t ta_size = 0;
|
|
printf("Installing \"%s\"\n", filename);
|
ta = read_ta(dirname, filename, &ta_size);
|
install_ta(sess, ta, ta_size);
|
free(ta);
|
}
|
|
static void install_dir(TEEC_Session *sess, const char *dirname)
|
{
|
DIR *dirp = NULL;
|
|
printf("Searching directory \"%s\" for TAs\n", dirname);
|
dirp = opendir(dirname);
|
if (!dirp)
|
err(1, "opendir(\"%s\")", dirname);
|
|
while (true) {
|
struct dirent *dent = readdir(dirp);
|
|
if (!dent)
|
break;
|
|
if (fnmatch("*.ta", dent->d_name, 0))
|
continue;
|
|
install_file(sess, dirname, dent->d_name);
|
}
|
|
closedir(dirp);
|
}
|
|
int install_ta_runner_cmd_parser(int argc, char *argv[])
|
{
|
TEEC_Result res = TEEC_ERROR_GENERIC;
|
uint32_t err_origin = 0;
|
TEEC_UUID uuid = PTA_SECSTOR_TA_MGMT_UUID;
|
TEEC_Context ctx = { };
|
TEEC_Session sess = { };
|
int i = 0;
|
|
res = TEEC_InitializeContext(NULL, &ctx);
|
if (res)
|
errx(1, "TEEC_InitializeContext: %#" PRIx32, res);
|
|
res = TEEC_OpenSession(&ctx, &sess, &uuid, TEEC_LOGIN_PUBLIC, NULL,
|
NULL, &err_origin);
|
if (res)
|
errx(1, "TEEC_OpenSession: res %#" PRIx32 " err_orig %#" PRIx32,
|
res, err_origin);
|
|
for (i = 1; i < argc; i++) {
|
struct stat sb = { };
|
|
if (stat(argv[i], &sb)) {
|
printf("Skipping \"%s\": %s", argv[i], strerror(errno));
|
continue;
|
}
|
|
if (S_ISDIR(sb.st_mode))
|
install_dir(&sess, argv[i]);
|
else if (S_ISREG(sb.st_mode))
|
install_file(&sess, NULL, argv[i]);
|
else
|
printf("Skipping unknown file type \"%s\", mode 0%o",
|
argv[i], sb.st_mode);
|
}
|
|
TEEC_CloseSession(&sess);
|
TEEC_FinalizeContext(&ctx);
|
|
printf("Installing TAs done\n");
|
|
return 0;
|
}
|