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