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