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 HCF_ALG_VALUE 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(HCF_ALG_PARA_VALUE value,HcfKeyAgreementParams * paramsObj)59 static void SetKeyType(HCF_ALG_PARA_VALUE 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->keyLen = value;
67 paramsObj->algo = HCF_ALG_ECC;
68 break;
69 default:
70 break;
71 }
72 }
73
ParseKeyAgreementParams(const HcfParaConfig * config,void * params)74 static HcfResult ParseKeyAgreementParams(const HcfParaConfig* config, void *params)
75 {
76 if (config == NULL || params == NULL) {
77 return HCF_INVALID_PARAMS;
78 }
79 HcfResult ret = HCF_SUCCESS;
80 HcfKeyAgreementParams *paramsObj = (HcfKeyAgreementParams *)params;
81 LOGI("Set Parameter: %s", config->tag);
82 switch (config->paraType) {
83 case HCF_ALG_KEY_TYPE:
84 SetKeyType(config->paraValue, paramsObj);
85 break;
86 default:
87 ret = HCF_INVALID_PARAMS;
88 break;
89 }
90 return ret;
91 }
92
93 // export interfaces
GetKeyAgreementClass(void)94 static const char *GetKeyAgreementClass(void)
95 {
96 return "HcfKeyAgreement";
97 }
98
GetAlgoName(HcfKeyAgreement * self)99 static const char *GetAlgoName(HcfKeyAgreement *self)
100 {
101 if (self == NULL) {
102 LOGE("The input self ptr is NULL!");
103 return NULL;
104 }
105 if (!IsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
106 return NULL;
107 }
108 return ((HcfKeyAgreementImpl *)self)->algoName;
109 }
110
GenerateSecret(HcfKeyAgreement * self,HcfPriKey * priKey,HcfPubKey * pubKey,HcfBlob * returnSecret)111 static HcfResult GenerateSecret(HcfKeyAgreement *self, HcfPriKey *priKey,
112 HcfPubKey *pubKey, HcfBlob *returnSecret)
113 {
114 if (self == NULL) {
115 LOGE("Invalid input parameter.");
116 return HCF_INVALID_PARAMS;
117 }
118 if (!IsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
119 return HCF_INVALID_PARAMS;
120 }
121
122 return ((HcfKeyAgreementImpl *)self)->spiObj->engineGenerateSecret(
123 ((HcfKeyAgreementImpl *)self)->spiObj, priKey, pubKey, returnSecret);
124 }
125
DestroyKeyAgreement(HcfObjectBase * self)126 static void DestroyKeyAgreement(HcfObjectBase *self)
127 {
128 if (self == NULL) {
129 return;
130 }
131 if (!IsClassMatch((HcfObjectBase *)self, GetKeyAgreementClass())) {
132 return;
133 }
134 HcfKeyAgreementImpl *impl = (HcfKeyAgreementImpl *)self;
135 HcfObjDestroy(impl->spiObj);
136 impl->spiObj = NULL;
137 HcfFree(impl);
138 }
139
HcfKeyAgreementCreate(const char * algoName,HcfKeyAgreement ** returnObj)140 HcfResult HcfKeyAgreementCreate(const char *algoName, HcfKeyAgreement **returnObj)
141 {
142 if ((!IsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) {
143 return HCF_INVALID_PARAMS;
144 }
145
146 HcfKeyAgreementParams params = { 0 };
147 if (ParseAndSetParameter(algoName, ¶ms, ParseKeyAgreementParams) != HCF_SUCCESS) {
148 LOGE("Failed to parser parmas!");
149 return HCF_INVALID_PARAMS;
150 }
151
152 HcfKeyAgreementSpiCreateFunc createSpifunc = FindAbility(¶ms);
153 if (createSpifunc == NULL) {
154 return HCF_NOT_SUPPORT;
155 }
156
157 HcfKeyAgreementImpl *returnGenerator = (HcfKeyAgreementImpl *)HcfMalloc(sizeof(HcfKeyAgreementImpl), 0);
158 if (returnGenerator == NULL) {
159 LOGE("Failed to allocate returnGenerator memory!");
160 return HCF_ERR_MALLOC;
161 }
162 if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) {
163 LOGE("Failed to copy algoName!");
164 HcfFree(returnGenerator);
165 return HCF_ERR_COPY;
166 }
167 HcfKeyAgreementSpi *spiObj = NULL;
168 int32_t res = createSpifunc(¶ms, &spiObj);
169 if (res != HCF_SUCCESS) {
170 LOGE("Failed to create spi object!");
171 HcfFree(returnGenerator);
172 return res;
173 }
174 returnGenerator->base.base.destroy = DestroyKeyAgreement;
175 returnGenerator->base.base.getClass = GetKeyAgreementClass;
176 returnGenerator->base.generateSecret = GenerateSecret;
177 returnGenerator->base.getAlgoName = GetAlgoName;
178 returnGenerator->spiObj = spiObj;
179
180 *returnObj = (HcfKeyAgreement *)returnGenerator;
181 return HCF_SUCCESS;
182 }
183