1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "tzdriver_compat.h"
33 #include "mbedtls/aes.h"
34
KthreadRun(int (* threadfn)(UINTPTR data,int dataLen),void * data,int dataLen,char * name)35 LosTaskCB *KthreadRun(int (*threadfn)(UINTPTR data, int dataLen), void *data, int dataLen, char *name)
36 {
37 LosTaskCB *ktask = NULL;
38 UINT32 taskId = 0;
39 UINT32 ret;
40 TSK_INIT_PARAM_S taskInitParam;
41
42 if (threadfn == NULL) {
43 return NULL;
44 }
45
46 if (memset_s(&taskInitParam, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)) != EOK) {
47 return NULL;
48 }
49
50 taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)threadfn;
51 taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
52 taskInitParam.pcName = name;
53 taskInitParam.usTaskPrio = 1;
54 taskInitParam.auwArgs[0] = (UINTPTR)data;
55 taskInitParam.auwArgs[1] = dataLen;
56 taskInitParam.uwResved = LOS_TASK_STATUS_DETACHED;
57
58 ret = LOS_TaskCreate(&taskId, &taskInitParam);
59 if (ret != LOS_OK) {
60 return NULL;
61 }
62
63 ktask = (LosTaskCB *)OS_TCB_FROM_TID(taskId);
64 (VOID)LOS_TaskYield();
65 return ktask;
66 }
67
KthreadStop(const LosTaskCB * k)68 void KthreadStop(const LosTaskCB *k)
69 {
70 if (k != NULL) {
71 LOS_TaskDelete(k->taskID);
72 }
73 }
74
KthreadShouldStop(void)75 int KthreadShouldStop(void)
76 {
77 return (OsCurrTaskGet()->signal == SIGNAL_KILL);
78 }
79
SimpleReadFromBuffer(void __user * to,size_t count,const void * from,size_t available)80 ssize_t SimpleReadFromBuffer(void __user *to, size_t count,
81 const void *from, size_t available)
82 {
83 size_t ret;
84
85 if (count == 0 || available == 0) {
86 return 0;
87 }
88
89 if (count > available) {
90 count = available;
91 }
92
93 ret = copy_to_user(to, from, count);
94 if (ret == count) {
95 return -EFAULT;
96 }
97 count -= ret;
98 return count;
99 }
100
101 #define MAX_ORDER 31
102
MailboxPoolAllocPages(unsigned int order)103 LosVmPage *MailboxPoolAllocPages(unsigned int order)
104 {
105 if (order > MAX_ORDER) {
106 return NULL;
107 }
108 void *ptr = LOS_PhysPagesAllocContiguous(1UL << order);
109 if (ptr == NULL) {
110 PRINTK("mailbox pool contiguous ptr null size %x\n", 1 << order);
111 return NULL;
112 }
113 for (int i = 0; i < (1UL << order); i++) {
114 // mempool is used to mmap, add ref to prevent pmm free page to free list.
115 LosVmPage *page = OsVmVaddrToPage((void *)((intptr_t)ptr + PAGE_SIZE * i));
116 if (page != NULL) {
117 LOS_AtomicInc(&page->refCounts);
118 }
119 }
120
121 return OsVmVaddrToPage(ptr);
122 }
123
MailboxPoolFreePages(LosVmPage * pageArray,size_t order)124 void MailboxPoolFreePages(LosVmPage *pageArray, size_t order)
125 {
126 if (pageArray == NULL || order > MAX_ORDER) {
127 return;
128 }
129
130 for (int i = 0; i < (1UL << order); i++) {
131 LOS_AtomicDec(&(pageArray[i].refCounts));
132 }
133 LOS_PhysPagesFreeContiguous(pageArray, (1UL << order));
134 }
135
DoVmallocRemap(LosVmMapRegion * vma,void * kvaddr)136 INT32 DoVmallocRemap(LosVmMapRegion *vma, void *kvaddr)
137 {
138 int i;
139 int ret = 0;
140 paddr_t pa;
141 UINT32 uflags = VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE | VM_MAP_REGION_FLAG_PERM_USER;
142 LosVmPage *vmPage = NULL;
143
144 if (vma == NULL || kvaddr == NULL) {
145 return -EINVAL;
146 }
147
148 LosVmSpace *vSpace = LOS_SpaceGet(vma->range.base);
149 if (vSpace == NULL) {
150 return -EINVAL;
151 }
152
153 vaddr_t kva = (vaddr_t)(uintptr_t)kvaddr;
154 vaddr_t uva = vma->range.base;
155 unsigned int page;
156
157 (VOID)LOS_MuxAcquire(&vSpace->regionMux);
158 for (i = 0; i < (vma->range.size >> PAGE_SHIFT); i++) {
159 page = (unsigned int)i;
160 pa = LOS_PaddrQuery((void *)(uintptr_t)(kva + (page << PAGE_SHIFT)));
161 if (pa == 0) {
162 PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
163 ret = -EINVAL;
164 break;
165 }
166 vmPage = LOS_VmPageGet(pa);
167 if (vmPage == NULL) {
168 PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
169 ret = -EINVAL;
170 break;
171 }
172 status_t err = LOS_ArchMmuMap(&vSpace->archMmu, uva + (page << PAGE_SHIFT), pa, 1, uflags);
173 if (err < 0) {
174 ret = err;
175 PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
176 break;
177 }
178 LOS_AtomicInc(&vmPage->refCounts);
179 }
180 /* if any failure happened, rollback */
181 if (i < (vma->range.size >> PAGE_SHIFT)) {
182 for (i = i - 1; i >= 0; i--) {
183 page = (unsigned int)i;
184 pa = LOS_PaddrQuery((void *)(uintptr_t)(kva + (page << PAGE_SHIFT)));
185 vmPage = LOS_VmPageGet(pa);
186 (VOID)LOS_ArchMmuUnmap(&vSpace->archMmu, uva + (page << PAGE_SHIFT), 1);
187 (VOID)LOS_PhysPageFree(vmPage);
188 }
189 }
190
191 (VOID)LOS_MuxRelease(&vSpace->regionMux);
192 return ret;
193 }
194
RemapVmallocRange(LosVmMapRegion * vma,void * addr,unsigned long pgoff)195 int RemapVmallocRange(LosVmMapRegion *vma, void *addr,
196 unsigned long pgoff)
197 {
198 if (pgoff != 0) {
199 return -1;
200 }
201 return DoVmallocRemap(vma, addr);
202 }
203
CreateTcClientDevice(const char * devName,const struct file_operations_vfs * op)204 int CreateTcClientDevice(const char *devName, const struct file_operations_vfs *op)
205 {
206 int ret = register_driver(devName, op, TEE_DEV_PRI, NULL);
207 if (unlikely(ret)) {
208 return -1;
209 }
210
211 return EOK;
212 }
213
214 #define IV_LEN 16
215 #define KEY_BITS 256
216 #define MAX_AES_CRYPT_SIZE SZ_4M
CryptoAescbcKey256(unsigned char * output,const unsigned char * input,struct AesParam * param)217 int CryptoAescbcKey256(unsigned char *output, const unsigned char *input, struct AesParam *param)
218 {
219 mbedtls_aes_context ctx;
220 int ret;
221 if (!output || !input) {
222 return -1;
223 }
224
225 if (!param || !param->iv || !param->key ||
226 param->size < 0 || param->size > MAX_AES_CRYPT_SIZE) {
227 return -1;
228 }
229 int mode = param->encryptoType ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT;
230 unsigned char ivTmp[IV_LEN] = {0};
231
232 ret = memcpy_s(ivTmp, IV_LEN, param->iv, IV_LEN);
233 if (ret != EOK) {
234 return -1;
235 }
236 mbedtls_aes_init(&ctx);
237
238 if (mode == MBEDTLS_AES_ENCRYPT) {
239 ret = mbedtls_aes_setkey_enc(&ctx, param->key, KEY_BITS);
240 } else {
241 ret = mbedtls_aes_setkey_dec(&ctx, param->key, KEY_BITS);
242 }
243 if (ret) {
244 return -1;
245 }
246 return mbedtls_aes_crypt_cbc(&ctx, mode, param->size, ivTmp, input, output);
247 }
248
SetVmmRegionCodeStart(UINTPTR codeStart,UINT32 codeSize)249 void SetVmmRegionCodeStart(UINTPTR codeStart, UINT32 codeSize)
250 {
251 LosVmSpace *space = NULL;
252 space = OsCurrProcessGet()->vmSpace;
253 if (space->codeStart != 0) {
254 return;
255 }
256
257 if (codeSize == 0 || codeStart + codeSize < codeStart) {
258 return;
259 }
260 space->codeStart = codeStart;
261 space->codeEnd = codeStart + codeSize;
262 }
263