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