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