• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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