1 /*
2 * Copyright (C) 2022-2023 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 "key_agreement.h"
17
18 #include <securec.h>
19
20 #include "key_agreement_spi.h"
21 #include "config.h"
22 #include "dh_openssl.h"
23 #include "ecdh_openssl.h"
24 #include "x25519_openssl.h"
25 #include "log.h"
26 #include "memory.h"
27 #include "params_parser.h"
28 #include "utils.h"
29
30 typedef HcfResult (*HcfKeyAgreementSpiCreateFunc)(HcfKeyAgreementParams *, HcfKeyAgreementSpi **);
31
32 typedef struct {
33 HcfKeyAgreement base;
34
35 HcfKeyAgreementSpi *spiObj;
36
37 char algoName[HCF_MAX_ALGO_NAME_LEN];
38 } HcfKeyAgreementImpl;
39
40 typedef struct {
41 HcfAlgValue algo;
42
43 HcfKeyAgreementSpiCreateFunc createSpiFunc;
44 } HcfKeyAgreementGenAbility;
45
46 static const HcfKeyAgreementGenAbility KEY_AGREEMENT_GEN_ABILITY_SET[] = {
47 { HCF_ALG_ECC, HcfKeyAgreementSpiEcdhCreate },
48 { HCF_ALG_X25519, HcfKeyAgreementSpiX25519Create },
49 { HCF_ALG_DH, HcfKeyAgreementSpiDhCreate }
50 };
51
FindAbility(HcfKeyAgreementParams * params)52 static HcfKeyAgreementSpiCreateFunc FindAbility(HcfKeyAgreementParams *params)
53 {
54 for (uint32_t i = 0; i < sizeof(KEY_AGREEMENT_GEN_ABILITY_SET) / sizeof(KEY_AGREEMENT_GEN_ABILITY_SET[0]); i++) {
55 if (KEY_AGREEMENT_GEN_ABILITY_SET[i].algo == params->algo) {
56 return KEY_AGREEMENT_GEN_ABILITY_SET[i].createSpiFunc;
57 }
58 }
59 LOGE("Algo not support! [Algo]: %d", params->algo);
60 return NULL;
61 }
62
SetKeyType(HcfAlgParaValue value,HcfKeyAgreementParams * paramsObj)63 static void SetKeyType(HcfAlgParaValue value, HcfKeyAgreementParams *paramsObj)
64 {
65 switch (value) {
66 case HCF_ALG_ECC_224:
67 case HCF_ALG_ECC_256:
68 case HCF_ALG_ECC_384:
69 case HCF_ALG_ECC_521:
70 case HCF_ALG_ECC_BP160R1:
71 case HCF_ALG_ECC_BP160T1:
72 case HCF_ALG_ECC_BP192R1:
73 case HCF_ALG_ECC_BP192T1:
74 case HCF_ALG_ECC_BP224R1:
75 case HCF_ALG_ECC_BP224T1:
76 case HCF_ALG_ECC_BP256R1:
77 case HCF_ALG_ECC_BP256T1:
78 case HCF_ALG_ECC_BP320R1:
79 case HCF_ALG_ECC_BP320T1:
80 case HCF_ALG_ECC_BP384R1:
81 case HCF_ALG_ECC_BP384T1:
82 case HCF_ALG_ECC_BP512R1:
83 case HCF_ALG_ECC_BP512T1:
84 case HCF_ALG_ECC_SECP256K1:
85 paramsObj->algo = HCF_ALG_ECC;
86 break;
87 case HCF_ALG_X25519_256:
88 paramsObj->algo = HCF_ALG_X25519;
89 break;
90 case HCF_OPENSSL_DH_MODP_1536:
91 case HCF_OPENSSL_DH_MODP_2048:
92 case HCF_OPENSSL_DH_MODP_3072:
93 case HCF_OPENSSL_DH_MODP_4096:
94 case HCF_OPENSSL_DH_MODP_6144:
95 case HCF_OPENSSL_DH_MODP_8192:
96 case HCF_OPENSSL_DH_FFDHE_2048:
97 case HCF_OPENSSL_DH_FFDHE_3072:
98 case HCF_OPENSSL_DH_FFDHE_4096:
99 case HCF_OPENSSL_DH_FFDHE_6144:
100 case HCF_OPENSSL_DH_FFDHE_8192:
101 paramsObj->algo = HCF_ALG_DH;
102 break;
103 default:
104 LOGE("Invalid algo %u.", value);
105 break;
106 }
107 }
108
SetKeyTypeDefault(HcfAlgParaValue value,HcfKeyAgreementParams * paramsObj)109 static void SetKeyTypeDefault(HcfAlgParaValue value, HcfKeyAgreementParams *paramsObj)
110 {
111 switch (value) {
112 case HCF_ALG_ECC_DEFAULT:
113 paramsObj->algo = HCF_ALG_ECC;
114 break;
115 case HCF_ALG_X25519_DEFAULT:
116 paramsObj->algo = HCF_ALG_X25519;
117 break;
118 case HCF_ALG_DH_DEFAULT:
119 paramsObj->algo = HCF_ALG_DH;
120 break;
121 default:
122 LOGE("Invalid algo %u.", value);
123 break;
124 }
125 }
126
ParseKeyAgreementParams(const HcfParaConfig * config,void * params)127 static HcfResult ParseKeyAgreementParams(const HcfParaConfig *config, void *params)
128 {
129 if (config == NULL || params == NULL) {
130 LOGE("Invalid key agreement params");
131 return HCF_INVALID_PARAMS;
132 }
133 HcfResult ret = HCF_SUCCESS;
134 HcfKeyAgreementParams *paramsObj = (HcfKeyAgreementParams *)params;
135 LOGD("Set Parameter: %s", config->tag);
136 switch (config->paraType) {
137 case HCF_ALG_TYPE:
138 SetKeyTypeDefault(config->paraValue, paramsObj);
139 break;
140 case HCF_ALG_KEY_TYPE:
141 SetKeyType(config->paraValue, paramsObj);
142 break;
143 default:
144 ret = HCF_INVALID_PARAMS;
145 break;
146 }
147 return ret;
148 }
149
150 // export interfaces
GetKeyAgreementClass(void)151 static const char *GetKeyAgreementClass(void)
152 {
153 return "HcfKeyAgreement";
154 }
155
GetAlgoName(HcfKeyAgreement * self)156 static const char *GetAlgoName(HcfKeyAgreement *self)
157 {
158 if (self == NULL) {
159 LOGE("The input self ptr is NULL!");
160 return NULL;
161 }
162 if (!HcfIsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
163 return NULL;
164 }
165 return ((HcfKeyAgreementImpl *)self)->algoName;
166 }
167
GenerateSecret(HcfKeyAgreement * self,HcfPriKey * priKey,HcfPubKey * pubKey,HcfBlob * returnSecret)168 static HcfResult GenerateSecret(HcfKeyAgreement *self, HcfPriKey *priKey,
169 HcfPubKey *pubKey, HcfBlob *returnSecret)
170 {
171 if (self == NULL) {
172 LOGE("Invalid input parameter.");
173 return HCF_INVALID_PARAMS;
174 }
175 if (!HcfIsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
176 return HCF_INVALID_PARAMS;
177 }
178
179 return ((HcfKeyAgreementImpl *)self)->spiObj->engineGenerateSecret(
180 ((HcfKeyAgreementImpl *)self)->spiObj, priKey, pubKey, returnSecret);
181 }
182
DestroyKeyAgreement(HcfObjectBase * self)183 static void DestroyKeyAgreement(HcfObjectBase *self)
184 {
185 if (self == NULL) {
186 return;
187 }
188 if (!HcfIsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
189 return;
190 }
191 HcfKeyAgreementImpl *impl = (HcfKeyAgreementImpl *)self;
192 HcfObjDestroy(impl->spiObj);
193 impl->spiObj = NULL;
194 HcfFree(impl);
195 }
196
HcfKeyAgreementCreate(const char * algoName,HcfKeyAgreement ** returnObj)197 HcfResult HcfKeyAgreementCreate(const char *algoName, HcfKeyAgreement **returnObj)
198 {
199 if ((!HcfIsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) {
200 return HCF_INVALID_PARAMS;
201 }
202
203 HcfKeyAgreementParams params = { 0 };
204 if (ParseAndSetParameter(algoName, ¶ms, ParseKeyAgreementParams) != HCF_SUCCESS) {
205 LOGE("Failed to parse params!");
206 return HCF_INVALID_PARAMS;
207 }
208
209 HcfKeyAgreementSpiCreateFunc createSpiFunc = FindAbility(¶ms);
210 if (createSpiFunc == NULL) {
211 return HCF_NOT_SUPPORT;
212 }
213
214 HcfKeyAgreementImpl *returnGenerator = (HcfKeyAgreementImpl *)HcfMalloc(sizeof(HcfKeyAgreementImpl), 0);
215 if (returnGenerator == NULL) {
216 LOGE("Failed to allocate returnGenerator memory!");
217 return HCF_ERR_MALLOC;
218 }
219 if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) {
220 LOGE("Failed to copy algoName!");
221 HcfFree(returnGenerator);
222 return HCF_INVALID_PARAMS;
223 }
224 HcfKeyAgreementSpi *spiObj = NULL;
225 HcfResult res = createSpiFunc(¶ms, &spiObj);
226 if (res != HCF_SUCCESS) {
227 LOGE("Failed to create spi object!");
228 HcfFree(returnGenerator);
229 return res;
230 }
231 returnGenerator->base.base.destroy = DestroyKeyAgreement;
232 returnGenerator->base.base.getClass = GetKeyAgreementClass;
233 returnGenerator->base.generateSecret = GenerateSecret;
234 returnGenerator->base.getAlgoName = GetAlgoName;
235 returnGenerator->spiObj = spiObj;
236
237 *returnObj = (HcfKeyAgreement *)returnGenerator;
238 return HCF_SUCCESS;
239 }
240