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 if (IsAdditionOverflow(blob->size, DEFAULT_ALIGN_MASK_SIZE)) {
36 return HKS_ERROR_INVALID_ARGUMENT;
37 }
38 if (IsAdditionOverflow(ALIGN_SIZE(blob->size), sizeof(blob->size))) {
39 return HKS_ERROR_INVALID_ARGUMENT;
40 }
41 *bufSize = ALIGN_SIZE(blob->size) + sizeof(blob->size);
42 return HKS_SUCCESS;
43 }
44
GetParamSize(const struct HksBlob * key,const struct HksParamSet * paramSet,uint32_t * bufSize)45 static uint32_t GetParamSize(const struct HksBlob *key, const struct HksParamSet *paramSet, uint32_t *bufSize)
46 {
47 if ((key->size > MAX_PROCESS_SIZE) || (paramSet->paramSetSize > MAX_PROCESS_SIZE)) {
48 return HKS_ERROR_INVALID_ARGUMENT;
49 }
50
51 *bufSize = ALIGN_SIZE(key->size) + sizeof(key->size) + ALIGN_SIZE(paramSet->paramSetSize);
52 return HKS_SUCCESS;
53 }
54
GetDataSize(uint32_t cmdId,const struct HksBlob * inData,const struct HksBlob * outData,uint32_t * bufSize)55 static uint32_t GetDataSize(uint32_t cmdId, const struct HksBlob *inData, const struct HksBlob *outData,
56 uint32_t *bufSize)
57 {
58 uint32_t inBuffData;
59 HKS_IF_NOT_SUCC_RETURN(GetBlobBufSize(inData, &inBuffData), HKS_ERROR_INVALID_ARGUMENT)
60
61 uint32_t bufOutDataSize;
62 if (cmdId == HKS_MSG_VERIFY) {
63 HKS_IF_NOT_SUCC_RETURN(GetBlobBufSize(outData, &bufOutDataSize), HKS_ERROR_INVALID_ARGUMENT)
64 } else {
65 bufOutDataSize = sizeof(outData->size);
66 }
67
68 if (IsAdditionOverflow(inBuffData, bufOutDataSize)) {
69 return HKS_ERROR_INVALID_ARGUMENT;
70 }
71 *bufSize = inBuffData + bufOutDataSize;
72 return HKS_SUCCESS;
73 }
74
ProcessDataOnce(uint32_t cmdId,const struct HksBlob * key,const struct HksParamSet * paramSet,struct HksBlob * inData,struct HksBlob * outData)75 static int32_t ProcessDataOnce(uint32_t cmdId, const struct HksBlob *key, const struct HksParamSet *paramSet,
76 struct HksBlob *inData, struct HksBlob *outData)
77 {
78 HKS_LOG_D("invoke ProcessOnce cmdId %" LOG_PUBLIC "u", cmdId);
79
80 uint32_t paramBufSize, dataBufSize;
81 if ((GetParamSize(key, paramSet, ¶mBufSize) != HKS_SUCCESS) ||
82 (GetDataSize(cmdId, inData, outData, &dataBufSize) != HKS_SUCCESS)) {
83 return HKS_ERROR_INVALID_ARGUMENT;
84 }
85 uint32_t totalBufSize = paramBufSize + dataBufSize;
86 uint8_t *buffer = (uint8_t *)HksMalloc(totalBufSize);
87 HKS_IF_NULL_RETURN(buffer, HKS_ERROR_MALLOC_FAIL)
88 struct HksBlob ipcBlob = { totalBufSize, buffer };
89
90 uint32_t offset = 0;
91 int32_t ret = HksOnceParamPack(&ipcBlob, key, paramSet, &offset);
92 if (ret != HKS_SUCCESS) {
93 HKS_LOG_E("HksOnceParamPack fail");
94 HKS_FREE_BLOB(ipcBlob);
95 return ret;
96 }
97
98 if (cmdId == HKS_MSG_VERIFY) {
99 ret = HksOnceDataPack(&ipcBlob, inData, outData, NULL, &offset);
100 } else {
101 ret = HksOnceDataPack(&ipcBlob, inData, NULL, outData, &offset);
102 }
103 if (ret != HKS_SUCCESS) {
104 HKS_LOG_E("HksOnceDataPack fail");
105 HKS_FREE_BLOB(ipcBlob);
106 return ret;
107 }
108
109 if (cmdId == HKS_MSG_VERIFY) {
110 ret = HksSendRequest(cmdId, &ipcBlob, NULL, paramSet);
111 } else {
112 ret = HksSendRequest(cmdId, &ipcBlob, outData, paramSet);
113 }
114 HKS_FREE_BLOB(ipcBlob);
115 return ret;
116 }
117
HksSliceDataEntry(uint32_t cmdId,const struct HksBlob * key,const struct HksParamSet * paramSet,struct HksBlob * inData,struct HksBlob * outData)118 int32_t HksSliceDataEntry(uint32_t cmdId, const struct HksBlob *key, const struct HksParamSet *paramSet,
119 struct HksBlob *inData, struct HksBlob *outData)
120 {
121 if (!IsSliceCmd(cmdId)) {
122 HKS_LOG_E("cmd %" LOG_PUBLIC "u not support slice!", cmdId);
123 return HKS_ERROR_INVALID_ARGUMENT;
124 }
125
126 uint32_t paramBufSize;
127 uint32_t dataBufSize;
128 if ((GetParamSize(key, paramSet, ¶mBufSize) != HKS_SUCCESS) ||
129 (GetDataSize(cmdId, inData, outData, &dataBufSize) != HKS_SUCCESS)) {
130 return HKS_ERROR_INVALID_ARGUMENT;
131 }
132 if (IsAdditionOverflow(paramBufSize, dataBufSize)) {
133 return HKS_ERROR_INVALID_ARGUMENT;
134 }
135
136 uint32_t totalBufSize = paramBufSize + dataBufSize;
137 if (totalBufSize <= MAX_PROCESS_SIZE) {
138 return ProcessDataOnce(cmdId, key, paramSet, inData, outData);
139 }
140 return HKS_ERROR_INVALID_ARGUMENT;
141 }
142