• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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