blob: a1f8d0d8acc6f917500a05cbfa92a85e2402acdc [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 <compiler.h>
8#include <stdarg.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
Jens Wiklander29326472018-04-20 11:22:15 +020012#include <ta_crypt.h>
13#include <tee_api_types.h>
Jens Wiklander950ea1c2018-04-30 15:39:22 +020014#include <adbg.h>
15
16#ifdef OPENSSL_FOUND
17#include <openssl/x509_vfy.h>
18#include <openssl/pem.h>
19#include <openssl/err.h>
20#include <openssl/crypto.h>
21#endif
Jens Wiklander97d6e292018-04-23 13:00:31 +020022
23#include "regression_8100_ca_crt.h"
24#include "regression_8100_mid_crt.h"
25#include "regression_8100_my_crt.h"
Jens Wiklander950ea1c2018-04-30 15:39:22 +020026#include "regression_8100_my_csr.h"
Jens Wiklander97d6e292018-04-23 13:00:31 +020027
28#ifdef CFG_TA_MBEDTLS
Jens Wiklander29326472018-04-20 11:22:15 +020029
30static void test_8101(ADBG_Case_t *c __maybe_unused)
31{
32#ifdef CFG_TA_MBEDTLS_SELF_TEST
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010033 TEEC_Session session = { };
34 uint32_t ret_orig = 0;
Jens Wiklander29326472018-04-20 11:22:15 +020035
36 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
37 &session, &crypt_user_ta_uuid,
38 NULL, &ret_orig)))
39 return;
40 ADBG_EXPECT_TEEC_SUCCESS(c,
41 TEEC_InvokeCommand(&session, TA_CRYPT_CMD_MBEDTLS_SELF_TESTS,
42 NULL, &ret_orig));
43 TEEC_CloseSession(&session);
44#else
45 Do_ADBG_Log("CFG_TA_MBEDTLS_SELF_TEST not set, test skipped");
46#endif
47}
48ADBG_CASE_DEFINE(regression, 8101, test_8101, "TA mbedTLS self tests");
Jens Wiklander97d6e292018-04-23 13:00:31 +020049
50static int __printf(2, 3) myasprintf(char **strp, const char *fmt, ...)
51{
52 char *str = NULL;
53 int rc = 0;
54 va_list ap;
55
56 va_start(ap, fmt);
57 rc = vsnprintf(str, rc, fmt, ap);
58 if (rc <= 0)
59 goto out;
60
61 str = malloc(rc);
62 if (!str) {
63 rc = -1;
64 goto out;
65 }
66
67 rc = vsnprintf(str, rc, fmt, ap);
68 if (rc <= 0)
69 free(str);
70 else
71 *strp = str;
72
73out:
74 va_end(ap);
75 return rc;
76}
77
78static void test_8102(ADBG_Case_t *c)
79{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010080 TEEC_Session session = { };
Jens Wiklander97d6e292018-04-23 13:00:31 +020081 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010082 uint32_t ret_orig = 0;
Jens Wiklander97d6e292018-04-23 13:00:31 +020083 char *chain = NULL;
84 int clen = 0;
85 char *trust = NULL;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +010086 int tlen = 0;
Jens Wiklander97d6e292018-04-23 13:00:31 +020087
88 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
89 &session, &crypt_user_ta_uuid,
90 NULL, &ret_orig)))
91 return;
92
93 clen = myasprintf(&chain, "%*s\n%*s",
Ricardo Salveti78ec4e92019-06-26 17:32:11 -030094 (int)regression_8100_my_crt_size,
Jens Wiklander97d6e292018-04-23 13:00:31 +020095 regression_8100_my_crt,
Ricardo Salveti78ec4e92019-06-26 17:32:11 -030096 (int)regression_8100_mid_crt_size,
Jens Wiklander97d6e292018-04-23 13:00:31 +020097 regression_8100_mid_crt);
98 if (!ADBG_EXPECT_COMPARE_SIGNED(c, clen, !=, -1))
99 goto out;
Ricardo Salveti78ec4e92019-06-26 17:32:11 -0300100 tlen = myasprintf(&trust, "%*s", (int)regression_8100_ca_crt_size,
Jens Wiklander97d6e292018-04-23 13:00:31 +0200101 regression_8100_ca_crt);
102 if (!ADBG_EXPECT_COMPARE_SIGNED(c, tlen, !=, -1))
103 goto out;
104
105 op.params[0].tmpref.buffer = chain;
106 op.params[0].tmpref.size = clen;
107 op.params[1].tmpref.buffer = trust;
108 op.params[1].tmpref.size = tlen;
109 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
110 TEEC_MEMREF_TEMP_INPUT,
111 TEEC_NONE, TEEC_NONE);
112
113 ADBG_EXPECT_TEEC_SUCCESS(c,
114 TEEC_InvokeCommand(&session, TA_CRYPT_CMD_MBEDTLS_CHECK_CERT,
115 &op, &ret_orig));
116out:
117 free(chain);
118 free(trust);
119 TEEC_CloseSession(&session);
120}
121ADBG_CASE_DEFINE(regression, 8102, test_8102, "TA mbedTLS test cert chain");
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200122
123#ifdef OPENSSL_FOUND
124static void osslerr(void)
125{
126 while (true) {
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100127 unsigned long e = 0;
128 char b[256] = { };
129 const char *f = NULL;
130 int l = 0;
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200131
132 e = ERR_get_error_line(&f, &l);
133 if (!e)
134 return;
135 ERR_error_string_n(e, b, sizeof(b));
136 Do_ADBG_Log("%s:%d \"%s\"", f, l, b);
137 }
138}
139
140static bool get_cert(ADBG_Case_t *c, const char *crt_str, X509 **crt)
141{
142 bool ret = false;
143 size_t slen = strlen(crt_str) + 1;
144 BIO *buf = BIO_new(BIO_s_mem());
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100145 size_t b = 0;
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200146
147 if (!ADBG_EXPECT_NOT_NULL(c, buf))
148 goto out;
149
150 b = BIO_write(buf, crt_str, slen);
151 if (!ADBG_EXPECT_COMPARE_UNSIGNED(c, b, ==, slen))
152 goto out;
153
154 if (!PEM_read_bio_X509(buf, crt, 0, NULL))
155 goto out;
156
157 ret = true;
158out:
159 if (!ret)
160 osslerr();
161 BIO_free(buf);
162 return ret;
163}
164
165static bool push_cert(ADBG_Case_t *c, const char *crt_str, STACK_OF(X509) *cs)
166{
167 X509 *crt = NULL;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100168 int rc = 0;
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200169
170 if (!get_cert(c, crt_str, &crt))
171 return false;
172 rc = sk_X509_push(cs, crt);
173 if (!ADBG_EXPECT_COMPARE_SIGNED(c, rc, >, 0)) {
174 osslerr();
175 X509_free(crt);
176 return false;
177 }
178
179 return true;
180}
181
182static bool check(ADBG_Case_t *c, STACK_OF(X509) *trusted,
183 STACK_OF(X509) *untrusted, X509 *crt)
184{
185 bool ret = false;
186 X509_STORE *store = NULL;
187 X509_STORE_CTX *csc = NULL;
188 X509_VERIFY_PARAM *pm = NULL;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100189 int i = 0;
190 time_t vfy_time = 0;
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200191
192 pm = X509_VERIFY_PARAM_new();
193 vfy_time = 1526898005; /* Mon, 21 May 2018 10:20:05 +0000 */
194 X509_VERIFY_PARAM_set_time(pm, vfy_time);
195
196 store = X509_STORE_new();
197 if (!ADBG_EXPECT_NOT_NULL(c, store))
198 goto out;
199 X509_STORE_set_flags(store, 0);
200 if (!ADBG_EXPECT_TRUE(c, X509_STORE_set1_param(store, pm)))
201 goto out;
202
203 csc = X509_STORE_CTX_new();
204 if (!ADBG_EXPECT_NOT_NULL(c, csc))
205 goto out;
206
207 if (!ADBG_EXPECT_TRUE(c, X509_STORE_CTX_init(csc, store, crt,
208 untrusted)))
209 goto out;
210 X509_STORE_CTX_trusted_stack(csc, trusted);
211
212 i = X509_verify_cert(csc);
213 if (!ADBG_EXPECT_COMPARE_SIGNED(c, i, >, 0))
214 goto out;
215 i = X509_STORE_CTX_get_error(csc);
216 if (!ADBG_EXPECT_COMPARE_SIGNED(c, i, ==, X509_V_OK))
217 goto out;
218 ret = true;
219out:
220 if (!ret)
221 osslerr();
222 X509_VERIFY_PARAM_free(pm);
223 X509_STORE_free(store);
224 X509_STORE_CTX_free(csc);
225 return ret;
226}
227
228static bool verify_cert(ADBG_Case_t *c, const char *ca, const char *mid,
229 const char *cert)
230{
231 bool ret = false;
232 STACK_OF(X509) *trusted = NULL;
233 STACK_OF(X509) *untrusted = NULL;
234 X509 *crt = NULL;
235
236 trusted = sk_X509_new_null();
237 if (!ADBG_EXPECT_NOT_NULL(c, trusted))
238 goto out;
239 untrusted = sk_X509_new_null();
240 if (!ADBG_EXPECT_NOT_NULL(c, untrusted))
241 goto out;
242
243 if (!ADBG_EXPECT_TRUE(c, get_cert(c, cert, &crt)))
244 goto out;
245 if (!ADBG_EXPECT_TRUE(c, push_cert(c, mid, untrusted)))
246 goto out;
247 if (!ADBG_EXPECT_TRUE(c, push_cert(c, ca, trusted)))
248 goto out;
249
250 ret = ADBG_EXPECT_TRUE(c, check(c, trusted, untrusted, crt));
251out:
252 if (!ret)
253 osslerr();
254 X509_free(crt);
255 sk_X509_pop_free(untrusted, X509_free);
256 sk_X509_pop_free(trusted, X509_free);
257 return ret;
258}
259#else /*!OPENSSL_FOUND*/
260static bool verify_cert(ADBG_Case_t *c __unused, const char *ca __unused,
261 const char *mid __unused, const char *cert __unused)
262{
263 Do_ADBG_Log("OpenSSL not available, skipping certificate verification");
264 return true;
265}
266#endif
267
268static void test_8103(ADBG_Case_t *c)
269{
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100270 TEEC_Result res = TEEC_ERROR_GENERIC;
271 TEEC_Session session = { };
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200272 TEEC_Operation op = TEEC_OPERATION_INITIALIZER;
Etienne Carrieree4ec9e42019-03-28 13:30:21 +0100273 uint32_t ret_orig = 0;
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200274 char *csr = NULL;
275 int clen = 0;
276 char cert[2048];
277 char chain[4096];
278 char *ca = NULL;
279
280 if (!ADBG_EXPECT_TEEC_SUCCESS(c, xtest_teec_open_session(
281 &session, &crypt_user_ta_uuid,
282 NULL, &ret_orig)))
283 return;
284
Ricardo Salveti78ec4e92019-06-26 17:32:11 -0300285 clen = myasprintf(&csr, "%*s", (int)regression_8100_my_csr_size,
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200286 regression_8100_my_csr);
287 if (!ADBG_EXPECT_COMPARE_SIGNED(c, clen, >=, 0))
288 goto out;
289 op.params[0].tmpref.buffer = csr;
290 op.params[0].tmpref.size = clen;
291 op.params[1].tmpref.buffer = cert;
292 op.params[1].tmpref.size = sizeof(cert);
293 op.params[2].tmpref.buffer = chain;
294 op.params[2].tmpref.size = sizeof(chain);
295 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
296 TEEC_MEMREF_TEMP_OUTPUT,
297 TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE);
298 res = TEEC_InvokeCommand(&session, TA_CRYPT_CMD_MBEDTLS_SIGN_CERT, &op,
299 &ret_orig);
300 if (!ADBG_EXPECT_TEEC_SUCCESS(c, res))
301 goto out;
302
Ricardo Salveti78ec4e92019-06-26 17:32:11 -0300303 myasprintf(&ca, "%*s", (int)regression_8100_ca_crt_size,
Jens Wiklander950ea1c2018-04-30 15:39:22 +0200304 regression_8100_ca_crt);
305 if (!ADBG_EXPECT_NOT_NULL(c, ca))
306 goto out;
307 verify_cert(c, ca, op.params[2].tmpref.buffer,
308 op.params[1].tmpref.buffer);
309out:
310 free(ca);
311 free(csr);
312 TEEC_CloseSession(&session);
313}
314ADBG_CASE_DEFINE(regression, 8103, test_8103,
315 "TA mbedTLS process certificate request");
Jens Wiklander97d6e292018-04-23 13:00:31 +0200316#endif /*CFG_TA_MBEDTLS*/