1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #if defined(HITLS_CRYPTO_ENTROPY) && defined(HITLS_CRYPTO_ENTROPY_SYS)
18
19 #include <stdint.h>
20 #include "securec.h"
21 #include "bsl_err_internal.h"
22 #include "bsl_sal.h"
23 #include "crypt_errno.h"
24 #include "es_entropy_pool.h"
25
ES_EntropyPoolInit(uint32_t size)26 ES_EntropyPool *ES_EntropyPoolInit(uint32_t size)
27 {
28 ES_EntropyPool *pool = NULL;
29 uint32_t maxSize = size + 1;
30 if (size == 0) {
31 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
32 return NULL;
33 }
34
35 pool = (ES_EntropyPool *)BSL_SAL_Malloc(sizeof(ES_EntropyPool));
36 if (pool == NULL) {
37 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
38 return NULL;
39 }
40
41 pool->buf = (uint8_t *)BSL_SAL_Malloc(maxSize);
42 if (pool->buf == NULL) {
43 BSL_SAL_FREE(pool);
44 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
45 return NULL;
46 }
47
48 pool->front = 0;
49 pool->rear = 0;
50 pool->maxSize = maxSize;
51 return pool;
52 }
53
ES_EntropyPoolDeInit(ES_EntropyPool * pool)54 void ES_EntropyPoolDeInit(ES_EntropyPool *pool)
55 {
56 if (pool == NULL) {
57 return;
58 }
59
60 (void)memset_s(pool->buf, pool->maxSize, 0, pool->maxSize);
61 BSL_SAL_FREE(pool->buf);
62 BSL_SAL_Free(pool);
63 return;
64 }
65
ES_EntropyPoolGetMaxSize(ES_EntropyPool * pool)66 int32_t ES_EntropyPoolGetMaxSize(ES_EntropyPool *pool)
67 {
68 return pool->maxSize - 1;
69 }
70
ES_EntropyPoolGetCurSize(ES_EntropyPool * pool)71 uint32_t ES_EntropyPoolGetCurSize(ES_EntropyPool *pool)
72 {
73 return (pool->rear - pool->front + pool->maxSize) % pool->maxSize;
74 }
75
ES_EntropyPoolPushBytes(ES_EntropyPool * pool,uint8_t * buf,uint32_t bufLen)76 int32_t ES_EntropyPoolPushBytes(ES_EntropyPool *pool, uint8_t *buf, uint32_t bufLen)
77 {
78 uint32_t partA, partB;
79 partA = (bufLen > (pool->maxSize - pool->rear)) ? pool->maxSize - pool->rear : bufLen;
80 (void)memcpy_s(&pool->buf[pool->rear], pool->maxSize - pool->rear, buf, partA);
81 pool->rear = (pool->rear + partA) % pool->maxSize;
82 if (partA < bufLen) {
83 partB = bufLen - partA;
84 (void)memcpy_s(&pool->buf[pool->rear], pool->maxSize - pool->rear, buf + partA, partB);
85 pool->rear = (pool->rear + partB) % pool->maxSize;
86 }
87 return CRYPT_SUCCESS;
88 }
89
ES_EntropyPoolPopBytes(ES_EntropyPool * pool,uint8_t * data,uint32_t size)90 uint32_t ES_EntropyPoolPopBytes(ES_EntropyPool *pool, uint8_t *data, uint32_t size)
91 {
92 uint32_t bufLen, partA, partB;
93 if (ES_EntropyPoolGetMaxSize(pool) == 0 || size == 0) {
94 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
95 return 0;
96 }
97
98 bufLen = (ES_EntropyPoolGetCurSize(pool) < size) ? ES_EntropyPoolGetCurSize(pool) : size;
99
100 partA = (bufLen <= pool->maxSize - pool->front) ? bufLen : pool->maxSize - pool->front;
101 (void)memcpy_s(data, bufLen, &pool->buf[pool->front], partA);
102 pool->front = (pool->front + partA) % pool->maxSize;
103 partB = bufLen - partA;
104 if (partB != 0) {
105 (void)memcpy_s(data + partA, bufLen - partA, &pool->buf[pool->front], partB);
106 pool->front = (pool->front + partB) % pool->maxSize;
107 }
108
109 return bufLen;
110 }
111
112 #endif