xref: /OK3568_Linux_fs/external/security/rk_tee_user/v2/host/xtest/regression_8100.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018, Linaro Limited */
3 
4 #include "xtest_test.h"
5 #include "xtest_helpers.h"
6 
7 #include <stdarg.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ta_crypt.h>
12 #include <tee_api_types.h>
13 #include <adbg.h>
14 
15 #ifdef OPENSSL_FOUND
16 #include <openssl/x509_vfy.h>
17 #include <openssl/pem.h>
18 #include <openssl/err.h>
19 #include <openssl/crypto.h>
20 #endif
21 
22 #include "regression_8100_ca_crt.h"
23 #include "regression_8100_mid_crt.h"
24 #include "regression_8100_my_crt.h"
25 #include "regression_8100_my_csr.h"
26 
27 #ifdef CFG_TA_MBEDTLS
28 
test_8101(ADBG_Case_t * c __maybe_unused)29 static void test_8101(ADBG_Case_t *c __maybe_unused)
30 {
31 #ifdef CFG_TA_MBEDTLS_SELF_TEST
32 	TEEC_Session session = { };
33 	uint32_t ret_orig = 0;
34 
35 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
36 					      &session, &crypt_user_ta_uuid,
37 					      NULL, &ret_orig)))
38 		return;
39 	ADBG_EXPECT_TEEC_SUCCESS(c,
40 		TEEC_InvokeCommand(&session, TA_CRYPT_CMD_MBEDTLS_SELF_TESTS,
41 				   NULL, &ret_orig));
42 	TEEC_CloseSession(&session);
43 #else
44 	Do_ADBG_Log("CFG_TA_MBEDTLS_SELF_TEST not set, test skipped");
45 #endif
46 }
47 ADBG_CASE_DEFINE(regression, 8101, test_8101, "TA mbedTLS self tests");
48 
myasprintf(char ** strp,const char * fmt,...)49 static int __printf(2, 3) myasprintf(char **strp, const char *fmt, ...)
50 {
51 	char *str = NULL;
52 	int rc = 0;
53 	va_list ap;
54 
55 	va_start(ap, fmt);
56 	rc = vsnprintf(str, rc, fmt, ap);
57 	if (rc <= 0)
58 		goto out;
59 
60 	str = malloc(rc);
61 	if (!str) {
62 		rc = -1;
63 		goto out;
64 	}
65 
66 	rc = vsnprintf(str, rc, fmt, ap);
67 	if (rc <= 0)
68 		free(str);
69 	else
70 		*strp = str;
71 
72 out:
73 	va_end(ap);
74 	return rc;
75 }
76 
test_8102(ADBG_Case_t * c)77 static void test_8102(ADBG_Case_t *c)
78 {
79 	TEEC_Session session = { };
80 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
81 	uint32_t ret_orig = 0;
82 	char *chain = NULL;
83 	int clen = 0;
84 	char *trust = NULL;
85 	int tlen = 0;
86 
87 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
88 					      &session, &crypt_user_ta_uuid,
89 					      NULL, &ret_orig)))
90 		return;
91 
92 	clen = myasprintf(&chain, "%*s\n%*s",
93 			  (int)regression_8100_my_crt_size,
94 			  regression_8100_my_crt,
95 			  (int)regression_8100_mid_crt_size,
96 			   regression_8100_mid_crt);
97 	if (!ADBG_EXPECT_COMPARE_SIGNED(c, clen, !=, -1))
98 		goto out;
99 	tlen = myasprintf(&trust, "%*s", (int)regression_8100_ca_crt_size,
100 			  regression_8100_ca_crt);
101 	if (!ADBG_EXPECT_COMPARE_SIGNED(c, tlen, !=, -1))
102 		goto out;
103 
104 	op.params[0].tmpref.buffer = chain;
105 	op.params[0].tmpref.size = clen;
106 	op.params[1].tmpref.buffer = trust;
107 	op.params[1].tmpref.size = tlen;
108 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
109 					 TEEC_MEMREF_TEMP_INPUT,
110 					 TEEC_NONE, TEEC_NONE);
111 
112 	ADBG_EXPECT_TEEC_SUCCESS(c,
113 		TEEC_InvokeCommand(&session, TA_CRYPT_CMD_MBEDTLS_CHECK_CERT,
114 				   &op, &ret_orig));
115 out:
116 	free(chain);
117 	free(trust);
118 	TEEC_CloseSession(&session);
119 }
120 ADBG_CASE_DEFINE(regression, 8102, test_8102, "TA mbedTLS test cert chain");
121 
122 #ifdef OPENSSL_FOUND
osslerr(void)123 static void osslerr(void)
124 {
125 	while (true) {
126 		unsigned long e = 0;
127 		char b[256] = { };
128 		const char *f = NULL;
129 		int l = 0;
130 
131 		e = ERR_get_error_line(&f, &l);
132 		if (!e)
133 			return;
134 		ERR_error_string_n(e, b, sizeof(b));
135 		Do_ADBG_Log("%s:%d \"%s\"", f, l, b);
136 	}
137 }
138 
get_cert(ADBG_Case_t * c,const char * crt_str,X509 ** crt)139 static bool get_cert(ADBG_Case_t *c, const char *crt_str, X509 **crt)
140 {
141 	bool ret = false;
142 	size_t slen = strlen(crt_str) + 1;
143 	BIO *buf = BIO_new(BIO_s_mem());
144 	size_t b = 0;
145 
146 	if (!ADBG_EXPECT_NOT_NULL(c, buf))
147 		goto out;
148 
149 	b = BIO_write(buf, crt_str, slen);
150 	if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, b, ==, slen))
151 		goto out;
152 
153 	if (!PEM_read_bio_X509(buf, crt, 0, NULL))
154 		goto out;
155 
156 	ret = true;
157 out:
158 	if (!ret)
159 		osslerr();
160 	BIO_free(buf);
161 	return ret;
162 }
163 
push_cert(ADBG_Case_t * c,const char * crt_str,STACK_OF (X509)* cs)164 static bool push_cert(ADBG_Case_t *c, const char *crt_str, STACK_OF(X509) *cs)
165 {
166 	X509 *crt = NULL;
167 	int rc = 0;
168 
169 	if (!get_cert(c, crt_str, &crt))
170 		return false;
171 	rc = sk_X509_push(cs, crt);
172 	if (!ADBG_EXPECT_COMPARE_SIGNED(c, rc, >, 0)) {
173 		osslerr();
174 		X509_free(crt);
175 		return false;
176 	}
177 
178 	return true;
179 }
180 
check(ADBG_Case_t * c,STACK_OF (X509)* trusted,STACK_OF (X509)* untrusted,X509 * crt)181 static bool check(ADBG_Case_t *c, STACK_OF(X509) *trusted,
182 		  STACK_OF(X509) *untrusted, X509 *crt)
183 {
184 	bool ret = false;
185 	X509_STORE *store = NULL;
186 	X509_STORE_CTX *csc = NULL;
187 	X509_VERIFY_PARAM *pm = NULL;
188 	int i = 0;
189 	time_t vfy_time = 0;
190 
191 	pm = X509_VERIFY_PARAM_new();
192 	vfy_time = 1526898005; /* Mon, 21 May 2018 10:20:05 +0000 */
193 	X509_VERIFY_PARAM_set_time(pm, vfy_time);
194 
195 	store = X509_STORE_new();
196 	if (!ADBG_EXPECT_NOT_NULL(c, store))
197 		goto out;
198 	X509_STORE_set_flags(store, 0);
199 	if (!ADBG_EXPECT_TRUE(c, X509_STORE_set1_param(store, pm)))
200 		goto out;
201 
202 	csc = X509_STORE_CTX_new();
203 	if (!ADBG_EXPECT_NOT_NULL(c, csc))
204 		goto out;
205 
206 	if (!ADBG_EXPECT_TRUE(c, X509_STORE_CTX_init(csc, store, crt,
207 						     untrusted)))
208 		goto out;
209 	X509_STORE_CTX_trusted_stack(csc, trusted);
210 
211 	i = X509_verify_cert(csc);
212 	if (!ADBG_EXPECT_COMPARE_SIGNED(c, i, >, 0))
213 		goto out;
214 	i = X509_STORE_CTX_get_error(csc);
215 	if (!ADBG_EXPECT_COMPARE_SIGNED(c, i, ==, X509_V_OK))
216 		goto out;
217 	ret = true;
218 out:
219 	if (!ret)
220 		osslerr();
221 	X509_VERIFY_PARAM_free(pm);
222 	X509_STORE_free(store);
223 	X509_STORE_CTX_free(csc);
224 	return ret;
225 }
226 
verify_cert(ADBG_Case_t * c,const char * ca,const char * mid,const char * cert)227 static bool verify_cert(ADBG_Case_t *c, const char *ca, const char *mid,
228 			const char *cert)
229 {
230 	bool ret = false;
231 	STACK_OF(X509) *trusted = NULL;
232 	STACK_OF(X509) *untrusted = NULL;
233 	X509 *crt = NULL;
234 
235 	trusted = sk_X509_new_null();
236 	if (!ADBG_EXPECT_NOT_NULL(c, trusted))
237 		goto out;
238 	untrusted = sk_X509_new_null();
239 	if (!ADBG_EXPECT_NOT_NULL(c, untrusted))
240 		goto out;
241 
242 	if (!ADBG_EXPECT_TRUE(c, get_cert(c, cert, &crt)))
243 		goto out;
244 	if (!ADBG_EXPECT_TRUE(c, push_cert(c, mid, untrusted)))
245 		goto out;
246 	if (!ADBG_EXPECT_TRUE(c, push_cert(c, ca, trusted)))
247 		goto out;
248 
249 	ret = ADBG_EXPECT_TRUE(c, check(c, trusted, untrusted, crt));
250 out:
251 	if (!ret)
252 		osslerr();
253 	X509_free(crt);
254 	sk_X509_pop_free(untrusted, X509_free);
255 	sk_X509_pop_free(trusted, X509_free);
256 	return ret;
257 }
258 #else /*!OPENSSL_FOUND*/
verify_cert(ADBG_Case_t * c,const char * ca,const char * mid,const char * cert)259 static bool verify_cert(ADBG_Case_t *c, const char *ca,
260 			const char *mid, const char *cert)
261 {
262 	UNUSED(c);
263 	UNUSED(ca);
264 	UNUSED(mid);
265 	UNUSED(cert);
266 	Do_ADBG_Log("OpenSSL not available, skipping certificate verification");
267 	return true;
268 }
269 #endif
270 
test_8103(ADBG_Case_t * c)271 static void test_8103(ADBG_Case_t *c)
272 {
273 	TEEC_Result res = TEEC_ERROR_GENERIC;
274 	TEEC_Session session = { };
275 	TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
276 	uint32_t ret_orig = 0;
277 	char *csr = NULL;
278 	int clen = 0;
279 	char cert[2048];
280 	char chain[4096];
281 	char *ca = NULL;
282 
283 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
284 					      &session, &crypt_user_ta_uuid,
285 					      NULL, &ret_orig)))
286 		return;
287 
288 	clen = myasprintf(&csr, "%*s", (int)regression_8100_my_csr_size,
289 			  regression_8100_my_csr);
290 	if (!ADBG_EXPECT_COMPARE_SIGNED(c, clen, >=, 0))
291 		goto out;
292 	op.params[0].tmpref.buffer = csr;
293 	op.params[0].tmpref.size = clen;
294 	op.params[1].tmpref.buffer = cert;
295 	op.params[1].tmpref.size = sizeof(cert);
296 	op.params[2].tmpref.buffer = chain;
297 	op.params[2].tmpref.size = sizeof(chain);
298 	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
299 					 TEEC_MEMREF_TEMP_OUTPUT,
300 					 TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE);
301 	res = TEEC_InvokeCommand(&session, TA_CRYPT_CMD_MBEDTLS_SIGN_CERT, &op,
302 				 &ret_orig);
303 	if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
304 		goto out;
305 
306 	myasprintf(&ca, "%*s", (int)regression_8100_ca_crt_size,
307 		   regression_8100_ca_crt);
308 	if (!ADBG_EXPECT_NOT_NULL(c, ca))
309 		goto out;
310 	verify_cert(c, ca, op.params[2].tmpref.buffer,
311 		    op.params[1].tmpref.buffer);
312 out:
313 	free(ca);
314 	free(csr);
315 	TEEC_CloseSession(&session);
316 }
317 ADBG_CASE_DEFINE(regression, 8103, test_8103,
318 		 "TA mbedTLS process certificate request");
319 #endif /*CFG_TA_MBEDTLS*/
320