1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #if defined(HITLS_CRYPTO_CODECSKEY) && defined(HITLS_CRYPTO_PROVIDER)
18 #include "crypt_eal_implprovider.h"
19 #include "crypt_eal_pkey.h"
20 #include "crypt_provider.h"
21 #include "crypt_params_key.h"
22 #include "crypt_types.h"
23 #include "crypt_errno.h"
24 #include "crypt_utils.h"
25 #include "eal_pkey.h"
26 #include "crypt_decode_key_impl.h"
27 #include "bsl_err_internal.h"
28
29 typedef struct {
30 CRYPT_EAL_LibCtx *libCtx;
31 const char *targetAttrName;
32 const char *outFormat;
33 const char *outType;
34 } DECODER_Lowkey2PkeyCtx;
35
DECODER_LowKeyObject2PkeyObjectNewCtx(void * provCtx)36 void *DECODER_LowKeyObject2PkeyObjectNewCtx(void *provCtx)
37 {
38 (void)provCtx;
39 DECODER_Lowkey2PkeyCtx *ctx = (DECODER_Lowkey2PkeyCtx *)BSL_SAL_Calloc(1, sizeof(DECODER_Lowkey2PkeyCtx));
40 if (ctx == NULL) {
41 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
42 return NULL;
43 }
44
45 ctx->outFormat = "OBJECT";
46 ctx->outType = "HIGH_KEY";
47 return (void *)ctx;
48 }
49
DECODER_LowKeyObject2PkeyObjectSetParam(void * ctx,const BSL_Param * param)50 int32_t DECODER_LowKeyObject2PkeyObjectSetParam(void *ctx, const BSL_Param *param)
51 {
52 DECODER_Lowkey2PkeyCtx *decoderCtx = (DECODER_Lowkey2PkeyCtx *)ctx;
53 if (decoderCtx == NULL || param == NULL) {
54 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
55 return CRYPT_NULL_INPUT;
56 }
57 const BSL_Param *libCtxParam = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_DECODE_LIB_CTX);
58 if (libCtxParam != NULL) {
59 if (libCtxParam->valueType != BSL_PARAM_TYPE_CTX_PTR) {
60 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
61 return CRYPT_INVALID_ARG;
62 }
63 decoderCtx->libCtx = (CRYPT_EAL_LibCtx *)(uintptr_t)libCtxParam->value;
64 }
65 const BSL_Param *targetAttrNameParam = BSL_PARAM_FindConstParam(param, CRYPT_PARAM_DECODE_TARGET_ATTR_NAME);
66 if (targetAttrNameParam != NULL) {
67 if (targetAttrNameParam->valueType != BSL_PARAM_TYPE_OCTETS_PTR) {
68 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
69 return CRYPT_INVALID_ARG;
70 }
71 decoderCtx->targetAttrName = (const char *)(uintptr_t)targetAttrNameParam->value;
72 }
73
74 return CRYPT_SUCCESS;
75 }
76
DECODER_LowKeyObject2PkeyObjectGetParam(void * ctx,BSL_Param * param)77 int32_t DECODER_LowKeyObject2PkeyObjectGetParam(void *ctx, BSL_Param *param)
78 {
79 DECODER_Lowkey2PkeyCtx *decoderCtx = (DECODER_Lowkey2PkeyCtx *)ctx;
80 if (decoderCtx == NULL) {
81 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
82 return CRYPT_NULL_INPUT;
83 }
84 DECODER_CommonCtx commonCtx = {
85 .outFormat = decoderCtx->outFormat,
86 .outType = decoderCtx->outType
87 };
88 return DECODER_CommonGetParam(&commonCtx, param);
89 }
90 typedef struct LowKeyObjectMethodInfo {
91 CRYPT_EAL_ImplPkeyMgmtExport export;
92 CRYPT_EAL_ImplPkeyMgmtDupCtx dupCtx;
93 CRYPT_EAL_ImplPkeyMgmtFreeCtx freeCtx;
94 } LowKeyObjectMethodInfo;
95
GetLowKeyObjectInfo(const BSL_Param * inParam,void ** object,int32_t * objectType,LowKeyObjectMethodInfo * method)96 static int32_t GetLowKeyObjectInfo(const BSL_Param *inParam, void **object, int32_t *objectType,
97 LowKeyObjectMethodInfo *method)
98 {
99 const BSL_Param *lowObjectRef = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_OBJECT_DATA);
100 if (lowObjectRef == NULL || lowObjectRef->valueType != BSL_PARAM_TYPE_CTX_PTR) {
101 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
102 return CRYPT_INVALID_ARG;
103 }
104 const BSL_Param *lowObjectRefType = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_OBJECT_TYPE);
105 if (lowObjectRefType == NULL || lowObjectRefType->valueType != BSL_PARAM_TYPE_INT32) {
106 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
107 return CRYPT_INVALID_ARG;
108 }
109 const BSL_Param *exportFunc = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_PKEY_EXPORT_METHOD_FUNC);
110 if (exportFunc == NULL || exportFunc->valueType != BSL_PARAM_TYPE_FUNC_PTR) {
111 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
112 return CRYPT_INVALID_ARG;
113 }
114 const BSL_Param *dupFunc = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_PKEY_DUP_METHOD_FUNC);
115 if (dupFunc == NULL || dupFunc->valueType != BSL_PARAM_TYPE_FUNC_PTR) {
116 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
117 return CRYPT_INVALID_ARG;
118 }
119 const BSL_Param *freeFunc = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_PKEY_FREE_METHOD_FUNC);
120 if (freeFunc == NULL || freeFunc->valueType != BSL_PARAM_TYPE_FUNC_PTR) {
121 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
122 return CRYPT_INVALID_ARG;
123 }
124 if (lowObjectRef->value == NULL || lowObjectRefType->value == NULL) {
125 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
126 return CRYPT_NULL_INPUT;
127 }
128 *object = (void *)(uintptr_t)lowObjectRef->value;
129 *objectType = *((int32_t *)(uintptr_t)lowObjectRefType->value);
130 method->export = (CRYPT_EAL_ImplPkeyMgmtExport)(uintptr_t)exportFunc->value;
131 method->dupCtx = (CRYPT_EAL_ImplPkeyMgmtDupCtx)(uintptr_t)dupFunc->value;
132 method->freeCtx = (CRYPT_EAL_ImplPkeyMgmtFreeCtx)(uintptr_t)freeFunc->value;
133 return CRYPT_SUCCESS;
134 }
135
GetProviderInfo(const BSL_Param * inParam,CRYPT_EAL_ProvMgrCtx ** lastDecoderProviderCtx)136 static int32_t GetProviderInfo(const BSL_Param *inParam, CRYPT_EAL_ProvMgrCtx **lastDecoderProviderCtx)
137 {
138 const BSL_Param *lastDecoderProvCtxParam = BSL_PARAM_FindConstParam(inParam, CRYPT_PARAM_DECODE_PROVIDER_CTX);
139 if (lastDecoderProvCtxParam != NULL) {
140 if (lastDecoderProvCtxParam->valueType != BSL_PARAM_TYPE_CTX_PTR) {
141 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
142 return CRYPT_INVALID_ARG;
143 }
144 *lastDecoderProviderCtx = (CRYPT_EAL_ProvMgrCtx *)(uintptr_t)lastDecoderProvCtxParam->value;
145 }
146 return CRYPT_SUCCESS;
147 }
148
149 typedef struct {
150 CRYPT_EAL_PkeyMgmtInfo *pkeyAlgInfo;
151 void *targetKeyRef;
152 } ImportTargetPkeyArgs;
153
ImportTargetPkey(const BSL_Param * param,void * args)154 static int32_t ImportTargetPkey(const BSL_Param *param, void *args)
155 {
156 if (param == NULL || args == NULL) {
157 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
158 return CRYPT_NULL_INPUT;
159 }
160
161 ImportTargetPkeyArgs *importTargetPkeyArgs = (ImportTargetPkeyArgs *)args;
162 void *provCtx = NULL;
163 CRYPT_EAL_PkeyMgmtInfo *pkeyAlgInfo = importTargetPkeyArgs->pkeyAlgInfo;
164 if (pkeyAlgInfo == NULL || pkeyAlgInfo->keyMgmtMethod->provNewCtx == NULL ||
165 pkeyAlgInfo->keyMgmtMethod->import == NULL || pkeyAlgInfo->keyMgmtMethod->freeCtx == NULL) {
166 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
167 return CRYPT_NULL_INPUT;
168 }
169 int32_t ret = CRYPT_EAL_ProviderCtrl(pkeyAlgInfo->mgrCtx, CRYPT_PROVIDER_GET_USER_CTX, &provCtx, sizeof(provCtx));
170 if (ret != CRYPT_SUCCESS) {
171 BSL_ERR_PUSH_ERROR(ret);
172 return ret;
173 }
174 void *keyRef = pkeyAlgInfo->keyMgmtMethod->provNewCtx(provCtx, pkeyAlgInfo->algId);
175 if (keyRef == NULL) {
176 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
177 return CRYPT_MEM_ALLOC_FAIL;
178 }
179 ret = pkeyAlgInfo->keyMgmtMethod->import(keyRef, param);
180 if (ret != CRYPT_SUCCESS) {
181 BSL_ERR_PUSH_ERROR(ret);
182 pkeyAlgInfo->keyMgmtMethod->freeCtx(keyRef);
183 return ret;
184 }
185 importTargetPkeyArgs->targetKeyRef = keyRef;
186 return CRYPT_SUCCESS;
187 }
188
TransLowKeyToTargetLowKey(CRYPT_EAL_PkeyMgmtInfo * pkeyAlgInfo,const LowKeyObjectMethodInfo * method,void * lowObjectRef,void ** targetKeyRef)189 static int32_t TransLowKeyToTargetLowKey(CRYPT_EAL_PkeyMgmtInfo *pkeyAlgInfo, const LowKeyObjectMethodInfo *method,
190 void *lowObjectRef, void **targetKeyRef)
191 {
192 ImportTargetPkeyArgs importTargetPkeyArgs = {0};
193 importTargetPkeyArgs.pkeyAlgInfo = pkeyAlgInfo;
194
195 if (method->export == NULL) {
196 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
197 return CRYPT_NULL_INPUT;
198 }
199 BSL_Param param[3] = {
200 {CRYPT_PARAM_PKEY_PROCESS_FUNC, BSL_PARAM_TYPE_FUNC_PTR, ImportTargetPkey, 0, 0},
201 {CRYPT_PARAM_PKEY_PROCESS_ARGS, BSL_PARAM_TYPE_CTX_PTR, &importTargetPkeyArgs, 0, 0},
202 BSL_PARAM_END
203 };
204 int32_t ret = method->export(lowObjectRef, param);
205 if (ret != CRYPT_SUCCESS) {
206 BSL_ERR_PUSH_ERROR(ret);
207 return ret;
208 }
209
210 *targetKeyRef = importTargetPkeyArgs.targetKeyRef;
211 return CRYPT_SUCCESS;
212 }
213
DupLowKey(const LowKeyObjectMethodInfo * method,void * lowObjectRef,void ** targetKeyRef)214 static int32_t DupLowKey(const LowKeyObjectMethodInfo *method, void *lowObjectRef, void **targetKeyRef)
215 {
216 if (method->dupCtx == NULL) {
217 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
218 return CRYPT_NULL_INPUT;
219 }
220
221 *targetKeyRef = method->dupCtx(lowObjectRef);
222 if (*targetKeyRef == NULL) {
223 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
224 return CRYPT_MEM_ALLOC_FAIL;
225 }
226
227 return CRYPT_SUCCESS;
228 }
229
ConstructOutObjectParam(BSL_Param ** outParam,void * object)230 static int32_t ConstructOutObjectParam(BSL_Param **outParam, void *object)
231 {
232 BSL_Param *result = BSL_SAL_Calloc(2, sizeof(BSL_Param));
233 if (result == NULL) {
234 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
235 return CRYPT_MEM_ALLOC_FAIL;
236 }
237 int32_t ret = BSL_PARAM_InitValue(&result[0], CRYPT_PARAM_DECODE_OBJECT_DATA, BSL_PARAM_TYPE_CTX_PTR,
238 object, 0);
239 if (ret != CRYPT_SUCCESS) {
240 BSL_SAL_Free(result);
241 BSL_ERR_PUSH_ERROR(ret);
242 }
243 *outParam = result;
244 return ret;
245 }
246
247 /* input is pem format buffer, output is der format buffer */
DECODER_LowKeyObject2PkeyObjectDecode(void * ctx,const BSL_Param * inParam,BSL_Param ** outParam)248 int32_t DECODER_LowKeyObject2PkeyObjectDecode(void *ctx, const BSL_Param *inParam, BSL_Param **outParam)
249 {
250 if (ctx == NULL || inParam == NULL || outParam == NULL) {
251 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
252 return CRYPT_NULL_INPUT;
253 }
254 DECODER_Lowkey2PkeyCtx *decoderCtx = (DECODER_Lowkey2PkeyCtx *)ctx;
255 void *lowObjectRef = NULL;
256 int32_t lowObjectRefType = 0;
257 CRYPT_EAL_ProvMgrCtx *lastDecoderProviderCtx = NULL;
258 LowKeyObjectMethodInfo method = {0};
259 void *targetKeyRef = NULL;
260 CRYPT_EAL_PkeyMgmtInfo pkeyAlgInfo = {0};
261 int32_t ret = 0;
262 RETURN_RET_IF_ERR(GetLowKeyObjectInfo(inParam, &lowObjectRef, &lowObjectRefType, &method), ret);
263 if (method.freeCtx == NULL) {
264 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
265 return CRYPT_NULL_INPUT;
266 }
267 RETURN_RET_IF_ERR(GetProviderInfo(inParam, &lastDecoderProviderCtx), ret);
268 RETURN_RET_IF_ERR(CRYPT_EAL_GetPkeyAlgInfo(decoderCtx->libCtx, lowObjectRefType, decoderCtx->targetAttrName,
269 &pkeyAlgInfo), ret);
270 if (pkeyAlgInfo.mgrCtx != lastDecoderProviderCtx) {
271 ret = TransLowKeyToTargetLowKey(&pkeyAlgInfo, &method, lowObjectRef, &targetKeyRef);
272 } else {
273 ret = DupLowKey(&method, lowObjectRef, &targetKeyRef);
274 }
275 if (ret != CRYPT_SUCCESS) {
276 goto EXIT;
277 }
278 CRYPT_EAL_PkeyCtx *ealPKey = CRYPT_EAL_MakeKeyByPkeyAlgInfo(&pkeyAlgInfo, targetKeyRef, sizeof(void *));
279 if (ealPKey == NULL) {
280 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
281 goto EXIT;
282 }
283 ret = ConstructOutObjectParam(outParam, ealPKey);
284 if (ret != CRYPT_SUCCESS) {
285 CRYPT_EAL_PkeyFreeCtx(ealPKey);
286 BSL_ERR_PUSH_ERROR(ret);
287 }
288 return ret;
289
290 EXIT:
291 BSL_SAL_Free(pkeyAlgInfo.keyMgmtMethod);
292 if (targetKeyRef != NULL) {
293 method.freeCtx(targetKeyRef);
294 }
295 return ret;
296 }
297
DECODER_LowKeyObject2PkeyObjectFreeOutData(void * ctx,BSL_Param * outParam)298 void DECODER_LowKeyObject2PkeyObjectFreeOutData(void *ctx, BSL_Param *outParam)
299 {
300 DECODER_Lowkey2PkeyCtx *decoderCtx = (DECODER_Lowkey2PkeyCtx *)ctx;
301 if (outParam == NULL || decoderCtx == NULL) {
302 return;
303 }
304 BSL_Param *objectDataParam = BSL_PARAM_FindParam(outParam, CRYPT_PARAM_DECODE_OBJECT_DATA);
305 if (objectDataParam == NULL || objectDataParam->valueType != BSL_PARAM_TYPE_CTX_PTR ||
306 objectDataParam->value == NULL) {
307 return;
308 }
309 CRYPT_EAL_PkeyCtx *ealPKey = (CRYPT_EAL_PkeyCtx *)objectDataParam->value;
310 CRYPT_EAL_PkeyFreeCtx(ealPKey);
311 BSL_SAL_Free(outParam);
312 }
313
DECODER_LowKeyObject2PkeyObjectFreeCtx(void * ctx)314 void DECODER_LowKeyObject2PkeyObjectFreeCtx(void *ctx)
315 {
316 if (ctx == NULL) {
317 return;
318 }
319 BSL_SAL_Free(ctx);
320 }
321
322 #endif