1 /*
2 * Copyright (c) 2017, Linaro Limited
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7 #include <dirent.h>
8 #include <err.h>
9 #include <errno.h>
10 #include <fnmatch.h>
11 #include <inttypes.h>
12 #include <pta_secstor_ta_mgmt.h>
13 #include <stdbool.h>
14 #include <stdint.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <tee_client_api.h>
21 #include <unistd.h>
22
23 #include "install_ta.h"
24 #include "xtest_helpers.h"
25 #include "xtest_test.h"
26
read_ta(const char * dname,const char * fname,size_t * size)27 static void *read_ta(const char *dname, const char *fname, size_t *size)
28 {
29 char nbuf[PATH_MAX];
30 FILE *f = NULL;
31 void *buf = NULL;
32 size_t s = 0;
33
34 if (dname)
35 snprintf(nbuf, sizeof(nbuf), "%s/%s", dname, fname);
36 else
37 snprintf(nbuf, sizeof(nbuf), "%s", fname);
38
39 f = fopen(nbuf, "rb");
40 if (!f)
41 err(1, "fopen(\"%s\")", nbuf);
42
43 if (fseek(f, 0, SEEK_END))
44 err(1, "fseek");
45
46 s = ftell(f);
47 rewind(f);
48
49 buf = malloc(s);
50 if (!buf)
51 err(1, "malloc(%zu)", s);
52
53 if (fread(buf, 1, s, f) != s)
54 err(1, "fread");
55
56 *size = s;
57 return buf;
58 }
59
install_ta(TEEC_Session * sess,void * buf,size_t blen)60 static void install_ta(TEEC_Session *sess, void *buf, size_t blen)
61 {
62 TEEC_Result res = TEEC_ERROR_GENERIC;
63 uint32_t err_origin = 0;
64 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
65
66 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE,
67 TEEC_NONE, TEEC_NONE);
68 op.params[0].tmpref.buffer = buf;
69 op.params[0].tmpref.size = blen;
70
71 res = TEEC_InvokeCommand(sess, PTA_SECSTOR_TA_MGMT_BOOTSTRAP, &op,
72 &err_origin);
73 if (res)
74 errx(1, "install_ta: TEEC_InvokeCommand: %#" PRIx32
75 " err_origin %#" PRIx32, res, err_origin);
76 }
77
install_file(TEEC_Session * sess,const char * dirname,const char * filename)78 static void install_file(TEEC_Session *sess, const char *dirname,
79 const char *filename)
80 {
81 void *ta = NULL;
82 size_t ta_size = 0;
83
84 printf("Installing \"%s\"\n", filename);
85 ta = read_ta(dirname, filename, &ta_size);
86 install_ta(sess, ta, ta_size);
87 free(ta);
88 }
89
install_dir(TEEC_Session * sess,const char * dirname)90 static void install_dir(TEEC_Session *sess, const char *dirname)
91 {
92 DIR *dirp = NULL;
93
94 printf("Searching directory \"%s\" for TAs\n", dirname);
95 dirp = opendir(dirname);
96 if (!dirp)
97 err(1, "opendir(\"%s\")", dirname);
98
99 while (true) {
100 struct dirent *dent = readdir(dirp);
101
102 if (!dent)
103 break;
104
105 if (fnmatch("*.ta", dent->d_name, 0))
106 continue;
107
108 install_file(sess, dirname, dent->d_name);
109 }
110
111 closedir(dirp);
112 }
113
install_ta_runner_cmd_parser(int argc,char * argv[])114 int install_ta_runner_cmd_parser(int argc, char *argv[])
115 {
116 TEEC_Result res = TEEC_ERROR_GENERIC;
117 uint32_t err_origin = 0;
118 TEEC_UUID uuid = PTA_SECSTOR_TA_MGMT_UUID;
119 TEEC_Context ctx = { };
120 TEEC_Session sess = { };
121 int i = 0;
122
123 res = TEEC_InitializeContext(NULL, &ctx);
124 if (res)
125 errx(1, "TEEC_InitializeContext: %#" PRIx32, res);
126
127 res = TEEC_OpenSession(&ctx, &sess, &uuid, TEEC_LOGIN_PUBLIC, NULL,
128 NULL, &err_origin);
129 if (res)
130 errx(1, "TEEC_OpenSession: res %#" PRIx32 " err_orig %#" PRIx32,
131 res, err_origin);
132
133 for (i = 1; i < argc; i++) {
134 struct stat sb = { };
135
136 if (stat(argv[i], &sb)) {
137 printf("Skipping \"%s\": %s", argv[i], strerror(errno));
138 continue;
139 }
140
141 if (S_ISDIR(sb.st_mode))
142 install_dir(&sess, argv[i]);
143 else if (S_ISREG(sb.st_mode))
144 install_file(&sess, NULL, argv[i]);
145 else
146 printf("Skipping unknown file type \"%s\", mode 0%o",
147 argv[i], sb.st_mode);
148 }
149
150 TEEC_CloseSession(&sess);
151 TEEC_FinalizeContext(&ctx);
152
153 printf("Installing TAs done\n");
154
155 return 0;
156 }
157