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_3DES_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_3des.h"
31 #include "hks_openssl_des.h"
32 #include "hks_openssl_engine.h"
33 #include "hks_template.h"
34 #include "securec.h"
35
Check3DesKeySize(const struct HksBlob * key)36 static int32_t Check3DesKeySize(const struct HksBlob *key)
37 {
38 HKS_IF_TRUE_RETURN(key->size != HKS_KEY_BYTES(HKS_3DES_KEY_SIZE_128) &&
39 key->size != HKS_KEY_BYTES(HKS_3DES_KEY_SIZE_192), HKS_ERROR_INVALID_KEY_SIZE)
40 return HKS_SUCCESS;
41 }
42
43 #ifdef HKS_SUPPORT_3DES_GENERATE_KEY
HksOpenssl3DesGenerateKey(const struct HksKeySpec * spec,struct HksBlob * key)44 int32_t HksOpenssl3DesGenerateKey(const struct HksKeySpec *spec, struct HksBlob *key)
45 {
46 HKS_IF_TRUE_RETURN(spec->keyLen != HKS_3DES_KEY_SIZE_128 && spec->keyLen != HKS_3DES_KEY_SIZE_192,
47 HKS_ERROR_INVALID_KEY_SIZE)
48
49 const uint32_t keyByteLen = spec->keyLen / HKS_BITS_PER_BYTE;
50 uint8_t *outKey = (uint8_t *)HksMalloc(keyByteLen);
51 HKS_IF_NULL_RETURN(outKey, HKS_ERROR_MALLOC_FAIL)
52
53 DES_cblock desKey;
54 for (uint32_t i = 0; i < spec->keyLen / HKS_DES_KEY_SIZE_64; i++) {
55 if (DES_random_key(&desKey) != HKS_OPENSSL_SUCCESS) {
56 HKS_LOG_E("DES_random_key 3des key failed");
57 HKS_FREE(outKey);
58 return HKS_ERROR_CRYPTO_ENGINE_ERROR;
59 }
60 if (memcpy_s(outKey + i * HKS_DES_BLOCK_SIZE, keyByteLen - i * HKS_DES_BLOCK_SIZE, desKey,
61 HKS_DES_BLOCK_SIZE) != EOK) {
62 HKS_LOG_E("memcpy 3des key failed!");
63 HKS_FREE(outKey);
64 return HKS_ERROR_BUFFER_TOO_SMALL;
65 }
66 }
67
68 key->data = outKey;
69 key->size = keyByteLen;
70
71 return HKS_SUCCESS;
72 }
73 #endif /* HKS_SUPPORT_3DES_GENERATE_KEY */
74
Des3CryptInit(void ** cryptoCtx,const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const bool encrypt)75 static int32_t Des3CryptInit(void **cryptoCtx, const struct HksBlob *key,
76 const struct HksUsageSpec *usageSpec, const bool encrypt)
77 {
78 switch (usageSpec->padding) {
79 #if defined(HKS_SUPPORT_3DES_CBC_NOPADDING) || defined(HKS_SUPPORT_3DES_ECB_NOPADDING)
80 case HKS_PADDING_NONE:
81 return DesNoPaddingCryptInit(cryptoCtx, key, usageSpec, encrypt);
82 #endif
83 default:
84 HKS_LOG_E("Unsupport padding! mode = 0x%" LOG_PUBLIC "X", usageSpec->padding);
85 return HKS_ERROR_INVALID_PADDING;
86 }
87 }
88
Des3CryptUpdate(void * cryptoCtx,const uint8_t padding,const struct HksBlob * message,struct HksBlob * cipherText,const bool encrypt)89 static int32_t Des3CryptUpdate(void *cryptoCtx, const uint8_t padding, const struct HksBlob *message,
90 struct HksBlob *cipherText, const bool encrypt)
91 {
92 switch (padding) {
93 #if defined(HKS_SUPPORT_3DES_CBC_NOPADDING) || defined(HKS_SUPPORT_3DES_ECB_NOPADDING)
94 case HKS_PADDING_NONE:
95 return DesNoPaddingCryptUpdate(cryptoCtx, message, encrypt, cipherText);
96 #endif
97 default:
98 HKS_LOG_E("Unsupport padding! mode = 0x%" LOG_PUBLIC "X", padding);
99 return HKS_ERROR_INVALID_PADDING;
100 }
101 }
102
Des3CryptFinal(void ** cryptoCtx,const uint8_t padding,const struct HksBlob * message,struct HksBlob * cipherText,const bool encrypt)103 static int32_t Des3CryptFinal(void **cryptoCtx, const uint8_t padding, const struct HksBlob *message,
104 struct HksBlob *cipherText, const bool encrypt)
105 {
106 switch (padding) {
107 #if defined(HKS_SUPPORT_3DES_CBC_NOPADDING) || defined(HKS_SUPPORT_3DES_ECB_NOPADDING)
108 case HKS_PADDING_NONE:
109 return DesNoPaddingCryptFinal(cryptoCtx, message, encrypt, cipherText);
110 #endif
111 default:
112 HKS_LOG_E("Unsupport padding! mode = 0x%" LOG_PUBLIC "X", padding);
113 return HKS_ERROR_INVALID_PADDING;
114 }
115 }
116
HksOpenssl3DesCryptoInit(void ** cryptoCtx,const struct HksBlob * key,const struct HksUsageSpec * usageSpec,const bool encrypt)117 int32_t HksOpenssl3DesCryptoInit(void **cryptoCtx, const struct HksBlob *key, const struct HksUsageSpec *usageSpec,
118 const bool encrypt)
119 {
120 HKS_IF_TRUE_LOGE_RETURN(Check3DesKeySize(key) != HKS_SUCCESS || cryptoCtx == NULL || usageSpec == NULL,
121 HKS_ERROR_INVALID_ARGUMENT, "Invalid 3des keySize = 0x%" LOG_PUBLIC "X", key->size)
122
123 switch (usageSpec->mode) {
124 #if defined(HKS_SUPPORT_3DES_CBC_NOPADDING)
125 case HKS_MODE_CBC:
126 return Des3CryptInit(cryptoCtx, key, usageSpec, encrypt);
127 #endif
128 #if defined(HKS_SUPPORT_3DES_ECB_NOPADDING)
129 case HKS_MODE_ECB:
130 return Des3CryptInit(cryptoCtx, key, usageSpec, encrypt);
131 #endif
132 default:
133 HKS_LOG_E("Unsupport key alg! mode = 0x%" LOG_PUBLIC "X", usageSpec->mode);
134 return HKS_ERROR_INVALID_MODE;
135 }
136 }
137
HksOpenssl3DesCryptoUpdate(void * cryptoCtx,const struct HksBlob * message,struct HksBlob * cipherText,const bool encrypt)138 int32_t HksOpenssl3DesCryptoUpdate(void *cryptoCtx, const struct HksBlob *message, struct HksBlob *cipherText,
139 const bool encrypt)
140 {
141 HKS_IF_NULL_LOGE_RETURN(cryptoCtx, HKS_ERROR_INVALID_ARGUMENT, "Openssl 3DES encrypt update param is null")
142 struct HksOpensslDesCtx *desEncryptCtx = (struct HksOpensslDesCtx *)cryptoCtx;
143
144 switch (desEncryptCtx->mode) {
145 #if defined(HKS_SUPPORT_3DES_CBC_NOPADDING)
146 case HKS_MODE_CBC:
147 return Des3CryptUpdate(cryptoCtx, desEncryptCtx->padding, message, cipherText, encrypt);
148 #endif
149 #if defined(HKS_SUPPORT_3DES_ECB_NOPADDING)
150 case HKS_MODE_ECB:
151 return Des3CryptUpdate(cryptoCtx, desEncryptCtx->padding, message, cipherText, encrypt);
152 #endif
153 default:
154 HKS_LOG_E("Unsupport key alg! mode = 0x%" LOG_PUBLIC "X", desEncryptCtx->mode);
155 return HKS_ERROR_INVALID_MODE;
156 }
157 }
158
HksOpenssl3DesCryptoFinal(void ** cryptoCtx,const struct HksBlob * message,struct HksBlob * cipherText,struct HksBlob * tagAead,const bool encrypt)159 int32_t HksOpenssl3DesCryptoFinal(void **cryptoCtx, const struct HksBlob *message, struct HksBlob *cipherText,
160 struct HksBlob *tagAead, const bool encrypt)
161 {
162 (void)tagAead;
163 struct HksOpensslDesCtx *desEncryptCtx = (struct HksOpensslDesCtx *)*cryptoCtx;
164 switch (desEncryptCtx->mode) {
165 #if defined(HKS_SUPPORT_3DES_CBC_NOPADDING)
166 case HKS_MODE_CBC:
167 return Des3CryptFinal(cryptoCtx, desEncryptCtx->padding, message, cipherText, encrypt);
168 #endif
169 #if defined(HKS_SUPPORT_3DES_ECB_NOPADDING)
170 case HKS_MODE_ECB:
171 return Des3CryptFinal(cryptoCtx, desEncryptCtx->padding, message, cipherText, encrypt);
172 #endif
173 default:
174 HKS_LOG_E("Unsupport key alg! mode = 0x%" LOG_PUBLIC "X", desEncryptCtx->mode);
175 return HKS_ERROR_INVALID_MODE;
176 }
177 }
178
HksOpenssl3DesHalFreeCtx(void ** cryptCtx)179 void HksOpenssl3DesHalFreeCtx(void **cryptCtx)
180 {
181 HKS_IF_TRUE_LOGE_RETURN_VOID(cryptCtx == NULL || *cryptCtx == NULL, "FreeCtx param context null")
182 HKS_FREE(*cryptCtx);
183 }
184 #endif /* HKS_SUPPORT_3DES_C */
185