1 /*
2 * Copyright (c) 2024 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 #ifdef HKS_CONFIG_FILE
17 #include HKS_CONFIG_FILE
18 #else
19 #include "hks_config.h"
20 #endif
21
22 #ifdef HKS_SUPPORT_DES_C
23
24 #include <openssl/des.h>
25 #include <openssl/evp.h>
26
27 #include "hks_cfi.h"
28 #include "hks_log.h"
29 #include "hks_mem.h"
30 #include "hks_openssl_des.h"
31 #include "hks_openssl_engine.h"
32 #include "hks_template.h"
33 #include "securec.h"
34
CheckDesKeySize(const struct HksBlob * key)35 static int32_t CheckDesKeySize(const struct HksBlob *key)
36 {
37 if (key->size != HKS_KEY_BYTES(HKS_DES_KEY_SIZE_64)) {
38 return HKS_ERROR_INVALID_KEY_SIZE;
39 }
40 return HKS_SUCCESS;
41 }
42
43 #ifdef HKS_SUPPORT_DES_GENERATE_KEY
HksOpensslDesGenerateKey(const struct HksKeySpec * spec,struct HksBlob * key)44 int32_t HksOpensslDesGenerateKey(const struct HksKeySpec *spec, struct HksBlob *key)
45 {
46 if (spec->keyLen != HKS_DES_KEY_SIZE_64) {
47 return HKS_ERROR_INVALID_KEY_SIZE;
48 }
49
50 const uint32_t keyByteLen = spec->keyLen / HKS_BITS_PER_BYTE;
51 uint8_t *outKey = (uint8_t *)HksMalloc(keyByteLen);
52 HKS_IF_NULL_RETURN(outKey, HKS_ERROR_MALLOC_FAIL)
53
54 DES_cblock desKey;
55 if (DES_random_key(&desKey) != HKS_OPENSSL_SUCCESS) {
56 HKS_LOG_E("DES_random_key failed");
57 HKS_FREE(outKey);
58 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
59 }
60
61 (void)memcpy_s(outKey, keyByteLen, desKey, keyByteLen);
62 key->data = outKey;
63 key->size = keyByteLen;
64
65 return HKS_SUCCESS;
66 }
67 #endif /* HKS_SUPPORT_DES_GENERATE_KEY */
68
ENABLE_CFI(const EVP_CIPHER * OpensslGetDesCipherType (uint32_t keySize,uint32_t mode))69 ENABLE_CFI(const EVP_CIPHER *OpensslGetDesCipherType(uint32_t keySize, uint32_t mode))
70 {
71 if (keySize == HKS_KEY_BYTES(HKS_DES_KEY_SIZE_64)) {
72 switch (mode) {
73 case HKS_MODE_CBC:
74 return EVP_des_cbc();
75 case HKS_MODE_ECB:
76 return EVP_des_ecb();
77 default:
78 return NULL;
79 }
80 } else if (keySize == HKS_KEY_BYTES(HKS_3DES_KEY_SIZE_128)) {
81 switch (mode) {
82 case HKS_MODE_CBC:
83 return EVP_des_ede_cbc();
84 case HKS_MODE_ECB:
85 return EVP_des_ede_ecb();
86 default:
87 return NULL;
88 }
89 } else if (keySize == HKS_KEY_BYTES(HKS_3DES_KEY_SIZE_192)) {
90 switch (mode) {
91 case HKS_MODE_CBC:
92 return EVP_des_ede3_cbc();
93 case HKS_MODE_ECB:
94 return EVP_des_ede3_ecb();
95 default:
96 return NULL;
97 }
98 }
99 return NULL;
100 }
101
OpensslDesCipherInitParams(const struct HksBlob * key,EVP_CIPHER_CTX * ctx,bool isEncrypt,struct HksCipherParam * cipherParam)102 static int32_t OpensslDesCipherInitParams(const struct HksBlob *key, EVP_CIPHER_CTX *ctx, bool isEncrypt,
103 struct HksCipherParam *cipherParam)
104 {
105 int32_t ret;
106 if (isEncrypt) {
107 ret = EVP_EncryptInit_ex(ctx, NULL, NULL, key->data, (cipherParam == NULL) ? NULL : cipherParam->iv.data);
108 } else {
109 ret = EVP_DecryptInit_ex(ctx, NULL, NULL, key->data, (cipherParam == NULL) ? NULL : cipherParam->iv.data);
110 }
111 if (ret != HKS_OPENSSL_SUCCESS) {
112 HksLogOpensslError();
113 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
114 }
115
116 ret = EVP_CIPHER_CTX_set_padding(ctx, OPENSSL_CTX_PADDING_NONE);
117 if (ret != HKS_OPENSSL_SUCCESS) {
118 HksLogOpensslError();
119 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
120 }
121 return HKS_SUCCESS;
122 }
123
OpensslDesCipherInit(const struct HksBlob * key,const struct HksUsageSpec * usageSpec,bool isEncrypt,struct HksOpensslDesCtx * outCtx)124 static int32_t OpensslDesCipherInit(const struct HksBlob *key, const struct HksUsageSpec *usageSpec, bool isEncrypt,
125 struct HksOpensslDesCtx *outCtx)
126 {
127 int32_t ret;
128 struct HksCipherParam *cipherParam = (struct HksCipherParam *)usageSpec->algParam;
129
130 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
131 if (ctx == NULL) {
132 HksLogOpensslError();
133 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
134 }
135
136 const EVP_CIPHER *cipher = OpensslGetDesCipherType(key->size, usageSpec->mode);
137 if (cipher == NULL) {
138 EVP_CIPHER_CTX_free(ctx);
139 return HKS_ERROR_INVALID_MODE;
140 }
141
142 if (isEncrypt) {
143 ret = EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL);
144 } else {
145 ret = EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL);
146 }
147 if (ret != HKS_OPENSSL_SUCCESS) {
148 HksLogOpensslError();
149 EVP_CIPHER_CTX_free(ctx);
150 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
151 }
152
153 ret = OpensslDesCipherInitParams(key, ctx, isEncrypt, cipherParam);
154 if (ret != HKS_SUCCESS) {
155 EVP_CIPHER_CTX_free(ctx);
156 HKS_LOG_E("OpensslBlockCipherCryptInitParams fail, ret = %" LOG_PUBLIC "d", ret);
157 return ret;
158 }
159 outCtx->append = (void *)ctx;
160
161 return HKS_SUCCESS;
162 }
163
DesNoPaddingCryptInit(void ** cryptoCtx,const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const bool encrypt)164 int32_t DesNoPaddingCryptInit(void **cryptoCtx, const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
165 const bool encrypt)
166 {
167 struct HksCipherParam *iv = (struct HksCipherParam *)(usageSpec->algParam);
168 if (usageSpec ->mode == HKS_MODE_CBC && iv->iv.size != HKS_DES_IV_SIZE) {
169 HKS_LOG_E("initialize iv fail");
170 return HKS_ERROR_INVALID_IV;
171 }
172
173 struct HksOpensslDesCtx *outCtx = (struct HksOpensslDesCtx *)HksMalloc(sizeof(struct HksOpensslDesCtx));
174 if (outCtx == NULL) {
175 HKS_LOG_E("initialize outCtx fail");
176 return HKS_ERROR_MALLOC_FAIL;
177 }
178
179 int32_t ret = OpensslDesCipherInit(key, usageSpec, encrypt, outCtx);
180 if (ret != HKS_SUCCESS) {
181 HKS_LOG_E("openssl initialize des cipher fail");
182 HKS_FREE(outCtx);
183 return ret;
184 }
185
186 outCtx->mode = usageSpec->mode;
187 outCtx->padding = usageSpec->padding;
188
189 *cryptoCtx = (void *)outCtx;
190 return HKS_SUCCESS;
191 }
192
DesNoPaddingCryptUpdate(void * cryptoCtx,const struct HksBlob * message,const bool encrypt,struct HksBlob * cipherText)193 int32_t DesNoPaddingCryptUpdate(void *cryptoCtx, const struct HksBlob *message, const bool encrypt,
194 struct HksBlob *cipherText)
195 {
196 struct HksOpensslDesCtx *desCtx = (struct HksOpensslDesCtx *)cryptoCtx;
197 EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)desCtx->append;
198 HKS_IF_NULL_RETURN(ctx, HKS_ERROR_NULL_POINTER)
199
200 if (message->size % HKS_DES_BLOCK_SIZE != 0) {
201 HKS_LOG_E("DesCbcNoPaddingCryptUpdate data size invalid!");
202 return HKS_ERROR_INVALID_ARGUMENT;
203 }
204
205 int32_t outLen = 0;
206 int evpRet = encrypt
207 ? EVP_EncryptUpdate(ctx, cipherText->data, &outLen, message->data, message->size)
208 : EVP_DecryptUpdate(ctx, cipherText->data, &outLen, message->data, message->size);
209 if (evpRet != HKS_OPENSSL_SUCCESS) {
210 HksLogOpensslError();
211 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
212 }
213 cipherText->size = (uint32_t)outLen;
214
215 return HKS_SUCCESS;
216 }
217
DesNoPaddingCryptFinal(void ** cryptoCtx,const struct HksBlob * message,const bool encrypt,struct HksBlob * cipherText)218 int32_t DesNoPaddingCryptFinal(void **cryptoCtx, const struct HksBlob *message, const bool encrypt,
219 struct HksBlob *cipherText)
220 {
221 struct HksOpensslDesCtx *desCtx = (struct HksOpensslDesCtx *)*cryptoCtx;
222 EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)desCtx->append;
223 HKS_IF_NULL_RETURN(ctx, HKS_ERROR_NULL_POINTER)
224
225 if (message->size % HKS_DES_BLOCK_SIZE != 0) {
226 HKS_LOG_E("DesCbcNoPaddingCryptFinal data size invalid!");
227 return HKS_ERROR_INVALID_ARGUMENT;
228 }
229
230 int32_t ret = HKS_SUCCESS;
231 do {
232 int32_t outLen = 0;
233 int evpRet;
234 if (message->size != 0) {
235 evpRet = encrypt
236 ? EVP_EncryptUpdate(ctx, cipherText->data, &outLen, message->data, message->size)
237 : EVP_DecryptUpdate(ctx, cipherText->data, &outLen, message->data, message->size);
238 if (evpRet != HKS_OPENSSL_SUCCESS) {
239 HksLogOpensslError();
240 ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
241 break;
242 }
243 }
244 cipherText->size = (uint32_t)outLen;
245 evpRet = encrypt
246 ? EVP_EncryptFinal_ex(ctx, (cipherText->data + outLen), &outLen)
247 : EVP_DecryptFinal_ex(ctx, (cipherText->data + outLen), &outLen);
248 if (evpRet != HKS_OPENSSL_SUCCESS) {
249 HksLogOpensslError();
250 ret = HKS_ERROR_CRYPTO_ENGINE_ERROR;
251 break;
252 }
253 cipherText->size += (uint32_t)outLen;
254 } while (0);
255
256 EVP_CIPHER_CTX_free(ctx);
257 desCtx->append = NULL;
258
259 HksOpensslDesHalFreeCtx(cryptoCtx);
260 return ret;
261 }
262
DesCryptInit(void ** cryptoCtx,const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const bool encrypt)263 static int32_t DesCryptInit(void **cryptoCtx, const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
264 const bool encrypt)
265 {
266 switch (usageSpec->padding) {
267 #if defined(HKS_SUPPORT_DES_CBC_NOPADDING) || defined(HKS_SUPPORT_DES_ECB_NOPADDING)
268 case HKS_PADDING_NONE:
269 return DesNoPaddingCryptInit(cryptoCtx, key, usageSpec, encrypt);
270 #endif
271 default:
272 HKS_LOG_E("Unsupport padding! mode = 0x%" LOG_PUBLIC "X", usageSpec->padding);
273 return HKS_ERROR_INVALID_PADDING;
274 }
275 }
276
DesCryptUpdate(void * cryptoCtx,const uint8_t padding,const struct HksBlob * message,struct HksBlob * cipherText,const bool encrypt)277 static int32_t DesCryptUpdate(void *cryptoCtx, const uint8_t padding, const struct HksBlob *message,
278 struct HksBlob *cipherText, const bool encrypt)
279 {
280 switch (padding) {
281 #if defined(HKS_SUPPORT_DES_CBC_NOPADDING) || defined(HKS_SUPPORT_DES_ECB_NOPADDING)
282 case HKS_PADDING_NONE:
283 return DesNoPaddingCryptUpdate(cryptoCtx, message, encrypt, cipherText);
284 #endif
285 default:
286 HKS_LOG_E("Unsupport padding! mode = 0x%" LOG_PUBLIC "X", padding);
287 return HKS_ERROR_INVALID_PADDING;
288 }
289 }
290
DesCryptFinal(void ** cryptoCtx,const uint8_t padding,const struct HksBlob * message,struct HksBlob * cipherText,const bool encrypt)291 static int32_t DesCryptFinal(void **cryptoCtx, const uint8_t padding, const struct HksBlob *message,
292 struct HksBlob *cipherText, const bool encrypt)
293 {
294 switch (padding) {
295 #if defined(HKS_SUPPORT_DES_CBC_NOPADDING) || defined(HKS_SUPPORT_DES_ECB_NOPADDING)
296 case HKS_PADDING_NONE:
297 return DesNoPaddingCryptFinal(cryptoCtx, message, encrypt, cipherText);
298 #endif
299 default:
300 HKS_LOG_E("Unsupport padding! mode = 0x%" LOG_PUBLIC "X", padding);
301 return HKS_ERROR_INVALID_PADDING;
302 }
303 }
304
HksOpensslDesCryptoInit(void ** cryptoCtx,const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const bool encrypt)305 int32_t HksOpensslDesCryptoInit(void **cryptoCtx, const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
306 const bool encrypt)
307 {
308 if (CheckDesKeySize(key) != HKS_SUCCESS || cryptoCtx == NULL || usageSpec == NULL) {
309 HKS_LOG_E("Invalid des keySize = 0x%" LOG_PUBLIC "X", key->size);
310 return HKS_ERROR_INVALID_ARGUMENT;
311 }
312
313 switch (usageSpec->mode) {
314 #if defined(HKS_SUPPORT_DES_CBC_NOPADDING)
315 case HKS_MODE_CBC:
316 return DesCryptInit(cryptoCtx, key, usageSpec, encrypt);
317 #endif
318 #if defined(HKS_SUPPORT_DES_ECB_NOPADDING)
319 case HKS_MODE_ECB:
320 return DesCryptInit(cryptoCtx, key, usageSpec, encrypt);
321 #endif
322 default:
323 HKS_LOG_E("Unsupport key alg! mode = 0x%" LOG_PUBLIC "X", usageSpec->mode);
324 return HKS_ERROR_INVALID_MODE;
325 }
326 }
327
HksOpensslDesCryptoUpdate(void * cryptoCtx,const struct HksBlob * message,struct HksBlob * cipherText,const bool encrypt)328 int32_t HksOpensslDesCryptoUpdate(void *cryptoCtx, const struct HksBlob *message, struct HksBlob *cipherText,
329 const bool encrypt)
330 {
331 HKS_IF_NULL_LOGE_RETURN(cryptoCtx, HKS_ERROR_INVALID_ARGUMENT, "Openssl DES encrypt update param is null")
332 struct HksOpensslDesCtx *desEncryptCtx = (struct HksOpensslDesCtx *)cryptoCtx;
333
334 switch (desEncryptCtx->mode) {
335 #if defined(HKS_SUPPORT_DES_CBC_NOPADDING)
336 case HKS_MODE_CBC:
337 return DesCryptUpdate(cryptoCtx, desEncryptCtx->padding, message, cipherText, encrypt);
338 #endif
339 #if defined(HKS_SUPPORT_DES_ECB_NOPADDING)
340 case HKS_MODE_ECB:
341 return DesCryptUpdate(cryptoCtx, desEncryptCtx->padding, message, cipherText, encrypt);
342 #endif
343 default:
344 HKS_LOG_E("Unsupport key alg! mode = 0x%" LOG_PUBLIC "X", desEncryptCtx->mode);
345 return HKS_ERROR_INVALID_MODE;
346 }
347 }
348
HksOpensslDesCryptoFinal(void ** cryptoCtx,const struct HksBlob * message,struct HksBlob * cipherText,struct HksBlob * tagAead,const bool encrypt)349 int32_t HksOpensslDesCryptoFinal(void **cryptoCtx, const struct HksBlob *message, struct HksBlob *cipherText,
350 struct HksBlob *tagAead, const bool encrypt)
351 {
352 (void)tagAead;
353 struct HksOpensslDesCtx *desEncryptCtx = (struct HksOpensslDesCtx *)*cryptoCtx;
354 switch (desEncryptCtx->mode) {
355 #if defined(HKS_SUPPORT_DES_CBC_NOPADDING)
356 case HKS_MODE_CBC:
357 return DesCryptFinal(cryptoCtx, desEncryptCtx->padding, message, cipherText, encrypt);
358 #endif
359 #if defined(HKS_SUPPORT_DES_ECB_NOPADDING)
360 case HKS_MODE_ECB:
361 return DesCryptFinal(cryptoCtx, desEncryptCtx->padding, message, cipherText, encrypt);
362 #endif
363 default:
364 HKS_LOG_E("Unsupport key alg! mode = 0x%" LOG_PUBLIC "X", desEncryptCtx->mode);
365 return HKS_ERROR_INVALID_MODE;
366 }
367 }
368
HksOpensslDesHalFreeCtx(void ** cryptCtx)369 void HksOpensslDesHalFreeCtx(void **cryptCtx)
370 {
371 if (cryptCtx == NULL || *cryptCtx == NULL) {
372 HKS_LOG_E("FreeCtx param context null");
373 return;
374 }
375 HKS_FREE(*cryptCtx);
376 }
377 #endif /* HKS_SUPPORT_DES_C */
378