• 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 "gp_ops.h"
33 #include <securec.h>
34 #include "agent.h"
35 #include "mailbox_mempool.h"
36 #include "mem.h"
37 #include "smc.h"
38 #include "tc_client_sub_driver.h"
39 #include "tc_ns_log.h"
40 #include "teek_client_constants.h"
41 #include "tzdriver_compat.h"
42 
43 #ifdef SECURITY_AUTH_ENHANCE
44 #include "security_auth_enhance.h"
45 #define AES_LOGIN_MAXLEN   (((MAX_PUBKEY_LEN) > (MAX_PACKAGE_NAME_LEN)) ? \
46     (MAX_PUBKEY_LEN) : (MAX_PACKAGE_NAME_LEN))
47 static int DoEncryption(uint8_t *buffer, uint32_t bufferSize,
48     uint32_t payloadSize, const uint8_t *key);
49 static int EncryptLoginInfo(uint32_t loginInfoSize, uint8_t *buffer,
50     const uint8_t *key);
51 #endif
52 
53 typedef struct {
54     TcNsDevFile *devFile;
55     TcNsClientContext *clientContext;
56     TcNsSession *session;
57     TcNsTempBuf *localTempBuffer;
58     unsigned int tmpBufSize;
59 } TcCallParams;
60 
61 typedef struct {
62     TcNsDevFile *devFile;
63     TcNsClientContext *clientContext;
64     TcNsSession *session;
65     TcNsOperation *operation;
66     TcNsTempBuf *localTempBuffer;
67     unsigned int tmpBufSize;
68     unsigned int *transParamTypeToTee;
69     unsigned int TransParamTypeSize;
70 } AllocParams;
71 
72 typedef struct {
73     TcNsDevFile *devFile;
74     TcNsClientContext *clientContext;
75     TcNsOperation *operation;
76     TcNsTempBuf *localTempBuffer;
77     unsigned int tmpBufSize;
78     bool isComplete;
79 } UpdateParams;
80 
81 #define MAX_SHARED_SIZE 0x100000      /* 1 MiB */
82 #define TEEC_PARAM_TYPES(param0_type, param1_type, param2_type, param3_type) \
83     (((param3_type) << 12) | ((param2_type) << 8) | \
84      ((param1_type) << 4) | (param0_type))
85 
86 #define TEEC_PARAM_TYPE_GET(paramTypes, index) \
87     (((paramTypes) >> ((index) << 2)) & 0x0F)
88 
89 #define ROUND_UP(N, S) (((N)+(S)-1)&(~((S)-1)))
90 
91 static void FreeOperation(TcCallParams *params, TcNsOperation *operation);
92 
93 #define INPUT_DIR 0
94 #define OUTPUT_DIR 1
95 #define BOTH_DIR 2
96 /* dir: 0-inclue input, 1-include output, 2-both */
TeecValueType(unsigned int type,int dir)97 static inline bool TeecValueType(unsigned int type, int dir)
98 {
99     return (((dir == INPUT_DIR || dir == BOTH_DIR) && type == TEEC_VALUE_INPUT) ||
100         ((dir == OUTPUT_DIR || dir == BOTH_DIR) && type == TEEC_VALUE_OUTPUT) ||
101         type == TEEC_VALUE_INOUT) ? true : false;
102 }
103 
TeecTmpmemType(unsigned int type,int dir)104 static inline bool TeecTmpmemType(unsigned int type, int dir)
105 {
106     return (((dir == INPUT_DIR || dir == BOTH_DIR) && type == TEEC_MEMREF_TEMP_INPUT) ||
107         ((dir == OUTPUT_DIR || dir == BOTH_DIR) && type == TEEC_MEMREF_TEMP_OUTPUT) ||
108         type == TEEC_MEMREF_TEMP_INOUT) ? true : false;
109 }
110 
TeecMemrefType(unsigned int type,int dir)111 static inline bool TeecMemrefType(unsigned int type, int dir)
112 {
113     return (((dir == INPUT_DIR || dir == BOTH_DIR) && type == TEEC_MEMREF_PARTIAL_INPUT) ||
114         ((dir == OUTPUT_DIR || dir == BOTH_DIR) && type == TEEC_MEMREF_PARTIAL_OUTPUT) ||
115         type == TEEC_MEMREF_PARTIAL_INOUT) ? true : false;
116 }
117 
CheckUserParamValue(const TcNsClientContext * clientContext,unsigned int index)118 static int CheckUserParamValue(const TcNsClientContext *clientContext,
119     unsigned int index)
120 {
121     if (clientContext == NULL) {
122         tloge("clientContext is null.\n");
123         return -EINVAL;
124     }
125     if (index > TEE_PARAM_FOUR) {
126         tloge("index is invalid, index:%x.\n", index);
127         return -EINVAL;
128     }
129     return 0;
130 }
131 
IsMemParam(unsigned int paramType)132 static int IsMemParam(unsigned int paramType)
133 {
134     return (paramType == TEEC_MEMREF_TEMP_INPUT) ||
135         (paramType == TEEC_MEMREF_TEMP_OUTPUT) ||
136         (paramType == TEEC_MEMREF_TEMP_INOUT) ||
137         (paramType == TEEC_MEMREF_PARTIAL_INPUT) ||
138         (paramType == TEEC_MEMREF_PARTIAL_OUTPUT) ||
139         (paramType == TEEC_MEMREF_PARTIAL_INOUT);
140 }
141 
IsValueParam(unsigned int paramType)142 static int IsValueParam(unsigned int paramType)
143 {
144     return (paramType == TEEC_VALUE_INPUT) ||
145         (paramType == TEEC_VALUE_OUTPUT) ||
146         (paramType == TEEC_VALUE_INOUT) ||
147         (paramType == TEEC_ION_INPUT) ||
148         (paramType == TEEC_ION_SGLIST_INPUT);
149 }
150 
CheckMemParam(TcNsClientParam * clientParam)151 static int CheckMemParam(TcNsClientParam *clientParam)
152 {
153     uint32_t size;
154     /* Check the size and buffer addresses  have valid userspace addresses */
155     if (!AccessOk(VERIFY_READ,
156         (unsigned long)(uintptr_t)clientParam->memref.sizeAddr,
157         sizeof(uint32_t))) {
158         return -EFAULT;
159     }
160     GetUser(&size,
161         (uint32_t *)(uintptr_t)clientParam->memref.sizeAddr);
162     /* Check if the buffer address is valid user space address */
163     if (!AccessOk(VERIFY_READ,
164         (unsigned long)(uintptr_t)clientParam->memref.buffer,
165         size)) {
166         return -EFAULT;
167     }
168     return 0;
169 }
170 
CheckValueParam(TcNsClientParam * clientParam)171 static int CheckValueParam(TcNsClientParam *clientParam)
172 {
173     if (!AccessOk(VERIFY_READ,
174         (unsigned long)(uintptr_t)clientParam->value.aAddr,
175         sizeof(uint32_t))) {
176         return -EFAULT;
177     }
178     if (!AccessOk(VERIFY_READ,
179         (unsigned long)(uintptr_t)clientParam->value.bAddr,
180         sizeof(uint32_t))) {
181         return -EFAULT;
182     }
183     return 0;
184 }
185 
TcUserParamValid(TcNsClientContext * clientContext,unsigned int index)186 int TcUserParamValid(TcNsClientContext *clientContext,
187     unsigned int index)
188 {
189     TcNsClientParam *clientParam = NULL;
190     unsigned int paramType;
191     int checkResult = CheckUserParamValue(clientContext, index);
192     if (checkResult != 0) {
193         return checkResult;
194     }
195 
196     clientParam = &(clientContext->params[index]);
197     paramType = TEEC_PARAM_TYPE_GET(clientContext->paramTypes, index);
198     tlogd("Param %u type is %x\n", index, paramType);
199     if (paramType == TEEC_NONE) {
200         tlogd("paramType is TEEC_NONE.\n");
201         return 0;
202     }
203     if (IsMemParam(paramType)) {
204         return CheckMemParam(clientParam);
205     } else if (IsValueParam(paramType)) {
206         return CheckValueParam(clientParam);
207     } else {
208         tloge("paramTypes is not supported.\n");
209         return -EFAULT;
210     }
211 }
212 
213 /*
214  * These function handle read from client. Because client here can be
215  * kernel client or user space client, we must use the proper function
216  */
ReadFromClient(void * dest,size_t destSize,const void * src,size_t size,uint8_t kernelApi)217 static int ReadFromClient(void *dest, size_t destSize,
218     const void *src, size_t size, uint8_t kernelApi)
219 {
220     int ret;
221     bool checkValue = false;
222 
223     checkValue = (dest == NULL) || (src == NULL);
224     if (checkValue == true) {
225         tloge("src or dest is NULL input buffer\n");
226         return -EINVAL;
227     }
228     /*  to be sure that size is <= dest's buffer size. */
229     if (size > destSize) {
230         tloge("size is larger than destSize or size is 0\n");
231         return -EINVAL;
232     }
233     if (size == 0) {
234         return 0;
235     }
236 
237     if (kernelApi) {
238         checkValue = (!LOS_IsUserAddress((uintptr_t)src) && LOS_PaddrQuery((void *)src));
239         if (!checkValue) {
240             tloge("invalid addr\n");
241             return -EFAULT;
242         }
243         ret = memcpy_s(dest, destSize, src, size);
244         if (ret != EOK) {
245             tloge("memcpy fail. line=%d, s_ret=%d\n",
246                 __LINE__, ret);
247             return ret;
248         }
249         return ret;
250     }
251     /* buffer is in user space(CA call TEE API) */
252     if (copy_from_user(dest, src, size)) {
253         tloge("copy from user failed\n");
254         return -EFAULT;
255     }
256 
257     return 0;
258 }
259 
WriteToClient(void * dest,size_t destSize,const void * src,size_t size,uint8_t kernelApi)260 static int WriteToClient(void *dest, size_t destSize,
261     const void *src, size_t size, uint8_t kernelApi)
262 {
263     int ret;
264     bool checkValue = false;
265 
266     checkValue = (dest == NULL) || (src == NULL);
267     if (checkValue == true) {
268         tloge("src or dest is NULL input buffer\n");
269         return -EINVAL;
270     }
271     /*  to be sure that size is <= dest's buffer size. */
272     if (size > destSize) {
273         tloge("size is larger than destSize\n");
274         return -EINVAL;
275     }
276     if (size == 0) {
277         return 0;
278     }
279 
280     if (kernelApi) {
281         checkValue = (!LOS_IsUserAddress((uintptr_t)src) && LOS_PaddrQuery((void *)src));
282         if (!checkValue) {
283             tloge("invalid addr\n");
284             return -EFAULT;
285         }
286         ret = memcpy_s(dest, destSize, src, size);
287         if (ret != EOK) {
288             tloge("write to client fail. line=%d, ret=%d\n",
289                   __LINE__, ret);
290             return ret;
291         }
292         return ret;
293     }
294     /* buffer is in user space(CA call TEE API) */
295     if (copy_to_user(dest, src, size)) {
296         tloge("copy to user failed\n");
297         return -EFAULT;
298     }
299     return 0;
300 }
301 
CheckParamsForAlloc(const TcCallParams * params,const TcNsOperation * operation)302 static int CheckParamsForAlloc(const TcCallParams *params,
303     const TcNsOperation *operation)
304 {
305     if (params->devFile == NULL) {
306         tloge("devFile is null");
307         return -EINVAL;
308     }
309     if (params->session == NULL) {
310         tloge("session is null\n");
311         return -EINVAL;
312     }
313     if (operation == NULL) {
314         tloge("operation is null\n");
315         return -EINVAL;
316     }
317     if (params->localTempBuffer == NULL) {
318         tloge("localTempBuffer is null");
319         return -EINVAL;
320     }
321     if (params->tmpBufSize != (unsigned int)TEE_PARAM_NUM) {
322         tloge("tmpBufSize is wrong");
323         return -EINVAL;
324     }
325     return 0;
326 }
327 
CheckContextForAlloc(const TcNsClientContext * clientContext)328 static int CheckContextForAlloc(const TcNsClientContext *clientContext)
329 {
330     if (clientContext == NULL) {
331         tloge("clientContext is null");
332         return -EINVAL;
333     }
334     if (clientContext->paramTypes == 0) {
335         tloge("invalid param type\n");
336         return -EINVAL;
337     }
338     return 0;
339 }
340 
SetKernelParamsForOpenSession(uint8_t flags,int index,uint8_t * kernelParams)341 static void SetKernelParamsForOpenSession(uint8_t flags,
342     int index, uint8_t *kernelParams)
343 {
344     /*
345      * Normally kernelParams = kernelApi
346      * But when TC_CALL_LOGIN, params 2/3 will
347      * be filled by kernel. so under this circumstance,
348      * params 2/3 has to be set to kernel mode; and
349      * param 0/1 will keep the same with kernelApi.
350      */
351     bool checkValue = (flags & TC_CALL_LOGIN) && (index >= TEE_PARAM_THREE);
352     if (checkValue) {
353         *kernelParams = TEE_REQ_FROM_KERNEL_MODE;
354     }
355     return;
356 }
357 
358 #ifdef SECURITY_AUTH_ENHANCE
359 static bool IsOpenSessionByIndex(uint8_t flags, uint32_t cmdId,
360     int index);
361 #endif
362 
CheckSizeForAlloc(const AllocParams * paramsIn,unsigned int index)363 static int CheckSizeForAlloc(const AllocParams *paramsIn, unsigned int index)
364 {
365     bool checkValue = false;
366 
367     checkValue = (paramsIn->TransParamTypeSize != TEE_PARAM_NUM ||
368         paramsIn->tmpBufSize != TEE_PARAM_NUM ||
369         index >= TEE_PARAM_NUM);
370     if (checkValue == true) {
371         tloge("buf size or params type or index is invalid.\n");
372         return -EFAULT;
373     }
374     return 0;
375 }
376 
CheckAllocTmpMem(AllocParams * paramsIn,unsigned int index,TcNsClientParam ** clientParam,uint32_t * bufferSize,uint8_t kernelParams)377 static int CheckAllocTmpMem(AllocParams *paramsIn, unsigned int index, TcNsClientParam **clientParam,
378     uint32_t *bufferSize, uint8_t kernelParams)
379 {
380     TcNsClientContext *clientContext = paramsIn->clientContext;
381     if (CheckSizeForAlloc(paramsIn, index) != 0) {
382         return -EFAULT;
383     }
384     /* For interface compatibility sake we assume buffer size to be 32bits */
385     *clientParam = &(clientContext->params[index]);
386     if (ReadFromClient(bufferSize, sizeof(*bufferSize),
387         (uint32_t __user *)(uintptr_t)(*clientParam)->memref.sizeAddr,
388         sizeof(uint32_t), kernelParams)) {
389         tloge("copy memref.sizeAddr failed\n");
390         return -EFAULT;
391     }
392     /* Don't allow unbounded malloc requests */
393     if (*bufferSize > MAX_SHARED_SIZE) {
394         tloge("bufferSize %u from user is too large\n", *bufferSize);
395         return -EFAULT;
396     }
397     return 0;
398 }
399 
AllocForTmpMem(AllocParams * paramsIn,uint8_t kernelParams,unsigned int paramType,uint8_t flags,unsigned int index)400 static int AllocForTmpMem(AllocParams *paramsIn,
401     uint8_t kernelParams, unsigned int paramType, uint8_t flags,
402     unsigned int index)
403 {
404     TcNsClientContext *clientContext = paramsIn->clientContext;
405     TcNsTempBuf *localTempBuffer = paramsIn->localTempBuffer;
406     TcNsOperation *operation = paramsIn->operation;
407     TcNsSession *session = paramsIn->session;
408     unsigned int *transParamTypeToTee = paramsIn->transParamTypeToTee;
409     TcNsClientParam *clientParam = NULL;
410     void *tempBuf = NULL;
411     uint32_t bufferSize = 0;
412     bool checkValue = false;
413     int ret;
414 
415     ret = CheckAllocTmpMem(paramsIn, index, &clientParam, &bufferSize, kernelParams);
416     if (ret) {
417         return ret;
418     }
419     tempBuf = MailboxAlloc(bufferSize, MB_FLAG_ZERO);
420     /* If buffer size is zero or malloc failed */
421     if (tempBuf == NULL) {
422         tloge("tempBuf malloc failed, i = %u.\n", index);
423         return -ENOMEM;
424     }
425     tlogd("tempBuf malloc ok, i = %u.\n", index);
426     localTempBuffer[index].tempBuffer = tempBuf;
427     localTempBuffer[index].size = bufferSize;
428     checkValue = (paramType == TEEC_MEMREF_TEMP_INPUT) ||
429         (paramType == TEEC_MEMREF_TEMP_INOUT);
430     if (checkValue == true) {
431         tlogv("clientParam->memref.buffer=0x%llx\n",
432             clientParam->memref.buffer);
433         /* Kernel side buffer */
434         if (ReadFromClient(tempBuf, bufferSize,
435             (void *)(uintptr_t)clientParam->memref.buffer,
436             bufferSize, kernelParams)) {
437             tloge("copy memref.buffer failed\n");
438             return -EFAULT;
439         }
440     }
441 #ifdef SECURITY_AUTH_ENHANCE
442     if (IsOpenSessionByIndex(flags, clientContext->cmdId, index) == true) {
443         ret = EncryptLoginInfo(bufferSize,
444             tempBuf, session->secureInfo.cryptoInfo.key);
445         if (ret != 0) {
446             tloge("SECURITY_AUTH_ENHANCE:encry failed\n");
447             return ret;
448         }
449     }
450 #endif
451     operation->params[index].memref.buffer = LOS_PaddrQuery((void *)tempBuf);
452     operation->bufferHaddr[index] = 0;
453     operation->params[index].memref.size = bufferSize;
454     /* TEEC_MEMREF_TEMP_INPUT equal to TEE_PARAM_TYPE_MEMREF_INPUT */
455     transParamTypeToTee[index] = paramType;
456     return ret;
457 }
458 
CheckBufferForRef(uint32_t * bufferSize,const TcNsClientParam * clientParam,uint8_t kernelParams)459 static int CheckBufferForRef(uint32_t *bufferSize,
460     const TcNsClientParam *clientParam, uint8_t kernelParams)
461 {
462     if (ReadFromClient(bufferSize, sizeof(*bufferSize),
463         (uint32_t __user *)(uintptr_t)clientParam->memref.sizeAddr,
464         sizeof(uint32_t), kernelParams)) {
465         tloge("copy memref.sizeAddr failed\n");
466         return -EFAULT;
467     }
468     if (*bufferSize == 0) {
469         tloge("bufferSize from user is 0\n");
470         return -ENOMEM;
471     }
472     return 0;
473 }
474 
CheckRefSharedMem(TcNsSharedMem * sharedMem,TcNsClientParam * clientParam,uint32_t bufferSize,int index,TcNsOperation * operation)475 static int CheckRefSharedMem(TcNsSharedMem *sharedMem, TcNsClientParam *clientParam,
476     uint32_t bufferSize, int index, TcNsOperation *operation)
477 {
478     /* arbitrary CA can control offset by ioctl, so in here
479     * offset must be checked, and avoid integer overflow.
480     */
481     int checkValue = ((sharedMem->len -
482         clientParam->memref.offset) >= bufferSize) &&
483         (sharedMem->len > clientParam->memref.offset);
484     if (checkValue == true) {
485         void *bufferAddr =
486             (void *)(uintptr_t)((uintptr_t)sharedMem->kernelAddr + clientParam->memref.offset);
487         bufferAddr = MailboxCopyAlloc(bufferAddr, bufferSize);
488         if (bufferAddr == NULL) {
489             tloge("alloc mailbox copy failed\n");
490             return -ENOMEM;
491         }
492         operation->mbBuffer[index] = bufferAddr;
493         operation->params[index].memref.buffer = LOS_PaddrQuery(bufferAddr);
494         operation->bufferHaddr[index] = 0;
495         /* save sharedMem in operation
496          * so that we can use it while FreeOperation
497          */
498         operation->sharemem[index] = sharedMem;
499         GetSharememStruct(sharedMem);
500     } else {
501         tloge("Unexpected size %u vs %u",
502             sharedMem->len, bufferSize);
503     }
504     return 0;
505 }
506 
AllocForRefMem(AllocParams * paramsIn,uint8_t kernelParams,unsigned int paramType,int index)507 static int AllocForRefMem(AllocParams *paramsIn,
508     uint8_t kernelParams, unsigned int paramType, int index)
509 {
510     TcNsClientContext *clientContext = paramsIn->clientContext;
511     TcNsOperation *operation = paramsIn->operation;
512     unsigned int *transParamTypeToTee = paramsIn->transParamTypeToTee;
513     TcNsDevFile *devFile = paramsIn->devFile;
514     TcNsClientParam *clientParam = NULL;
515     TcNsSharedMem *sharedMem = NULL;
516     uint32_t bufferSize = 0;
517     bool checkValue = false;
518     int ret;
519 
520     if (CheckSizeForAlloc(paramsIn, index) != 0) {
521         return -EFAULT;
522     }
523     clientParam = &(clientContext->params[index]);
524     ret = CheckBufferForRef(&bufferSize, clientParam, kernelParams);
525     if (ret != 0) {
526         return ret;
527     }
528     operation->params[index].memref.buffer = 0;
529     /* find kernel addr referred to user addr */
530     mutex_lock(&devFile->sharedMemLock);
531     list_for_each_entry(sharedMem, &devFile->sharedMemList, head) {
532         if (sharedMem->userAddr ==
533             (void *)(uintptr_t)clientParam->memref.buffer) {
534             ret = CheckRefSharedMem(sharedMem, clientParam, bufferSize, index, operation);
535             break;
536         }
537     }
538     mutex_unlock(&devFile->sharedMemLock);
539     /* for 8G physical memory device, there is a chance that
540      * operation->params[i].memref.buffer could be all 0,
541      * bufferHaddr cannot be 0 in the same time.
542      */
543     checkValue = (!operation->params[index].memref.buffer) &&
544         (!operation->bufferHaddr[index]);
545     if (checkValue == true) {
546         tloge("can not find shared buffer, exit\n");
547         return -EINVAL;
548     }
549     operation->params[index].memref.size = bufferSize;
550     /* Change TEEC_MEMREF_PARTIAL_XXXXX  to TEE_PARAM_TYPE_MEMREF_XXXXX */
551     transParamTypeToTee[index] = paramType -
552         (TEEC_MEMREF_PARTIAL_INPUT - TEE_PARAM_TYPE_MEMREF_INPUT);
553     return ret;
554 }
555 
CopyForValue(AllocParams * paramsIn,uint8_t kernelParams,unsigned int paramType,int index)556 static int CopyForValue(AllocParams *paramsIn, uint8_t kernelParams,
557     unsigned int paramType, int index)
558 {
559     TcNsOperation *operation = paramsIn->operation;
560     unsigned int *transParamTypeToTee = paramsIn->transParamTypeToTee;
561     TcNsClientContext *clientContext = paramsIn->clientContext;
562     int ret = 0;
563     TcNsClientParam *clientParam = NULL;
564 
565     if (CheckSizeForAlloc(paramsIn, index) != 0) {
566         return -EFAULT;
567     }
568 
569     clientParam = &(clientContext->params[index]);
570     if (ReadFromClient(&operation->params[index].value.a,
571         sizeof(operation->params[index].value.a),
572         (void *)(uintptr_t)clientParam->value.aAddr,
573         sizeof(operation->params[index].value.a),
574         kernelParams)) {
575         tloge("copy value.aAddr failed\n");
576         return -EFAULT;
577     }
578     if (ReadFromClient(&operation->params[index].value.b,
579         sizeof(operation->params[index].value.b),
580         (void *)(uintptr_t)clientParam->value.bAddr,
581         sizeof(operation->params[index].value.b),
582         kernelParams)) {
583         tloge("copy value.bAddr failed\n");
584         return -EFAULT;
585     }
586     /* TEEC_VALUE_INPUT equal
587      * to TEE_PARAM_TYPE_VALUE_INPUT
588      */
589     transParamTypeToTee[index] = paramType;
590     return ret;
591 }
592 
AllocOperationParam(TcCallParams * params,AllocParams * paramsIn,uint8_t flags,uint8_t kernelParams,int index)593 static int AllocOperationParam(TcCallParams *params, AllocParams *paramsIn,
594     uint8_t flags, uint8_t kernelParams, int index)
595 {
596     SetKernelParamsForOpenSession(flags, index, &kernelParams);
597     unsigned int paramType = TEEC_PARAM_TYPE_GET(
598         params->clientContext->paramTypes, index);
599     tlogd("Param %u type is %x\n", index, paramType);
600     if (TeecTmpmemType(paramType, TEE_PARAM_THREE)) {
601         /* temp buffers we need to allocate/deallocate
602             * for every operation
603             */
604         return AllocForTmpMem(paramsIn, kernelParams,
605             paramType, flags, index);
606     } else if (TeecMemrefType(paramType, TEE_PARAM_THREE)) {
607         /* MEMREF_PARTIAL buffers are already allocated so we just
608             * need to search for the sharedMem ref;
609             * For interface compatibility we assume buffer size to be 32bits
610             */
611         return AllocForRefMem(paramsIn, kernelParams,
612             paramType, index);
613     } else if (TeecValueType(paramType, TEE_PARAM_THREE)) {
614         return CopyForValue(paramsIn, kernelParams,
615             paramType, index);
616     } else {
617         tlogd("paramType = TEEC_NONE\n");
618     }
619     return 0;
620 }
621 
AllocOperation(TcCallParams * params,TcNsOperation * operation,uint8_t flags)622 static int AllocOperation(TcCallParams *params,
623     TcNsOperation *operation, uint8_t flags)
624 {
625     int ret;
626     unsigned int index;
627     unsigned int transParamTypeToTee[TEE_PARAM_NUM] = { TEE_PARAM_TYPE_NONE };
628     uint8_t kernelParams;
629     AllocParams paramsIn = {
630         params->devFile, params->clientContext, params->session,
631         operation, params->localTempBuffer, TEE_PARAM_NUM,
632         transParamTypeToTee, TEE_PARAM_NUM,
633     };
634     ret = CheckParamsForAlloc(params, operation);
635     if (ret != 0) {
636         return ret;
637     }
638     ret = CheckContextForAlloc(params->clientContext);
639     if (ret != 0) {
640         return ret;
641     }
642     kernelParams = params->devFile->kernelApi;
643     tlogd("Allocating param types %08X\n",
644         params->clientContext->paramTypes);
645     /* Get the 4 params from the client context */
646     for (index = 0; index < TEE_PARAM_NUM; index++) {
647         /*
648          * Normally kernelParams = kernelApi
649          * But when TC_CALL_LOGIN(open session), params 2/3 will
650          * be filled by kernel for authentication. so under this circumstance,
651          * params 2/3 has to be set to kernel mode for  authentication; and
652          * param 0/1 will keep the same with user_api.
653          */
654         ret = AllocOperationParam(params, &paramsIn, flags, kernelParams, index);
655         if (ret != 0) {
656             break;
657         }
658     }
659     if (ret != 0) {
660         FreeOperation(params, operation);
661         return ret;
662     }
663     operation->paramTypes =
664         TEEC_PARAM_TYPES(transParamTypeToTee[TEE_PARAM_ONE],
665         transParamTypeToTee[TEE_PARAM_TWO],
666         transParamTypeToTee[TEE_PARAM_THREE],
667         transParamTypeToTee[TEE_PARAM_FOUR]);
668     return ret;
669 }
670 
CheckParamsForUpdate(const TcCallParams * inParams)671 static int CheckParamsForUpdate(const TcCallParams *inParams)
672 {
673     if (inParams->devFile == NULL) {
674         tloge("devFile is null");
675         return -EINVAL;
676     }
677     if (inParams->clientContext == NULL) {
678         tloge("clientContext is null");
679         return -EINVAL;
680     }
681     if (inParams->localTempBuffer == NULL) {
682         tloge("localTempBuffer is null");
683         return -EINVAL;
684     }
685     if (inParams->tmpBufSize != TEE_PARAM_NUM) {
686         tloge("tmpBufSize is invalid");
687         return -EINVAL;
688     }
689     return 0;
690 }
691 
UpdateForTmpMem(UpdateParams * paramsIn,int index)692 static int UpdateForTmpMem(UpdateParams *paramsIn, int index)
693 {
694     TcNsClientParam *clientParam = NULL;
695     uint32_t bufferSize;
696     TcNsDevFile *devFile = paramsIn->devFile;
697     TcNsClientContext *clientContext = paramsIn->clientContext;
698     TcNsOperation *operation = paramsIn->operation;
699     TcNsTempBuf *localTempBuffer = paramsIn->localTempBuffer;
700     bool isComplete = paramsIn->isComplete;
701     bool checkValue = paramsIn->tmpBufSize != TEE_PARAM_NUM ||
702         index >= TEE_PARAM_NUM;
703 
704     if (checkValue == true) {
705         tloge("tmpBufSize or index is invalid\n");
706         return -EFAULT;
707     }
708     /* temp buffer */
709     bufferSize = operation->params[index].memref.size;
710     clientParam = &(clientContext->params[index]);
711     /* Size is updated all the time */
712     if (WriteToClient((void *)(uintptr_t)clientParam->memref.sizeAddr,
713         sizeof(bufferSize),
714         &bufferSize, sizeof(bufferSize),
715         devFile->kernelApi)) {
716         tloge("copy tempbuf size failed\n");
717         return -EFAULT;
718     }
719     if (bufferSize > localTempBuffer[index].size) {
720         /* incomplete case, when the buffer size is invalid see next param */
721         if (!isComplete)
722             return 0;
723         /* complete case, operation is allocated from mailbox
724          *  and share with gtask, so it's possible to be changed
725          */
726         tloge("clientParam->memref.size has been changed larger than the initial\n");
727         return -EFAULT;
728     }
729     /* Only update the buffer when the buffer size is valid in complete case */
730     if (WriteToClient((void *)(uintptr_t)clientParam->memref.buffer,
731         operation->params[index].memref.size,
732         localTempBuffer[index].tempBuffer,
733         operation->params[index].memref.size, devFile->kernelApi)) {
734         tloge("copy tempbuf failed\n");
735         return -ENOMEM;
736     }
737     return 0;
738 }
739 
UpdateForRefMem(UpdateParams * paramsIn,unsigned int index)740 static int UpdateForRefMem(UpdateParams *paramsIn, unsigned int index)
741 {
742     TcNsClientParam *clientParam = NULL;
743     uint32_t bufferSize;
744     bool checkValue = false;
745     unsigned int origSize = 0;
746     TcNsDevFile *devFile = paramsIn->devFile;
747     TcNsClientContext *clientContext = paramsIn->clientContext;
748     TcNsOperation *operation = paramsIn->operation;
749 
750     if (index >= TEE_PARAM_NUM) {
751         tloge("index is invalid\n");
752         return -EFAULT;
753     }
754     /* update size */
755     bufferSize = operation->params[index].memref.size;
756     clientParam = &(clientContext->params[index]);
757 
758     if (ReadFromClient(&origSize,
759         sizeof(origSize),
760         (uint32_t __user *)(uintptr_t)clientParam->memref.sizeAddr,
761         sizeof(origSize), devFile->kernelApi)) {
762         tloge("copy orig memref.sizeAddr failed\n");
763         return -EFAULT;
764     }
765     if (WriteToClient((void *)(uintptr_t)clientParam->memref.sizeAddr,
766         sizeof(bufferSize),
767         &bufferSize, sizeof(bufferSize), devFile->kernelApi)) {
768         tloge("copy buf size failed\n");
769         return -EFAULT;
770     }
771     /* copy from mbBuffer to sharemem */
772     checkValue = operation->mbBuffer[index] && origSize >= bufferSize;
773     if (checkValue == true) {
774         void *bufferAddr =
775             (void *)(uintptr_t)((uintptr_t)
776             operation->sharemem[index]->kernelAddr +
777             clientParam->memref.offset);
778         if (memcpy_s(bufferAddr,
779             operation->sharemem[index]->len -
780             clientParam->memref.offset,
781             operation->mbBuffer[index], bufferSize)) {
782             tloge("copy to sharemem failed\n");
783             return -EFAULT;
784         }
785     }
786     return 0;
787 }
788 
UpdateForValue(UpdateParams * paramsIn,unsigned int index)789 static int UpdateForValue(UpdateParams *paramsIn, unsigned int index)
790 {
791     TcNsClientParam *clientParam = NULL;
792     TcNsDevFile *devFile = paramsIn->devFile;
793     TcNsClientContext *clientContext = paramsIn->clientContext;
794     TcNsOperation *operation = paramsIn->operation;
795 
796     if (index >= TEE_PARAM_NUM) {
797         tloge("index is invalid\n");
798         return -EFAULT;
799     }
800     clientParam = &(clientContext->params[index]);
801     if (WriteToClient((void *)(uintptr_t)clientParam->value.aAddr,
802         sizeof(operation->params[index].value.a),
803         &operation->params[index].value.a,
804         sizeof(operation->params[index].value.a),
805         devFile->kernelApi)) {
806         tloge("inc copy value.aAddr failed\n");
807         return -EFAULT;
808     }
809     if (WriteToClient((void *)(uintptr_t)clientParam->value.bAddr,
810         sizeof(operation->params[index].value.b),
811         &operation->params[index].value.b,
812         sizeof(operation->params[index].value.b),
813         devFile->kernelApi)) {
814         tloge("inc copy value.bAddr failed\n");
815         return -EFAULT;
816     }
817     return 0;
818 }
819 
UpdateClientOperation(TcCallParams * params,TcNsOperation * operation,bool isComplete)820 static int UpdateClientOperation(TcCallParams *params,
821     TcNsOperation *operation, bool isComplete)
822 {
823     int ret;
824     unsigned int paramType;
825     unsigned int index;
826     UpdateParams paramsIn = {
827         params->devFile, params->clientContext,
828         operation, params->localTempBuffer, TEE_PARAM_NUM,
829         isComplete
830     };
831     ret = CheckParamsForUpdate(params);
832     if (ret != 0) {
833         return -EINVAL;
834     }
835     /* if paramTypes is NULL, no need to update */
836     if (params->clientContext->paramTypes == 0) {
837         return 0;
838     }
839     for (index = 0; index < TEE_PARAM_NUM; index++) {
840         paramType = TEEC_PARAM_TYPE_GET(
841             params->clientContext->paramTypes, index);
842         if (TeecTmpmemType(paramType, OUTPUT_DIR)) {
843             ret = UpdateForTmpMem(&paramsIn, index);
844         } else if (TeecMemrefType(paramType, OUTPUT_DIR)) {
845             ret = UpdateForRefMem(&paramsIn, index);
846         } else if (isComplete &&
847             TeecValueType(paramType, OUTPUT_DIR)) {
848             ret = UpdateForValue(&paramsIn, index);
849         } else {
850             tlogd("paramType:%u don't need to update.\n",
851                 paramType);
852         }
853         if (ret != 0) {
854             break;
855         }
856     }
857     return ret;
858 }
859 
FreeOperation(TcCallParams * params,TcNsOperation * operation)860 static void FreeOperation(TcCallParams *params, TcNsOperation *operation)
861 {
862     unsigned int paramType;
863     unsigned int index;
864     void *tempBuf = NULL;
865     bool checkTempMem = false;
866     bool checkPartMem = false;
867     TcNsTempBuf *localTempBuffer = params->localTempBuffer;
868     TcNsClientContext *clientContext = params->clientContext;
869 
870     if (params->tmpBufSize != TEE_PARAM_NUM) {
871         tloge("tmpBufSize is invalid %x.\n", params->tmpBufSize);
872     }
873     for (index = 0; index < TEE_PARAM_NUM; index++) {
874         paramType = TEEC_PARAM_TYPE_GET(
875             clientContext->paramTypes, index);
876         checkTempMem = paramType == TEEC_MEMREF_TEMP_INPUT ||
877             paramType == TEEC_MEMREF_TEMP_OUTPUT ||
878             paramType == TEEC_MEMREF_TEMP_INOUT;
879         checkPartMem = paramType == TEEC_MEMREF_PARTIAL_INPUT ||
880             paramType == TEEC_MEMREF_PARTIAL_OUTPUT ||
881             paramType == TEEC_MEMREF_PARTIAL_INOUT;
882         if (checkTempMem == true) {
883             /* free temp buffer */
884             tempBuf = localTempBuffer[index].tempBuffer;
885             tlogd("Free temp buf, i = %u\n", index);
886             if (LOS_PaddrQuery(tempBuf) &&
887                 !ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)tempBuf)) {
888                 MailboxFree(tempBuf);
889                 tempBuf = NULL;
890             }
891         } else if (checkPartMem == true) {
892             PutSharememStruct(operation->sharemem[index]);
893             if (operation->mbBuffer[index]) {
894                 MailboxFree(operation->mbBuffer[index]);
895             }
896         }
897     }
898 }
899 
900 #ifdef SECURITY_AUTH_ENHANCE
901 unsigned char g_authHashBuf[MAX_SHA_256_SZ * NUM_OF_SO + HASH_PLAINTEXT_ALIGNED_SIZE + IV_BYTESIZE];
902 #else
903 unsigned char g_authHashBuf[MAX_SHA_256_SZ * NUM_OF_SO + MAX_SHA_256_SZ];
904 #endif
905 
906 #ifdef SECURITY_AUTH_ENHANCE
SaveTokenInfo(void * dstTeec,uint32_t dstSize,uint8_t * srcBuf,uint32_t srcSize,uint8_t kernelApi)907 static int32_t SaveTokenInfo(void *dstTeec, uint32_t dstSize,
908     uint8_t *srcBuf, uint32_t srcSize, uint8_t kernelApi)
909 {
910     uint8_t tempTeecToken[TOKEN_SAVE_LEN] = {0};
911     bool checkValue = (dstTeec == NULL || srcBuf == NULL ||
912         dstSize != TOKEN_SAVE_LEN || srcSize == 0);
913 
914     if (checkValue == true) {
915         tloge("dst data or src data is invalid.\n");
916         return -EINVAL;
917     }
918     /* copy libteec_token && timestamp to libteec */
919     if (memmove_s(tempTeecToken, sizeof(tempTeecToken),
920         srcBuf, TIMESTAMP_SAVE_INDEX) != EOK) {
921         tloge("copy teec token failed.\n");
922         return -EFAULT;
923     }
924     if (memmove_s(&tempTeecToken[TIMESTAMP_SAVE_INDEX],
925         TIMESTAMP_LEN_DEFAULT, &srcBuf[TIMESTAMP_BUFFER_INDEX],
926         TIMESTAMP_LEN_DEFAULT) != EOK) {
927         tloge("copy teec timestamp failed.\n");
928         return -EFAULT;
929     }
930     /* copy libteec_token to libteec */
931     if (WriteToClient(dstTeec, dstSize,
932         tempTeecToken, TOKEN_SAVE_LEN,
933         kernelApi) != EOK) {
934         tloge("copy teec token & timestamp failed.\n");
935         return -EFAULT;
936     }
937     /* clear libteec(16byte) */
938     if (memset_s(srcBuf, TIMESTAMP_SAVE_INDEX, 0,
939         TIMESTAMP_SAVE_INDEX) != EOK) {
940         tloge("clear libteec failed.\n");
941         return -EFAULT;
942     }
943     return EOK;
944 }
945 
CheckParamsForFillToken(const TcNsSmcCmd * smcCmd,const TcNsToken * tcToken,const uint8_t * mbPackToken,uint32_t mbPackTokenSize,const TcNsClientContext * clientContext)946 static int CheckParamsForFillToken(const TcNsSmcCmd *smcCmd,
947     const TcNsToken *tcToken, const uint8_t *mbPackToken,
948     uint32_t mbPackTokenSize, const TcNsClientContext *clientContext)
949 {
950     if (smcCmd == NULL || tcToken == NULL || mbPackToken == NULL ||
951         clientContext == NULL || mbPackTokenSize < TOKEN_BUFFER_LEN) {
952         tloge("in parameter is ivalid.\n");
953         return -EFAULT;
954     }
955 
956     if (clientContext->teecToken == NULL ||
957         tcToken->tokenBuffer == NULL) {
958         tloge("teecToken or tokenBuffer is NULL, error!\n");
959         return -EFAULT;
960     }
961     return 0;
962 }
963 
FillSessionToken(uint8_t * tempLibteecToken,int len,TcNsToken * tcToken,const TcNsClientContext * clientContext,const TcNsDevFile * devFile)964 int FillSessionToken(uint8_t *tempLibteecToken, int len, TcNsToken *tcToken,
965     const TcNsClientContext *clientContext, const TcNsDevFile *devFile)
966 {
967     errno_t retErr;
968     if (len != TOKEN_SAVE_LEN) {
969         return -EFAULT;
970     }
971     if (ReadFromClient(tempLibteecToken,
972         TOKEN_SAVE_LEN,
973         clientContext->teecToken, TOKEN_SAVE_LEN,
974         devFile->kernelApi)) {
975         tloge("copy libteec token failed!\n");
976         return -EFAULT;
977     }
978     if (memcmp(&tempLibteecToken[TIMESTAMP_SAVE_INDEX],
979         &tcToken->tokenBuffer[TIMESTAMP_BUFFER_INDEX],
980         TIMESTAMP_LEN_DEFAULT)) {
981         tloge("timestamp compare failed!\n");
982         return -EFAULT;
983     }
984     /* combine tokenBuffer teecToken, 0-15byte */
985     if (memmove_s(tcToken->tokenBuffer,
986         TIMESTAMP_SAVE_INDEX, tempLibteecToken,
987         TIMESTAMP_SAVE_INDEX) != EOK) {
988         tloge("copy buffer failed!\n");
989         retErr = memset_s(tcToken->tokenBuffer,
990             tcToken->tokenLen, 0, TOKEN_BUFFER_LEN);
991         if (retErr != EOK)
992             tloge("memset buffer error=%d\n", retErr);
993         return -EFAULT;
994     }
995     /* kernal_api, 40byte */
996     if (memmove_s((tcToken->tokenBuffer + KERNAL_API_INDEX),
997         KERNAL_API_LEN, &devFile->kernelApi,
998         KERNAL_API_LEN) != EOK) {
999         tloge("copy KERNAL_API_LEN failed!\n");
1000         retErr = memset_s(tcToken->tokenBuffer,
1001             tcToken->tokenLen, 0, TOKEN_BUFFER_LEN);
1002         if (retErr != EOK)
1003             tloge("fill info memset error=%d\n", retErr);
1004         return -EFAULT;
1005     }
1006     return 0;
1007 }
1008 
FillTokenInfo(TcNsSmcCmd * smcCmd,const TcNsClientContext * clientContext,TcNsToken * tcToken,const TcNsDevFile * devFile,bool global,uint8_t * mbPackToken,uint32_t mbPackTokenSize)1009 static int FillTokenInfo(TcNsSmcCmd *smcCmd,
1010     const TcNsClientContext *clientContext, TcNsToken *tcToken,
1011     const TcNsDevFile *devFile, bool global, uint8_t *mbPackToken,
1012     uint32_t mbPackTokenSize)
1013 {
1014     uint8_t tempLibteecToken[TOKEN_SAVE_LEN] = {0};
1015     int ret;
1016     bool checkValue = true;
1017 
1018     ret = CheckParamsForFillToken(smcCmd, tcToken, mbPackToken,
1019         mbPackTokenSize, clientContext);
1020     if (ret != 0) {
1021         return ret;
1022     }
1023     checkValue = (clientContext->cmdId == GLOBAL_CMD_ID_CLOSE_SESSION) ||
1024         (!global);
1025     if (checkValue == true) {
1026         ret = FillSessionToken(tempLibteecToken, TOKEN_SAVE_LEN, tcToken, clientContext, devFile);
1027         if (ret) {
1028             return ret;
1029         }
1030     } else { /* open_session, set tokenBuffer 0 */
1031         if (memset_s(tcToken->tokenBuffer, tcToken->tokenLen,
1032             0, TOKEN_BUFFER_LEN) != EOK) {
1033             tloge("alloc TcNsToken->tokenBuffer error.\n");
1034             return -EFAULT;
1035         }
1036     }
1037     if (memcpy_s(mbPackToken, mbPackTokenSize, tcToken->tokenBuffer,
1038         tcToken->tokenLen)) {
1039         tloge("copy token failed\n");
1040         return -EFAULT;
1041     }
1042 
1043     smcCmd->pid = OsCurrTaskGet()->processID;
1044     smcCmd->tokenPhys = LOS_PaddrQuery(mbPackToken);
1045     smcCmd->tokenHphys = 0;
1046     return EOK;
1047 }
1048 
LoadSecurityEnhanceInfo(TcCallParams * params,TcNsSmcCmd * smcCmd,TcNsToken * tcToken,struct MbCmdPack * mbPack,bool global,bool IsTokenWork)1049 static int LoadSecurityEnhanceInfo(TcCallParams *params,
1050     TcNsSmcCmd *smcCmd, TcNsToken *tcToken,
1051     struct MbCmdPack *mbPack, bool global, bool IsTokenWork)
1052 {
1053     int ret;
1054     bool IsOpenSessionCmd = false;
1055     TcNsDevFile *devFile = params->devFile;
1056     TcNsClientContext *clientContext = params->clientContext;
1057     TcNsSession *session = params->session;
1058 
1059     if (smcCmd == NULL || mbPack == NULL) {
1060         tloge("in parameter is invalid.\n");
1061         return -EFAULT;
1062     }
1063     if (IsTokenWork == true) {
1064         ret = FillTokenInfo(smcCmd, clientContext, tcToken,
1065             devFile, global, mbPack->token, sizeof(mbPack->token));
1066         if (ret != EOK) {
1067             tloge("fill info failed. global=%u, cmdId=%u, sessionId=%u\n",
1068                 global, smcCmd->cmdId, smcCmd->contextId);
1069             return -EFAULT;
1070         }
1071     }
1072     IsOpenSessionCmd = global &&
1073         (smcCmd->cmdId == GLOBAL_CMD_ID_OPEN_SESSION);
1074     if (IsOpenSessionCmd) {
1075         if (session == NULL) {
1076             tloge("invalid session when load secure info\n");
1077             return -EFAULT;
1078         }
1079         if (GenerateEncryptedSessionSecureParams(
1080             &session->secureInfo, mbPack->secureParams,
1081             sizeof(mbPack->secureParams))) {
1082             tloge("Can't get encrypted session parameters buffer!");
1083             return -EFAULT;
1084         }
1085         smcCmd->paramsPhys =
1086             LOS_PaddrQuery((void *)mbPack->secureParams);
1087         smcCmd->paramsHphys = 0;
1088     }
1089     return EOK;
1090 }
1091 
1092 #ifdef TC_ASYNC_NOTIFY_SUPPORT
CheckParamsForAppendToken(const TcNsClientContext * clientContext,const TcNsToken * tcToken,const TcNsDevFile * devFile,uint32_t mbPackTokenSize)1093 static int CheckParamsForAppendToken(
1094     const TcNsClientContext *clientContext,
1095     const TcNsToken *tcToken, const TcNsDevFile *devFile,
1096     uint32_t mbPackTokenSize)
1097 {
1098     if (clientContext == NULL || devFile == NULL || tcToken == NULL) {
1099         tloge("in parameter is invalid.\n");
1100         return -EFAULT;
1101     }
1102     if (clientContext->teecToken == NULL ||
1103         tcToken->tokenBuffer == NULL) {
1104         tloge("teecToken or tokenBuffer is NULL, error!\n");
1105         return -EFAULT;
1106     }
1107     if (mbPackTokenSize < TOKEN_BUFFER_LEN) {
1108         tloge("mbPackTokenSize is invalid.\n");
1109         return -EFAULT;
1110     }
1111     return 0;
1112 }
1113 
AppendTeecToken(const TcNsClientContext * clientContext,TcNsToken * tcToken,const TcNsDevFile * devFile,bool global,uint8_t * mbPackToken,uint32_t mbPackTokenSize)1114 static int AppendTeecToken(const TcNsClientContext *clientContext,
1115     TcNsToken *tcToken, const TcNsDevFile *devFile, bool global,
1116     uint8_t *mbPackToken, uint32_t mbPackTokenSize)
1117 {
1118     uint8_t tempLibteecToken[TOKEN_SAVE_LEN] = {0};
1119     int sret;
1120     int ret;
1121 
1122     ret = CheckParamsForAppendToken(clientContext, tcToken,
1123         devFile, mbPackTokenSize);
1124     if (ret) {
1125         return ret;
1126     }
1127     if (!global) {
1128         if (ReadFromClient(tempLibteecToken,
1129             TOKEN_SAVE_LEN,
1130             clientContext->teecToken, TOKEN_SAVE_LEN,
1131             devFile->kernelApi)) {
1132             tloge("copy libteec token failed!\n");
1133             return -EFAULT;
1134         }
1135         /* combine tokenBuffer ,teecToken, 0-15byte */
1136         if (memmove_s(tcToken->tokenBuffer, tcToken->tokenLen,
1137             tempLibteecToken, TIMESTAMP_SAVE_INDEX) != EOK) {
1138             tloge("copy tempLibteecToken failed!\n");
1139             sret = memset_s(tcToken->tokenBuffer,
1140                 tcToken->tokenLen, 0, TOKEN_BUFFER_LEN);
1141             if (sret != 0) {
1142                 tloge("memset failed!\n");
1143                 return -EFAULT;
1144             }
1145             return -EFAULT;
1146         }
1147         if (memcpy_s(mbPackToken, mbPackTokenSize,
1148             tcToken->tokenBuffer, tcToken->tokenLen)) {
1149             tloge("copy token failed\n");
1150             return -EFAULT;
1151         }
1152     }
1153     return EOK;
1154 }
1155 #endif
1156 
PostProcessToken(const TcNsSmcCmd * smcCmd,TcNsClientContext * clientContext,TcNsToken * tcToken,uint8_t * mbPackToken,uint32_t mbPackTokenSize,uint8_t kernelApi,bool global)1157 static int PostProcessToken(const TcNsSmcCmd *smcCmd,
1158     TcNsClientContext *clientContext, TcNsToken *tcToken,
1159     uint8_t *mbPackToken, uint32_t mbPackTokenSize,
1160     uint8_t kernelApi, bool global)
1161 {
1162     int ret;
1163     bool checkValue = false;
1164 
1165     checkValue = (mbPackToken == NULL || tcToken == NULL ||
1166         clientContext == NULL || clientContext->teecToken == NULL ||
1167         tcToken->tokenBuffer == NULL ||
1168         mbPackTokenSize < TOKEN_BUFFER_LEN);
1169     if (checkValue == true) {
1170         tloge("in parameter is invalid.\n");
1171         return -EINVAL;
1172     }
1173     if (memcpy_s(tcToken->tokenBuffer, tcToken->tokenLen, mbPackToken,
1174         mbPackTokenSize)) {
1175         tloge("copy token failed\n");
1176         return -EFAULT;
1177     }
1178     if (memset_s(mbPackToken, mbPackTokenSize, 0, mbPackTokenSize)) {
1179         tloge("memset mbPack token error.\n");
1180         return -EFAULT;
1181     }
1182     if (SyncTimestamp(smcCmd, tcToken->tokenBuffer, tcToken->tokenLen, global)
1183         != TEEC_SUCCESS) {
1184         tloge("sync time stamp error.\n");
1185         return -EFAULT;
1186     }
1187 
1188     ret = SaveTokenInfo(clientContext->teecToken, clientContext->tokenLen,
1189         tcToken->tokenBuffer, tcToken->tokenLen, kernelApi);
1190     if (ret != EOK) {
1191         tloge("save token info  failed.\n");
1192         return -EFAULT;
1193     }
1194     return EOK;
1195 }
1196 
1197 #define TEE_TZMP \
1198 { \
1199     0xf8028dca, \
1200     0xaba0, \
1201     0x11e6, \
1202     { \
1203         0x80, 0xf5, 0x76, 0x30, 0x4d, 0xec, 0x7e, 0xb7 \
1204     } \
1205 }
1206 #define INVALID_TZMP_UID   0xffffffff
1207 static DEFINE_MUTEX(g_tzmpLock);
1208 static unsigned int g_tzmpUid = INVALID_TZMP_UID;
1209 
Tzmp2Uid(const TcNsClientContext * clientContext,TcNsSmcCmd * smcCmd,bool global)1210 int Tzmp2Uid(const TcNsClientContext *clientContext,
1211     TcNsSmcCmd *smcCmd, bool global)
1212 {
1213     TeecUuid uuidTzmp = TEE_TZMP;
1214     bool checkValue = false;
1215 
1216     if (clientContext == NULL || smcCmd == NULL) {
1217         tloge("clientContext or smcCmd is null! ");
1218         return -EINVAL;
1219     }
1220     if (memcmp(clientContext->uuid, (unsigned char *)&uuidTzmp,
1221         sizeof(clientContext->uuid)) == 0) {
1222         checkValue = smcCmd->cmdId == GLOBAL_CMD_ID_OPEN_SESSION &&
1223             global;
1224         if (checkValue == true) {
1225             /* save tzmp_uid */
1226             mutex_lock(&g_tzmpLock);
1227             g_tzmpUid = 0; /* for multisesion, we use same uid */
1228             smcCmd->uid = 0;
1229             tlogv("openSession , tzmp_uid.uid is %u", g_tzmpUid);
1230             mutex_unlock(&g_tzmpLock);
1231             return EOK;
1232         }
1233         mutex_lock(&g_tzmpLock);
1234         if (g_tzmpUid == INVALID_TZMP_UID) {
1235             tloge("tzmp_uid.uid error!");
1236             mutex_unlock(&g_tzmpLock);
1237             return -EFAULT;
1238         }
1239         smcCmd->uid = g_tzmpUid;
1240         tlogv("invokeCommand or closeSession , tzmp_uid is %u, global is %d",
1241             g_tzmpUid, global);
1242         mutex_unlock(&g_tzmpLock);
1243         return EOK;
1244     }
1245     return EOK;
1246 }
1247 #endif
1248 
CheckParamsForClientCall(const TcNsDevFile * devFile,const TcNsClientContext * clientContext)1249 static int CheckParamsForClientCall(const TcNsDevFile *devFile,
1250     const TcNsClientContext *clientContext)
1251 {
1252     if (devFile == NULL) {
1253         tloge("devFile is null");
1254         return -EINVAL;
1255     }
1256     if (clientContext == NULL) {
1257         tloge("clientContext is null");
1258         return -EINVAL;
1259     }
1260     return 0;
1261 }
1262 
AllocForClientCall(TcNsSmcCmd ** smcCmd,struct MbCmdPack ** mbPack)1263 static int AllocForClientCall(TcNsSmcCmd **smcCmd,
1264     struct MbCmdPack **mbPack)
1265 {
1266     *smcCmd = calloc(1, sizeof(**smcCmd));
1267     if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)(*smcCmd))) {
1268         tloge("smcCmd malloc failed.\n");
1269         return -ENOMEM;
1270     }
1271     *mbPack = MailboxAllocCmdPack();
1272     if (*mbPack == NULL) {
1273         free(*smcCmd);
1274         *smcCmd = NULL;
1275         return -ENOMEM;
1276     }
1277     return 0;
1278 }
1279 
InitSmcCmd(const TcNsDevFile * devFile,const TcNsClientContext * clientContext,TcNsSmcCmd * smcCmd,const struct MbCmdPack * mbPack,bool global)1280 static int InitSmcCmd(const TcNsDevFile *devFile,
1281     const TcNsClientContext *clientContext, TcNsSmcCmd *smcCmd,
1282     const struct MbCmdPack *mbPack, bool global)
1283 {
1284     smcCmd->globalCmd = global;
1285     if (memcpy_s(smcCmd->uuid, sizeof(smcCmd->uuid),
1286         clientContext->uuid, UUID_LEN)) {
1287         tloge("memcpy_s uuid error.\n");
1288         return -EFAULT;
1289     }
1290     smcCmd->cmdId = clientContext->cmdId;
1291     smcCmd->devFileId = devFile->devFileId;
1292     smcCmd->contextId = clientContext->sessionId;
1293     smcCmd->errOrigin = clientContext->returns.origin;
1294     smcCmd->started = clientContext->started;
1295 #ifdef SECURITY_AUTH_ENHANCE
1296     if (Tzmp2Uid(clientContext, smcCmd, global) != EOK) {
1297         tloge("caution! tzmp uid failed !\n\n");
1298     }
1299 #endif
1300     tlogv("current uid is %u\n", smcCmd->uid);
1301     if (clientContext->paramTypes != 0) {
1302         smcCmd->operationPhys = LOS_PaddrQuery((void *)&mbPack->operation);
1303         smcCmd->operationHphys = 0;
1304     } else {
1305         smcCmd->operationPhys = 0;
1306         smcCmd->operationHphys = 0;
1307     }
1308     smcCmd->loginMethod = clientContext->login.method;
1309     return 0;
1310 }
1311 
CheckLoginForEncrypt(TcNsClientContext * clientContext,TcNsSession * session,TcNsSmcCmd * smcCmd,struct MbCmdPack * mbPack,int needCheckLogin)1312 static int CheckLoginForEncrypt(TcNsClientContext *clientContext,
1313     TcNsSession *session, TcNsSmcCmd *smcCmd,
1314     struct MbCmdPack *mbPack, int needCheckLogin)
1315 {
1316     int ret;
1317 
1318     if (needCheckLogin && session != NULL) {
1319 #ifdef SECURITY_AUTH_ENHANCE
1320         ret = DoEncryption(session->authHashBuf,
1321             sizeof(session->authHashBuf),
1322             MAX_SHA_256_SZ * (NUM_OF_SO + 1),
1323             session->secureInfo.cryptoInfo.key);
1324         if (ret) {
1325             tloge("hash encryption failed ret=%d\n", ret);
1326             return ret;
1327         }
1328 #endif
1329         if (memcpy_s(mbPack->loginData, sizeof(mbPack->loginData),
1330             session->authHashBuf,
1331             sizeof(session->authHashBuf))) {
1332             tloge("copy login data failed\n");
1333             return -EFAULT;
1334         }
1335         smcCmd->loginDataPhy = LOS_PaddrQuery(mbPack->loginData);
1336         smcCmd->loginDataHaddr = 0;
1337         smcCmd->loginDataLen = MAX_SHA_256_SZ * (NUM_OF_SO + 1);
1338     } else {
1339         smcCmd->loginDataPhy = 0;
1340         smcCmd->loginDataHaddr = 0;
1341         smcCmd->loginDataLen = 0;
1342     }
1343     return 0;
1344 }
1345 
GetUidForCmd(uint32_t * uid)1346 static void GetUidForCmd(uint32_t *uid)
1347 {
1348     *uid = GetTaskUid(OsCurrTaskGet());
1349 }
1350 
ProcCheckLoginForOpenSession(TcCallParams * params,struct MbCmdPack * mbPack,bool global,TcNsSmcCmd * smcCmd)1351 static int ProcCheckLoginForOpenSession(
1352     TcCallParams *params, struct MbCmdPack *mbPack,
1353     bool global, TcNsSmcCmd *smcCmd)
1354 {
1355     int ret;
1356     int needCheckLogin;
1357     TcNsDevFile *devFile = params->devFile;
1358     TcNsClientContext *clientContext = params->clientContext;
1359     TcNsSession *session = params->session;
1360 
1361     ret = InitSmcCmd(devFile, clientContext,
1362         smcCmd, mbPack, global);
1363     if (ret != 0) {
1364         return ret;
1365     }
1366     needCheckLogin = devFile->pubKeyLen == sizeof(uint32_t) &&
1367         smcCmd->cmdId == GLOBAL_CMD_ID_OPEN_SESSION &&
1368         (!IsKernelThread(OsCurrTaskGet())) && global;
1369     ret = CheckLoginForEncrypt(clientContext, session,
1370         smcCmd, mbPack, needCheckLogin);
1371     if (ret != 0) {
1372         return ret;
1373     }
1374 #ifdef CONFIG_TEE_SMP
1375     smcCmd->caPid = GetCurrentPid();
1376 #endif
1377     return ret;
1378 }
1379 
ResetSessionId(TcNsClientContext * clientContext,bool global,TcNsSmcCmd * smcCmd,int teeRet)1380 static void ResetSessionId(TcNsClientContext *clientContext,
1381     bool global, TcNsSmcCmd *smcCmd, int teeRet)
1382 {
1383     int needReset;
1384 
1385     clientContext->sessionId = smcCmd->contextId;
1386     // if teeRet error except TEEC_PENDING, but contextId is set, need to reset to 0.
1387     needReset = global &&
1388         clientContext->cmdId == GLOBAL_CMD_ID_OPEN_SESSION &&
1389         teeRet != 0 && TEEC_PENDING != teeRet;
1390     if (needReset) {
1391         clientContext->sessionId = 0;
1392     }
1393     return;
1394 }
1395 
1396 #ifdef TC_ASYNC_NOTIFY_SUPPORT
PendCaThread(TcNsSession * session,const TcNsSmcCmd * smcCmd)1397 static void PendCaThread(TcNsSession *session, const TcNsSmcCmd *smcCmd)
1398 {
1399     struct TcWaitData *wq = NULL;
1400 
1401     if (session != NULL) {
1402         wq = &session->waitData;
1403     }
1404     if (wq != NULL) {
1405         tlogv("before wait event\n");
1406         /* use wait_event instead of wait_event_interruptible so
1407          * that ap suspend will not wake up the TEE wait call
1408          */
1409         wait_event(wq->sendCmdWq, wq->sendWaitFlag);
1410         wq->sendWaitFlag = 0;
1411     }
1412     tlogv("operation start is :%d\n", smcCmd->started);
1413     return;
1414 }
1415 #endif
1416 
ProcErrorSituation(TcCallParams * params,struct MbCmdPack * mbPack,const TcNsSmcCmd * smcCmd,int teeRet,bool operationInit)1417 static void ProcErrorSituation(TcCallParams *params,
1418     struct MbCmdPack *mbPack, const TcNsSmcCmd *smcCmd,
1419     int teeRet, bool operationInit)
1420 {
1421     /* free(NULL) is safe and this check is probably not required */
1422     params->clientContext->returns.code = teeRet;
1423     params->clientContext->returns.origin = smcCmd->errOrigin;
1424     /* when CA invoke command and crash,
1425      * Gtask happen to release service node ,tzdriver need to kill ion;
1426      * ta crash ,tzdriver also need to kill ion
1427      */
1428     if (teeRet == TEE_ERROR_TAGET_DEAD || teeRet == TEEC_ERROR_GENERIC) {
1429         tloge("ta_crash or ca is killed or some error happen\n");
1430     }
1431     if (operationInit && mbPack != NULL) {
1432         FreeOperation(params, &mbPack->operation);
1433     }
1434     free((void *)smcCmd);
1435     MailboxFree(mbPack);
1436     return;
1437 }
1438 
ProcShortBufferSituation(TcCallParams * params,TcNsOperation * operation,TcNsSmcCmd * smcCmd,bool operationInit)1439 static void ProcShortBufferSituation(TcCallParams *params,
1440     TcNsOperation *operation, TcNsSmcCmd *smcCmd,
1441     bool operationInit)
1442 {
1443     int ret;
1444     /* update size */
1445     if (operationInit) {
1446         ret = UpdateClientOperation(params, operation, false);
1447         if (ret) {
1448             smcCmd->errOrigin = TEEC_ORIGIN_COMMS;
1449             return;
1450         }
1451     }
1452     return;
1453 }
1454 
1455 struct TcClientCallPreprocStruct {
1456     TcNsSmcCmd *smcCmd;
1457     bool global;
1458 #ifdef SECURITY_AUTH_ENHANCE
1459     bool IsTokenWork;
1460     TcNsToken *tcToken;
1461 #endif
1462     TcCallParams inParams;
1463     struct MbCmdPack *mbPack;
1464     bool operationInit;
1465 };
1466 
TcClientCallPreprocess(TcNsClientContext * clientContext,TcNsDevFile * devFile,TcNsSession * session,uint8_t flags,struct TcClientCallPreprocStruct * preproc)1467 static int TcClientCallPreprocess(TcNsClientContext *clientContext,
1468     TcNsDevFile *devFile, TcNsSession *session, uint8_t flags, struct TcClientCallPreprocStruct *preproc)
1469 {
1470     int ret;
1471     TcNsTempBuf localTempBuffer[TEE_PARAM_NUM] = {
1472         { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }
1473     };
1474     preproc->global = flags & TC_CALL_GLOBAL;
1475     uint32_t uid = 0;
1476 #ifdef SECURITY_AUTH_ENHANCE
1477     preproc->tcToken = (session != NULL) ? &session->TcNsToken : NULL;
1478 #endif
1479     TcCallParams tmpCallParams = {
1480         devFile, clientContext, session, localTempBuffer, TEE_PARAM_NUM
1481     };
1482     if (memcpy_s(&preproc->inParams, sizeof(preproc->inParams), &tmpCallParams, sizeof(tmpCallParams)) != EOK) {
1483         return -EINVAL;
1484     }
1485 
1486     GetUidForCmd(&uid);
1487     ret = CheckParamsForClientCall(devFile, clientContext);
1488     if (ret != 0) {
1489         return ret;
1490     }
1491     ret = AllocForClientCall(&preproc->smcCmd, &preproc->mbPack);
1492     if (ret != 0) {
1493         return ret;
1494     }
1495     preproc->smcCmd->uid = uid;
1496     if (clientContext->paramTypes != 0) {
1497         ret = AllocOperation(&preproc->inParams, &preproc->mbPack->operation, flags);
1498         if (ret) {
1499             tloge("AllocOperation malloc failed");
1500             goto ERROR;
1501         }
1502         preproc->operationInit = true;
1503     }
1504     ret = ProcCheckLoginForOpenSession(&preproc->inParams, preproc->mbPack, preproc->global, preproc->smcCmd);
1505     if (ret != 0) {
1506         goto ERROR;
1507     }
1508 #ifdef SECURITY_AUTH_ENHANCE
1509     /* invoke cmd(global is false) or open session */
1510     preproc->IsTokenWork = (!preproc->global) || (preproc->smcCmd->cmdId == GLOBAL_CMD_ID_OPEN_SESSION);
1511     ret = LoadSecurityEnhanceInfo(&preproc->inParams, preproc->smcCmd, preproc->tcToken,
1512         preproc->mbPack, preproc->global, preproc->IsTokenWork);
1513     if (ret != EOK) {
1514         tloge("LoadSecurityEnhanceInfo failed.\n");
1515         goto ERROR;
1516     }
1517 #endif
1518     return ret;
1519 ERROR:
1520     ProcErrorSituation(&preproc->inParams, preproc->mbPack, preproc->smcCmd, 0, preproc->operationInit);
1521     return ret;
1522 }
1523 
TcClientCallFail(TcNsClientContext * clientContext,int teeRetFirst,TcNsDevFile * devFile,TcNsSession * session,struct TcClientCallPreprocStruct * preproc)1524 static int TcClientCallFail(TcNsClientContext *clientContext, int teeRetFirst,
1525     TcNsDevFile *devFile, TcNsSession *session, struct TcClientCallPreprocStruct *preproc)
1526 {
1527     int teeRet = teeRetFirst;
1528     int ret = 0;
1529 #ifdef TC_ASYNC_NOTIFY_SUPPORT
1530     while (teeRet == TEEC_PENDING) {
1531         PendCaThread(session, preproc->smcCmd);
1532 #ifdef SECURITY_AUTH_ENHANCE
1533         if (preproc->IsTokenWork) {
1534             ret = AppendTeecToken(clientContext, preproc->tcToken, devFile, preproc->global,
1535                 preproc->mbPack->token, sizeof(preproc->mbPack->token));
1536             if (ret != EOK) {
1537                 tloge("append teec's member failed. global=%d, cmdId=%u, sessionId=%u\n",
1538                       preproc->global, preproc->smcCmd->cmdId, preproc->smcCmd->contextId);
1539                 goto ERROR;
1540             }
1541         }
1542 #endif
1543         teeRet = TcNsSmcWithNoNr(preproc->smcCmd);
1544 #ifdef SECURITY_AUTH_ENHANCE
1545         if (preproc->IsTokenWork) {
1546             ret = PostProcessToken(preproc->smcCmd, clientContext, preproc->tcToken, preproc->mbPack->token,
1547                 sizeof(preproc->mbPack->token), devFile->kernelApi, preproc->global);
1548             if (ret != EOK) {
1549                 tloge("NO NR, PostProcessToken failed.\n");
1550                 goto ERROR;
1551             }
1552         }
1553 #endif
1554     }
1555 #endif
1556     /* Client was interrupted, return and let it handle it's own signals first then retry */
1557     if (teeRet == TEEC_CLIENT_INTR) {
1558         ret = -ERESTARTSYS;
1559         goto ERROR;
1560     } else if (teeRet) {
1561         tloge("smc_call returns error ret 0x%x\n", teeRet);
1562         tloge("smc_call smc cmd ret 0x%x\n", preproc->smcCmd->retVal);
1563         goto SHORT_BUFFER;
1564     }
1565     clientContext->sessionId = preproc->smcCmd->contextId;
1566     return ret;
1567 
1568 SHORT_BUFFER:
1569     if (teeRet == TEEC_ERROR_SHORT_BUFFER) {
1570         ProcShortBufferSituation(&preproc->inParams, &preproc->mbPack->operation,
1571             preproc->smcCmd, preproc->operationInit);
1572     }
1573     ret = EFAULT;
1574 ERROR:
1575     ProcErrorSituation(&preproc->inParams, preproc->mbPack, preproc->smcCmd, teeRet, preproc->operationInit);
1576     return ret;
1577 }
1578 
TcClientCall(TcNsClientContext * clientContext,TcNsDevFile * devFile,TcNsSession * session,uint8_t flags)1579 int TcClientCall(TcNsClientContext *clientContext,
1580     TcNsDevFile *devFile, TcNsSession *session, uint8_t flags)
1581 {
1582     struct TcClientCallPreprocStruct preproc;
1583     if (memset_s(&preproc, sizeof(preproc), 0, sizeof(preproc)) != EOK) {
1584         return -ENOMEM;
1585     }
1586 
1587     int ret = TcClientCallPreprocess(clientContext, devFile, session, flags, &preproc);
1588     if (ret) {
1589         return ret;
1590     }
1591 
1592     /* send smc to secure world */
1593     int teeRet = TcNsSmc(preproc.smcCmd);
1594 
1595     ResetSessionId(clientContext, preproc.global, preproc.smcCmd, teeRet);
1596 #ifdef SECURITY_AUTH_ENHANCE
1597     if (preproc.IsTokenWork) {
1598         ret = PostProcessToken(preproc.smcCmd, clientContext, preproc.tcToken,
1599             preproc.mbPack->token, sizeof(preproc.mbPack->token), devFile->kernelApi, preproc.global);
1600         if (ret != EOK) {
1601             tloge("PostProcessToken failed.\n");
1602             preproc.smcCmd->errOrigin = TEEC_ORIGIN_COMMS;
1603             goto ERROR;
1604         }
1605     }
1606 #endif
1607 
1608     if (teeRet != 0) {
1609         ret = TcClientCallFail(clientContext, teeRet, devFile, session, &preproc);
1610         if (ret != EOK) {
1611             return ret;
1612         }
1613     }
1614     /* wake_up tee log reader */
1615     if (preproc.operationInit) {
1616         ret = UpdateClientOperation(&preproc.inParams, &preproc.mbPack->operation, true);
1617         if (ret) {
1618             preproc.smcCmd->errOrigin = TEEC_ORIGIN_COMMS;
1619             goto ERROR;
1620         }
1621     }
1622     ret = 0;
1623 ERROR:
1624     ProcErrorSituation(&preproc.inParams, preproc.mbPack, preproc.smcCmd, teeRet, preproc.operationInit);
1625     return ret;
1626 }
1627 
1628 #ifdef SECURITY_AUTH_ENHANCE
IsOpenSessionByIndex(uint8_t flags,uint32_t cmdId,int index)1629 static bool IsOpenSessionByIndex(uint8_t flags, uint32_t cmdId,
1630     int index)
1631 {
1632     /* params[2] for application certificate or native ca uid;
1633      * params[3] for pkg name; therefore we set i>= 2
1634      */
1635     bool global = flags & TC_CALL_GLOBAL;
1636     bool login_en = (global && (index >= TEE_PARAM_THREE) &&
1637         (cmdId == GLOBAL_CMD_ID_OPEN_SESSION));
1638     return login_en;
1639 }
1640 
IsValidSize(uint32_t bufferSize,uint32_t tempSize)1641 static bool IsValidSize(uint32_t bufferSize, uint32_t tempSize)
1642 {
1643     bool overFlow = false;
1644 
1645     if (bufferSize > AES_LOGIN_MAXLEN) {
1646         tloge("SECURITY_AUTH_ENHANCE: bufferSize is not right\n");
1647         return false;
1648     }
1649     overFlow = (tempSize > ROUND_UP(bufferSize, SZ_4K)) ? true : false;
1650     if (overFlow) {
1651         tloge("SECURITY_AUTH_ENHANCE: input data exceeds limit\n");
1652         return false;
1653     }
1654     return true;
1655 }
CheckParamForEncryption(uint8_t * buffer,uint32_t bufferSize,uint8_t ** plaintext,uint32_t * plainTextBufferSize)1656 static int CheckParamForEncryption(uint8_t *buffer,
1657     uint32_t bufferSize, uint8_t **plaintext,
1658     uint32_t *plainTextBufferSize)
1659 {
1660     if (buffer == NULL || bufferSize == 0) {
1661         tloge("bad params before encryption!\n");
1662         return -EINVAL;
1663     }
1664     *plainTextBufferSize = bufferSize;
1665     *plaintext = calloc(1, *plainTextBufferSize);
1666     if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)(*plaintext))) {
1667         tloge("malloc plaintext failed\n");
1668         return -ENOMEM;
1669     }
1670     if (memcpy_s(*plaintext, *plainTextBufferSize,
1671         buffer, bufferSize)) {
1672         tloge("memcpy failed\n");
1673         free(*plaintext);
1674         *plaintext = NULL;
1675         return -EINVAL;
1676     }
1677     return 0;
1678 }
1679 
HandleEnd(uint8_t * plaintext,uint8_t * cryptotext,int ret)1680 static int HandleEnd(uint8_t *plaintext, uint8_t *cryptotext, int ret)
1681 {
1682     free(plaintext);
1683     if (cryptotext != NULL) {
1684         free((void *)cryptotext);
1685     }
1686     return ret;
1687 }
1688 
GetTotalAndCheck(uint32_t * plaintextSize,uint32_t payloadSize,uint32_t bufferSize,uint32_t * plaintextAlignedSize,uint32_t * totalSize)1689 static int GetTotalAndCheck(uint32_t *plaintextSize,
1690     uint32_t payloadSize, uint32_t bufferSize,
1691     uint32_t *plaintextAlignedSize, uint32_t *totalSize)
1692 {
1693     int ret = 0;
1694     /* Payload + Head + Padding */
1695     *plaintextSize = payloadSize + sizeof(struct EncryptionHead);
1696     *plaintextAlignedSize =
1697         ROUND_UP(*plaintextSize, CIPHER_BLOCK_BYTESIZE);
1698     /* Need 16 bytes to store AES-CBC iv */
1699     *totalSize = *plaintextAlignedSize + IV_BYTESIZE;
1700     if (*totalSize > bufferSize) {
1701         tloge("Do encryption buffer is not enough!\n");
1702         ret = -ENOMEM;
1703     }
1704     return ret;
1705 }
1706 
DoEncryption(uint8_t * buffer,uint32_t bufferSize,uint32_t payloadSize,const uint8_t * key)1707 static int DoEncryption(uint8_t *buffer, uint32_t bufferSize,
1708     uint32_t payloadSize, const uint8_t *key)
1709 {
1710     uint32_t plaintextSize;
1711     uint32_t plaintextAlignedSize;
1712     uint32_t totalSize;
1713     uint8_t *cryptotext = NULL;
1714     uint8_t *plaintext = NULL;
1715     uint32_t plainTextBufferSize;
1716     struct EncryptionHead head;
1717     int ret = CheckParamForEncryption(buffer, bufferSize, &plaintext, &plainTextBufferSize);
1718     if (ret != 0) {
1719         return ret;
1720     }
1721 
1722     ret = GetTotalAndCheck(&plaintextSize, payloadSize, bufferSize, &plaintextAlignedSize, &totalSize);
1723     if (ret != 0) {
1724         goto END;
1725     }
1726     cryptotext = calloc(1, totalSize);
1727     if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)cryptotext)) {
1728         tloge("Malloc failed when doing encryption!\n");
1729         ret = -ENOMEM;
1730         goto END;
1731     }
1732     /* Setting encryption head */
1733     ret = SetEncryptionHead(&head, payloadSize);
1734     if (ret) {
1735         tloge("Set encryption head failed, ret = %d.\n", ret);
1736         goto END;
1737     }
1738     ret = memcpy_s((void *)(plaintext + payloadSize), plainTextBufferSize - payloadSize, (void *)&head, sizeof(head));
1739     if (ret) {
1740         tloge("Copy encryption head failed, ret = %d.\n", ret);
1741         goto END;
1742     }
1743     /* Setting padding data */
1744     ret = CryptoAescbcCmsPadding(plaintext, plaintextAlignedSize, plaintextSize);
1745     if (ret) {
1746         tloge("Set encryption padding data failed, ret = %d.\n", ret);
1747         goto END;
1748     }
1749     ret = CryptoSessionAescbcKey256(plaintext, plaintextAlignedSize, cryptotext, totalSize, key, NULL, ENCRYPT);
1750     if (ret) {
1751         tloge("Encrypt failed, ret=%d.\n", ret);
1752         goto END;
1753     }
1754     ret = memcpy_s((void *)buffer, bufferSize, (void *)cryptotext, totalSize);
1755     if (ret) {
1756         tloge("Copy cryptotext failed, ret=%d.\n", ret);
1757     }
1758 END:
1759     return HandleEnd(plaintext, cryptotext, ret);
1760 }
1761 
EncryptLoginInfo(uint32_t loginInfoSize,uint8_t * buffer,const uint8_t * key)1762 static int EncryptLoginInfo(uint32_t loginInfoSize,
1763     uint8_t *buffer, const uint8_t *key)
1764 {
1765     uint32_t payloadSize;
1766     uint32_t plaintextSize;
1767     uint32_t plaintextAlignedSize;
1768     uint32_t totalSize;
1769 
1770     if (buffer == NULL) {
1771         tloge("Login information buffer is null!\n");
1772         return -EINVAL;
1773     }
1774     /* Need adding the termination null byte ('\0') to the end. */
1775     payloadSize = loginInfoSize + sizeof(char);
1776 
1777     /* Payload + Head + Padding */
1778     plaintextSize = payloadSize + sizeof(struct EncryptionHead);
1779     plaintextAlignedSize = ROUND_UP(plaintextSize, CIPHER_BLOCK_BYTESIZE);
1780     /* Need 16 bytes to store AES-CBC iv */
1781     totalSize = plaintextAlignedSize + IV_BYTESIZE;
1782     if (!IsValidSize(loginInfoSize, totalSize)) {
1783         tloge("Login information encryption size is invalid!\n");
1784         return -EFAULT;
1785     }
1786     return DoEncryption(buffer, totalSize, payloadSize, key);
1787 }
1788 #endif
1789