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