• 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 #include "crypto_hal.h"
13 #include <securec.h>
14 #include <tee_log.h>
15 #include <tee_crypto_hal.h>
16 #include <mem_ops.h>
17 #include "crypto_manager.h"
18 #include "soft_common_api.h"
19 #include "crypto_mgr_syscall.h"
20 #include "tee_drv_client.h"
21 
alloc_ctx_handle(uint32_t alg_type,uint32_t engine)22 struct ctx_handle_t *alloc_ctx_handle(uint32_t alg_type, uint32_t engine)
23 {
24     struct ctx_handle_t *ctx = TEE_Malloc(sizeof(*ctx), 0);
25     if (ctx == NULL) {
26         tloge("Malloc ctx handle failed\n");
27         return NULL;
28     }
29     ctx->alg_type = alg_type;
30     ctx->engine = engine;
31     if (engine == SOFT_CRYPTO)
32         return ctx;
33 
34     return driver_alloc_ctx_handle(alg_type, engine, ctx);
35 }
36 
free_crypto_cache(struct crypto_cache_t * crypto_cache)37 static void free_crypto_cache(struct crypto_cache_t *crypto_cache)
38 {
39     if (crypto_cache != NULL) {
40         if (crypto_cache->buffer != NULL) {
41             (void)memset_s(crypto_cache->buffer, crypto_cache->total_len, 0, crypto_cache->total_len);
42             TEE_Free(crypto_cache->buffer);
43             crypto_cache->buffer = NULL;
44         }
45         TEE_Free(crypto_cache);
46         crypto_cache = NULL;
47     }
48 }
49 
tee_crypto_ctx_cache_copy(const struct ctx_handle_t * src_ctx,struct ctx_handle_t * dest_ctx)50 static int32_t tee_crypto_ctx_cache_copy(const struct ctx_handle_t *src_ctx, struct ctx_handle_t *dest_ctx)
51 {
52     struct crypto_cache_t *src_cache = (struct crypto_cache_t *)(uintptr_t)(src_ctx->cache_buffer);
53     struct crypto_cache_t *dest_cache = (struct crypto_cache_t *)(uintptr_t)(dest_ctx->cache_buffer);
54 
55     free_crypto_cache(dest_cache);
56     dest_ctx->cache_buffer = 0;
57 
58     if (src_ctx->cache_buffer == 0)
59         return CRYPTO_SUCCESS;
60 
61     bool check = ((src_cache->total_len == 0) || (src_cache->total_len > MAX_CRYPTO_DATA_LEN));
62     if (check) {
63         tloge("The src cache len is invalid");
64         return CRYPTO_BAD_PARAMETERS;
65     }
66 
67     dest_cache = TEE_Malloc(sizeof(*dest_cache), 0);
68     if (dest_cache == NULL) {
69         tloge("Malloc cache buffer failed\n");
70         return CRYPTO_ERROR_OUT_OF_MEMORY;
71     }
72 
73     dest_cache->buffer = TEE_Malloc(src_cache->total_len, 0);
74     if (dest_cache->buffer == NULL) {
75         tloge("Malloc cache buffer failed\n");
76         TEE_Free(dest_cache);
77         return CRYPTO_ERROR_OUT_OF_MEMORY;
78     }
79     (void)memcpy_s(dest_cache->buffer, src_cache->total_len, src_cache->buffer, src_cache->total_len);
80 
81     dest_cache->total_len = src_cache->total_len;
82     dest_cache->effective_len = src_cache->effective_len;
83 
84     dest_ctx->cache_buffer = (uint64_t)(uintptr_t)dest_cache;
85 
86     return CRYPTO_SUCCESS;
87 }
88 
free_ctx_buff(struct ctx_handle_t * ctx)89 static void free_ctx_buff(struct ctx_handle_t *ctx)
90 {
91     if (ctx->ctx_buffer != 0) {
92         if (ctx->free_context != NULL) {
93             ctx->free_context(&(ctx->ctx_buffer));
94         } else {
95             uint8_t *ctx_ctx_buffer = (uint8_t *)(uintptr_t)(ctx->ctx_buffer);
96             (void)memset_s(ctx_ctx_buffer, ctx->ctx_size, 0x0, ctx->ctx_size);
97             TEE_Free(ctx_ctx_buffer);
98             ctx_ctx_buffer = NULL;
99         }
100         ctx->ctx_buffer = 0;
101     }
102 }
103 
tee_crypto_free_sharemem(struct ctx_handle_t * ctx)104 void tee_crypto_free_sharemem(struct ctx_handle_t *ctx)
105 {
106     if (ctx == NULL)
107         return;
108 
109     if (ctx->ctx_buffer != 0) {
110         (void)memset_s((void *)(uintptr_t)ctx->ctx_buffer, ctx->ctx_size, 0, ctx->ctx_size);
111         free_sharemem((void *)(uintptr_t)ctx->ctx_buffer, ctx->ctx_size);
112         ctx->ctx_buffer = 0;
113         ctx->ctx_size = 0;
114     }
115 }
116 
tee_crypto_ctx_free(struct ctx_handle_t * ctx)117 void tee_crypto_ctx_free(struct ctx_handle_t *ctx)
118 {
119     if (ctx == NULL)
120         return;
121 
122     if (ctx->engine == SOFT_CRYPTO)
123         free_ctx_buff(ctx);
124     else
125 #ifndef CRYPTO_MGR_SERVER_ENABLE
126     free_ctx_buff(ctx);
127 #else
128     tee_crypto_free_sharemem(ctx);
129 #endif
130     struct crypto_cache_t *cache = (struct crypto_cache_t *)(uintptr_t)(ctx->cache_buffer);
131     free_crypto_cache(cache);
132     cache = NULL;
133     if (ctx->fd > 0) {
134         int32_t ret = tee_drv_close(ctx->fd);
135         if (ret != 0)
136             tloge("close fd fail fd = 0x%x, ret = 0x%x\n", ctx->fd, ret);
137     }
138     TEE_Free(ctx);
139 }
140 
ctx_copy_normal(const struct ctx_handle_t * src_ctx,struct ctx_handle_t * dest_ctx)141 static void ctx_copy_normal(const struct ctx_handle_t *src_ctx, struct ctx_handle_t *dest_ctx)
142 {
143     dest_ctx->alg_type = src_ctx->alg_type;
144     dest_ctx->ctx_size = src_ctx->ctx_size;
145     dest_ctx->direction = src_ctx->direction;
146     dest_ctx->engine = src_ctx->engine;
147     dest_ctx->is_support_ae_update = src_ctx->is_support_ae_update;
148     dest_ctx->tag_len = src_ctx->tag_len;
149     dest_ctx->aad_size = src_ctx->aad_size;
150     dest_ctx->driver_ability = src_ctx->driver_ability;
151 
152     (void)memcpy_s(dest_ctx->cbc_mac_buffer, sizeof(dest_ctx->cbc_mac_buffer),
153         src_ctx->cbc_mac_buffer, sizeof(src_ctx->cbc_mac_buffer));
154     (void)memcpy_s(dest_ctx->cipher_cache_data, sizeof(dest_ctx->cipher_cache_data),
155         src_ctx->cipher_cache_data, sizeof(src_ctx->cipher_cache_data));
156 
157     dest_ctx->cipher_cache_len = src_ctx->cipher_cache_len;
158     dest_ctx->free_context = src_ctx->free_context;
159 }
160 
tee_crypto_ctx_copy(const struct ctx_handle_t * src_ctx,struct ctx_handle_t * dest_ctx)161 int32_t tee_crypto_ctx_copy(const struct ctx_handle_t *src_ctx, struct ctx_handle_t *dest_ctx)
162 {
163     if ((src_ctx == NULL) || (dest_ctx == NULL) || src_ctx->ctx_size > MAX_CRYPTO_CTX_SIZE)
164         return CRYPTO_BAD_PARAMETERS;
165 
166     if (src_ctx == dest_ctx)
167         return CRYPTO_SUCCESS;
168 
169     ctx_copy_normal(src_ctx, dest_ctx);
170 
171     int32_t ret;
172     if (src_ctx->engine == SOFT_CRYPTO) {
173         ret = soft_crypto_ctx_copy(src_ctx, dest_ctx);
174     } else {
175         ret = driver_ctx_buffer_prepare(src_ctx, dest_ctx);
176         if (ret != CRYPTO_SUCCESS)
177             return ret;
178 
179         ret = crypto_driver_ctx_copy(src_ctx, dest_ctx);
180     }
181     if (ret != CRYPTO_SUCCESS)
182         goto free_ctx;
183 
184     if (src_ctx->cache_buffer == 0)
185         return CRYPTO_SUCCESS;
186 
187     ret = tee_crypto_ctx_cache_copy(src_ctx, dest_ctx);
188     if (ret != CRYPTO_SUCCESS)
189         goto free_ctx;
190     return CRYPTO_SUCCESS;
191 
192 free_ctx:
193     tloge("copy stx failed, ret = %d", ret);
194     if (src_ctx->engine != SOFT_CRYPTO) {
195         TEE_Free((void *)(uintptr_t)(dest_ctx->ctx_buffer));
196         dest_ctx->ctx_buffer = 0;
197         if (dest_ctx->fd > 0)
198             tee_drv_close(dest_ctx->fd);
199     } else {
200         free_ctx_buff(dest_ctx);
201     }
202     return ret;
203 }
204 
205 #define LCG96_RAND_NUM 63
206 #define U32_VAL_MAX    0xffffffffull
207 #define U32_BITS       32
208 #define WORD_SIZE      4
209 
210 static uint32_t g_seed = 0xa897213f;
211 
212 enum {
213     LCG96_U32_LOW = 0,
214     LCG96_U32_MID = 1,
215     LCG96_U32_HIG = 2,
216     LCG96_U32_NUM = 3
217 };
218 
219 /*
220  * LCG(Linear Congruential Generator) is an algorithm that yields a sequence
221  * of pseudo-randomized numbers calculated with a discontinuous piecewise
222  * linear equation.
223  * The generator is defined by recurrence relation:
224  * X(i+1) = (a * X(i) + c) (mod m), i >= 0 && i < n
225  * The "X(0...n-1)" is just the "g_lcg96_rand[]" array
226  */
227 static unsigned long long g_lcg96_rand[LCG96_RAND_NUM];
228 
229 #define MULTIPLIER_NUM1 0x5aa1cae5
230 #define MULTIPLIER_NUM2 0xd0cf37be
231 #define MULTIPLIER_NUM3 0x92efd1b8
232 
233 /* The "a" in the above formula is the g_multiplier, and its value is 5^41 */
234 static const unsigned int g_multiplier[LCG96_U32_NUM] = {
235     MULTIPLIER_NUM1,
236     MULTIPLIER_NUM2,
237     MULTIPLIER_NUM3
238 };
239 
240 /* Calculate: x1 = (g_multiplier[] * x0 + 1) (mod 2^96) */
lcg96_calc(const unsigned int * x0,unsigned int * x1)241 static void lcg96_calc(const unsigned int *x0, unsigned int *x1)
242 {
243     int i, j, k, h;
244     unsigned int t[LCG96_U32_NUM];
245     unsigned long long tmp, carry;
246 
247     for (i = 0; i < LCG96_U32_NUM; i++) {
248         x1[i] = 0;
249         t[i] = 0;
250     }
251     x1[0] = 1;
252 
253     for (i = 0; i < LCG96_U32_NUM; i++) {
254         for (j = 0; j < LCG96_U32_NUM && (i + j) < LCG96_U32_NUM; j++) {
255             tmp = (unsigned long long)g_multiplier[i] *
256                   (unsigned long long)x0[j];
257             t[1] = (unsigned int)(tmp >> U32_BITS);
258             t[0] = (unsigned int)tmp;
259             carry = 0ull;
260             for (k = i + j; k < LCG96_U32_NUM; k++) {
261                 h = k - (i + j);
262                 tmp = (unsigned long long)x1[k] + t[h] + carry;
263                 carry = (tmp > U32_VAL_MAX) ? 1ull : 0ull;
264                 x1[k] = (unsigned int)tmp;
265             }
266         }
267     }
268 }
269 
random_seed(unsigned int seed)270 static void random_seed(unsigned int seed)
271 {
272 #define LCG96_XI_NUM    2
273     int i, j;
274     unsigned int x_i[LCG96_XI_NUM][LCG96_U32_NUM];
275 
276     for (i = 0; i < LCG96_XI_NUM; i++) {
277         for (j = LCG96_U32_LOW; j < LCG96_U32_NUM; j++)
278             x_i[i][j] = 0;
279     }
280     x_i[0][LCG96_U32_LOW] = seed;
281     j = 0;
282     for (i = 0; i < LCG96_RAND_NUM; i++) {
283         lcg96_calc(x_i[j], x_i[1 - j]);
284         j = 1 - j;
285         /* Take bits 95...32 of "Xi[]" as g_lcg96_rand numbers */
286         g_lcg96_rand[i] =
287             (unsigned long long)x_i[j][LCG96_U32_HIG] |
288             ((unsigned long long)x_i[j][LCG96_U32_MID] << U32_BITS);
289     }
290     /* make sure g_lcg96_rand contains at least one odd number */
291     g_lcg96_rand[0] |= 1ull;
292 #undef LCG96_XI_NUM
293 }
294 
295 #define NEXT_SEED_NUM1 0x57e32a47
296 #define NEXT_SEED_NUM2 0x207c87a3
297 
next_seed(void)298 static void next_seed(void)
299 {
300     g_seed = (uint32_t)(g_seed * NEXT_SEED_NUM1 + NEXT_SEED_NUM2);
301 }
302 
random_arch_get(void)303 static uint32_t random_arch_get(void)
304 {
305     next_seed();
306 #define LCG96_OFFSET    5
307     static int rand_idx = 1;
308     int i = rand_idx;
309     int j = (i + LCG96_OFFSET) % LCG96_RAND_NUM;
310 
311     random_seed(g_seed);
312 
313     g_lcg96_rand[j] += g_lcg96_rand[i];
314     rand_idx = (rand_idx + 1) % LCG96_RAND_NUM;
315 
316     return (uint32_t)g_lcg96_rand[j];
317 #undef LCG96_OFFSET
318 }
319 
soft_random_get(uint8_t * trng_addr,uint32_t length)320 int32_t soft_random_get(uint8_t *trng_addr, uint32_t length)
321 {
322     uint32_t i;
323     uint32_t value;
324     uint32_t *tmp_addr = NULL;
325     uint32_t left;
326 
327     if (trng_addr == NULL) {
328         tloge("bad param!\n");
329         return -1;
330     }
331 
332     left = length % WORD_SIZE;
333     tmp_addr = (uint32_t *)(void *)trng_addr;
334 
335     for (i = 0; i < length / WORD_SIZE; i++) {
336         tmp_addr[i] = random_arch_get();
337         if (tmp_addr[i] == 0) {
338             tloge("get rng value error!\n");
339             return -1;
340         }
341     }
342 
343     if (left == 0)
344         return 0;
345 
346     value = random_arch_get();
347     if (memcpy_s(trng_addr + i * WORD_SIZE, length - i * WORD_SIZE, (char *)(&value), left) != EOK) {
348         tloge("copy random error!\n");
349         return -1;
350     }
351 
352     return 0;
353 }
354 
tee_crypto_generate_random(void * buffer,uint32_t size,bool is_hw_rand)355 int32_t tee_crypto_generate_random(void *buffer, uint32_t size, bool is_hw_rand)
356 {
357     if ((buffer == NULL) || (size == 0)) {
358         tloge("Invalid params\n");
359         return CRYPTO_BAD_PARAMETERS;
360     }
361 
362     if (size > MAX_RANDOM_SIZE) {
363         tloge("this random size is too large!");
364         return CRYPTO_BAD_PARAMETERS;
365     }
366 
367     size_t offset_len = 0;
368     int32_t ret;
369 
370     while (size > MAX_CRYPTO_RANDOM_LEN) {
371 #if !defined(CRYPTO_MGR_SERVER_ENABLE)
372         ret = soft_random_get(buffer + offset_len, MAX_CRYPTO_RANDOM_LEN);
373 #else
374         ret = crypto_driver_generate_random(buffer + offset_len, MAX_CRYPTO_RANDOM_LEN, is_hw_rand);
375 #endif
376         if (ret != CRYPTO_SUCCESS) {
377             tloge("driver generate random failed, ret = 0x%x\n", ret);
378             return ret;
379         }
380         size -= MAX_CRYPTO_RANDOM_LEN;
381         offset_len += MAX_CRYPTO_RANDOM_LEN;
382     }
383 #if !defined(CRYPTO_MGR_SERVER_ENABLE)
384     ret = soft_random_get(buffer + offset_len, size);
385     (void)is_hw_rand;
386 #else
387     ret = crypto_driver_generate_random(buffer + offset_len, size, is_hw_rand);
388 #endif
389     return ret;
390 }
391 
392 #ifdef OPENSSL_ENABLE
tee_crypto_free_openssl_drbg(void)393 void tee_crypto_free_openssl_drbg(void)
394 {
395     free_openssl_drbg_mem();
396 }
397 #endif
398