blob: f94a5b4dd28336b138e92f4d589dabc303a49474 [file] [log] [blame]
Jens Wiklanderac27ec12015-07-15 15:23:14 +02001/*
2 * Copyright (c) 2015, Linaro Limited
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <tee_ta_api.h>
29#include <tee_api.h>
30#include <ta_concurrent.h>
31#include <trace.h>
32#include <utee_defines.h>
33
34uint32_t atomic_inc(uint32_t *v);
35uint32_t atomic_dec(uint32_t *v);
36
37TEE_Result TA_CreateEntryPoint(void)
38{
39 return TEE_SUCCESS;
40}
41
42void TA_DestroyEntryPoint(void)
43{
44}
45
46TEE_Result TA_OpenSessionEntryPoint(uint32_t param_types,
47 TEE_Param params[4],
48 void **session_ctx)
49{
50 (void)param_types;
51 (void)params;
52 (void)session_ctx;
53 return TEE_SUCCESS;
54}
55
56void TA_CloseSessionEntryPoint(void *session_ctx)
57{
58 (void)session_ctx;
59}
60
61static uint32_t inc_active_count(struct ta_concurrent_shm *shm)
62{
63 return atomic_inc(&shm->active_count);
64}
65
66static uint32_t dec_active_count(struct ta_concurrent_shm *shm)
67{
68 return atomic_dec(&shm->active_count);
69}
70
71
72static TEE_Result ta_entry_busy_loop(uint32_t param_types, TEE_Param params[4])
73{
74 size_t num_rounds;
75 uint32_t req_param_types =
76 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
77 TEE_PARAM_TYPE_VALUE_INOUT,
78 TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);
79
80 if (param_types != req_param_types) {
81 EMSG("got param_types 0x%x, expected 0x%x",
82 param_types, req_param_types);
83 return TEE_ERROR_BAD_PARAMETERS;
84 }
85
86 if (params[0].memref.size < sizeof(struct ta_concurrent_shm))
87 return TEE_ERROR_BAD_PARAMETERS;
88
89 params[1].value.b = inc_active_count(params[0].memref.buffer);
90
91 num_rounds = params[1].value.a;
92 while (num_rounds) {
93 volatile size_t n = 1000;
94
95 while (n)
96 n--;
97
98 num_rounds--;
99 }
100
101 dec_active_count(params[0].memref.buffer);
102 return TEE_SUCCESS;
103}
104
105static TEE_Result ta_entry_sha256(uint32_t param_types, TEE_Param params[4])
106{
107 TEE_Result res;
108 TEE_OperationHandle op = TEE_HANDLE_NULL;
109 void *out;
110 uint32_t out_len;
111 size_t num_rounds;
112 uint32_t req_param_types =
113 TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
114 TEE_PARAM_TYPE_VALUE_INOUT,
115 TEE_PARAM_TYPE_MEMREF_INPUT,
116 TEE_PARAM_TYPE_MEMREF_OUTPUT);
117
118 if (param_types != req_param_types) {
119 EMSG("got param_types 0x%x, expected 0x%x",
120 param_types, req_param_types);
121 return TEE_ERROR_BAD_PARAMETERS;
122 }
123
124 if (params[0].memref.size < sizeof(struct ta_concurrent_shm))
125 return TEE_ERROR_BAD_PARAMETERS;
126 if (params[3].memref.size < TEE_SHA256_HASH_SIZE)
127 return TEE_ERROR_BAD_PARAMETERS;
128
129 params[1].value.b = inc_active_count(params[0].memref.buffer);
130
131 out_len = params[3].memref.size;
132 out = TEE_Malloc(out_len, 0);
133 if (!out) {
134 res = TEE_ERROR_OUT_OF_MEMORY;
135 goto out;
136 }
137
138 res = TEE_AllocateOperation(&op, TEE_ALG_SHA256, TEE_MODE_DIGEST, 0);
139 if (res != TEE_SUCCESS)
140 goto out;
141
142
143 num_rounds = params[1].value.a;
144 while (num_rounds) {
145 TEE_ResetOperation(op);
146 res = TEE_DigestDoFinal(op, params[2].memref.buffer,
147 params[2].memref.size, out, &out_len);
148 num_rounds--;
149 }
150
151 TEE_MemMove(params[3].memref.buffer, out, out_len);
152 params[3].memref.size = out_len;
153
154out:
155 if (out)
156 TEE_Free(out);
157 if (op)
158 TEE_FreeOperation(op);
159 dec_active_count(params[0].memref.buffer);
160 return res;
161}
162
163TEE_Result TA_InvokeCommandEntryPoint(void *session_ctx,
164 uint32_t cmd_id, uint32_t param_types,
165 TEE_Param params[4])
166{
167 (void)session_ctx;
168
169 switch (cmd_id) {
170 case TA_CONCURRENT_CMD_BUSY_LOOP:
171 return ta_entry_busy_loop(param_types, params);
172 case TA_CONCURRENT_CMD_SHA256:
173 return ta_entry_sha256(param_types, params);
174 default:
175 return TEE_ERROR_BAD_PARAMETERS;
176 }
177}