1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12
13 #include "soft_common_api.h"
14 #include <openssl/evp.h>
15 #include <openssl/md5.h>
16 #include <openssl/sha.h>
17 #include <openssl/hmac.h>
18 #include <openssl/cmac.h>
19 #ifdef OPENSSL_ENABLE
20 #include <crypto/siphash.h>
21 #include <siphash/siphash_local.h>
22 #elif defined OPENSSL3_ENABLE
23 #include <crypto/siphash.h>
24 #endif
25 #include <openssl/rand.h>
26 #include <securec.h>
27 #include <tee_log.h>
28 #include "soft_gmssl.h"
29 #include "soft_err.h"
30 #include "crypto/rand.h"
31 #include "openssl/crypto.h"
32
check_params(const struct asymmetric_params_t * params)33 int32_t check_params(const struct asymmetric_params_t *params)
34 {
35 if ((params != NULL) && (params->param_count > TEE_PARAM_MAX)) {
36 tloge("the param_count is too big param_count = %u", params->param_count);
37 return CRYPTO_BAD_PARAMETERS;
38 }
39 return TEE_SUCCESS;
40 }
41
check_valid_algorithm(uint32_t algorithm,const uint32_t * array,uint32_t array_size)42 int32_t check_valid_algorithm(uint32_t algorithm, const uint32_t *array, uint32_t array_size)
43 {
44 if (array == NULL || array_size > MAX_VALID_ALGO_SIZE)
45 return CRYPTO_BAD_PARAMETERS;
46 uint32_t index;
47 for (index = 0; index < array_size; index++) {
48 if (algorithm == array[index])
49 return CRYPTO_SUCCESS;
50 }
51 return CRYPTO_NOT_SUPPORTED;
52 }
53
get_hash_context_size(uint32_t algorithm)54 uint32_t get_hash_context_size(uint32_t algorithm)
55 {
56 switch (algorithm) {
57 case CRYPTO_TYPE_DIGEST_MD5:
58 return sizeof(MD5_CTX);
59 case CRYPTO_TYPE_DIGEST_SHA1:
60 return sizeof(SHA_CTX);
61 case CRYPTO_TYPE_DIGEST_SHA224:
62 return sizeof(SHA256_CTX);
63 case CRYPTO_TYPE_DIGEST_SHA256:
64 return sizeof(SHA256_CTX);
65 case CRYPTO_TYPE_DIGEST_SHA384:
66 return sizeof(SHA512_CTX);
67 case CRYPTO_TYPE_DIGEST_SHA512:
68 return sizeof(SHA512_CTX);
69 default:
70 break;
71 }
72
73 return 0;
74 }
75
free_cipher_context(uint64_t * ctx)76 void free_cipher_context(uint64_t *ctx)
77 {
78 if (ctx == NULL || *ctx == 0)
79 return;
80 EVP_CIPHER_CTX_free((void *)(uintptr_t)*ctx);
81 *ctx = 0;
82 }
83
free_hmac_context(uint64_t * ctx)84 void free_hmac_context(uint64_t *ctx)
85 {
86 if (ctx == NULL || *ctx == 0)
87 return;
88 HMAC_CTX_free((void *)(uintptr_t)*ctx);
89 *ctx = 0;
90 }
91
soft_copy_aes_des_info(struct ctx_handle_t * dest,const struct ctx_handle_t * src)92 static int32_t soft_copy_aes_des_info(struct ctx_handle_t *dest, const struct ctx_handle_t *src)
93 {
94 if (dest->ctx_buffer != 0) {
95 EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)(uintptr_t)(dest->ctx_buffer));
96 dest->ctx_buffer = 0;
97 }
98 if (src->ctx_buffer == 0)
99 return CRYPTO_SUCCESS;
100
101 EVP_CIPHER_CTX *new_ctx = EVP_CIPHER_CTX_new();
102 if (new_ctx == NULL) {
103 tloge("Aes ctx copy failed");
104 return CRYPTO_ERROR_OUT_OF_MEMORY;
105 }
106 int32_t ret = EVP_CIPHER_CTX_copy(new_ctx, (EVP_CIPHER_CTX *)(uintptr_t)(src->ctx_buffer));
107 if (ret != BORINGSSL_OK) {
108 tloge("Aes ctx copy failed");
109 EVP_CIPHER_CTX_free(new_ctx);
110 return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
111 }
112 dest->ctx_buffer = (uint64_t)(uintptr_t)new_ctx;
113
114 return CRYPTO_SUCCESS;
115 }
116
soft_copy_cmac_info(struct ctx_handle_t * dest,const struct ctx_handle_t * src)117 static int32_t soft_copy_cmac_info(struct ctx_handle_t *dest, const struct ctx_handle_t *src)
118 {
119 if (dest->ctx_buffer != 0) {
120 CMAC_CTX_free((CMAC_CTX *)(uintptr_t)(dest->ctx_buffer));
121 dest->ctx_buffer = 0;
122 }
123 if (src->ctx_buffer == 0)
124 return CRYPTO_SUCCESS;
125
126 CMAC_CTX *new_ctx = CMAC_CTX_new();
127 if (new_ctx == NULL) {
128 tloge("New aes cmac ctx failed\n");
129 return CRYPTO_ERROR_OUT_OF_MEMORY;
130 }
131 int32_t ret = CMAC_CTX_copy(new_ctx, (CMAC_CTX *)(uintptr_t)(src->ctx_buffer));
132 if (ret != BORINGSSL_OK) {
133 tloge("Copy aes ctx failed");
134 CMAC_CTX_free(new_ctx);
135 return CRYPTO_BAD_PARAMETERS;
136 }
137 dest->ctx_buffer = (uint64_t)(uintptr_t)new_ctx;
138
139 return CRYPTO_SUCCESS;
140 }
141
soft_copy_digest_info(struct ctx_handle_t * dest,const struct ctx_handle_t * src)142 static int32_t soft_copy_digest_info(struct ctx_handle_t *dest, const struct ctx_handle_t *src)
143 {
144 TEE_Free((void *)(uintptr_t)(dest->ctx_buffer));
145 dest->ctx_buffer = 0;
146
147 if (src->ctx_buffer == 0)
148 return CRYPTO_SUCCESS;
149
150 uint32_t hash_size = get_hash_context_size(src->alg_type);
151 if (hash_size == 0) {
152 tloge("algorithm is incorrect!");
153 return CRYPTO_BAD_PARAMETERS;
154 }
155
156 dest->ctx_buffer = (uintptr_t)TEE_Malloc(hash_size, 0);
157 if (dest->ctx_buffer == 0) {
158 tloge("hash new ctx failed");
159 return CRYPTO_ERROR_OUT_OF_MEMORY;
160 }
161
162 errno_t rc = memcpy_s((void *)(uintptr_t)(dest->ctx_buffer), hash_size,
163 (void *)(uintptr_t)(src->ctx_buffer), src->ctx_size);
164 if (rc != EOK) {
165 tloge("Copy digest ctx failed, rc %x", rc);
166 TEE_Free((void *)(uintptr_t)(dest->ctx_buffer));
167 dest->ctx_buffer = 0;
168 return CRYPTO_ERROR_SECURITY;
169 }
170 dest->ctx_size = src->ctx_size;
171
172 return CRYPTO_SUCCESS;
173 }
174
soft_copy_hmac_info(struct ctx_handle_t * dest,const struct ctx_handle_t * src)175 static int32_t soft_copy_hmac_info(struct ctx_handle_t *dest, const struct ctx_handle_t *src)
176 {
177 free_hmac_context(&(dest->ctx_buffer));
178 if (src->ctx_buffer == 0)
179 return CRYPTO_SUCCESS;
180
181 dest->ctx_buffer = (uint64_t)(uintptr_t)HMAC_CTX_new();
182 if (dest->ctx_buffer == 0) {
183 tloge("hmac new ctx failed");
184 return CRYPTO_ERROR_OUT_OF_MEMORY;
185 }
186 int32_t rc = HMAC_CTX_copy((HMAC_CTX *)(uintptr_t)(dest->ctx_buffer), (HMAC_CTX *)(uintptr_t)(src->ctx_buffer));
187 if (rc != BORINGSSL_OK) {
188 tloge("Copy hmac ctx failed");
189 HMAC_CTX_free((void *)(uintptr_t)(dest->ctx_buffer));
190 dest->ctx_buffer = 0;
191 return get_soft_crypto_error(CRYPTO_ERROR_SECURITY);
192 }
193
194 return CRYPTO_SUCCESS;
195 }
196
197 #if defined(OPENSSL_ENABLE) || defined (OPENSSL3_ENABLE)
soft_copy_siphash_info(struct ctx_handle_t * dest,const struct ctx_handle_t * src)198 static int32_t soft_copy_siphash_info(struct ctx_handle_t *dest, const struct ctx_handle_t *src)
199 {
200 TEE_Free((void *)(uintptr_t)(dest->ctx_buffer));
201 if (src->ctx_buffer == 0)
202 return CRYPTO_SUCCESS;
203
204 dest->ctx_buffer = (uint64_t)(uintptr_t)TEE_Malloc(sizeof(SIPHASH), 0);
205 if (dest->ctx_buffer == 0) {
206 tloge("siphash new ctx failed");
207 return CRYPTO_ERROR_OUT_OF_MEMORY;
208 }
209
210 int32_t rc = memcpy_s((void *)(uintptr_t)(dest->ctx_buffer), sizeof(SIPHASH),
211 (void *)(uintptr_t)(src->ctx_buffer), src->ctx_size);
212 if (rc != EOK) {
213 tloge("Copy siphash ctx failed, rc = %d", rc);
214 TEE_Free((void *)(uintptr_t)(dest->ctx_buffer));
215 dest->ctx_buffer = 0;
216 return get_soft_crypto_error(CRYPTO_ERROR_SECURITY);
217 }
218
219 return CRYPTO_SUCCESS;
220 }
221 #endif
222
223 typedef int32_t (*copy_ctx_func)(struct ctx_handle_t *dest, const struct ctx_handle_t *src);
224 struct soft_ctx_copy {
225 uint32_t algorithm;
226 copy_ctx_func copy_call_back;
227 };
228
229 static struct soft_ctx_copy g_soft_copy_ctx[] = {
230 { CRYPTO_TYPE_DIGEST_SM3, soft_copy_gmssl_info },
231 { CRYPTO_TYPE_DIGEST_MD5, soft_copy_digest_info },
232 { CRYPTO_TYPE_DIGEST_SHA1, soft_copy_digest_info },
233 { CRYPTO_TYPE_DIGEST_SHA224, soft_copy_digest_info },
234 { CRYPTO_TYPE_DIGEST_SHA256, soft_copy_digest_info },
235 { CRYPTO_TYPE_DIGEST_SHA384, soft_copy_digest_info },
236 { CRYPTO_TYPE_DIGEST_SHA512, soft_copy_digest_info },
237 { CRYPTO_TYPE_HMAC_SM3, soft_copy_gmssl_info },
238 { CRYPTO_TYPE_HMAC_MD5, soft_copy_hmac_info },
239 { CRYPTO_TYPE_HMAC_SHA1, soft_copy_hmac_info },
240 { CRYPTO_TYPE_HMAC_SHA224, soft_copy_hmac_info },
241 { CRYPTO_TYPE_HMAC_SHA256, soft_copy_hmac_info },
242 { CRYPTO_TYPE_HMAC_SHA384, soft_copy_hmac_info },
243 { CRYPTO_TYPE_HMAC_SHA512, soft_copy_hmac_info },
244 #if defined(OPENSSL_ENABLE) || defined (OPENSSL3_ENABLE)
245 { CRYPTO_TYPE_SIP_HASH, soft_copy_siphash_info },
246 #endif
247 { CRYPTO_TYPE_SM4_ECB, soft_copy_gmssl_info },
248 { CRYPTO_TYPE_SM4_CBC, soft_copy_gmssl_info },
249 { CRYPTO_TYPE_SM4_CBC_PKCS7, soft_copy_gmssl_info },
250 { CRYPTO_TYPE_SM4_CTR, soft_copy_gmssl_info },
251 { CRYPTO_TYPE_SM4_CFB128, soft_copy_gmssl_info },
252 { CRYPTO_TYPE_SM4_GCM, soft_copy_gmssl_info },
253 { CRYPTO_TYPE_AES_ECB_NOPAD, soft_copy_aes_des_info },
254 { CRYPTO_TYPE_AES_ECB_PKCS5, soft_copy_aes_des_info },
255 { CRYPTO_TYPE_AES_CBC_PKCS5, soft_copy_aes_des_info },
256 { CRYPTO_TYPE_AES_CBC_NOPAD, soft_copy_aes_des_info },
257 { CRYPTO_TYPE_DES_ECB_NOPAD, soft_copy_aes_des_info },
258 { CRYPTO_TYPE_DES_CBC_NOPAD, soft_copy_aes_des_info },
259 { CRYPTO_TYPE_DES3_ECB_NOPAD, soft_copy_aes_des_info },
260 { CRYPTO_TYPE_DES3_CBC_NOPAD, soft_copy_aes_des_info },
261 { CRYPTO_TYPE_AES_CTR, soft_copy_aes_des_info },
262 { CRYPTO_TYPE_AES_XTS, soft_copy_aes_des_info },
263 { CRYPTO_TYPE_AES_CBC_MAC_NOPAD, soft_copy_aes_des_info },
264 { CRYPTO_TYPE_AES_CMAC, soft_copy_cmac_info },
265 { CRYPTO_TYPE_AES_CCM, soft_copy_aes_des_info },
266 { CRYPTO_TYPE_AES_GCM, soft_copy_aes_des_info },
267
268 };
269
soft_crypto_ctx_copy(const struct ctx_handle_t * src_ctx,struct ctx_handle_t * dest_ctx)270 int32_t soft_crypto_ctx_copy(const struct ctx_handle_t *src_ctx, struct ctx_handle_t *dest_ctx)
271 {
272 if (src_ctx == NULL || dest_ctx == NULL) {
273 tloge("The src ctx or dest ctx is null\n");
274 return CRYPTO_BAD_PARAMETERS;
275 }
276
277 uint32_t i = 0;
278 for (; i < ARRAY_NUM(g_soft_copy_ctx); i++) {
279 if (src_ctx->alg_type == g_soft_copy_ctx[i].algorithm)
280 return g_soft_copy_ctx[i].copy_call_back(dest_ctx, src_ctx);
281 }
282
283 return CRYPTO_SUCCESS;
284 }
285
get_boring_nid_by_tee_curve(uint32_t tee_domain,uint32_t * nid)286 int32_t get_boring_nid_by_tee_curve(uint32_t tee_domain, uint32_t *nid)
287 {
288 uint32_t index = 0;
289 if (nid == NULL) {
290 tloge("nid is null");
291 return CRYPTO_BAD_PARAMETERS;
292 }
293 crypto_uint2uint domain_to_curve[] = {
294 { ECC_CURVE_NIST_P192, NID_X9_62_prime192v1 },
295 { ECC_CURVE_NIST_P224, NID_secp224r1 },
296 { ECC_CURVE_NIST_P256, NID_X9_62_prime256v1 },
297 { ECC_CURVE_NIST_P384, NID_secp384r1 },
298 { ECC_CURVE_NIST_P521, NID_secp521r1 },
299 };
300 for (; index < sizeof(domain_to_curve) / sizeof(crypto_uint2uint); index++) {
301 if (tee_domain == domain_to_curve[index].src) {
302 *nid = domain_to_curve[index].dest;
303 return CRYPTO_SUCCESS;
304 }
305 }
306
307 tloge("invalid tee_domain 0x%x\n", tee_domain);
308 return CRYPTO_BAD_PARAMETERS;
309 }
310
311 #ifdef OPENSSL_ENABLE
get_openssl_rand(unsigned char * buf,int num)312 int32_t get_openssl_rand(unsigned char *buf, int num)
313 {
314 if (num == 0 || num > INT32_MAX)
315 return CRYPTO_BAD_PARAMETERS;
316 int32_t ret = RAND_priv_bytes(buf, num);
317 free_openssl_drbg_mem();
318 return ret;
319 }
320
free_openssl_drbg_mem(void)321 void free_openssl_drbg_mem(void)
322 {
323 drbg_delete_thread_state();
324 OPENSSL_thread_stop();
325 }
326 #endif
327