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