1 /*
2 * Copyright (c) 2021 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_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
HksCheckIpcGenerateKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSetIn)28 int32_t HksCheckIpcGenerateKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSetIn)
29 {
30 int32_t ret = HksCheckBlobAndParamSet(keyAlias, paramSetIn);
31 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or paramSetIn failed")
32
33 if ((keyAlias->size > MAX_PROCESS_SIZE) ||
34 ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + ALIGN_SIZE(paramSetIn->paramSetSize) +
35 sizeof(uint32_t)) > MAX_PROCESS_SIZE)) {
36 HKS_LOG_E("ipc generate key check size failed");
37 return HKS_ERROR_INVALID_ARGUMENT;
38 }
39
40 return HKS_SUCCESS;
41 }
42
HksCheckIpcImportKey(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksBlob * key)43 int32_t HksCheckIpcImportKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
44 const struct HksBlob *key)
45 {
46 int32_t ret = HksCheckBlob2AndParamSet(keyAlias, key, paramSet);
47 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or key or paramSetIn failed")
48
49 if ((keyAlias->size > MAX_PROCESS_SIZE) || (key->size > MAX_PROCESS_SIZE)) {
50 return HKS_ERROR_INVALID_ARGUMENT;
51 }
52 if ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + ALIGN_SIZE(paramSet->paramSetSize) +
53 sizeof(key->size) + ALIGN_SIZE(key->size) > MAX_PROCESS_SIZE)) {
54 return HKS_ERROR_INVALID_ARGUMENT;
55 }
56 return HKS_SUCCESS;
57 }
58
HksCheckIpcImportWrappedKey(const struct HksBlob * keyAlias,const struct HksBlob * wrappingKeyAlias,const struct HksParamSet * paramSet,const struct HksBlob * wrappedKeyData)59 int32_t HksCheckIpcImportWrappedKey(const struct HksBlob *keyAlias, const struct HksBlob *wrappingKeyAlias,
60 const struct HksParamSet *paramSet, const struct HksBlob *wrappedKeyData)
61 {
62 int32_t ret = HksCheckBlob3AndParamSet(keyAlias, wrappingKeyAlias, wrappedKeyData, paramSet);
63 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check keyAlias or wrappingKeyAlias or wrappedKeyData or paramSet failed")
64
65 if ((keyAlias->size > MAX_PROCESS_SIZE) || (wrappingKeyAlias->size > MAX_PROCESS_SIZE) ||
66 (wrappedKeyData->size > MAX_PROCESS_SIZE)) {
67 return HKS_ERROR_INVALID_ARGUMENT;
68 }
69
70 if ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) +
71 sizeof(wrappingKeyAlias->size) + ALIGN_SIZE(wrappingKeyAlias->size) + ALIGN_SIZE(paramSet->paramSetSize) +
72 sizeof(wrappedKeyData->size) + ALIGN_SIZE(wrappedKeyData->size)) > MAX_PROCESS_SIZE) {
73 return HKS_ERROR_INVALID_ARGUMENT;
74 }
75 return HKS_SUCCESS;
76 }
77
HksCheckIpcExportPublicKey(const struct HksBlob * keyAlias,const struct HksBlob * key)78 int32_t HksCheckIpcExportPublicKey(const struct HksBlob *keyAlias, const struct HksBlob *key)
79 {
80 HKS_IF_NOT_SUCC_RETURN(HksCheckBlob2(keyAlias, key), HKS_ERROR_INVALID_ARGUMENT)
81 if (keyAlias->size > MAX_PROCESS_SIZE) {
82 return HKS_ERROR_INVALID_ARGUMENT;
83 }
84 if ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + sizeof(key->size)) > MAX_PROCESS_SIZE) {
85 return HKS_ERROR_INVALID_ARGUMENT;
86 }
87 return HKS_SUCCESS;
88 }
89
HksCheckIpcGetKeyParamSet(const struct HksBlob * keyAlias,struct HksParamSet * paramSet)90 int32_t HksCheckIpcGetKeyParamSet(const struct HksBlob *keyAlias, struct HksParamSet *paramSet)
91 {
92 HKS_IF_NOT_SUCC_RETURN(CheckBlob(keyAlias), HKS_ERROR_INVALID_ARGUMENT)
93 if (keyAlias->size > MAX_PROCESS_SIZE) {
94 return HKS_ERROR_INVALID_ARGUMENT;
95 }
96 if (paramSet->paramSetSize == 0) {
97 return HKS_ERROR_INVALID_ARGUMENT;
98 }
99 if ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) + sizeof(paramSet->paramSetSize)) > MAX_PROCESS_SIZE) {
100 return HKS_ERROR_INVALID_ARGUMENT;
101 }
102 return HKS_SUCCESS;
103 }
104
HksCheckIpcAgreeKey(const struct HksParamSet * paramSet,const struct HksBlob * privateKey,const struct HksBlob * peerPublicKey,const struct HksBlob * agreedKey)105 int32_t HksCheckIpcAgreeKey(const struct HksParamSet *paramSet, const struct HksBlob *privateKey,
106 const struct HksBlob *peerPublicKey, const struct HksBlob *agreedKey)
107 {
108 int32_t ret = HksCheckBlob3AndParamSet(privateKey, peerPublicKey, agreedKey, paramSet);
109 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check key or paramSetIn failed")
110
111 if ((privateKey->size > MAX_PROCESS_SIZE) || (peerPublicKey->size > MAX_PROCESS_SIZE)) {
112 return HKS_ERROR_INVALID_ARGUMENT;
113 }
114 if ((ALIGN_SIZE(paramSet->paramSetSize) + sizeof(privateKey->size) + ALIGN_SIZE(privateKey->size) +
115 sizeof(peerPublicKey->size) + ALIGN_SIZE(peerPublicKey->size) + sizeof(agreedKey->size) > MAX_PROCESS_SIZE)) {
116 return HKS_ERROR_INVALID_ARGUMENT;
117 }
118 return HKS_SUCCESS;
119 }
120
HksCheckIpcDeriveKey(const struct HksParamSet * paramSet,const struct HksBlob * mainKey,const struct HksBlob * derivedKey)121 int32_t HksCheckIpcDeriveKey(const struct HksParamSet *paramSet, const struct HksBlob *mainKey,
122 const struct HksBlob *derivedKey)
123 {
124 int32_t ret = HksCheckBlob2AndParamSet(mainKey, derivedKey, paramSet);
125 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check key or paramSetIn failed")
126
127 if (mainKey->size > MAX_PROCESS_SIZE) {
128 return HKS_ERROR_INVALID_ARGUMENT;
129 }
130 if ((ALIGN_SIZE(paramSet->paramSetSize) + sizeof(mainKey->size) + ALIGN_SIZE(mainKey->size) +
131 sizeof(derivedKey->size)) > MAX_PROCESS_SIZE) {
132 return HKS_ERROR_INVALID_ARGUMENT;
133 }
134 return HKS_SUCCESS;
135 }
136
HksCheckIpcGetKeyInfoList(const struct HksKeyInfo * keyInfoList,uint32_t listCount)137 int32_t HksCheckIpcGetKeyInfoList(const struct HksKeyInfo *keyInfoList, uint32_t listCount)
138 {
139 if ((listCount == 0) || (listCount > (MAX_PROCESS_SIZE / (sizeof(uint32_t) + sizeof(uint32_t))))) {
140 return HKS_ERROR_INVALID_ARGUMENT;
141 }
142 for (uint32_t i = 0; i < listCount; ++i) {
143 if ((CheckBlob(&keyInfoList[i].alias) != HKS_SUCCESS) ||
144 (keyInfoList[i].paramSet == NULL) || (keyInfoList[i].paramSet->paramSetSize == 0)) {
145 return HKS_ERROR_INVALID_ARGUMENT;
146 }
147 }
148
149 uint32_t keyInfoBufSize = sizeof(listCount);
150 for (uint32_t i = 0; i < listCount; ++i) {
151 if (IsAdditionOverflow(keyInfoBufSize, sizeof(keyInfoList[i].alias.size))) {
152 return HKS_ERROR_INVALID_ARGUMENT;
153 }
154 keyInfoBufSize += sizeof(keyInfoList[i].alias.size);
155 if ((IsAdditionOverflow(keyInfoList[i].alias.size, DEFAULT_ALIGN_MASK_SIZE)) ||
156 (IsAdditionOverflow(keyInfoList[i].paramSet->paramSetSize, DEFAULT_ALIGN_MASK_SIZE))) {
157 return HKS_ERROR_INVALID_ARGUMENT;
158 }
159 if (IsAdditionOverflow(keyInfoBufSize, ALIGN_SIZE(keyInfoList[i].alias.size))) {
160 return HKS_ERROR_INVALID_ARGUMENT;
161 }
162 keyInfoBufSize += ALIGN_SIZE(keyInfoList[i].alias.size);
163 if (IsAdditionOverflow(keyInfoBufSize, ALIGN_SIZE(keyInfoList[i].paramSet->paramSetSize))) {
164 return HKS_ERROR_INVALID_ARGUMENT;
165 }
166 keyInfoBufSize += ALIGN_SIZE(keyInfoList[i].paramSet->paramSetSize);
167 }
168 return HKS_SUCCESS;
169 }
170
HksCheckIpcCertificateChain(const struct HksBlob * keyAlias,const struct HksParamSet * paramSet,const struct HksCertChain * certChain)171 int32_t HksCheckIpcCertificateChain(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
172 const struct HksCertChain *certChain)
173 {
174 if ((certChain->certs == NULL) || (certChain->certsCount < MIN_CERT_COUNT)) {
175 return HKS_ERROR_INVALID_ARGUMENT;
176 }
177 HKS_IF_NOT_SUCC_RETURN(HksCheckParamSet(paramSet, paramSet->paramSetSize), HKS_ERROR_INVALID_ARGUMENT)
178 if ((keyAlias->size > MAX_PROCESS_SIZE) ||
179 ((sizeof(keyAlias->size) + ALIGN_SIZE(keyAlias->size) +
180 ALIGN_SIZE(paramSet->paramSetSize)) > MAX_PROCESS_SIZE)) {
181 return HKS_ERROR_INVALID_ARGUMENT;
182 }
183
184 uint32_t certBufSize = sizeof(certChain->certsCount);
185 for (uint32_t i = 0; i < certChain->certsCount; ++i) {
186 if (IsAdditionOverflow(certBufSize, sizeof(certChain->certs[i].size))) {
187 return HKS_ERROR_INVALID_ARGUMENT;
188 }
189 certBufSize += sizeof(certChain->certs[i].size);
190
191 if (IsAdditionOverflow(certChain->certs[i].size, DEFAULT_ALIGN_MASK_SIZE)) {
192 return HKS_ERROR_INVALID_ARGUMENT;
193 }
194 if (IsAdditionOverflow(certBufSize, ALIGN_SIZE(certChain->certs[i].size))) {
195 return HKS_ERROR_INVALID_ARGUMENT;
196 }
197 certBufSize += ALIGN_SIZE(certChain->certs[i].size);
198 }
199 return HKS_SUCCESS;
200 }
201