1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hks_ipc_slice.h"
17
18 #include <stdbool.h>
19 #include <stddef.h>
20
21 #include "hks_client_ipc_serialization.h"
22 #include "hks_log.h"
23 #include "hks_mem.h"
24 #include "hks_request.h"
25 #include "hks_template.h"
26
IsSliceCmd(uint32_t cmdId)27 static bool IsSliceCmd(uint32_t cmdId)
28 {
29 return (cmdId == HKS_MSG_SIGN) || (cmdId == HKS_MSG_VERIFY) || (cmdId == HKS_MSG_ENCRYPT) ||
30 (cmdId == HKS_MSG_DECRYPT) || (cmdId == HKS_MSG_MAC);
31 }
32
GetBlobBufSize(const struct HksBlob * blob,uint32_t * bufSize)33 static uint32_t GetBlobBufSize(const struct HksBlob *blob, uint32_t *bufSize)
34 {
35 HKS_IF_TRUE_RETURN(IsAdditionOverflow(blob->size, DEFAULT_ALIGN_MASK_SIZE), HKS_ERROR_INVALID_ARGUMENT)
36 HKS_IF_TRUE_RETURN(IsAdditionOverflow(ALIGN_SIZE(blob->size), sizeof(blob->size)), HKS_ERROR_INVALID_ARGUMENT)
37 *bufSize = ALIGN_SIZE(blob->size) + sizeof(blob->size);
38 return HKS_SUCCESS;
39 }
40
GetParamSize(const struct HksBlob * key,const struct HksParamSet * paramSet,uint32_t * bufSize)41 static uint32_t GetParamSize(const struct HksBlob *key, const struct HksParamSet *paramSet, uint32_t *bufSize)
42 {
43 HKS_IF_TRUE_RETURN(key->size > MAX_PROCESS_SIZE || paramSet->paramSetSize > MAX_PROCESS_SIZE,
44 HKS_ERROR_INVALID_ARGUMENT)
45
46 *bufSize = ALIGN_SIZE(key->size) + sizeof(key->size) + ALIGN_SIZE(paramSet->paramSetSize);
47 return HKS_SUCCESS;
48 }
49
GetDataSize(uint32_t cmdId,const struct HksBlob * inData,const struct HksBlob * outData,uint32_t * bufSize)50 static uint32_t GetDataSize(uint32_t cmdId, const struct HksBlob *inData, const struct HksBlob *outData,
51 uint32_t *bufSize)
52 {
53 uint32_t inBuffData;
54 HKS_IF_NOT_SUCC_RETURN(GetBlobBufSize(inData, &inBuffData), HKS_ERROR_INVALID_ARGUMENT)
55
56 uint32_t bufOutDataSize;
57 if (cmdId == HKS_MSG_VERIFY) {
58 HKS_IF_NOT_SUCC_RETURN(GetBlobBufSize(outData, &bufOutDataSize), HKS_ERROR_INVALID_ARGUMENT)
59 } else {
60 bufOutDataSize = sizeof(outData->size);
61 }
62
63 HKS_IF_TRUE_RETURN(IsAdditionOverflow(inBuffData, bufOutDataSize), HKS_ERROR_INVALID_ARGUMENT)
64 *bufSize = inBuffData + bufOutDataSize;
65 return HKS_SUCCESS;
66 }
67
ProcessDataOnce(uint32_t cmdId,const struct HksBlob * key,const struct HksParamSet * paramSet,struct HksBlob * inData,struct HksBlob * outData)68 static int32_t ProcessDataOnce(uint32_t cmdId, const struct HksBlob *key, const struct HksParamSet *paramSet,
69 struct HksBlob *inData, struct HksBlob *outData)
70 {
71 HKS_LOG_D("invoke ProcessOnce cmdId %" LOG_PUBLIC "u", cmdId);
72
73 uint32_t paramBufSize, dataBufSize;
74 HKS_IF_TRUE_RETURN(GetParamSize(key, paramSet, ¶mBufSize) != HKS_SUCCESS ||
75 GetDataSize(cmdId, inData, outData, &dataBufSize) != HKS_SUCCESS, HKS_ERROR_INVALID_ARGUMENT)
76 uint32_t totalBufSize = paramBufSize + dataBufSize;
77 uint8_t *buffer = (uint8_t *)HksMalloc(totalBufSize);
78 HKS_IF_NULL_RETURN(buffer, HKS_ERROR_MALLOC_FAIL)
79 struct HksBlob ipcBlob = { totalBufSize, buffer };
80
81 uint32_t offset = 0;
82 int32_t ret = HksOnceParamPack(&ipcBlob, key, paramSet, &offset);
83 if (ret != HKS_SUCCESS) {
84 HKS_LOG_E("HksOnceParamPack fail");
85 HKS_FREE_BLOB(ipcBlob);
86 return ret;
87 }
88
89 if (cmdId == HKS_MSG_VERIFY) {
90 ret = HksOnceDataPack(&ipcBlob, inData, outData, NULL, &offset);
91 } else {
92 ret = HksOnceDataPack(&ipcBlob, inData, NULL, outData, &offset);
93 }
94 if (ret != HKS_SUCCESS) {
95 HKS_LOG_E("HksOnceDataPack fail");
96 HKS_FREE_BLOB(ipcBlob);
97 return ret;
98 }
99
100 if (cmdId == HKS_MSG_VERIFY) {
101 ret = HksSendRequest(cmdId, &ipcBlob, NULL, paramSet);
102 } else {
103 ret = HksSendRequest(cmdId, &ipcBlob, outData, paramSet);
104 }
105 HKS_FREE_BLOB(ipcBlob);
106 return ret;
107 }
108
HksSliceDataEntry(uint32_t cmdId,const struct HksBlob * key,const struct HksParamSet * paramSet,struct HksBlob * inData,struct HksBlob * outData)109 int32_t HksSliceDataEntry(uint32_t cmdId, const struct HksBlob *key, const struct HksParamSet *paramSet,
110 struct HksBlob *inData, struct HksBlob *outData)
111 {
112 HKS_IF_NOT_TRUE_LOGE_RETURN(IsSliceCmd(cmdId), HKS_ERROR_INVALID_ARGUMENT,
113 "cmd %" LOG_PUBLIC "u not support slice!", cmdId)
114
115 uint32_t paramBufSize;
116 uint32_t dataBufSize;
117 HKS_IF_TRUE_RETURN(GetParamSize(key, paramSet, ¶mBufSize) != HKS_SUCCESS ||
118 GetDataSize(cmdId, inData, outData, &dataBufSize) != HKS_SUCCESS, HKS_ERROR_INVALID_ARGUMENT)
119 HKS_IF_TRUE_RETURN(IsAdditionOverflow(paramBufSize, dataBufSize), HKS_ERROR_INVALID_ARGUMENT)
120
121 uint32_t totalBufSize = paramBufSize + dataBufSize;
122 HKS_IF_TRUE_RETURN(totalBufSize > MAX_PROCESS_SIZE, HKS_ERROR_INVALID_ARGUMENT)
123 return ProcessDataOnce(cmdId, key, paramSet, inData, outData);
124 }
125