• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef HITLS_CRYPTO_BN
18 
19 #include <stdint.h>
20 #include <string.h>
21 #include "securec.h"
22 #include "bsl_err_internal.h"
23 #include "bsl_sal.h"
24 #include "crypt_errno.h"
25 #include "bn_optimizer.h"
26 
BN_OptimizerCreate(void)27 BN_Optimizer *BN_OptimizerCreate(void)
28 {
29     BN_Optimizer *opt = BSL_SAL_Calloc(1u, sizeof(BN_Optimizer));
30     if (opt == NULL) {
31         return NULL;
32     }
33     opt->curChunk = BSL_SAL_Calloc(1u, sizeof(Chunk));
34     if (opt->curChunk == NULL) {
35         BSL_SAL_FREE(opt);
36         return NULL;
37     }
38     return opt;
39 }
40 
BN_OptimizerSetLibCtx(void * libCtx,BN_Optimizer * opt)41 void BN_OptimizerSetLibCtx(void *libCtx, BN_Optimizer *opt)
42 {
43     opt->libCtx = libCtx;
44 }
45 
BN_OptimizerGetLibCtx(BN_Optimizer * opt)46 void *BN_OptimizerGetLibCtx(BN_Optimizer *opt)
47 {
48     return opt->libCtx;
49 }
50 
BN_OptimizerDestroy(BN_Optimizer * opt)51 void BN_OptimizerDestroy(BN_Optimizer *opt)
52 {
53     if (opt == NULL) {
54         return;
55     }
56     Chunk *curChunk = opt->curChunk;
57     Chunk *nextChunk = curChunk->next;
58     Chunk *prevChunk = curChunk->prev;
59 
60     while (nextChunk != NULL) {
61         for (uint32_t i = 0; i < HITLS_CRYPT_OPTIMIZER_BN_NUM; i++) {
62             BSL_SAL_CleanseData((void *)(nextChunk->bigNums[i].data), nextChunk->bigNums[i].size * sizeof(BN_UINT));
63             BSL_SAL_FREE(nextChunk->bigNums[i].data);
64         }
65         Chunk *tmp = nextChunk->next;
66         BSL_SAL_Free(nextChunk);
67         nextChunk = tmp;
68     }
69 
70     while (prevChunk != NULL) {
71         for (uint32_t i = 0; i < HITLS_CRYPT_OPTIMIZER_BN_NUM; i++) {
72             BSL_SAL_CleanseData((void *)(prevChunk->bigNums[i].data), prevChunk->bigNums[i].size * sizeof(BN_UINT));
73             BSL_SAL_FREE(prevChunk->bigNums[i].data);
74         }
75         Chunk *tmp = prevChunk->prev;
76         BSL_SAL_Free(prevChunk);
77         prevChunk = tmp;
78     }
79     // curChunk != NULL
80     for (uint32_t i = 0; i < HITLS_CRYPT_OPTIMIZER_BN_NUM; i++) {
81         BSL_SAL_CleanseData((void *)(curChunk->bigNums[i].data), curChunk->bigNums[i].size * sizeof(BN_UINT));
82         BSL_SAL_FREE(curChunk->bigNums[i].data);
83     }
84     BSL_SAL_Free(curChunk);
85     BSL_SAL_Free(opt);
86 }
87 
OptimizerStart(BN_Optimizer * opt)88 int32_t OptimizerStart(BN_Optimizer *opt)
89 {
90     if (opt->deep != CRYPT_OPTIMIZER_MAXDEEP) {
91         opt->deep++;
92         return CRYPT_SUCCESS;
93     }
94     BSL_ERR_PUSH_ERROR(CRYPT_BN_OPTIMIZER_STACK_FULL);
95     return CRYPT_BN_OPTIMIZER_STACK_FULL;
96 }
97 /* create a new room that has not been initialized */
GetPresetBn(BN_Optimizer * opt,Chunk * curChunk)98 static BN_BigNum *GetPresetBn(BN_Optimizer *opt, Chunk *curChunk)
99 {
100     if (curChunk->occupied != HITLS_CRYPT_OPTIMIZER_BN_NUM) {
101         curChunk->occupied++;
102         return &curChunk->bigNums[curChunk->occupied - 1];
103     }
104     if (curChunk->prev != NULL) {
105         opt->curChunk = curChunk->prev;
106         opt->curChunk->occupied++; // new chunk and occupied = 0;
107         return &opt->curChunk->bigNums[opt->curChunk->occupied - 1];
108     }
109     // We has used all chunks.
110     Chunk *newChunk = BSL_SAL_Calloc(1u, sizeof(Chunk));
111     if (newChunk == NULL) {
112         return NULL;
113     }
114     newChunk->next = curChunk;
115     curChunk->prev = newChunk;
116     opt->curChunk = newChunk;
117     newChunk->occupied++;
118     return &newChunk->bigNums[newChunk->occupied - 1];
119 }
120 
BnMake(BN_BigNum * r,uint32_t room)121 static int32_t BnMake(BN_BigNum *r, uint32_t room)
122 {
123     if (r->room < room) {
124         if (room > BITS_TO_BN_UNIT(BN_MAX_BITS)) {
125             BSL_ERR_PUSH_ERROR(CRYPT_BN_BITS_TOO_MAX);
126             return CRYPT_BN_BITS_TOO_MAX;
127         }
128         BN_UINT *tmp = (BN_UINT *)BSL_SAL_Calloc(1u, room * sizeof(BN_UINT));
129         if (tmp == NULL) {
130             BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
131             return CRYPT_MEM_ALLOC_FAIL;
132         }
133         if (r->size > 0) {
134             BSL_SAL_CleanseData(r->data, r->size * sizeof(BN_UINT));
135         }
136         BSL_SAL_FREE(r->data);
137         r->data = tmp;
138         r->room = room;
139     } else {
140         (void)memset_s(r->data, r->room * sizeof(BN_UINT), 0, r->room * sizeof(BN_UINT));
141     }
142     r->size = 0;
143     r->sign = false;
144     r->flag |= CRYPT_BN_FLAG_OPTIMIZER;
145     return CRYPT_SUCCESS;
146 }
147 /* create a BigNum and initialize to 0 */
OptimizerGetBn(BN_Optimizer * opt,uint32_t room)148 BN_BigNum *OptimizerGetBn(BN_Optimizer *opt, uint32_t room)
149 {
150     if (opt->deep == 0) {
151         return NULL;
152     }
153     if ((opt->used[opt->deep - 1] + 1) < opt->used[opt->deep - 1]) {
154         // Avoid overflow
155         return NULL;
156     }
157     BN_BigNum *tmp = GetPresetBn(opt, opt->curChunk);
158     if (tmp == NULL) {
159         return NULL;
160     }
161     if (BnMake(tmp, room) != CRYPT_SUCCESS) {
162         return NULL;
163     }
164     opt->used[opt->deep - 1]++;
165     return tmp;
166 }
167 
OptimizerEnd(BN_Optimizer * opt)168 void OptimizerEnd(BN_Optimizer *opt)
169 {
170     if (opt->deep == 0) {
171         return;
172     }
173     opt->deep--;
174     uint32_t usedNum = opt->used[opt->deep];
175     opt->used[opt->deep] = 0;
176     Chunk *curChunk = opt->curChunk;
177     if (usedNum <= curChunk->occupied) {
178         curChunk->occupied -= usedNum;
179         return;
180     }
181     usedNum -= curChunk->occupied;
182     curChunk->occupied = 0;
183     while (usedNum >= HITLS_CRYPT_OPTIMIZER_BN_NUM) {
184         curChunk = curChunk->next;
185         curChunk->occupied = 0;
186         usedNum -= HITLS_CRYPT_OPTIMIZER_BN_NUM;
187     }
188     if (usedNum != 0) {
189         curChunk = curChunk->next;
190         curChunk->occupied = HITLS_CRYPT_OPTIMIZER_BN_NUM - usedNum;
191     }
192     opt->curChunk = curChunk;
193     return;
194 }
195 #endif /* HITLS_CRYPTO_BN */
196