• 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 "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