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 paramsObj->algo = HCF_ALG_ECC;
85 break;
86 case HCF_ALG_X25519_256:
87 paramsObj->algo = HCF_ALG_X25519;
88 break;
89 case HCF_OPENSSL_DH_MODP_1536:
90 case HCF_OPENSSL_DH_MODP_2048:
91 case HCF_OPENSSL_DH_MODP_3072:
92 case HCF_OPENSSL_DH_MODP_4096:
93 case HCF_OPENSSL_DH_MODP_6144:
94 case HCF_OPENSSL_DH_MODP_8192:
95 case HCF_OPENSSL_DH_FFDHE_2048:
96 case HCF_OPENSSL_DH_FFDHE_3072:
97 case HCF_OPENSSL_DH_FFDHE_4096:
98 case HCF_OPENSSL_DH_FFDHE_6144:
99 case HCF_OPENSSL_DH_FFDHE_8192:
100 paramsObj->algo = HCF_ALG_DH;
101 break;
102 default:
103 LOGE("Invalid algo %u.", value);
104 break;
105 }
106 }
107
SetKeyTypeDefault(HcfAlgParaValue value, HcfKeyAgreementParams *paramsObj)108 static void SetKeyTypeDefault(HcfAlgParaValue value, HcfKeyAgreementParams *paramsObj)
109 {
110 switch (value) {
111 case HCF_ALG_ECC_DEFAULT:
112 paramsObj->algo = HCF_ALG_ECC;
113 break;
114 case HCF_ALG_X25519_DEFAULT:
115 paramsObj->algo = HCF_ALG_X25519;
116 break;
117 case HCF_ALG_DH_DEFAULT:
118 paramsObj->algo = HCF_ALG_DH;
119 break;
120 default:
121 LOGE("Invalid algo %u.", value);
122 break;
123 }
124 }
125
ParseKeyAgreementParams(const HcfParaConfig *config, void *params)126 static HcfResult ParseKeyAgreementParams(const HcfParaConfig *config, void *params)
127 {
128 if (config == NULL || params == NULL) {
129 LOGE("Invalid key agreement params");
130 return HCF_INVALID_PARAMS;
131 }
132 HcfResult ret = HCF_SUCCESS;
133 HcfKeyAgreementParams *paramsObj = (HcfKeyAgreementParams *)params;
134 LOGD("Set Parameter: %s", config->tag);
135 switch (config->paraType) {
136 case HCF_ALG_TYPE:
137 SetKeyTypeDefault(config->paraValue, paramsObj);
138 break;
139 case HCF_ALG_KEY_TYPE:
140 SetKeyType(config->paraValue, paramsObj);
141 break;
142 default:
143 ret = HCF_INVALID_PARAMS;
144 break;
145 }
146 return ret;
147 }
148
149 // export interfaces
GetKeyAgreementClass(void)150 static const char *GetKeyAgreementClass(void)
151 {
152 return "HcfKeyAgreement";
153 }
154
GetAlgoName(HcfKeyAgreement *self)155 static const char *GetAlgoName(HcfKeyAgreement *self)
156 {
157 if (self == NULL) {
158 LOGE("The input self ptr is NULL!");
159 return NULL;
160 }
161 if (!HcfIsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
162 return NULL;
163 }
164 return ((HcfKeyAgreementImpl *)self)->algoName;
165 }
166
GenerateSecret(HcfKeyAgreement *self, HcfPriKey *priKey, HcfPubKey *pubKey, HcfBlob *returnSecret)167 static HcfResult GenerateSecret(HcfKeyAgreement *self, HcfPriKey *priKey,
168 HcfPubKey *pubKey, HcfBlob *returnSecret)
169 {
170 if (self == NULL) {
171 LOGE("Invalid input parameter.");
172 return HCF_INVALID_PARAMS;
173 }
174 if (!HcfIsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
175 return HCF_INVALID_PARAMS;
176 }
177
178 return ((HcfKeyAgreementImpl *)self)->spiObj->engineGenerateSecret(
179 ((HcfKeyAgreementImpl *)self)->spiObj, priKey, pubKey, returnSecret);
180 }
181
DestroyKeyAgreement(HcfObjectBase *self)182 static void DestroyKeyAgreement(HcfObjectBase *self)
183 {
184 if (self == NULL) {
185 return;
186 }
187 if (!HcfIsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
188 return;
189 }
190 HcfKeyAgreementImpl *impl = (HcfKeyAgreementImpl *)self;
191 HcfObjDestroy(impl->spiObj);
192 impl->spiObj = NULL;
193 HcfFree(impl);
194 }
195
HcfKeyAgreementCreate(const char *algoName, HcfKeyAgreement **returnObj)196 HcfResult HcfKeyAgreementCreate(const char *algoName, HcfKeyAgreement **returnObj)
197 {
198 if ((!HcfIsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) {
199 return HCF_INVALID_PARAMS;
200 }
201
202 HcfKeyAgreementParams params = { 0 };
203 if (ParseAndSetParameter(algoName, ¶ms, ParseKeyAgreementParams) != HCF_SUCCESS) {
204 LOGE("Failed to parse params!");
205 return HCF_INVALID_PARAMS;
206 }
207
208 HcfKeyAgreementSpiCreateFunc createSpiFunc = FindAbility(¶ms);
209 if (createSpiFunc == NULL) {
210 return HCF_NOT_SUPPORT;
211 }
212
213 HcfKeyAgreementImpl *returnGenerator = (HcfKeyAgreementImpl *)HcfMalloc(sizeof(HcfKeyAgreementImpl), 0);
214 if (returnGenerator == NULL) {
215 LOGE("Failed to allocate returnGenerator memory!");
216 return HCF_ERR_MALLOC;
217 }
218 if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) {
219 LOGE("Failed to copy algoName!");
220 HcfFree(returnGenerator);
221 return HCF_INVALID_PARAMS;
222 }
223 HcfKeyAgreementSpi *spiObj = NULL;
224 HcfResult res = createSpiFunc(¶ms, &spiObj);
225 if (res != HCF_SUCCESS) {
226 LOGE("Failed to create spi object!");
227 HcfFree(returnGenerator);
228 return res;
229 }
230 returnGenerator->base.base.destroy = DestroyKeyAgreement;
231 returnGenerator->base.base.getClass = GetKeyAgreementClass;
232 returnGenerator->base.generateSecret = GenerateSecret;
233 returnGenerator->base.getAlgoName = GetAlgoName;
234 returnGenerator->spiObj = spiObj;
235
236 *returnObj = (HcfKeyAgreement *)returnGenerator;
237 return HCF_SUCCESS;
238 }
239