• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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