• 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_PAILLIER
18 
19 #include "crypt_types.h"
20 #include "crypt_paillier.h"
21 #include "crypt_utils.h"
22 #include "bsl_err_internal.h"
23 #include "paillier_local.h"
24 #include "crypt_errno.h"
25 #include "securec.h"
26 #include "bsl_sal.h"
27 #include "crypt_params_key.h"
28 
29 typedef struct {
30     BSL_Param *n;      /**< Paillier private key parameter marked as n */
31     BSL_Param *lambda; /**< Paillier private key parameter marked as lambda */
32     BSL_Param *mu;     /**< Paillier private key parameter marked as mu */
33     BSL_Param *n2;     /**< Paillier private key parameter marked as n2 */
34 } CRYPT_PaillierPrvParam;
35 
36 typedef struct {
37     BSL_Param *n;  /**< Paillier public key parameter marked as n */
38     BSL_Param *g;  /**< Paillier public key parameter marked as g */
39     BSL_Param *n2; /**< Paillier public key parameter marked as n2 */
40 } CRYPT_PaillierPubParam;
41 
42 #define PARAMISNULL(a) (a == NULL || a->value == NULL)
43 
CheckSquare(const BN_BigNum * n2,const BN_BigNum * n,uint32_t bits)44 static int32_t CheckSquare(const BN_BigNum *n2, const BN_BigNum *n, uint32_t bits)
45 {
46     BN_BigNum *tmp = BN_Create(bits);
47     BN_Optimizer *optimizer = BN_OptimizerCreate();
48     int32_t ret;
49     if (optimizer == NULL || tmp == NULL) {
50         ret = CRYPT_MEM_ALLOC_FAIL;
51         BSL_ERR_PUSH_ERROR(ret);
52         goto EXIT;
53     }
54 
55     ret = BN_Sqr(tmp, n, optimizer);
56     if (ret != CRYPT_SUCCESS) {
57         BSL_ERR_PUSH_ERROR(ret);
58         goto EXIT;
59     }
60 
61     if (BN_Cmp(tmp, n2) != 0) {
62         BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_INPUT_VALUE);
63         ret = CRYPT_PAILLIER_ERR_INPUT_VALUE;
64     }
65 
66 EXIT:
67     BN_Destroy(tmp);
68     BN_OptimizerDestroy(optimizer);
69     return ret;
70 }
71 
SetPrvPara(const CRYPT_PAILLIER_PrvKey * prvKey,const CRYPT_PaillierPrvParam * prv)72 static int32_t SetPrvPara(const CRYPT_PAILLIER_PrvKey *prvKey, const CRYPT_PaillierPrvParam *prv)
73 {
74     int32_t ret = BN_Bin2Bn(prvKey->n, prv->n->value, prv->n->valueLen);
75     if (ret != CRYPT_SUCCESS) {
76         BSL_ERR_PUSH_ERROR(ret);
77         return ret;
78     }
79 
80     uint32_t bnBits = BN_Bits(prvKey->n);
81     if (bnBits > PAILLIER_MAX_MODULUS_BITS || bnBits <= 0) {
82         BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_KEY_BITS);
83         return CRYPT_PAILLIER_ERR_KEY_BITS;
84     }
85 
86     ret = BN_Bin2Bn(prvKey->lambda, prv->lambda->value, prv->lambda->valueLen);
87     if (ret != CRYPT_SUCCESS) {
88         BSL_ERR_PUSH_ERROR(ret);
89         return ret;
90     }
91     ret = BN_Bin2Bn(prvKey->mu, prv->mu->value, prv->mu->valueLen);
92     if (ret != CRYPT_SUCCESS) {
93         BSL_ERR_PUSH_ERROR(ret);
94         return ret;
95     }
96     ret = BN_Bin2Bn(prvKey->n2, prv->n2->value, prv->n2->valueLen);
97     if (ret != CRYPT_SUCCESS) {
98         BSL_ERR_PUSH_ERROR(ret);
99         return ret;
100     }
101     ret = CheckSquare(prvKey->n2, prvKey->n, prv->n2->valueLen * 8);
102     if (ret != CRYPT_SUCCESS) {
103         BSL_ERR_PUSH_ERROR(ret);
104         return ret;
105     }
106     if (BN_IsZero(prvKey->mu) || BN_IsOne(prvKey->mu)) {
107         BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_INPUT_VALUE);
108         return CRYPT_PAILLIER_ERR_INPUT_VALUE;
109     }
110     return ret;
111 }
112 
SetPrvBasicCheck(const CRYPT_PAILLIER_Ctx * ctx,BSL_Param * para,CRYPT_PaillierPrvParam * prv)113 static int32_t SetPrvBasicCheck(const CRYPT_PAILLIER_Ctx *ctx, BSL_Param *para, CRYPT_PaillierPrvParam *prv)
114 {
115     if (ctx == NULL || para == NULL) {
116         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
117         return CRYPT_NULL_INPUT;
118     }
119     prv->n = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_N);
120     prv->lambda = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_LAMBDA);
121     prv->mu = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_MU);
122     prv->n2 = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_N2);
123     if (PARAMISNULL(prv->n) || PARAMISNULL(prv->lambda) || PARAMISNULL(prv->mu) || PARAMISNULL(prv->n2) ||
124         prv->lambda->valueLen == 0 || prv->mu->valueLen == 0 || prv->n->valueLen == 0 || prv->n2->valueLen == 0) {
125         BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_INPUT_VALUE);
126         return CRYPT_PAILLIER_ERR_INPUT_VALUE;
127     }
128     return CRYPT_SUCCESS;
129 }
130 
CRYPT_PAILLIER_SetPrvKey(CRYPT_PAILLIER_Ctx * ctx,const BSL_Param * para)131 int32_t CRYPT_PAILLIER_SetPrvKey(CRYPT_PAILLIER_Ctx *ctx, const BSL_Param *para)
132 {
133     CRYPT_PaillierPrvParam prv = {0};
134     int32_t ret = SetPrvBasicCheck(ctx, (BSL_Param *)(uintptr_t)para, &prv);
135     if (ret != CRYPT_SUCCESS) {
136         return ret;
137     }
138     CRYPT_PAILLIER_Ctx *newCtx = CRYPT_PAILLIER_NewCtx();
139     if (newCtx == NULL) {
140         return CRYPT_MEM_ALLOC_FAIL;
141     }
142     // Bit length is obtained by multiplying byte length by 8.
143     newCtx->prvKey = Paillier_NewPrvKey(prv.lambda->valueLen * 8);
144     if (newCtx->prvKey == NULL) {
145         ret = CRYPT_MEM_ALLOC_FAIL;
146         BSL_ERR_PUSH_ERROR(ret);
147         goto ERR;
148     }
149 
150     ret = SetPrvPara(newCtx->prvKey, &prv);
151     if (ret != CRYPT_SUCCESS) {
152         BSL_ERR_PUSH_ERROR(ret);
153         goto ERR;
154     }
155 
156     PAILLIER_FREE_PRV_KEY(ctx->prvKey);
157     ctx->prvKey = newCtx->prvKey;
158 
159     BSL_SAL_ReferencesFree(&(newCtx->references));
160     BSL_SAL_FREE(newCtx);
161     return ret;
162 ERR:
163     CRYPT_PAILLIER_FreeCtx(newCtx);
164     return ret;
165 }
166 
SetPubBasicCheck(const CRYPT_PAILLIER_Ctx * ctx,BSL_Param * para,CRYPT_PaillierPubParam * pub)167 static int32_t SetPubBasicCheck(const CRYPT_PAILLIER_Ctx *ctx, BSL_Param *para, CRYPT_PaillierPubParam *pub)
168 {
169     if (ctx == NULL || para == NULL) {
170         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
171         return CRYPT_NULL_INPUT;
172     }
173     pub->n = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_N);
174     pub->g = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_G);
175     pub->n2 = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_N2);
176     if (PARAMISNULL(pub->n) || PARAMISNULL(pub->g) || PARAMISNULL(pub->n2)) {
177         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
178         return CRYPT_NULL_INPUT;
179     }
180     return CRYPT_SUCCESS;
181 }
182 
CRYPT_PAILLIER_SetPubKey(CRYPT_PAILLIER_Ctx * ctx,const BSL_Param * para)183 int32_t CRYPT_PAILLIER_SetPubKey(CRYPT_PAILLIER_Ctx *ctx, const BSL_Param *para)
184 {
185     CRYPT_PaillierPubParam pub = {0};
186     int32_t ret = SetPubBasicCheck(ctx, (BSL_Param *)(uintptr_t)para, &pub);
187     if (ret != CRYPT_SUCCESS) {
188         BSL_ERR_PUSH_ERROR(ret);
189         return ret;
190     }
191     CRYPT_PAILLIER_PubKey *newPub = NULL;
192 
193     /* Bit length is obtained by multiplying byte length by 8. */
194     newPub = Paillier_NewPubKey(pub.n->valueLen * 8);
195     if (newPub == NULL) {
196         return CRYPT_MEM_ALLOC_FAIL;
197     }
198     GOTO_ERR_IF(BN_Bin2Bn(newPub->n, pub.n->value, pub.n->valueLen), ret);
199     uint32_t bnBits = BN_Bits(newPub->n);
200     if (bnBits > PAILLIER_MAX_MODULUS_BITS || bnBits <= 0) {
201         ret = CRYPT_PAILLIER_ERR_KEY_BITS;
202         BSL_ERR_PUSH_ERROR(ret);
203         goto ERR;
204     }
205     GOTO_ERR_IF(BN_Bin2Bn(newPub->g, pub.g->value, pub.g->valueLen), ret);
206     GOTO_ERR_IF(BN_Bin2Bn(newPub->n2, pub.n2->value, pub.n2->valueLen), ret);
207 
208     GOTO_ERR_IF(CheckSquare(newPub->n2, newPub->n, pub.n->valueLen * 8), ret);
209 
210     PAILLIER_FREE_PUB_KEY(ctx->pubKey);
211     ctx->pubKey = newPub;
212     return ret;
213 ERR:
214     PAILLIER_FREE_PUB_KEY(newPub);
215     return ret;
216 }
217 
GetPrvBasicCheck(const CRYPT_PAILLIER_Ctx * ctx,BSL_Param * para,CRYPT_PaillierPrvParam * prv)218 static int32_t GetPrvBasicCheck(const CRYPT_PAILLIER_Ctx *ctx, BSL_Param *para, CRYPT_PaillierPrvParam *prv)
219 {
220     if (ctx == NULL || ctx->prvKey == NULL || para == NULL) {
221         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
222         return CRYPT_NULL_INPUT;
223     }
224     prv->n = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_N);
225     prv->lambda = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_LAMBDA);
226     prv->mu = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_MU);
227     prv->n2 = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_N2);
228     if (PARAMISNULL(prv->lambda) || PARAMISNULL(prv->mu)) {
229         BSL_ERR_PUSH_ERROR(CRYPT_PAILLIER_ERR_INPUT_VALUE);
230         return CRYPT_PAILLIER_ERR_INPUT_VALUE;
231     }
232     return CRYPT_SUCCESS;
233 }
234 
CRYPT_PAILLIER_GetPrvKey(const CRYPT_PAILLIER_Ctx * ctx,BSL_Param * para)235 int32_t CRYPT_PAILLIER_GetPrvKey(const CRYPT_PAILLIER_Ctx *ctx, BSL_Param *para)
236 {
237     CRYPT_PaillierPrvParam prv = {0};
238     int32_t ret = GetPrvBasicCheck(ctx, para, &prv);
239     if (ret != CRYPT_SUCCESS) {
240         return ret;
241     }
242 
243     prv.lambda->useLen = prv.lambda->valueLen;
244     GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->lambda, prv.lambda->value, &(prv.lambda->useLen)), ret);
245     prv.mu->useLen = prv.mu->valueLen;
246     GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->mu, prv.mu->value, &(prv.mu->useLen)), ret);
247     if (!PARAMISNULL(prv.n)) {
248         prv.n->useLen = prv.n->valueLen;
249         GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->n, prv.n->value, &(prv.n->useLen)), ret);
250     }
251     if (!PARAMISNULL(prv.n2)) {
252         prv.n2->useLen = prv.n2->valueLen;
253         GOTO_ERR_IF(BN_Bn2Bin(ctx->prvKey->n2, prv.n2->value, &(prv.n2->useLen)), ret);
254     }
255     return CRYPT_SUCCESS;
256 ERR:
257     if (!PARAMISNULL(prv.lambda) && prv.lambda->useLen != 0) {
258         BSL_SAL_CleanseData(prv.lambda->value, prv.lambda->useLen);
259         prv.lambda->useLen = 0;
260     }
261     if (!PARAMISNULL(prv.mu) && prv.mu->useLen != 0) {
262         BSL_SAL_CleanseData(prv.mu->value, prv.mu->useLen);
263         prv.mu->useLen = 0;
264     }
265     if (!PARAMISNULL(prv.n) && prv.n->useLen != 0) {
266         BSL_SAL_CleanseData(prv.n->value, prv.n->useLen);
267         prv.n->useLen = 0;
268     }
269     if (!PARAMISNULL(prv.n2) && prv.n2->useLen != 0) {
270         BSL_SAL_CleanseData(prv.n2->value, prv.n2->useLen);
271         prv.n2->useLen = 0;
272     }
273     return ret;
274 }
275 
GetPubBasicCheck(const CRYPT_PAILLIER_Ctx * ctx,BSL_Param * para,CRYPT_PaillierPubParam * pub)276 static int32_t GetPubBasicCheck(const CRYPT_PAILLIER_Ctx *ctx, BSL_Param *para, CRYPT_PaillierPubParam *pub)
277 {
278     if (ctx == NULL || ctx->pubKey == NULL || para == NULL) {
279         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
280         return CRYPT_NULL_INPUT;
281     }
282     pub->n = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_N);
283     pub->g = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_G);
284     pub->n2 = BSL_PARAM_FindParam(para, CRYPT_PARAM_PAILLIER_N2);
285     if (PARAMISNULL(pub->n) || PARAMISNULL(pub->g) || PARAMISNULL(pub->n2)) {
286         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
287         return CRYPT_NULL_INPUT;
288     }
289     return CRYPT_SUCCESS;
290 }
291 
CRYPT_PAILLIER_GetPubKey(const CRYPT_PAILLIER_Ctx * ctx,BSL_Param * para)292 int32_t CRYPT_PAILLIER_GetPubKey(const CRYPT_PAILLIER_Ctx *ctx, BSL_Param *para)
293 {
294     CRYPT_PaillierPubParam pub = {0};
295     int32_t ret = GetPubBasicCheck(ctx, para, &pub);
296     if (ret != CRYPT_SUCCESS) {
297         BSL_ERR_PUSH_ERROR(ret);
298         return ret;
299     }
300 
301     pub.g->useLen = pub.g->valueLen;
302     ret = BN_Bn2Bin(ctx->pubKey->g, pub.g->value, &(pub.g->useLen));
303     if (ret != CRYPT_SUCCESS) {
304         BSL_ERR_PUSH_ERROR(ret);
305         return ret;
306     }
307     pub.n->useLen = pub.n->valueLen;
308     ret = BN_Bn2Bin(ctx->pubKey->n, pub.n->value, &(pub.n->useLen));
309     if (ret != CRYPT_SUCCESS) {
310         BSL_ERR_PUSH_ERROR(ret);
311         return ret;
312     }
313     if (pub.n2 != NULL) {
314         pub.n2->useLen = pub.n2->valueLen;
315         ret = BN_Bn2Bin(ctx->pubKey->n2, pub.n2->value, &pub.n2->useLen);
316         if (ret != CRYPT_SUCCESS) {
317             BSL_ERR_PUSH_ERROR(ret);
318         }
319     }
320     return ret;
321 }
322 
CRYPT_PAILLIER_GetSecBits(const CRYPT_PAILLIER_Ctx * ctx)323 int32_t CRYPT_PAILLIER_GetSecBits(const CRYPT_PAILLIER_Ctx *ctx)
324 {
325     if (ctx == NULL) {
326         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
327         return 0;
328     }
329     int32_t bits = (int32_t)CRYPT_PAILLIER_GetBits(ctx);
330     return BN_SecBits(bits, -1);
331 }
332 
333 #endif /* HITLS_CRYPTO_PAILLIER */