1 /*
2 * Copyright (c) 2021-2024 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_check.h"
17
18 #include <stddef.h>
19
20 #include "hks_common_check.h"
21 #include "hks_client_ipc_serialization.h"
22 #include "hks_log.h"
23 #include "hks_param.h"
24 #include "hks_template.h"
25
26 #define MIN_CERT_COUNT 3
27 #define MAX_CERT_COUNT 4
28
HksCheckIpcGenerateKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSetIn)29 int32_t HksCheckIpcGenerateKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSetIn)
30 {
31 int32_t ret = HksCheckBlobAndParamSet(keyAlias, paramSetIn);
32 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or paramSetIn failed")
33
34 if ((keyAlias->size > MAX_PROCESS_SIZE) ||
35 ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + ALIGN_SIZE(paramSetIn->paramSetSize) +
36 sizeof(uint32_t)) > MAX_PROCESS_SIZE)) {
37 HKS_LOG_E("ipc generate key check size failed");
38 return HKS_ERROR_INVALID_ARGUMENT;
39 }
40
41 return HKS_SUCCESS;
42 }
43
HksCheckIpcImportKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * key)44 int32_t HksCheckIpcImportKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
45 const struct HksBlob *key)
46 {
47 int32_t ret = HksCheckBlob2AndParamSet(keyAlias, key, paramSet);
48 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or key or paramSetIn failed")
49
50 if ((keyAlias->size > MAX_PROCESS_SIZE) || (key->size > MAX_PROCESS_SIZE)) {
51 return HKS_ERROR_INVALID_ARGUMENT;
52 }
53 if ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + ALIGN_SIZE(paramSet->paramSetSize) +
54 sizeof(key->size) + ALIGN_SIZE(key->size) > MAX_PROCESS_SIZE)) {
55 return HKS_ERROR_INVALID_ARGUMENT;
56 }
57 return HKS_SUCCESS;
58 }
59
HksCheckIpcImportWrappedKey(const struct HksBlob * keyAlias,const struct HksBlob * wrappingKeyAlias,const struct HksParamSet * paramSet,const struct HksBlob * wrappedKeyData)60 int32_t HksCheckIpcImportWrappedKey(const struct HksBlob *keyAlias, const struct HksBlob *wrappingKeyAlias,
61 const struct HksParamSet *paramSet, const struct HksBlob *wrappedKeyData)
62 {
63 int32_t ret = HksCheckBlob3AndParamSet(keyAlias, wrappingKeyAlias, wrappedKeyData, paramSet);
64 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or wrappingKeyAlias or wrappedKeyData or paramSet failed")
65
66 if ((keyAlias->size > MAX_PROCESS_SIZE) || (wrappingKeyAlias->size > MAX_PROCESS_SIZE) ||
67 (wrappedKeyData->size > MAX_PROCESS_SIZE)) {
68 return HKS_ERROR_INVALID_ARGUMENT;
69 }
70
71 if ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) +
72 sizeof(wrappingKeyAlias->size) + ALIGN_SIZE(wrappingKeyAlias->size) + ALIGN_SIZE(paramSet->paramSetSize) +
73 sizeof(wrappedKeyData->size) + ALIGN_SIZE(wrappedKeyData->size)) > MAX_PROCESS_SIZE) {
74 return HKS_ERROR_INVALID_ARGUMENT;
75 }
76 return HKS_SUCCESS;
77 }
78
HksCheckIpcDeleteKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet)79 int32_t HksCheckIpcDeleteKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet)
80 {
81 int32_t ret = HksCheckBlobAndParamSet(keyAlias, paramSet);
82 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or paramSet failed")
83
84 if (keyAlias->size > MAX_PROCESS_SIZE) {
85 return HKS_ERROR_INVALID_ARGUMENT;
86 }
87
88 if (((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) +
89 ALIGN_SIZE(paramSet->paramSetSize)) > MAX_PROCESS_SIZE)) {
90 HKS_LOG_E("ipc delete key check size failed");
91 return HKS_ERROR_INVALID_ARGUMENT;
92 }
93 return HKS_SUCCESS;
94 }
95
HksCheckIpcExportPublicKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * key)96 int32_t HksCheckIpcExportPublicKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
97 const struct HksBlob *key)
98 {
99 int32_t ret = HksCheckBlob2AndParamSet(keyAlias, key, paramSet);
100 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or key or paramSetIn failed")
101
102 if (keyAlias->size > MAX_PROCESS_SIZE) {
103 return HKS_ERROR_INVALID_ARGUMENT;
104 }
105 if ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + sizeof(key->size) +
106 ALIGN_SIZE(paramSet->paramSetSize)) > MAX_PROCESS_SIZE) {
107 HKS_LOG_E("ipc export public key check size failed");
108 return HKS_ERROR_INVALID_ARGUMENT;
109 }
110 return HKS_SUCCESS;
111 }
112
HksCheckIpcGetKeyParamSet(const struct HksBlob * keyAlias,const struct HksParamSet * paramSetIn,struct HksParamSet * paramSetOut)113 int32_t HksCheckIpcGetKeyParamSet(const struct HksBlob *keyAlias, const struct HksParamSet *paramSetIn,
114 struct HksParamSet *paramSetOut)
115 {
116 int32_t ret = HksCheckBlobAndParamSet(keyAlias, paramSetIn);
117 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or paramSetIn failed")
118
119 if (keyAlias->size > MAX_PROCESS_SIZE) {
120 return HKS_ERROR_INVALID_ARGUMENT;
121 }
122 if (paramSetOut->paramSetSize == 0) {
123 return HKS_ERROR_INVALID_ARGUMENT;
124 }
125 if ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + sizeof(paramSetOut->paramSetSize) +
126 ALIGN_SIZE(paramSetIn->paramSetSize)) > MAX_PROCESS_SIZE) {
127 HKS_LOG_E("ipc get key paramset check size failed");
128 return HKS_ERROR_INVALID_ARGUMENT;
129 }
130 return HKS_SUCCESS;
131 }
132
HksCheckIpcKeyExist(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet)133 int32_t HksCheckIpcKeyExist(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet)
134 {
135 int32_t ret = HksCheckBlobAndParamSet(keyAlias, paramSet);
136 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or paramSet failed")
137
138 if (keyAlias->size > MAX_PROCESS_SIZE) {
139 return HKS_ERROR_INVALID_ARGUMENT;
140 }
141
142 if (((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) +
143 ALIGN_SIZE(paramSet->paramSetSize)) > MAX_PROCESS_SIZE)) {
144 HKS_LOG_E("ipc key exist check size failed");
145 return HKS_ERROR_INVALID_ARGUMENT;
146 }
147 return HKS_SUCCESS;
148 }
149
HksCheckIpcAgreeKey(const struct HksParamSet * paramSet,const struct HksBlob * privateKey,const struct HksBlob * peerPublicKey,const struct HksBlob * agreedKey)150 int32_t HksCheckIpcAgreeKey(const struct HksParamSet *paramSet, const struct HksBlob *privateKey,
151 const struct HksBlob *peerPublicKey, const struct HksBlob *agreedKey)
152 {
153 int32_t ret = HksCheckBlob3AndParamSet(privateKey, peerPublicKey, agreedKey, paramSet);
154 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check key or paramSetIn failed")
155
156 if ((privateKey->size > MAX_PROCESS_SIZE) || (peerPublicKey->size > MAX_PROCESS_SIZE)) {
157 return HKS_ERROR_INVALID_ARGUMENT;
158 }
159 if ((ALIGN_SIZE(paramSet->paramSetSize) + sizeof(privateKey->size) + ALIGN_SIZE(privateKey->size) +
160 sizeof(peerPublicKey->size) + ALIGN_SIZE(peerPublicKey->size) + sizeof(agreedKey->size) > MAX_PROCESS_SIZE)) {
161 return HKS_ERROR_INVALID_ARGUMENT;
162 }
163 return HKS_SUCCESS;
164 }
165
HksCheckIpcDeriveKey(const struct HksParamSet * paramSet,const struct HksBlob * mainKey,const struct HksBlob * derivedKey)166 int32_t HksCheckIpcDeriveKey(const struct HksParamSet *paramSet, const struct HksBlob *mainKey,
167 const struct HksBlob *derivedKey)
168 {
169 int32_t ret = HksCheckBlob2AndParamSet(mainKey, derivedKey, paramSet);
170 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check key or paramSetIn failed")
171
172 if (mainKey->size > MAX_PROCESS_SIZE) {
173 return HKS_ERROR_INVALID_ARGUMENT;
174 }
175 if ((ALIGN_SIZE(paramSet->paramSetSize) + sizeof(mainKey->size) + ALIGN_SIZE(mainKey->size) +
176 sizeof(derivedKey->size)) > MAX_PROCESS_SIZE) {
177 return HKS_ERROR_INVALID_ARGUMENT;
178 }
179 return HKS_SUCCESS;
180 }
181
HksCheckIpcGetKeyInfoList(const struct HksKeyInfo * keyInfoList,const struct HksParamSet * paramSet,uint32_t listCount)182 int32_t HksCheckIpcGetKeyInfoList(const struct HksKeyInfo *keyInfoList, const struct HksParamSet *paramSet,
183 uint32_t listCount)
184 {
185 HKS_IF_NOT_SUCC_RETURN(HksCheckParamSet(paramSet, paramSet->paramSetSize), HKS_ERROR_INVALID_ARGUMENT)
186
187 enum {
188 HKS_GET_KEY_LIST_MAX_COUNT = 2048U,
189 };
190 if (listCount == 0 || listCount > HKS_GET_KEY_LIST_MAX_COUNT) {
191 HKS_LOG_E("invalid listCount %" LOG_PUBLIC "u", listCount);
192 return HKS_ERROR_INVALID_ARGUMENT;
193 }
194
195 if (listCount > (MAX_PROCESS_SIZE - ALIGN_SIZE(paramSet->paramSetSize) -
196 sizeof(uint32_t)) / (sizeof(uint32_t) + sizeof(uint32_t))) {
197 HKS_LOG_E("ipc get key info check size failed");
198 return HKS_ERROR_INVALID_ARGUMENT;
199 }
200
201 for (uint32_t i = 0; i < listCount; ++i) {
202 if ((CheckBlob(&keyInfoList[i].alias) != HKS_SUCCESS) ||
203 (keyInfoList[i].paramSet == NULL) || (keyInfoList[i].paramSet->paramSetSize == 0)) {
204 return HKS_ERROR_INVALID_ARGUMENT;
205 }
206 }
207
208 uint32_t keyInfoBufSize = sizeof(listCount);
209 for (uint32_t i = 0; i < listCount; ++i) {
210 if (IsAdditionOverflow(keyInfoBufSize, sizeof(keyInfoList[i].alias.size))) {
211 return HKS_ERROR_INVALID_ARGUMENT;
212 }
213 keyInfoBufSize += sizeof(keyInfoList[i].alias.size);
214 if ((IsAdditionOverflow(keyInfoList[i].alias.size, DEFAULT_ALIGN_MASK_SIZE)) ||
215 (IsAdditionOverflow(keyInfoList[i].paramSet->paramSetSize, DEFAULT_ALIGN_MASK_SIZE))) {
216 return HKS_ERROR_INVALID_ARGUMENT;
217 }
218 if (IsAdditionOverflow(keyInfoBufSize, ALIGN_SIZE(keyInfoList[i].alias.size))) {
219 return HKS_ERROR_INVALID_ARGUMENT;
220 }
221 keyInfoBufSize += ALIGN_SIZE(keyInfoList[i].alias.size);
222 if (IsAdditionOverflow(keyInfoBufSize, ALIGN_SIZE(keyInfoList[i].paramSet->paramSetSize))) {
223 return HKS_ERROR_INVALID_ARGUMENT;
224 }
225 keyInfoBufSize += ALIGN_SIZE(keyInfoList[i].paramSet->paramSetSize);
226 }
227 return HKS_SUCCESS;
228 }
229
HksCheckIpcCertificateChain(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksCertChain * certChain)230 int32_t HksCheckIpcCertificateChain(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
231 const struct HksCertChain *certChain)
232 {
233 if ((certChain->certs == NULL) || (certChain->certsCount < MIN_CERT_COUNT) ||
234 (certChain->certsCount > MAX_CERT_COUNT)) {
235 return HKS_ERROR_INVALID_ARGUMENT;
236 }
237 HKS_IF_NOT_SUCC_RETURN(HksCheckParamSet(paramSet, paramSet->paramSetSize), HKS_ERROR_INVALID_ARGUMENT)
238 if ((keyAlias->size > MAX_PROCESS_SIZE) ||
239 ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) +
240 ALIGN_SIZE(paramSet->paramSetSize)) > MAX_PROCESS_SIZE)) {
241 return HKS_ERROR_INVALID_ARGUMENT;
242 }
243
244 uint32_t certBufSize = sizeof(certChain->certsCount);
245 for (uint32_t i = 0; i < certChain->certsCount; ++i) {
246 if (IsAdditionOverflow(certBufSize, sizeof(certChain->certs[i].size))) {
247 return HKS_ERROR_INVALID_ARGUMENT;
248 }
249 certBufSize += sizeof(certChain->certs[i].size);
250
251 if (IsAdditionOverflow(certChain->certs[i].size, DEFAULT_ALIGN_MASK_SIZE)) {
252 return HKS_ERROR_INVALID_ARGUMENT;
253 }
254 if (IsAdditionOverflow(certBufSize, ALIGN_SIZE(certChain->certs[i].size))) {
255 return HKS_ERROR_INVALID_ARGUMENT;
256 }
257 certBufSize += ALIGN_SIZE(certChain->certs[i].size);
258 }
259 return HKS_SUCCESS;
260 }
261
HksCheckIpcListAliases(const struct HksParamSet * paramSet)262 int32_t HksCheckIpcListAliases(const struct HksParamSet *paramSet)
263 {
264 HKS_IF_NOT_SUCC_RETURN(HksCheckParamSet(paramSet, paramSet->paramSetSize), HKS_ERROR_INVALID_ARGUMENT)
265
266 if ((ALIGN_SIZE(paramSet->paramSetSize) > MAX_PROCESS_SIZE)) {
267 return HKS_ERROR_INVALID_ARGUMENT;
268 }
269 return HKS_SUCCESS;
270 }
271
HksCheckIpcRenameKeyAlias(const struct HksBlob * oldKeyAlias,const struct HksParamSet * paramSet,const struct HksBlob * newKeyAlias)272 int32_t HksCheckIpcRenameKeyAlias(const struct HksBlob *oldKeyAlias, const struct HksParamSet *paramSet,
273 const struct HksBlob *newKeyAlias)
274 {
275 int32_t ret = HksCheckBlob2AndParamSet(oldKeyAlias, newKeyAlias, paramSet);
276 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or paramSet failed")
277
278 if ((MAX_PROCESS_SIZE - sizeof(oldKeyAlias->size) - ALIGN_SIZE(oldKeyAlias->size) -
279 sizeof(newKeyAlias->size) - ALIGN_SIZE(newKeyAlias->size) < ALIGN_SIZE(paramSet->paramSetSize))) {
280 HKS_LOG_E("ipc rename key alias check size failed");
281 return HKS_ERROR_INVALID_ARGUMENT;
282 }
283 return HKS_SUCCESS;
284 }
285
HksCheckIpcChangeStorageLevel(const struct HksBlob * keyAlias,const struct HksParamSet * srcParamSet,const struct HksParamSet * destParamSet)286 int32_t HksCheckIpcChangeStorageLevel(const struct HksBlob *keyAlias, const struct HksParamSet *srcParamSet,
287 const struct HksParamSet *destParamSet)
288 {
289 int32_t ret = HksCheckBlobAndParamSet2(keyAlias, srcParamSet, destParamSet);
290 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or paramSet failed")
291
292 if (keyAlias->size > MAX_PROCESS_SIZE) {
293 return HKS_ERROR_INVALID_ARGUMENT;
294 }
295
296 if ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + ALIGN_SIZE(srcParamSet->paramSetSize) +
297 ALIGN_SIZE(destParamSet->paramSetSize)) > MAX_PROCESS_SIZE) {
298 HKS_LOG_E("ipc change storage level check size failed");
299 return HKS_ERROR_INVALID_ARGUMENT;
300 }
301
302 return HKS_SUCCESS;
303 }