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, ¶msIn, 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(¶msIn, index);
844 } else if (TeecMemrefType(paramType, OUTPUT_DIR)) {
845 ret = UpdateForRefMem(¶msIn, index);
846 } else if (isComplete &&
847 TeecValueType(paramType, OUTPUT_DIR)) {
848 ret = UpdateForValue(¶msIn, 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