1 /*
2 * Copyright (C) 2022 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 "log.h"
17 #include "memory.h"
18 #include "result.h"
19 #include "securec.h"
20 #include "utils.h"
21 #include "sym_common_defines.h"
22 #include "openssl_adapter.h"
23 #include "openssl_common.h"
24
25 #define MAX_KEY_STR_SIZE 12
26 #define MAX_KEY_LEN 4096
27 #define KEY_BIT 8
28 #define AES_ALG_NAME "AES"
29 #define SM4_ALG_NAME "SM4"
30 #define DES_ALG_NAME "3DES"
31
32 typedef struct {
33 HcfSymKeyGeneratorSpi base;
34 SymKeyAttr attr;
35 } HcfSymKeyGeneratorSpiOpensslImpl;
36
GetEncoded(HcfKey * self,HcfBlob * key)37 static HcfResult GetEncoded(HcfKey *self, HcfBlob *key)
38 {
39 if ((self == NULL) || (key == NULL)) {
40 LOGE("Invalid input parameter!");
41 return HCF_INVALID_PARAMS;
42 }
43 if (!IsClassMatch((const HcfObjectBase *)self, OPENSSL_SYM_KEY_CLASS)) {
44 LOGE("Class is not match.");
45 return HCF_INVALID_PARAMS;
46 }
47 SymKeyImpl *impl = (SymKeyImpl *)self;
48 if ((impl->keyMaterial.data == NULL) || (impl->keyMaterial.len == 0)) {
49 LOGE("Invalid SymKeyImpl parameter!");
50 return HCF_INVALID_PARAMS;
51 }
52 key->data = (uint8_t *)HcfMalloc(impl->keyMaterial.len, 0);
53 if (key->data == NULL) {
54 LOGE("malloc keyMaterial failed!");
55 return HCF_ERR_MALLOC;
56 }
57 (void)memcpy_s(key->data, impl->keyMaterial.len, impl->keyMaterial.data, impl->keyMaterial.len);
58 key->len = impl->keyMaterial.len;
59 return HCF_SUCCESS;
60 }
61
ClearMem(HcfSymKey * self)62 static void ClearMem(HcfSymKey *self)
63 {
64 if (self == NULL) {
65 LOGE("symKey is NULL.");
66 return;
67 }
68 if (!IsClassMatch((const HcfObjectBase *)self, OPENSSL_SYM_KEY_CLASS)) {
69 LOGE("Class is not match.");
70 return;
71 }
72 SymKeyImpl *impl = (SymKeyImpl *)self;
73 if ((impl->keyMaterial.data != NULL) && (impl->keyMaterial.len > 0)) {
74 (void)memset_s(impl->keyMaterial.data, impl->keyMaterial.len, 0, impl->keyMaterial.len);
75 }
76 }
77
GetFormat(HcfKey * self)78 static const char *GetFormat(HcfKey *self)
79 {
80 if (self == NULL) {
81 LOGE("Invalid input parameter!");
82 return NULL;
83 }
84 if (!IsClassMatch((const HcfObjectBase *)self, OPENSSL_SYM_KEY_CLASS)) {
85 LOGE("Class is not match.");
86 return NULL;
87 }
88
89 return "PKCS#8";
90 }
91
GetSymKeyGeneratorClass(void)92 static const char *GetSymKeyGeneratorClass(void)
93 {
94 return OPENSSL_SYM_GENERATOR_CLASS;
95 }
96
GetSymKeyClass(void)97 static const char *GetSymKeyClass(void)
98 {
99 return OPENSSL_SYM_KEY_CLASS;
100 }
101
GetAlgorithm(HcfKey * self)102 static const char *GetAlgorithm(HcfKey *self)
103 {
104 if (self == NULL) {
105 LOGE("Invalid input parameter!");
106 return NULL;
107 }
108 if (!IsClassMatch((const HcfObjectBase *)self, OPENSSL_SYM_KEY_CLASS)) {
109 LOGE("Class is not match.");
110 return NULL;
111 }
112 SymKeyImpl *impl = (SymKeyImpl *)self;
113 return (const char *)impl->algoName;
114 }
115
RandomSymmKey(int32_t keyLen,HcfBlob * symmKey)116 static HcfResult RandomSymmKey(int32_t keyLen, HcfBlob *symmKey)
117 {
118 uint8_t *keyMaterial = (uint8_t *)HcfMalloc(keyLen, 0);
119 if (keyMaterial == NULL) {
120 LOGE("keyMaterial malloc failed!");
121 return HCF_ERR_MALLOC;
122 }
123 int ret = Openssl_RAND_priv_bytes(keyMaterial, keyLen);
124 if (ret != HCF_OPENSSL_SUCCESS) {
125 LOGE("RAND_bytes failed!");
126 HcfPrintOpensslError();
127 HcfFree(keyMaterial);
128 return HCF_ERR_CRYPTO_OPERATION;
129 }
130 symmKey->data = keyMaterial;
131 symmKey->len = keyLen;
132 return HCF_SUCCESS;
133 }
134
HcfSymmKeySpiCreate(int32_t keyLen,SymKeyImpl * symKey)135 static HcfResult HcfSymmKeySpiCreate(int32_t keyLen, SymKeyImpl *symKey)
136 {
137 if ((keyLen == 0) || (symKey == NULL)) {
138 LOGE("Invalid input parameter!");
139 return HCF_INVALID_PARAMS;
140 }
141 HcfResult res = RandomSymmKey(keyLen, &symKey->keyMaterial);
142 if (res != HCF_SUCCESS) {
143 LOGE("RandomSymmKey failed!");
144 return res;
145 }
146 return res;
147 }
148
DestroySymKeyGeneratorSpi(HcfObjectBase * base)149 static void DestroySymKeyGeneratorSpi(HcfObjectBase *base)
150 {
151 if (base == NULL) {
152 LOGE("Invalid input parameter!");
153 return;
154 }
155 if (!IsClassMatch(base, GetSymKeyGeneratorClass())) {
156 LOGE("Class is not match!");
157 return;
158 }
159 HcfFree(base);
160 }
161
DestroySymKeySpi(HcfObjectBase * base)162 static void DestroySymKeySpi(HcfObjectBase *base)
163 {
164 if (base == NULL) {
165 LOGE("Invalid input parameter!");
166 return;
167 }
168 if (!IsClassMatch(base, OPENSSL_SYM_KEY_CLASS)) {
169 LOGE("Class is not match.");
170 return;
171 }
172 SymKeyImpl *impl = (SymKeyImpl *)base;
173 if (impl->algoName != NULL) {
174 HcfFree(impl->algoName);
175 impl->algoName = NULL;
176 }
177 if (impl->keyMaterial.data != NULL) {
178 (void)memset_s(impl->keyMaterial.data, impl->keyMaterial.len, 0, impl->keyMaterial.len);
179 HcfFree(impl->keyMaterial.data);
180 impl->keyMaterial.data = NULL;
181 impl->keyMaterial.len = 0;
182 }
183 HcfFree(impl);
184 }
185
GetAlgoNameType(HcfAlgValue type)186 static char *GetAlgoNameType(HcfAlgValue type)
187 {
188 switch (type) {
189 case HCF_ALG_AES:
190 return AES_ALG_NAME;
191 case HCF_ALG_SM4:
192 return SM4_ALG_NAME;
193 case HCF_ALG_DES:
194 return DES_ALG_NAME;
195 default:
196 LOGE("unsupport type!");
197 break;
198 }
199 return NULL;
200 }
201
GetAlgoName(HcfSymKeyGeneratorSpiOpensslImpl * impl)202 static char *GetAlgoName(HcfSymKeyGeneratorSpiOpensslImpl *impl)
203 {
204 char keySizeChar[MAX_KEY_STR_SIZE] = { 0 };
205 if (sprintf_s(keySizeChar, MAX_KEY_STR_SIZE, "%d", impl->attr.keySize) < 0) {
206 LOGE("Invalid input parameter!");
207 return NULL;
208 }
209 char *nameType = GetAlgoNameType(impl->attr.algo);
210 if (nameType == NULL) {
211 LOGE("get algo name type failed!");
212 return NULL;
213 }
214 int32_t nameSize = strlen(nameType);
215 char *algoName = (char *)HcfMalloc(MAX_KEY_STR_SIZE, 0);
216 if (algoName == NULL) {
217 LOGE("algoName malloc failed!");
218 return NULL;
219 }
220 if (strcpy_s(algoName, MAX_KEY_STR_SIZE, nameType) != EOK) {
221 LOGE("algoName strcpy_s failed!");
222 goto clearup;
223 }
224 if (strcpy_s(algoName + nameSize, MAX_KEY_STR_SIZE - nameSize, keySizeChar) != EOK) {
225 LOGE("algoName size strcpy_s failed!");
226 goto clearup;
227 }
228 return algoName;
229 clearup:
230 HcfFree(algoName);
231 return NULL;
232 }
233
CopySymmKey(const HcfBlob * srcKey,HcfBlob * dstKey)234 static HcfResult CopySymmKey(const HcfBlob *srcKey, HcfBlob *dstKey)
235 {
236 if ((srcKey->data == NULL) || (srcKey->len == 0)) {
237 LOGE("Invalid input parameter!");
238 return HCF_INVALID_PARAMS;
239 }
240 uint8_t *keyMaterial = (uint8_t *)HcfMalloc(srcKey->len, 0);
241 if (keyMaterial == NULL) {
242 LOGE("keyMaterial malloc failed!");
243 return HCF_ERR_MALLOC;
244 }
245 (void)memcpy_s(keyMaterial, srcKey->len, srcKey->data, srcKey->len);
246 dstKey->data = keyMaterial;
247 dstKey->len = srcKey->len;
248 return HCF_SUCCESS;
249 }
250
GenerateSymmKey(HcfSymKeyGeneratorSpi * self,HcfSymKey ** symmKey)251 static HcfResult GenerateSymmKey(HcfSymKeyGeneratorSpi *self, HcfSymKey **symmKey)
252 {
253 if ((self == NULL) || (symmKey == NULL)) {
254 LOGE("Invalid input parameter!");
255 return HCF_INVALID_PARAMS;
256 }
257 if (!IsClassMatch((const HcfObjectBase *)self, GetSymKeyGeneratorClass())) {
258 LOGE("Class is not match!");
259 return HCF_INVALID_PARAMS;
260 }
261 SymKeyImpl *returnSymmKey = (SymKeyImpl *)HcfMalloc(sizeof(SymKeyImpl), 0);
262 if (returnSymmKey == NULL) {
263 LOGE("Failed to allocate returnKeyPair memory!");
264 return HCF_ERR_MALLOC;
265 }
266 HcfSymKeyGeneratorSpiOpensslImpl *impl = (HcfSymKeyGeneratorSpiOpensslImpl *)self;
267 HcfResult res = HcfSymmKeySpiCreate(impl->attr.keySize / KEY_BIT, returnSymmKey);
268 if (res != HCF_SUCCESS) {
269 HcfFree(returnSymmKey);
270 return res;
271 }
272 returnSymmKey->algoName = GetAlgoName(impl);
273 returnSymmKey->key.clearMem = ClearMem;
274 returnSymmKey->key.key.getEncoded = GetEncoded;
275 returnSymmKey->key.key.getFormat = GetFormat;
276 returnSymmKey->key.key.getAlgorithm = GetAlgorithm;
277 returnSymmKey->key.key.base.destroy = DestroySymKeySpi;
278 returnSymmKey->key.key.base.getClass = GetSymKeyClass;
279 *symmKey = (HcfSymKey *)returnSymmKey;
280 return HCF_SUCCESS;
281 }
282
ConvertSymmKey(HcfSymKeyGeneratorSpi * self,const HcfBlob * key,HcfSymKey ** symmKey)283 static HcfResult ConvertSymmKey(HcfSymKeyGeneratorSpi *self, const HcfBlob *key, HcfSymKey **symmKey)
284 {
285 if ((self == NULL) || (symmKey == NULL) || !IsBlobValid(key)) {
286 LOGE("Invalid input parameter.");
287 return HCF_INVALID_PARAMS;
288 }
289 if (!IsClassMatch((const HcfObjectBase *)self, GetSymKeyGeneratorClass())) {
290 LOGE("Class is not match.");
291 return HCF_INVALID_PARAMS;
292 }
293 HcfSymKeyGeneratorSpiOpensslImpl *impl = (HcfSymKeyGeneratorSpiOpensslImpl *)self;
294
295 if ((key->len == 0) || (key->len > MAX_KEY_LEN) || ((impl->attr.keySize / KEY_BIT) != (int32_t)key->len)) {
296 LOGE("Invalid param: input key length is invalid!");
297 return HCF_INVALID_PARAMS;
298 }
299
300 SymKeyImpl *returnSymmKey = (SymKeyImpl *)HcfMalloc(sizeof(SymKeyImpl), 0);
301 if (returnSymmKey == NULL) {
302 LOGE("Failed to allocate returnKeyPair memory!");
303 return HCF_ERR_MALLOC;
304 }
305 HcfResult res = CopySymmKey(key, &returnSymmKey->keyMaterial);
306 if (res != HCF_SUCCESS) {
307 HcfFree(returnSymmKey);
308 return res;
309 }
310 returnSymmKey->algoName = GetAlgoName(impl);
311 returnSymmKey->key.clearMem = ClearMem;
312 returnSymmKey->key.key.getEncoded = GetEncoded;
313 returnSymmKey->key.key.getFormat = GetFormat;
314 returnSymmKey->key.key.getAlgorithm = GetAlgorithm;
315 returnSymmKey->key.key.base.destroy = DestroySymKeySpi;
316 returnSymmKey->key.key.base.getClass = GetSymKeyClass;
317 *symmKey = (HcfSymKey *)returnSymmKey;
318 return HCF_SUCCESS;
319 }
320
HcfSymKeyGeneratorSpiCreate(SymKeyAttr * attr,HcfSymKeyGeneratorSpi ** generator)321 HcfResult HcfSymKeyGeneratorSpiCreate(SymKeyAttr *attr, HcfSymKeyGeneratorSpi **generator)
322 {
323 if ((attr == NULL) || (generator == NULL)) {
324 LOGE("Invalid input parameter.");
325 return HCF_INVALID_PARAMS;
326 }
327 HcfSymKeyGeneratorSpiOpensslImpl *returnGenerator = (HcfSymKeyGeneratorSpiOpensslImpl *)HcfMalloc(
328 sizeof(HcfSymKeyGeneratorSpiOpensslImpl), 0);
329 if (returnGenerator == NULL) {
330 LOGE("Failed to allocate returnGenerator memory!");
331 return HCF_ERR_MALLOC;
332 }
333 (void)memcpy_s(&returnGenerator->attr, sizeof(SymKeyAttr), attr, sizeof(SymKeyAttr));
334 returnGenerator->base.engineGenerateSymmKey = GenerateSymmKey;
335 returnGenerator->base.engineConvertSymmKey = ConvertSymmKey;
336 returnGenerator->base.base.destroy = DestroySymKeyGeneratorSpi;
337 returnGenerator->base.base.getClass = GetSymKeyGeneratorClass;
338 *generator = (HcfSymKeyGeneratorSpi *)returnGenerator;
339 return HCF_SUCCESS;
340 }
341
342