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 "ecdh_openssl.h"
23 #include "log.h"
24 #include "memory.h"
25 #include "params_parser.h"
26 #include "utils.h"
27
28 typedef HcfResult (*HcfKeyAgreementSpiCreateFunc)(HcfKeyAgreementParams *, HcfKeyAgreementSpi **);
29
30 typedef struct {
31 HcfKeyAgreement base;
32
33 HcfKeyAgreementSpi *spiObj;
34
35 char algoName[HCF_MAX_ALGO_NAME_LEN];
36 } HcfKeyAgreementImpl;
37
38 typedef struct {
39 HcfAlgValue algo;
40
41 HcfKeyAgreementSpiCreateFunc createSpiFunc;
42 } HcfKeyAgreementGenAbility;
43
44 static const HcfKeyAgreementGenAbility KEY_AGREEMENT_GEN_ABILITY_SET[] = {
45 { HCF_ALG_ECC, HcfKeyAgreementSpiEcdhCreate }
46 };
47
FindAbility(HcfKeyAgreementParams * params)48 static HcfKeyAgreementSpiCreateFunc FindAbility(HcfKeyAgreementParams *params)
49 {
50 for (uint32_t i = 0; i < sizeof(KEY_AGREEMENT_GEN_ABILITY_SET) / sizeof(KEY_AGREEMENT_GEN_ABILITY_SET[0]); i++) {
51 if (KEY_AGREEMENT_GEN_ABILITY_SET[i].algo == params->algo) {
52 return KEY_AGREEMENT_GEN_ABILITY_SET[i].createSpiFunc;
53 }
54 }
55 LOGE("Algo not support! [Algo]: %d", params->algo);
56 return NULL;
57 }
58
SetKeyType(HcfAlgParaValue value,HcfKeyAgreementParams * paramsObj)59 static void SetKeyType(HcfAlgParaValue value, HcfKeyAgreementParams *paramsObj)
60 {
61 switch (value) {
62 case HCF_ALG_ECC_224:
63 case HCF_ALG_ECC_256:
64 case HCF_ALG_ECC_384:
65 case HCF_ALG_ECC_521:
66 paramsObj->algo = HCF_ALG_ECC;
67 break;
68 default:
69 break;
70 }
71 }
72
SetKeyTypeDefault(HcfAlgParaValue value,HcfKeyAgreementParams * paramsObj)73 static void SetKeyTypeDefault(HcfAlgParaValue value, HcfKeyAgreementParams *paramsObj)
74 {
75 switch (value) {
76 case HCF_ALG_ECC_DEFAULT:
77 paramsObj->algo = HCF_ALG_ECC;
78 break;
79 default:
80 LOGE("Invalid algo %u.", value);
81 break;
82 }
83 }
84
ParseKeyAgreementParams(const HcfParaConfig * config,void * params)85 static HcfResult ParseKeyAgreementParams(const HcfParaConfig* config, void *params)
86 {
87 if (config == NULL || params == NULL) {
88 return HCF_INVALID_PARAMS;
89 }
90 HcfResult ret = HCF_SUCCESS;
91 HcfKeyAgreementParams *paramsObj = (HcfKeyAgreementParams *)params;
92 LOGI("Set Parameter: %s", config->tag);
93 switch (config->paraType) {
94 case HCF_ALG_TYPE:
95 SetKeyTypeDefault(config->paraValue, paramsObj);
96 break;
97 case HCF_ALG_KEY_TYPE:
98 SetKeyType(config->paraValue, paramsObj);
99 break;
100 default:
101 ret = HCF_INVALID_PARAMS;
102 break;
103 }
104 return ret;
105 }
106
107 // export interfaces
GetKeyAgreementClass(void)108 static const char *GetKeyAgreementClass(void)
109 {
110 return "HcfKeyAgreement";
111 }
112
GetAlgoName(HcfKeyAgreement * self)113 static const char *GetAlgoName(HcfKeyAgreement *self)
114 {
115 if (self == NULL) {
116 LOGE("The input self ptr is NULL!");
117 return NULL;
118 }
119 if (!IsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
120 return NULL;
121 }
122 return ((HcfKeyAgreementImpl *)self)->algoName;
123 }
124
GenerateSecret(HcfKeyAgreement * self,HcfPriKey * priKey,HcfPubKey * pubKey,HcfBlob * returnSecret)125 static HcfResult GenerateSecret(HcfKeyAgreement *self, HcfPriKey *priKey,
126 HcfPubKey *pubKey, HcfBlob *returnSecret)
127 {
128 if (self == NULL) {
129 LOGE("Invalid input parameter.");
130 return HCF_INVALID_PARAMS;
131 }
132 if (!IsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
133 return HCF_INVALID_PARAMS;
134 }
135
136 return ((HcfKeyAgreementImpl *)self)->spiObj->engineGenerateSecret(
137 ((HcfKeyAgreementImpl *)self)->spiObj, priKey, pubKey, returnSecret);
138 }
139
DestroyKeyAgreement(HcfObjectBase * self)140 static void DestroyKeyAgreement(HcfObjectBase *self)
141 {
142 if (self == NULL) {
143 return;
144 }
145 if (!IsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
146 return;
147 }
148 HcfKeyAgreementImpl *impl = (HcfKeyAgreementImpl *)self;
149 HcfObjDestroy(impl->spiObj);
150 impl->spiObj = NULL;
151 HcfFree(impl);
152 }
153
HcfKeyAgreementCreate(const char * algoName,HcfKeyAgreement ** returnObj)154 HcfResult HcfKeyAgreementCreate(const char *algoName, HcfKeyAgreement **returnObj)
155 {
156 if ((!IsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) {
157 return HCF_INVALID_PARAMS;
158 }
159
160 HcfKeyAgreementParams params = { 0 };
161 if (ParseAndSetParameter(algoName, ¶ms, ParseKeyAgreementParams) != HCF_SUCCESS) {
162 LOGE("Failed to parser parmas!");
163 return HCF_INVALID_PARAMS;
164 }
165
166 HcfKeyAgreementSpiCreateFunc createSpiFunc = FindAbility(¶ms);
167 if (createSpiFunc == NULL) {
168 return HCF_NOT_SUPPORT;
169 }
170
171 HcfKeyAgreementImpl *returnGenerator = (HcfKeyAgreementImpl *)HcfMalloc(sizeof(HcfKeyAgreementImpl), 0);
172 if (returnGenerator == NULL) {
173 LOGE("Failed to allocate returnGenerator memory!");
174 return HCF_ERR_MALLOC;
175 }
176 if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) {
177 LOGE("Failed to copy algoName!");
178 HcfFree(returnGenerator);
179 return HCF_INVALID_PARAMS;
180 }
181 HcfKeyAgreementSpi *spiObj = NULL;
182 HcfResult res = createSpiFunc(¶ms, &spiObj);
183 if (res != HCF_SUCCESS) {
184 LOGE("Failed to create spi object!");
185 HcfFree(returnGenerator);
186 return res;
187 }
188 returnGenerator->base.base.destroy = DestroyKeyAgreement;
189 returnGenerator->base.base.getClass = GetKeyAgreementClass;
190 returnGenerator->base.generateSecret = GenerateSecret;
191 returnGenerator->base.getAlgoName = GetAlgoName;
192 returnGenerator->spiObj = spiObj;
193
194 *returnObj = (HcfKeyAgreement *)returnGenerator;
195 return HCF_SUCCESS;
196 }
197