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