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 "DES"
31 #define TRIPLE_DES_ALG_NAME "3DES"
32 #define HMAC_ALG_NAME "HMAC"
33
34 typedef struct {
35 HcfSymKeyGeneratorSpi base;
36 SymKeyAttr attr;
37 } HcfSymKeyGeneratorSpiOpensslImpl;
38
GetEncoded(HcfKey * self,HcfBlob * key)39 static HcfResult GetEncoded(HcfKey *self, HcfBlob *key)
40 {
41 if ((self == NULL) || (key == NULL)) {
42 LOGE("Invalid input parameter!");
43 return HCF_INVALID_PARAMS;
44 }
45 if (!HcfIsClassMatch((const HcfObjectBase *)self, OPENSSL_SYM_KEY_CLASS)) {
46 LOGE("Class is not match.");
47 return HCF_INVALID_PARAMS;
48 }
49 SymKeyImpl *impl = (SymKeyImpl *)self;
50 if ((impl->keyMaterial.data == NULL) || (impl->keyMaterial.len == 0)) {
51 LOGE("Invalid SymKeyImpl parameter!");
52 return HCF_INVALID_PARAMS;
53 }
54 key->data = (uint8_t *)HcfMalloc(impl->keyMaterial.len, 0);
55 if (key->data == NULL) {
56 LOGE("malloc keyMaterial failed!");
57 return HCF_ERR_MALLOC;
58 }
59 (void)memcpy_s(key->data, impl->keyMaterial.len, impl->keyMaterial.data, impl->keyMaterial.len);
60 key->len = impl->keyMaterial.len;
61 return HCF_SUCCESS;
62 }
63
ClearMem(HcfSymKey * self)64 static void ClearMem(HcfSymKey *self)
65 {
66 if (self == NULL) {
67 LOGE("symKey is NULL.");
68 return;
69 }
70 if (!HcfIsClassMatch((const HcfObjectBase *)self, OPENSSL_SYM_KEY_CLASS)) {
71 LOGE("Class is not match.");
72 return;
73 }
74 SymKeyImpl *impl = (SymKeyImpl *)self;
75 if ((impl->keyMaterial.data != NULL) && (impl->keyMaterial.len > 0)) {
76 (void)memset_s(impl->keyMaterial.data, impl->keyMaterial.len, 0, impl->keyMaterial.len);
77 }
78 }
79
GetFormat(HcfKey * self)80 static const char *GetFormat(HcfKey *self)
81 {
82 if (self == NULL) {
83 LOGE("Invalid input parameter!");
84 return NULL;
85 }
86 if (!HcfIsClassMatch((const HcfObjectBase *)self, OPENSSL_SYM_KEY_CLASS)) {
87 LOGE("Class is not match.");
88 return NULL;
89 }
90
91 return "PKCS#8";
92 }
93
GetSymKeyGeneratorClass(void)94 static const char *GetSymKeyGeneratorClass(void)
95 {
96 return OPENSSL_SYM_GENERATOR_CLASS;
97 }
98
GetSymKeyClass(void)99 static const char *GetSymKeyClass(void)
100 {
101 return OPENSSL_SYM_KEY_CLASS;
102 }
103
GetAlgorithm(HcfKey * self)104 static const char *GetAlgorithm(HcfKey *self)
105 {
106 if (self == NULL) {
107 LOGE("Invalid input parameter!");
108 return NULL;
109 }
110 if (!HcfIsClassMatch((const HcfObjectBase *)self, OPENSSL_SYM_KEY_CLASS)) {
111 LOGE("Class is not match.");
112 return NULL;
113 }
114 SymKeyImpl *impl = (SymKeyImpl *)self;
115 return (const char *)impl->algoName;
116 }
117
RandomSymmKey(int32_t keyLen,HcfBlob * symmKey)118 static HcfResult RandomSymmKey(int32_t keyLen, HcfBlob *symmKey)
119 {
120 uint8_t *keyMaterial = (uint8_t *)HcfMalloc(keyLen, 0);
121 if (keyMaterial == NULL) {
122 LOGE("keyMaterial malloc failed!");
123 return HCF_ERR_MALLOC;
124 }
125 int ret = OpensslRandPrivBytes(keyMaterial, keyLen);
126 if (ret != HCF_OPENSSL_SUCCESS) {
127 LOGD("[error] RAND_bytes failed!");
128 HcfPrintOpensslError();
129 HcfFree(keyMaterial);
130 keyMaterial = NULL;
131 return HCF_ERR_CRYPTO_OPERATION;
132 }
133 symmKey->data = keyMaterial;
134 symmKey->len = keyLen;
135 return HCF_SUCCESS;
136 }
137
HcfSymmKeySpiCreate(int32_t keyLen,SymKeyImpl * symKey)138 static HcfResult HcfSymmKeySpiCreate(int32_t keyLen, SymKeyImpl *symKey)
139 {
140 if ((keyLen == 0) || (symKey == NULL)) {
141 LOGE("Invalid input parameter!");
142 return HCF_INVALID_PARAMS;
143 }
144 HcfResult res = RandomSymmKey(keyLen, &symKey->keyMaterial);
145 if (res != HCF_SUCCESS) {
146 LOGD("[error] RandomSymmKey failed!");
147 return res;
148 }
149 return res;
150 }
151
HcfDesSymmKeySpiCreate(int32_t keyLen,SymKeyImpl * symKey)152 static HcfResult HcfDesSymmKeySpiCreate(int32_t keyLen, SymKeyImpl *symKey)
153 {
154 if ((keyLen == 0) || (symKey == NULL)) {
155 LOGE("Invalid input parameter!");
156 return HCF_INVALID_PARAMS;
157 }
158 uint8_t *keyMaterial = (uint8_t *)HcfMalloc(keyLen, 0);
159 if (keyMaterial == NULL) {
160 LOGE("keyMaterial malloc failed!");
161 return HCF_ERR_MALLOC;
162 }
163 EVP_CIPHER_CTX *ctx = OpensslEvpCipherCtxNew();
164 if (ctx == NULL) {
165 LOGE("Failed to create EVP_CIPHER_CTX!");
166 HcfFree(keyMaterial);
167 keyMaterial = NULL;
168 return HCF_ERR_CRYPTO_OPERATION;
169 }
170 if (OpensslEvpEncryptInit(ctx, OpensslEvpDesEcb(), NULL, NULL) != HCF_OPENSSL_SUCCESS) {
171 HcfPrintOpensslError();
172 HcfFree(keyMaterial);
173 keyMaterial = NULL;
174 EVP_CIPHER_CTX_free(ctx);
175 LOGD("[error] EVP_CipherInit failed!");
176 return HCF_ERR_CRYPTO_OPERATION;
177 }
178 if (OpensslEvpCipherCtxCtrl(ctx, EVP_CTRL_RAND_KEY, 0, keyMaterial) != 1) {
179 HcfPrintOpensslError();
180 LOGE("EVP_CIPHER_CTX_ctrl failed to validate DES key!");
181 EVP_CIPHER_CTX_free(ctx);
182 HcfFree(keyMaterial);
183 keyMaterial = NULL;
184 return HCF_INVALID_PARAMS;
185 }
186
187 EVP_CIPHER_CTX_free(ctx);
188 symKey->keyMaterial.data = keyMaterial;
189 symKey->keyMaterial.len = (size_t)keyLen;
190 return HCF_SUCCESS;
191 }
192
DestroySymKeyGeneratorSpi(HcfObjectBase * base)193 static void DestroySymKeyGeneratorSpi(HcfObjectBase *base)
194 {
195 if (base == NULL) {
196 LOGE("Invalid input parameter!");
197 return;
198 }
199 if (!HcfIsClassMatch(base, GetSymKeyGeneratorClass())) {
200 LOGE("Class is not match!");
201 return;
202 }
203 HcfFree(base);
204 }
205
DestroySymKeySpi(HcfObjectBase * base)206 static void DestroySymKeySpi(HcfObjectBase *base)
207 {
208 if (base == NULL) {
209 LOGE("Invalid input parameter!");
210 return;
211 }
212 if (!HcfIsClassMatch(base, OPENSSL_SYM_KEY_CLASS)) {
213 LOGE("Class is not match.");
214 return;
215 }
216 SymKeyImpl *impl = (SymKeyImpl *)base;
217 if (impl->algoName != NULL) {
218 HcfFree(impl->algoName);
219 impl->algoName = NULL;
220 }
221 if (impl->keyMaterial.data != NULL) {
222 (void)memset_s(impl->keyMaterial.data, impl->keyMaterial.len, 0, impl->keyMaterial.len);
223 HcfFree(impl->keyMaterial.data);
224 impl->keyMaterial.data = NULL;
225 impl->keyMaterial.len = 0;
226 }
227 HcfFree(impl);
228 }
229
GetAlgoNameType(HcfAlgValue type)230 static char *GetAlgoNameType(HcfAlgValue type)
231 {
232 switch (type) {
233 case HCF_ALG_AES:
234 return AES_ALG_NAME;
235 case HCF_ALG_SM4:
236 return SM4_ALG_NAME;
237 case HCF_ALG_DES:
238 return DES_ALG_NAME;
239 case HCF_ALG_3DES:
240 return TRIPLE_DES_ALG_NAME;
241 case HCF_ALG_HMAC:
242 return HMAC_ALG_NAME;
243 default:
244 LOGE("unsupport type!");
245 break;
246 }
247 return NULL;
248 }
249
GetAlgoName(HcfSymKeyGeneratorSpiOpensslImpl * impl,int keySize)250 static char *GetAlgoName(HcfSymKeyGeneratorSpiOpensslImpl *impl, int keySize)
251 {
252 char keySizeChar[MAX_KEY_STR_SIZE] = { 0 };
253 if (sprintf_s(keySizeChar, MAX_KEY_STR_SIZE, "%d", keySize) < 0) {
254 LOGE("Invalid input parameter!");
255 return NULL;
256 }
257 char *nameType = GetAlgoNameType(impl->attr.algo);
258 if (nameType == NULL) {
259 LOGE("get algo name type failed!");
260 return NULL;
261 }
262 int32_t nameSize = strlen(nameType);
263 char *algoName = (char *)HcfMalloc(MAX_KEY_STR_SIZE, 0);
264 if (algoName == NULL) {
265 LOGE("algoName malloc failed!");
266 return NULL;
267 }
268 if (strcpy_s(algoName, MAX_KEY_STR_SIZE, nameType) != EOK) {
269 LOGE("algoName strcpy_s failed!");
270 goto clearup;
271 }
272 if (strcpy_s(algoName + nameSize, MAX_KEY_STR_SIZE - nameSize, keySizeChar) != EOK) {
273 LOGE("algoName size strcpy_s failed!");
274 goto clearup;
275 }
276 return algoName;
277 clearup:
278 HcfFree(algoName);
279 algoName = NULL;
280 return NULL;
281 }
282
CopySymmKey(const HcfBlob * srcKey,HcfBlob * dstKey)283 static HcfResult CopySymmKey(const HcfBlob *srcKey, HcfBlob *dstKey)
284 {
285 if ((srcKey->data == NULL) || (srcKey->len == 0)) {
286 LOGE("Invalid input parameter!");
287 return HCF_INVALID_PARAMS;
288 }
289 uint8_t *keyMaterial = (uint8_t *)HcfMalloc(srcKey->len, 0);
290 if (keyMaterial == NULL) {
291 LOGE("keyMaterial malloc failed!");
292 return HCF_ERR_MALLOC;
293 }
294 (void)memcpy_s(keyMaterial, srcKey->len, srcKey->data, srcKey->len);
295 dstKey->data = keyMaterial;
296 dstKey->len = srcKey->len;
297 return HCF_SUCCESS;
298 }
299
GenerateSymmKey(HcfSymKeyGeneratorSpi * self,HcfSymKey ** symmKey)300 static HcfResult GenerateSymmKey(HcfSymKeyGeneratorSpi *self, HcfSymKey **symmKey)
301 {
302 if ((self == NULL) || (symmKey == NULL)) {
303 LOGE("Invalid input parameter!");
304 return HCF_INVALID_PARAMS;
305 }
306 if (!HcfIsClassMatch((const HcfObjectBase *)self, GetSymKeyGeneratorClass())) {
307 LOGE("Class is not match!");
308 return HCF_INVALID_PARAMS;
309 }
310 SymKeyImpl *returnSymmKey = (SymKeyImpl *)HcfMalloc(sizeof(SymKeyImpl), 0);
311 if (returnSymmKey == NULL) {
312 LOGE("Failed to allocate returnKeyPair memory!");
313 return HCF_ERR_MALLOC;
314 }
315 HcfSymKeyGeneratorSpiOpensslImpl *impl = (HcfSymKeyGeneratorSpiOpensslImpl *)self;
316 HcfResult res = HCF_SUCCESS;
317 if (impl->attr.algo == HCF_ALG_DES) {
318 res = HcfDesSymmKeySpiCreate(impl->attr.keySize / KEY_BIT, returnSymmKey);
319 if (res != HCF_SUCCESS) {
320 HcfFree(returnSymmKey);
321 returnSymmKey = NULL;
322 return res;
323 }
324 } else {
325 res = HcfSymmKeySpiCreate(impl->attr.keySize / KEY_BIT, returnSymmKey);
326 if (res != HCF_SUCCESS) {
327 HcfFree(returnSymmKey);
328 returnSymmKey = NULL;
329 return res;
330 }
331 }
332
333 returnSymmKey->algoName = GetAlgoName(impl, impl->attr.keySize);
334 returnSymmKey->key.clearMem = ClearMem;
335 returnSymmKey->key.key.getEncoded = GetEncoded;
336 returnSymmKey->key.key.getFormat = GetFormat;
337 returnSymmKey->key.key.getAlgorithm = GetAlgorithm;
338 returnSymmKey->key.key.base.destroy = DestroySymKeySpi;
339 returnSymmKey->key.key.base.getClass = GetSymKeyClass;
340 *symmKey = (HcfSymKey *)returnSymmKey;
341 return res;
342 }
343
IsBlobKeyLenValid(SymKeyAttr attr,const HcfBlob * key)344 static bool IsBlobKeyLenValid(SymKeyAttr attr, const HcfBlob *key)
345 {
346 if ((key->len == 0) || (key->len > MAX_KEY_LEN)) {
347 return false;
348 }
349
350 if ((attr.keySize / KEY_BIT) == (int32_t)key->len) {
351 return true;
352 }
353
354 if ((attr.algo == HCF_ALG_HMAC) && (attr.keySize == 0)) {
355 return true;
356 }
357
358 return false;
359 }
360
ConvertSymmKey(HcfSymKeyGeneratorSpi * self,const HcfBlob * key,HcfSymKey ** symmKey)361 static HcfResult ConvertSymmKey(HcfSymKeyGeneratorSpi *self, const HcfBlob *key, HcfSymKey **symmKey)
362 {
363 if ((self == NULL) || (symmKey == NULL) || !HcfIsBlobValid(key)) {
364 LOGE("Invalid input parameter.");
365 return HCF_INVALID_PARAMS;
366 }
367 if (!HcfIsClassMatch((const HcfObjectBase *)self, GetSymKeyGeneratorClass())) {
368 LOGE("Class is not match.");
369 return HCF_INVALID_PARAMS;
370 }
371 HcfSymKeyGeneratorSpiOpensslImpl *impl = (HcfSymKeyGeneratorSpiOpensslImpl *)self;
372
373 if (!IsBlobKeyLenValid(impl->attr, key)) {
374 LOGE("Invalid param: input key length is invalid!");
375 return HCF_INVALID_PARAMS;
376 }
377
378 SymKeyImpl *returnSymmKey = (SymKeyImpl *)HcfMalloc(sizeof(SymKeyImpl), 0);
379 if (returnSymmKey == NULL) {
380 LOGE("Failed to allocate returnKeyPair memory!");
381 return HCF_ERR_MALLOC;
382 }
383 HcfResult res = CopySymmKey(key, &returnSymmKey->keyMaterial);
384 if (res != HCF_SUCCESS) {
385 HcfFree(returnSymmKey);
386 returnSymmKey = NULL;
387 return res;
388 }
389 int keySize = impl->attr.keySize;
390 if (impl->attr.algo == HCF_ALG_HMAC && keySize == 0) {
391 keySize = (int)returnSymmKey->keyMaterial.len * KEY_BIT;
392 }
393 returnSymmKey->algoName = GetAlgoName(impl, keySize);
394 returnSymmKey->key.clearMem = ClearMem;
395 returnSymmKey->key.key.getEncoded = GetEncoded;
396 returnSymmKey->key.key.getFormat = GetFormat;
397 returnSymmKey->key.key.getAlgorithm = GetAlgorithm;
398 returnSymmKey->key.key.base.destroy = DestroySymKeySpi;
399 returnSymmKey->key.key.base.getClass = GetSymKeyClass;
400 *symmKey = (HcfSymKey *)returnSymmKey;
401 return HCF_SUCCESS;
402 }
403
HcfSymKeyGeneratorSpiCreate(SymKeyAttr * attr,HcfSymKeyGeneratorSpi ** generator)404 HcfResult HcfSymKeyGeneratorSpiCreate(SymKeyAttr *attr, HcfSymKeyGeneratorSpi **generator)
405 {
406 if ((attr == NULL) || (generator == NULL)) {
407 LOGE("Invalid input parameter.");
408 return HCF_INVALID_PARAMS;
409 }
410 HcfSymKeyGeneratorSpiOpensslImpl *returnGenerator = (HcfSymKeyGeneratorSpiOpensslImpl *)HcfMalloc(
411 sizeof(HcfSymKeyGeneratorSpiOpensslImpl), 0);
412 if (returnGenerator == NULL) {
413 LOGE("Failed to allocate returnGenerator memory!");
414 return HCF_ERR_MALLOC;
415 }
416 (void)memcpy_s(&returnGenerator->attr, sizeof(SymKeyAttr), attr, sizeof(SymKeyAttr));
417 returnGenerator->base.engineGenerateSymmKey = GenerateSymmKey;
418 returnGenerator->base.engineConvertSymmKey = ConvertSymmKey;
419 returnGenerator->base.base.destroy = DestroySymKeyGeneratorSpi;
420 returnGenerator->base.base.getClass = GetSymKeyGeneratorClass;
421 *generator = (HcfSymKeyGeneratorSpi *)returnGenerator;
422 return HCF_SUCCESS;
423 }
424