• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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