blob: 859ceccca30bf6740cda16b8cb5a9258d5a20cbb [file] [log] [blame]
Jens Wiklander29326472018-04-20 11:22:15 +02001// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2018, Linaro Limited */
3
4#include "xtest_test.h"
5#include "xtest_helpers.h"
6
Jens Wiklander97d6e292018-04-23 13:00:31 +02007#include <stdarg.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
Jens Wiklander29326472018-04-20 11:22:15 +020011#include <ta_crypt.h>
12#include <tee_api_types.h>
Jens Wiklander950ea1c2018-04-30 15:39:22 +020013#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
Jens Wiklander97d6e292018-04-23 13:00:31 +020021
22#include "regression_8100_ca_crt.h"
23#include "regression_8100_mid_crt.h"
24#include "regression_8100_my_crt.h"
Jens Wiklander950ea1c2018-04-30 15:39:22 +020025#include "regression_8100_my_csr.h"
Jens Wiklander97d6e292018-04-23 13:00:31 +020026
27#ifdef CFG_TA_MBEDTLS
Jens Wiklander29326472018-04-20 11:22:15 +020028
29static void test_8101(ADBG_Case_t *c __maybe_unused)
30{
31#ifdef CFG_TA_MBEDTLS_SELF_TEST
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010032 TEEC_Session session = { };
33 uint32_t ret_orig = 0;
Jens Wiklander29326472018-04-20 11:22:15 +020034
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}
47ADBG_CASE_DEFINE(regression, 8101, test_8101, "TA mbedTLS self tests");
Jens Wiklander97d6e292018-04-23 13:00:31 +020048
49static 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);
Jingdong Lu4502ca72021-06-24 10:25:56 +080057 va_end(ap);
Jens Wiklander97d6e292018-04-23 13:00:31 +020058 if (rc <= 0)
59 goto out;
60
61 str = malloc(rc);
62 if (!str) {
63 rc = -1;
64 goto out;
65 }
66
Jingdong Lu4502ca72021-06-24 10:25:56 +080067 va_start(ap, fmt);
Jens Wiklander97d6e292018-04-23 13:00:31 +020068 rc = vsnprintf(str, rc, fmt, ap);
Jingdong Lu4502ca72021-06-24 10:25:56 +080069 va_end(ap);
Jens Wiklander97d6e292018-04-23 13:00:31 +020070 if (rc <= 0)
71 free(str);
72 else
73 *strp = str;
74
75out:
Jens Wiklander97d6e292018-04-23 13:00:31 +020076 return rc;
77}
78
79static void test_8102(ADBG_Case_t *c)
80{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010081 TEEC_Session session = { };
Jens Wiklander97d6e292018-04-23 13:00:31 +020082 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010083 uint32_t ret_orig = 0;
Jens Wiklander97d6e292018-04-23 13:00:31 +020084 char *chain = NULL;
85 int clen = 0;
86 char *trust = NULL;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010087 int tlen = 0;
Jens Wiklander97d6e292018-04-23 13:00:31 +020088
89 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
90 &session, &crypt_user_ta_uuid,
91 NULL, &ret_orig)))
92 return;
93
94 clen = myasprintf(&chain, "%*s\n%*s",
Ricardo Salveti78ec4e92019-06-26 17:32:11 -030095 (int)regression_8100_my_crt_size,
Jens Wiklander97d6e292018-04-23 13:00:31 +020096 regression_8100_my_crt,
Ricardo Salveti78ec4e92019-06-26 17:32:11 -030097 (int)regression_8100_mid_crt_size,
Jens Wiklander97d6e292018-04-23 13:00:31 +020098 regression_8100_mid_crt);
99 if (!ADBG_EXPECT_COMPARE_SIGNED(c, clen, !=, -1))
100 goto out;
Ricardo Salveti78ec4e92019-06-26 17:32:11 -0300101 tlen = myasprintf(&trust, "%*s", (int)regression_8100_ca_crt_size,
Jens Wiklander97d6e292018-04-23 13:00:31 +0200102 regression_8100_ca_crt);
103 if (!ADBG_EXPECT_COMPARE_SIGNED(c, tlen, !=, -1))
104 goto out;
105
106 op.params[0].tmpref.buffer = chain;
107 op.params[0].tmpref.size = clen;
108 op.params[1].tmpref.buffer = trust;
109 op.params[1].tmpref.size = tlen;
110 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
111 TEEC_MEMREF_TEMP_INPUT,
112 TEEC_NONE, TEEC_NONE);
113
114 ADBG_EXPECT_TEEC_SUCCESS(c,
115 TEEC_InvokeCommand(&session, TA_CRYPT_CMD_MBEDTLS_CHECK_CERT,
116 &op, &ret_orig));
117out:
118 free(chain);
119 free(trust);
120 TEEC_CloseSession(&session);
121}
122ADBG_CASE_DEFINE(regression, 8102, test_8102, "TA mbedTLS test cert chain");
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200123
124#ifdef OPENSSL_FOUND
125static void osslerr(void)
126{
127 while (true) {
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100128 unsigned long e = 0;
129 char b[256] = { };
130 const char *f = NULL;
131 int l = 0;
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200132
133 e = ERR_get_error_line(&f, &l);
134 if (!e)
135 return;
136 ERR_error_string_n(e, b, sizeof(b));
137 Do_ADBG_Log("%s:%d \"%s\"", f, l, b);
138 }
139}
140
141static bool get_cert(ADBG_Case_t *c, const char *crt_str, X509 **crt)
142{
143 bool ret = false;
144 size_t slen = strlen(crt_str) + 1;
145 BIO *buf = BIO_new(BIO_s_mem());
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100146 size_t b = 0;
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200147
148 if (!ADBG_EXPECT_NOT_NULL(c, buf))
149 goto out;
150
151 b = BIO_write(buf, crt_str, slen);
152 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, b, ==, slen))
153 goto out;
154
155 if (!PEM_read_bio_X509(buf, crt, 0, NULL))
156 goto out;
157
158 ret = true;
159out:
160 if (!ret)
161 osslerr();
162 BIO_free(buf);
163 return ret;
164}
165
166static bool push_cert(ADBG_Case_t *c, const char *crt_str, STACK_OF(X509) *cs)
167{
168 X509 *crt = NULL;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100169 int rc = 0;
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200170
171 if (!get_cert(c, crt_str, &crt))
172 return false;
173 rc = sk_X509_push(cs, crt);
174 if (!ADBG_EXPECT_COMPARE_SIGNED(c, rc, >, 0)) {
175 osslerr();
176 X509_free(crt);
177 return false;
178 }
179
180 return true;
181}
182
183static bool check(ADBG_Case_t *c, STACK_OF(X509) *trusted,
184 STACK_OF(X509) *untrusted, X509 *crt)
185{
186 bool ret = false;
187 X509_STORE *store = NULL;
188 X509_STORE_CTX *csc = NULL;
189 X509_VERIFY_PARAM *pm = NULL;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100190 int i = 0;
191 time_t vfy_time = 0;
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200192
193 pm = X509_VERIFY_PARAM_new();
194 vfy_time = 1526898005; /* Mon, 21 May 2018 10:20:05 +0000 */
195 X509_VERIFY_PARAM_set_time(pm, vfy_time);
196
197 store = X509_STORE_new();
198 if (!ADBG_EXPECT_NOT_NULL(c, store))
199 goto out;
200 X509_STORE_set_flags(store, 0);
201 if (!ADBG_EXPECT_TRUE(c, X509_STORE_set1_param(store, pm)))
202 goto out;
203
204 csc = X509_STORE_CTX_new();
205 if (!ADBG_EXPECT_NOT_NULL(c, csc))
206 goto out;
207
208 if (!ADBG_EXPECT_TRUE(c, X509_STORE_CTX_init(csc, store, crt,
209 untrusted)))
210 goto out;
211 X509_STORE_CTX_trusted_stack(csc, trusted);
212
213 i = X509_verify_cert(csc);
214 if (!ADBG_EXPECT_COMPARE_SIGNED(c, i, >, 0))
215 goto out;
216 i = X509_STORE_CTX_get_error(csc);
217 if (!ADBG_EXPECT_COMPARE_SIGNED(c, i, ==, X509_V_OK))
218 goto out;
219 ret = true;
220out:
221 if (!ret)
222 osslerr();
223 X509_VERIFY_PARAM_free(pm);
224 X509_STORE_free(store);
225 X509_STORE_CTX_free(csc);
226 return ret;
227}
228
229static bool verify_cert(ADBG_Case_t *c, const char *ca, const char *mid,
230 const char *cert)
231{
232 bool ret = false;
233 STACK_OF(X509) *trusted = NULL;
234 STACK_OF(X509) *untrusted = NULL;
235 X509 *crt = NULL;
236
237 trusted = sk_X509_new_null();
238 if (!ADBG_EXPECT_NOT_NULL(c, trusted))
239 goto out;
240 untrusted = sk_X509_new_null();
241 if (!ADBG_EXPECT_NOT_NULL(c, untrusted))
242 goto out;
243
244 if (!ADBG_EXPECT_TRUE(c, get_cert(c, cert, &crt)))
245 goto out;
246 if (!ADBG_EXPECT_TRUE(c, push_cert(c, mid, untrusted)))
247 goto out;
248 if (!ADBG_EXPECT_TRUE(c, push_cert(c, ca, trusted)))
249 goto out;
250
251 ret = ADBG_EXPECT_TRUE(c, check(c, trusted, untrusted, crt));
252out:
253 if (!ret)
254 osslerr();
255 X509_free(crt);
256 sk_X509_pop_free(untrusted, X509_free);
257 sk_X509_pop_free(trusted, X509_free);
258 return ret;
259}
260#else /*!OPENSSL_FOUND*/
Jerome Forissier659e2212020-10-27 18:39:05 +0100261static bool verify_cert(ADBG_Case_t *c, const char *ca,
262 const char *mid, const char *cert)
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200263{
Victor Chong381bfab2020-11-26 18:17:15 +0900264 UNUSED(c);
265 UNUSED(ca);
266 UNUSED(mid);
267 UNUSED(cert);
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200268 Do_ADBG_Log("OpenSSL not available, skipping certificate verification");
269 return true;
270}
271#endif
272
273static void test_8103(ADBG_Case_t *c)
274{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100275 TEEC_Result res = TEEC_ERROR_GENERIC;
276 TEEC_Session session = { };
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200277 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100278 uint32_t ret_orig = 0;
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200279 char *csr = NULL;
280 int clen = 0;
281 char cert[2048];
282 char chain[4096];
283 char *ca = NULL;
284
285 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
286 &session, &crypt_user_ta_uuid,
287 NULL, &ret_orig)))
288 return;
289
Ricardo Salveti78ec4e92019-06-26 17:32:11 -0300290 clen = myasprintf(&csr, "%*s", (int)regression_8100_my_csr_size,
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200291 regression_8100_my_csr);
292 if (!ADBG_EXPECT_COMPARE_SIGNED(c, clen, >=, 0))
293 goto out;
294 op.params[0].tmpref.buffer = csr;
295 op.params[0].tmpref.size = clen;
296 op.params[1].tmpref.buffer = cert;
297 op.params[1].tmpref.size = sizeof(cert);
298 op.params[2].tmpref.buffer = chain;
299 op.params[2].tmpref.size = sizeof(chain);
300 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
301 TEEC_MEMREF_TEMP_OUTPUT,
302 TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE);
303 res = TEEC_InvokeCommand(&session, TA_CRYPT_CMD_MBEDTLS_SIGN_CERT, &op,
304 &ret_orig);
305 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
306 goto out;
307
Ricardo Salveti78ec4e92019-06-26 17:32:11 -0300308 myasprintf(&ca, "%*s", (int)regression_8100_ca_crt_size,
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200309 regression_8100_ca_crt);
310 if (!ADBG_EXPECT_NOT_NULL(c, ca))
311 goto out;
312 verify_cert(c, ca, op.params[2].tmpref.buffer,
313 op.params[1].tmpref.buffer);
314out:
315 free(ca);
316 free(csr);
317 TEEC_CloseSession(&session);
318}
319ADBG_CASE_DEFINE(regression, 8103, test_8103,
320 "TA mbedTLS process certificate request");
Jens Wiklander97d6e292018-04-23 13:00:31 +0200321#endif /*CFG_TA_MBEDTLS*/