SVACE: HEAP_LEAK, correct size in strncpy
[platform/core/security/tef-simulator.git] / ssflib / dep / cryptocore / source / base / cc_bignum.c
1 /**
2  * Copyright (c) 2006-2017 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 /**
18  * @file
19  * @author Jisoon Park
20  * @brief  Big number library
21  */
22
23
24 ////////////////////////////////////////////////////////////////////////////
25 // Include Header Files
26 ////////////////////////////////////////////////////////////////////////////
27 #include "cc_bignum.h"
28 #include "cc_fast_math.h"
29 ////////////////////////////////////////////////////////////////////////////
30 // Global Variables
31 ////////////////////////////////////////////////////////////////////////////
32 cc_u32                  DWD_Zero[2]     = {0, 0};
33 cc_u32                  DWD_One[2]      = {1, 0};
34
35 SDRM_BIG_NUM    _BN_Zero        = {0, 0, 2, DWD_Zero};
36 SDRM_BIG_NUM    _BN_One         = {0, 1, 2, DWD_One};
37
38 SDRM_BIG_NUM    *BN_Zero        = &_BN_Zero;
39 SDRM_BIG_NUM    *BN_One         = &_BN_One;
40
41 ////////////////////////////////////////////////////////////////////////////
42 // Local Functon Protypes
43 ////////////////////////////////////////////////////////////////////////////
44 int SDRM_DWD_Classical_REDC(cc_u32 *pdDest, cc_u32 DstLen, cc_u32 *pdModulus, cc_u32 ModLen);
45
46 #ifdef _OP64_NOTSUPPORTED
47
48 #define SDRM_HL(A)      (cc_u32)(((A) >> 16) & 0xffffu)
49 #define SDRM_LL(A)      (cc_u32)((A) & 0xffffu)
50 #define SDRM_LH(A)      (cc_u32)(((A) & 0xffffu) << 16)
51 #define NOT(A)          (~(A))
52
53 /*
54  * @fn          SDRM_DIGIT_Mul
55  * @brief       Double-width UINT32 Multiplication
56  *
57  * \n   Dest            [out]destination, 2-cc_u32-size array
58  * \n   Src1            [in]first element
59  * \n   Src2            [in]second element
60  *
61  * @return      void
62  */
63 void SDRM_DIGIT_Mul(cc_u32 *Dest, cc_u32 Src1, cc_u32 Src2)
64 {
65         cc_u32  Da, Db, R1, R0;
66
67         R1 = SDRM_HL(Src1) * SDRM_HL(Src2);
68         R0 = SDRM_LL(Src1) * SDRM_LL(Src2);
69
70         Da = SDRM_HL(Src1) * SDRM_LL(Src2);
71         Db = SDRM_LL(Src1) * SDRM_HL(Src2);
72
73         if ((Db += Da) < Da) {
74                 R1 += ((cc_u32)1) << 16;
75         }
76         if ((R0 += SDRM_LH(Db)) < SDRM_LH(Db)) {
77                 R1++;
78         }
79
80         Dest[0] = R0;
81         Dest[1] = R1 + SDRM_HL(Db);
82
83         return;
84 }
85
86 /*
87  * @fn          SDRM_DIGIT_Div
88  * @brief       Doublue-width DWROD Division
89  *
90  * \n   Src1            [in]upper-digit of dividend
91  * \n   Src2            [in]lower-digit of dividend
92  * \n   Div                     [in]divisor
93  */
94 cc_u32 SDRM_DIGIT_Div(cc_u32 Src1, cc_u32 Src2, cc_u32 Div)
95 {
96         cc_u32  Dq, Dr, Dx, Dy, Dt;
97
98         //      Estimate high half of quotient
99         Dq = Src1 / (SDRM_HL(Div) + 1);
100
101         //      Subtract the product of estimate and divisor from the dividend
102         Dr = Src1 - (SDRM_HL(Div) * Dq);
103         Dx = SDRM_HL(Dr);
104         Dy = SDRM_LH(Dr) + SDRM_HL(Src2);
105         if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy)
106         {
107                 Dx--;
108         }
109
110         //      Correct estimate
111         while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
112         {
113                 if((Dr -= Div) > NOT(Div))
114                 {
115                         Dx--;
116                 }
117                 Dq++;
118         }
119         Dt = SDRM_LH(Dq);
120
121         //      Estimate low half of quotient
122         Dq = Dr / (SDRM_HL(Div) + 1);
123
124         //      Subtract the product of estimate and divisor from the dividend
125         Dr -= SDRM_HL(Div) * Dq;
126         Dx = SDRM_HL(Dr);
127         Dy = SDRM_LH(Dr) + SDRM_LL(Src2);
128         if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy) {
129                 Dx--;
130         }
131
132         //      Correct estimate
133         while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
134         {
135                 if ((Dr -= Div) > NOT(Div))
136                 {
137                         Dx--;
138                 }
139                 Dq++;
140         }
141
142         return (Dt + Dq);
143 }
144
145 /*
146  * @fn          SDRM_DIGIT_Mod
147  * @brief       Doublue-width DWROD Modular
148  *
149  * \n   Src1            [in]upper-digit of dividend
150  * \n   Src2            [in]lower-digit of dividend
151  * \n   Div                     [in]divisor
152  */
153 cc_u32 SDRM_DIGIT_Mod(cc_u32 Src1, cc_u32 Src2, cc_u32 Div)
154 {
155         cc_u32  Dq, Dr, Dx, Dy;
156
157         //      Estimate high half of quotient
158         Dq = Src1 / (SDRM_HL(Div) + 1);
159
160         //      Subtract the from dividend the product of estimate and divisor
161         Dr = Src1 - (SDRM_HL(Div) * Dq);
162         Dx = SDRM_HL(Dr);
163         Dy = SDRM_LH(Dr) + SDRM_HL(Src2);
164         if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy)
165         {
166                 Dx--;
167         }
168
169         //      Correct estimate
170         while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
171         {
172                 if ((Dr -= Div) > NOT(Div))
173                 {
174                         Dx--;
175                 }
176         }
177
178         //      Estimate low half of quotient
179         Dq = Dr / (SDRM_HL(Div) + 1);
180
181         //      Subtract the from dividend the product of estimate and divisor
182         Dr -= SDRM_HL(Div) * Dq;
183         Dx = SDRM_HL(Dr);
184         Dy = SDRM_LH(Dr) + SDRM_LL(Src2);
185         if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy)
186         {
187                 Dx--;
188         }
189
190         //      Correct estimate
191         while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
192         {
193                 if ((Dr -= Div) > NOT(Div) )
194                 {
195                         Dx--;
196                 }
197         }
198
199         return Dr;
200 }
201
202 #endif //_OP64_NOTSUPPORTED
203
204 /*
205  * @fn          SDRM_DWD_Cmp
206  * @brief       cc_u32 Array Comparison
207  *
208  * @param       pdSrc1          [in]first element
209  * @param       dSrcLen1        [in]legnth of pdSrc1
210  * @param       pdSrc2          [in]second element
211  * @param       dSrcLen2        [in]legnth of pdSrc2
212  *
213  * @return      1 if pdSrc1 is larger than pdSrc2
214  * \n           0 if same
215  * \n           -1 if pdSrc2 is larger than pdSrc1
216  */
217 static int SDRM_DWD_Cmp(cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
218 {
219         cc_u32  i;
220
221         //When the length is different
222         if (dSrcLen1 >= dSrcLen2)
223         {
224                 for (i = dSrcLen1 - 1; i != dSrcLen2 - 1; i--)
225                 {
226                         if (pdSrc1[i])
227                         {
228                                 return +1;
229                         }
230                 }
231         }
232         else
233         {
234                 for (i = dSrcLen2 - 1; i != dSrcLen1 - 1; i--)
235                 {
236                         if (pdSrc2[i])
237                         {
238                                 return -1;
239                         }
240                 }
241         }
242
243         //Compare common digits
244         for (; i != (cc_u32)-1; i--)
245         {
246                 if (pdSrc1[i] == pdSrc2[i])
247                 {
248                         continue;
249                 }
250                 else
251                 {
252                         if (pdSrc1[i] > pdSrc2[i])
253                         {
254                                 return +1;
255                         }
256                         else
257                         {
258                                 return -1;
259                         }
260                 }
261         }
262
263         return 0;
264 }
265
266 /*
267  * @fn          SDRM_DWD_SHL
268  * @brief       Shift left the digit array
269  *
270  * @param       pdDest          [out]destination
271  * @param       pdSrc           [in]source
272  * @param       dSrcLen         [in]legnth of pdSrc
273  * @param       dNumOfShift     [in]shift amount
274  *
275  * @return      carry
276  */
277 static cc_u32 SDRM_DWD_SHL(cc_u32 *pdDest, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dNumOfShift)
278 {
279         cc_u32  i = dSrcLen - 1;
280         cc_u32  dRet;
281
282         if (dSrcLen == 0)
283         {
284                 *pdDest = 0;
285                 return 0;
286         }
287
288         dRet = pdSrc[i] >> (SDRM_BitsInDWORD - dNumOfShift);
289
290         for (; i != 0; i--)
291         {
292                 pdDest[i] = (pdSrc[i] << dNumOfShift) ^ (pdSrc[i - 1] >> (SDRM_BitsInDWORD - dNumOfShift));
293         }
294
295         pdDest[i] = pdSrc[i] << dNumOfShift;
296
297         return dRet;
298 }
299
300 /*
301  * @fn          SDRM_DWD_SHR
302  * @brief       Shift right the digit array
303  *
304  * @param       pdDest          [out]destination
305  * @param       pdSrc           [in]source
306  * @param       dSrcLen         [in]legnth of pdSrc
307  * @param       dNumOfShift     [in]shift amount
308  *
309  * @return      carry
310  */
311 static cc_u32 SDRM_DWD_SHR(cc_u32 *pdDest, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dNumOfShift)
312 {
313         cc_u32 i = 0;
314         cc_u32 dRet;
315
316         dRet = pdSrc[i] << (SDRM_BitsInDWORD - dNumOfShift);
317
318         for (; i < dSrcLen - 1; i++)
319         {
320                 pdDest[i] = (pdSrc[i] >> dNumOfShift) ^ (pdSrc[i + 1] << (SDRM_BitsInDWORD - dNumOfShift));
321         }
322
323         pdDest[i] = pdSrc[i] >> dNumOfShift;
324
325         return dRet;
326 }
327
328 /*
329  * @fn          SDRM_DWD_Add
330  * @brief       Add two digit array
331  *
332  * @param       pdDest          [out]destination
333  * @param       pdSrc1          [in]first element
334  * @param       dSrcLen1        [in]legnth of pdSrc1
335  * @param       pdSrc2          [in]second element
336  * @param       dSrcLen2        [in]legnth of pdSrc2
337  *
338  * @return      carry
339  */
340 static cc_u32 SDRM_DWD_Add(cc_u32 *pdDest, cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
341 {
342         cc_u32  i;
343         cc_u32  dCarry = 0, dTemp;
344
345         //add low digits
346         for (i = 0; i < dSrcLen2; i++)
347         {
348                 if ((pdSrc2[i] == ((cc_u32)-1)) && (dCarry))
349                 {
350                         pdDest[i] = pdSrc1[i];
351                 }
352                 else
353                 {
354                         dTemp = pdSrc2[i] + dCarry;
355                         pdDest[i] = pdSrc1[i] + dTemp;
356                         dCarry = (pdDest[i] < dTemp ) ? 1 : 0;
357                 }
358         }
359
360         //copy high digits
361         if (dSrcLen1 > i)
362         {
363                 memcpy(pdDest + i, pdSrc1 + i, (dSrcLen1 - i) * SDRM_SIZE_OF_DWORD);
364         }
365
366         //process carry
367         if (!dCarry)
368         {
369                 return 0;
370         }
371         else
372         {
373                 for (i = dSrcLen2; i < dSrcLen1; i++)
374                 {
375                         if (++pdDest[i])
376                         {
377                                 return 0;
378                         }
379                 }
380         }
381
382         return 1;
383 }
384
385 /*
386  * @fn          SDRM_DWD_Sub
387  * @brief       subtract digit array
388  *
389  * @param       pdDest          [out]destination
390  * @param       pdSrc1          [in]first element
391  * @param       dSrcLen1        [in]legnth of pdSrc1
392  * @param       pdSrc2          [in]second element
393  * @param       dSrcLen2        [in]legnth of pdSrc2
394  *
395  * @return      carry
396  */
397 static cc_u32 SDRM_DWD_Sub(cc_u32 *pdDest, cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
398 {
399         cc_u32  i;
400         cc_u32  dCarry = 0, dTemp;
401
402         //subtract low digits
403         for (i = 0; i < dSrcLen2; i++)
404         {
405                 if (pdSrc2[i] + dCarry == 0)
406                 {
407                         pdDest[i] = pdSrc1[i];
408                 }
409                 else
410                 {
411                         dTemp = pdSrc2[i] + dCarry;
412                         pdDest[i] = pdSrc1[i] - dTemp;
413                         dCarry = ((pdDest[i]) > ~(dTemp)) ? 1 : 0;
414                 }
415         }
416
417         //copy high digits
418         if (dSrcLen1 > i)
419         {
420                 memcpy(pdDest + i, pdSrc1 + i, (dSrcLen1 - i) * SDRM_SIZE_OF_DWORD);
421         }
422
423         //process carry
424         if (!dCarry)
425         {
426                 return 0;
427         }
428         else
429         {
430                 for (i = dSrcLen2  ; i < dSrcLen1; i++)
431                 {
432                         if (pdDest[i]--)
433                         {
434                                 return 0;
435                         }
436                 }
437         }
438
439         return (~0);
440 }
441
442 /*
443  * @fn          SDRM_DWD_MulAdd
444  * @brief       Add multiple
445  *
446  * @param       pdDest          [out]destination
447  * @param       dDstLen         [in]legnth of pbDest
448  * @param       pdSrc           [in]source
449  * @param       dSrcLen         [in]legnth of pdSrc
450  * @param       dMultiplier     [in]multiplier
451  *
452  * @return      carry
453  */
454 static cc_u32 SDRM_DWD_MulAdd(cc_u32 *pdDest, cc_u32 dDstLen, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dMultiplier)
455 {
456         cc_u32 i;
457         cc_u32 dTemp = 0;
458         cc_u64 pdDigit2;
459
460         //Multiplication part
461         for (i = 0; i < dSrcLen; i++)
462         {
463                 /*
464                 * Time code optimization. To be continue!
465                 */
466                 pdDigit2 =((cc_u64)pdSrc[i] * dMultiplier) + pdDest[i] + dTemp;
467         pdDest[i] = (cc_u32)pdDigit2;
468         dTemp = pdDigit2 >> 32;
469
470                 /*SDRM_DIGIT_Mul(pdDigit, dMultiplier, pdSrc[i]);
471                 if ((dTemp += pdDigit[0]) < pdDigit[0])
472                 {
473                         pdDigit[1]++;
474                 }
475
476                 if ((pdDest[i] += dTemp) < dTemp)
477                 {
478                         pdDigit[1]++;
479                 }
480
481                 dTemp = pdDigit[1];*/
482         }
483
484         if (i == dDstLen)
485         {
486                 return dTemp;
487         }
488
489         //process top digit
490         if ((pdDest[i] += dTemp) >= dTemp)
491         {
492                 return 0;
493         }
494
495         for (i++; i < dDstLen; i++)
496         {
497                 if ((++pdDest[i]) != 0)
498                 {
499                         return 0;
500                 }
501         }
502
503         return 1;
504 }
505
506 /*
507  * @fn          SDRM_DWD_MulSub
508  * @brief       Multiply and Subtract Digit Array
509  *
510  * @param       pdDest          [out]destination
511  * @param       dDstLen         [in]legnth of pbDest
512  * @param       pdSrc           [in]source
513  * @param       dSrcLen         [in]legnth of pdSrc
514  * @param       dMultiplier     [in]multiplier
515  *
516  * @return      carry
517  */
518 static cc_u32 SDRM_DWD_MulSub(cc_u32 *pdDest, cc_u32 dDstLen, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dMultiplier)
519 {
520         cc_u32  i;
521         cc_u32  pdDigit[2], dTemp = 0;
522
523         //Multiplication part
524         for (i = 0; i < dSrcLen; i++)
525         {
526                 SDRM_DIGIT_Mul(pdDigit, dMultiplier, pdSrc[i]);
527                 dTemp += pdDigit[0];
528
529                 if (dTemp < pdDigit[0])
530                 {
531                         pdDigit[1]++;
532                 }
533
534                 if (pdDest[i] < dTemp)
535                 {
536                         pdDigit[1]++;
537                 }
538
539                 pdDest[i] -= dTemp;
540                 dTemp = pdDigit[1];
541         }
542
543         if (i == dDstLen)
544         {
545                 return dTemp;
546         }
547
548         //process top digit
549         if (pdDest[i] >= dTemp)
550         {
551                 pdDest[i] -= dTemp;
552
553                 return 0;
554         }
555         else
556         {
557                 pdDest[i] -= dTemp;
558         }
559
560         for (i++; i < dDstLen; i++)
561         {
562                 if ((pdDest[i]--) != 0)
563                 {
564                         return 0;
565                 }
566         }
567
568         return 1;
569 }
570
571 /*
572  * @fn          SDRM_DWD_Mul
573  * @brief       Multiply tow Digit array
574  *
575  * @param       pdDest          [out]destination
576  * @param       pdSrc1          [in]first element
577  * @param       dSrcLen1        [in]legnth of pdSrc1
578  * @param       pdSrc2          [in]second element
579  * @param       dSrcLen2        [in]legnth of pdSrc2
580  *
581  * @return      void
582  */
583 static void SDRM_DWD_Mul(cc_u32 *pdDest, cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
584 {
585         cc_u32  i, j;
586         cc_u32  dTemp;
587         cc_u64 pdDigit2;
588
589         memset(pdDest, 0, (dSrcLen1 + dSrcLen2) * SDRM_SIZE_OF_DWORD);
590
591         for (j = 0; j < dSrcLen2; j++)
592         {
593                 dTemp = 0;
594                 for (i = 0; i < dSrcLen1; i++)
595                 {
596
597                         pdDigit2 =((cc_u64)pdSrc1[i] * pdSrc2[j]) + pdDest[i + j] + dTemp;
598             pdDest[i + j] = (cc_u32)pdDigit2;
599             dTemp = pdDigit2 >> 32;
600
601
602                         /*SDRM_DIGIT_Mul(pdDigit, pdSrc1[i], pdSrc2[j]);
603                         if ((dTemp += pdDigit[0]) < pdDigit[0])
604                         {
605                                 pdDigit[1]++;
606                         }
607
608                         if ((pdDest[i + j] += dTemp) < dTemp)
609                         {
610                                 pdDigit[1]++;
611                         }
612
613                         dTemp = pdDigit[1];*/
614                 }
615                 pdDest[i + j] = dTemp;
616         }
617 }
618
619 /*
620  * @fn          SDRM_DWD_Div
621  * @brief       Multiply tow Digit array
622  *
623  * @param       pdDest          [out]quotient
624  * @param       pdRem           [out]remainder
625  * @param       pdSrc1          [in]divisor
626  * @param       dSrcLen1        [in]legnth of pdSrc1
627  * @param       pdSrc2          [in]dividend
628  * @param       dSrcLen2        [in]legnth of pdSrc2
629  *
630  * @return      0 if reaminder is zero
631  * \n           1 otherwise
632  */
633 static cc_u32 SDRM_DWD_Div(cc_u32 *pdDest, cc_u32 *pdRem,
634                                                    cc_u32 *pdSrc1, cc_u32 dSrcLen1,
635                                                    cc_u32 *pdSrc2, cc_u32 dSrcLen2)
636 {
637         cc_u32  i, q, c, dNum_of_Shift = 0;
638         cc_u32  *C = (cc_u32*)malloc(SDRM_SIZE_OF_DWORD * 2 * (MAX2(dSrcLen1, dSrcLen2) + 2));
639
640         if (!C)
641         {
642                 return (cc_u32)CRYPTO_MEMORY_ALLOC_FAIL;
643         }
644
645         SDRM_DWD_Copy(C, pdSrc1, dSrcLen1);
646         C[dSrcLen1] = 0;
647         c = dSrcLen1 + 1;
648
649         //Remove lowest '0's
650         for (i = dSrcLen2 * SDRM_BitsInDWORD-1; !SDRM_CheckBitUINT32(pdSrc2, i); i--, dNum_of_Shift++);
651
652         if (dNum_of_Shift)
653         {
654                 SDRM_DWD_SHL(C, C, c, dNum_of_Shift);
655                 SDRM_DWD_SHL(pdSrc2, pdSrc2, dSrcLen2, dNum_of_Shift);
656         }
657
658         for (i = c-dSrcLen2 - 1; i != (cc_u32)-1; i--)
659         {
660                 if (C[dSrcLen2 + i]==pdSrc2[dSrcLen2 - 1] )
661                 {
662                         q = (cc_u32)-1;
663                 }
664                 else
665                 {
666                         q = SDRM_DIGIT_Div(C[dSrcLen2 + i], C[dSrcLen2 + i - 1], pdSrc2[dSrcLen2 - 1]);
667                 }
668
669                 if (SDRM_DWD_MulSub(C + i, dSrcLen2 + 1, pdSrc2, dSrcLen2, q) )
670                 {
671                         q--;
672                         if (!SDRM_DWD_Add(C + i, C + i, dSrcLen2 + 1, pdSrc2, dSrcLen2))
673                         {
674                                 q--;
675                                 SDRM_DWD_Add(C + i, C + i, dSrcLen2 + 1, pdSrc2, dSrcLen2);
676                         }
677                 }
678                 pdDest[i] = q;
679         }
680
681         //Recover lowest '0's
682         if (dNum_of_Shift)
683         {
684                 SDRM_DWD_SHR(pdSrc2, pdSrc2, dSrcLen2, dNum_of_Shift);
685                 SDRM_DWD_SHR(C, C, dSrcLen2, dNum_of_Shift);
686         }
687
688         if (pdRem)
689         {
690                 SDRM_DWD_Copy(pdRem, C, dSrcLen2);
691         }
692
693         for (i = 0; i < c; i++)
694         {
695                 if (C[i])
696                 {
697                         free(C);
698
699                         return 1;
700                 }
701         }
702         free(C);
703
704         return 0;
705 }
706
707 /*
708  * @fn          SDRM_DWD_Classical_REDC
709  * @brief       Classical Modular Reduction Algorithm
710  *
711  * @param       pdDest          [out]destination
712  * @param       DstLen          [in]length of pdDest
713  * @param       pdModulus       [in]modulus
714  * @param       ModLen          [in]legnth of pdModulus
715  *
716  * @return      CRYPTO_SUCCESS  if no error is occured
717  */
718 int SDRM_DWD_Classical_REDC(cc_u32 *pdDest, cc_u32 DstLen, cc_u32 *pdModulus, cc_u32 ModLen)
719 {
720         cc_u32  i;
721         cc_u32  MSB=0, TTTT=0, FLAG=0, D_Quotient, MSD_Modulus;
722
723         if (DstLen < ModLen)
724         {
725                 return CRYPTO_SUCCESS;
726         }
727
728         if (pdDest[DstLen - 1] >= pdModulus[ModLen - 1])
729         {
730                 FLAG++;
731                 TTTT = pdDest[DstLen];
732                 pdDest[DstLen++] = 0;
733         }
734
735         for (i = SDRM_BitsInDWORD - 1; i != (cc_u32)-1; i--)
736         {
737                 if (pdModulus[ModLen - 1] & ((cc_u32)1 << i))
738                 {
739                         break;
740                 }
741
742                 MSB++;
743         }
744
745         if (MSB)
746         {
747                 SDRM_DWD_SHL(pdModulus, pdModulus, ModLen, MSB);
748                 SDRM_DWD_SHL(pdDest, pdDest, DstLen, MSB);
749         }
750
751         //      Step 2 : main part
752         MSD_Modulus = pdModulus[ModLen - 1];
753         for (i = DstLen - ModLen - 1; i != (cc_u32)-1; i--)
754         {
755                 //      Step 2-1 : Estimate D_Quotient
756                 if (pdDest[ModLen + i] == MSD_Modulus)
757                 {
758                         D_Quotient = (cc_u32)-1;
759                 }
760                 else
761                 {
762                         D_Quotient = SDRM_DIGIT_Div(pdDest[ModLen + i], pdDest[ModLen + i - 1], MSD_Modulus);
763                 }
764
765                 //      Step 2-2 : Make pdDest <- pdDest-D_Quotient*pdModulus
766                 if (SDRM_DWD_MulSub(pdDest + i, ModLen + 1, pdModulus, ModLen, D_Quotient) )
767                 {
768                         if (SDRM_DWD_Add(pdDest + i, pdDest + i, ModLen + 1, pdModulus, ModLen) == 0)
769                         {
770                                 SDRM_DWD_Add(pdDest + i, pdDest + i, ModLen + 1, pdModulus, ModLen);
771                         }
772                 }
773         }
774
775         //      Step 4 : inverse part of Step 2
776         if (MSB)
777         {
778                 SDRM_DWD_SHR(pdModulus, pdModulus, ModLen, MSB);
779                 SDRM_DWD_SHR(pdDest, pdDest, ModLen, MSB);
780         }
781
782         //      Step 4.5 : inverse part of Step 1.5
783         if (FLAG)
784         {
785                 DstLen--;
786                 pdDest[DstLen] = TTTT;
787         }
788
789         return CRYPTO_SUCCESS;
790 }
791
792 /*
793  * @fn          SDRM_DIGIT_Gcd
794  * @brief       get gcd of two digits
795  *
796  * @param       s1                                      [in]first element
797  * @param       s2                                      [in]second element
798  *
799  * @return      gcd
800  */
801 cc_u32 SDRM_DIGIT_Gcd(cc_u32 s1, cc_u32 s2)
802  {
803         cc_u32 dTemp;
804
805         if (s1 < s2)
806         {
807                 dTemp = s1;
808                 s1 = s2;
809                 s2 = dTemp;
810         }
811
812         while(s2)
813         {
814                 dTemp = s1 % s2;
815                 s1 = s2;
816                 s2 = dTemp;
817         }
818
819         return s1;
820 }
821
822 /*
823  * @fn          SDRM_PrintBN
824  * @brief       Show out a Big Number
825  *
826  * @param       level           [in]log level
827  * @param       s                       [in]title
828  * @param       bn                      [in]big number to show out
829  *
830  * @return      void
831  */
832 void SDRM_PrintBN(const char* s, SDRM_BIG_NUM* bn)
833 {
834         cc_u32 i;
835         if(bn->sign == 0) {
836                 printf("%15s %d :", s, (int)(bn->Length));
837         }
838         else {
839                 printf("%15s-%d :", s, (int)(bn->Length));
840         }
841         for (i = 0; i < bn->Length ; i++)
842         {
843                 printf("%08x ", (int)(bn->pData[bn->Length - i -1]));
844         }
845
846         printf("\n");
847
848         return;
849 }
850
851 /*
852  * @fn          SDRM_BN2OS
853  * @brief       Convert Big Number to Octet String
854  *
855  * @param       BN_Src  [in]source integer
856  * @param       dDstLen [in]Byte-length of pbDst
857  * @param       pbDst   [out]output octet string
858  *
859  * @return      CRYPTO_SUCCESS  if no error is occured
860  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if arrary is too small
861  */
862 int     SDRM_BN2OS(SDRM_BIG_NUM *BN_Src, cc_u32 dDstLen, cc_u8 *pbDst)
863 {
864         cc_u32  i;
865
866         if ((BN_Src == NULL) || (pbDst == NULL))
867         {
868                 return CRYPTO_NULL_POINTER;
869         }
870
871         SDRM_BN_OPTIMIZE_LENGTH(BN_Src);
872
873         if (BN_Src->sign)
874         {
875                 pbDst[0] = '-';
876                 dDstLen += 1;
877         }
878
879         if ((SDRM_SIZE_OF_DWORD * BN_Src->Length) <= dDstLen)
880         {
881                 memset(pbDst, 0, dDstLen);
882
883                 for (i = 0; (dDstLen != 0) && (i < BN_Src->Length); i++)
884                 {
885                         pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]    ) & 0xff);
886                         pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>> 8) & 0xff);
887                         pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>16) & 0xff);
888                         pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>24) & 0xff);
889                 }
890         }
891         else
892         {
893                 i = (SDRM_SIZE_OF_DWORD * BN_Src->Length) - dDstLen;
894                 if (i >= SDRM_SIZE_OF_DWORD)
895                 {
896                         return CRYPTO_BUFFER_TOO_SMALL;
897                 }
898                 else if ( BN_Src->pData[BN_Src->Length - 1] >> (8 * (SDRM_SIZE_OF_DWORD - i)))
899                 {
900                         return CRYPTO_BUFFER_TOO_SMALL;
901                 }
902
903                 for (i = 0;; i++)
904                 {
905                         pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]    ) & 0xff);
906                         if (dDstLen == 0)
907                         {
908                                 break;
909                         }
910
911                         pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>> 8) & 0xFF);
912                         if (dDstLen == 0)
913                         {
914                                 break;
915                         }
916
917                         pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>16) & 0xFF);
918                         if (dDstLen == 0)
919                         {
920                                 break;
921                         }
922
923                         pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>24) & 0xFF);
924                         if (dDstLen == 0)
925                         {
926                                 break;
927                         }
928                 }
929         }
930
931         return CRYPTO_SUCCESS;
932 }
933
934 /*
935  * @fn          SDRM_OS2BN
936  * @brief       Convert Octet String to Big Number
937  *
938  * @param       pbSrc   [in]source octet string
939  * @param       dSrcLen [in]Byte-length of pbSrc
940  * @param       BN_Dst  [out]output big number
941  *
942  * @return      CRYPTO_SUCCESS  if no error is occured
943  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if arrary is too small
944  */
945 int     SDRM_OS2BN(cc_u8 *pbSrc, cc_u32 dSrcLen, SDRM_BIG_NUM *BN_Dst)
946 {
947         cc_u32  i;
948         int             ret;
949
950         if ((pbSrc == NULL) || (BN_Dst == NULL))
951         {
952                 return CRYPTO_INVALID_ARGUMENT;
953         }
954
955         SDRM_BN_Clr(BN_Dst);
956
957         for (i = 0; i < dSrcLen; i++)
958         {
959                 ret = SDRM_BN_SHL(BN_Dst, BN_Dst, 8);
960
961                 if (ret != CRYPTO_SUCCESS)
962                 {
963                         return ret;
964                 }
965
966                 BN_Dst->pData[0] ^= pbSrc[i];
967                 if (BN_Dst->Length == 0) {
968                         BN_Dst->Length = 1;
969                 }
970         }
971
972         return CRYPTO_SUCCESS;
973 }
974
975 /*
976  * @fn          SDRM_I2OSP
977  * @brief       Converts a nonnonegative integer to an octet string of a specified length
978  *
979  * @param       BN_Src                                  [in]nonnegative integer to be converted
980  * @param       dDstLen                                 [in]intended length of the resulting octet string
981  * @param       pbDst                                   [out]corresponding octet string of length dDstLen
982  *
983  * @return      CRYPTO_SUCCESS                  if no error is occured
984  */
985 int     SDRM_I2OSP(SDRM_BIG_NUM *BN_Src, cc_u32 dDstLen, cc_u8 *pbDst)
986 {
987         int count;
988
989         SDRM_BN_OPTIMIZE_LENGTH(BN_Src);
990
991         count = 0;
992         for (dDstLen--; (int)dDstLen >= 0; dDstLen--)
993         {
994                 pbDst[count++] = SDRM_CheckByteUINT32(BN_Src->pData, dDstLen);
995         }
996
997         return CRYPTO_SUCCESS;
998 }
999
1000 /*
1001  * @fn          SDRM_BN_Clr
1002  * @brief       Clear the SDRM_BIG_NUM structure
1003  *
1004  * @param       BN_Src          [in]source
1005  *
1006  * @return      CRYPTO_SUCCESS
1007  */
1008 int SDRM_BN_Clr(SDRM_BIG_NUM* BN_Src)
1009 {
1010         BN_Src->sign = 0;
1011         BN_Src->Length = 0;
1012
1013         memset(BN_Src->pData, 0, BN_Src->Size * SDRM_SIZE_OF_DWORD);
1014
1015         return CRYPTO_SUCCESS;
1016 }
1017
1018 /*
1019  * @fn          SDRM_BN_Copy
1020  * @brief       copy SDRM_BIG_NUM
1021  *
1022  * @param       BN_Dest         [out]destination
1023  * @param       BN_Src          [in]source
1024  *
1025  * @return      CRYPTO_SUCCESS
1026  */
1027 int SDRM_BN_Copy(SDRM_BIG_NUM* BN_Dest, SDRM_BIG_NUM* BN_Src)
1028 {
1029         if (BN_Src->Length > BN_Dest->Size)
1030         {
1031                 return CRYPTO_BUFFER_TOO_SMALL;
1032         }
1033
1034         BN_Dest->sign = BN_Src->sign;
1035         BN_Dest->Length = BN_Src->Length;
1036
1037         memcpy(BN_Dest->pData, BN_Src->pData, BN_Src->Length * SDRM_SIZE_OF_DWORD);
1038
1039         return CRYPTO_SUCCESS;
1040 }
1041
1042 /*
1043  * @fn          SDRM_BN_Alloc
1044  * @brief       allocate big number from buffer
1045  *
1046  * @param       pbSrc           [in]start pointer of buffer
1047  * @param       dSize           [in]buffer size of big number
1048  *
1049  * @return      pointer of SDRM_BIG_NUM structure
1050  */
1051 SDRM_BIG_NUM *SDRM_BN_Alloc(cc_u8* pbSrc, cc_u32 dSize)
1052 {
1053         SDRM_BIG_NUM    *BN_Dest = (SDRM_BIG_NUM*)(void*)pbSrc;
1054
1055         if (pbSrc == NULL)
1056         {
1057                 return NULL;
1058         }
1059
1060         memset(BN_Dest, 0, sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD);
1061         BN_Dest->pData = (cc_u32*)(void*)(pbSrc + sizeof(SDRM_BIG_NUM));
1062         BN_Dest->Size = dSize;
1063         BN_Dest->Length = 0;
1064
1065         return BN_Dest;
1066 }
1067
1068 /*
1069  * @fn          SDRM_BN_Init
1070  * @brief       Allocate a new big number object
1071  *
1072  * @param       dSize           [in]buffer size of big number
1073  *
1074  * @return      pointer of SDRM_BIG_NUM structure
1075  * \n           NULL if memory allocation is failed
1076  */
1077 SDRM_BIG_NUM *SDRM_BN_Init(cc_u32 dSize)
1078 {
1079         cc_u32                  AllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1080         cc_u8                   *pbBuf = (cc_u8*)malloc(AllocSize);
1081         SDRM_BIG_NUM    *BN_Src = (SDRM_BIG_NUM*)(void*)pbBuf;
1082         if (BN_Src == NULL)
1083         {
1084                 return NULL;
1085         }
1086
1087         memset(BN_Src, 0, AllocSize);
1088         BN_Src->pData = (cc_u32*)(void*)(pbBuf + sizeof(SDRM_BIG_NUM));
1089         BN_Src->Size = dSize;
1090
1091         return BN_Src;
1092 }
1093
1094 /*
1095  * @fn          SDRM_BN_Cmp
1096  * @brief       Compare two Big Number
1097  *
1098  * @param       BN_Src1         [in]first element
1099  * @param       BN_Src2         [in]second element
1100  *
1101  * @return      1 if BN_Src1 is larger than pdSrc2
1102  * \n           0 if same
1103  * \n           -1 if BN_Src2 is larger than pdSrc1
1104  */
1105 int SDRM_BN_Cmp(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
1106 {
1107         if (BN_Src1->Length >= BN_Src2->Length)
1108         {
1109                 return  SDRM_DWD_Cmp(BN_Src1->pData, BN_Src1->Length, BN_Src2->pData, BN_Src2->Length);
1110         }
1111         else
1112         {
1113                 return -SDRM_DWD_Cmp(BN_Src2->pData, BN_Src2->Length, BN_Src1->pData, BN_Src1->Length);
1114         }
1115 }
1116
1117 /*
1118  * @fn          SDRM_BN_Cmp_sign
1119  * @brief       Compare two Big Number considering sign
1120  *
1121  * @param       BN_Src1         [in]first element
1122  * @param       BN_Src2         [in]second element
1123  *
1124  * @return      1 if BN_Src1 is larger than pdSrc2
1125  * \n           0 if same
1126  * \n           -1 if BN_Src2 is larger than pdSrc1
1127  */
1128 int SDRM_BN_Cmp_sign(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
1129 {
1130         if (BN_Src1->sign > BN_Src2->sign)
1131         {
1132                 return -1;
1133         }
1134         else if (BN_Src1->sign < BN_Src2->sign)
1135         {
1136                 return 1;
1137         }
1138
1139         if ( BN_Src1->Length >= BN_Src2->Length )
1140         {
1141                 return  SDRM_DWD_Cmp(BN_Src1->pData, BN_Src1->Length, BN_Src2->pData, BN_Src2->Length);
1142         }
1143         else
1144         {
1145                 return -SDRM_DWD_Cmp(BN_Src2->pData, BN_Src2->Length, BN_Src1->pData, BN_Src1->Length);
1146         }
1147 }
1148
1149 /*
1150  * @fn          SDRM_BN_Rand
1151  * @brief       Generate simple random number
1152  *
1153  * @param       BN_Dst          [out]destination
1154  * @param       BitLen          [in]bit-length of generated random number
1155  *
1156  * @return      CRYPTO_SUCCESS if no error is occured
1157  */
1158 int SDRM_BN_Rand(SDRM_BIG_NUM *BN_Dst, cc_u32 BitLen)
1159 {
1160         cc_u32  i, j;
1161
1162         SDRM_BN_Clr(BN_Dst);
1163
1164         for (i = 0; i < (BitLen / SDRM_BitsInDWORD); i++)
1165         {
1166                 BN_Dst->pData[i] = rand() ^ (rand() << 11);
1167         }
1168
1169         j = BitLen % SDRM_BitsInDWORD;
1170         if (j)
1171         {
1172                 BN_Dst->pData[i] = rand() ^ (rand() << 11);
1173                 BN_Dst->pData[i] &= (((cc_u32)1) << j) - 1;
1174                 i++;
1175         }
1176
1177         BN_Dst->Length = ((BitLen - 1) / SDRM_BitsInDWORD) + 1;
1178
1179         SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1180
1181         return CRYPTO_SUCCESS;
1182 }
1183
1184 /*
1185  * @fn          SDRM_BN_SHL
1186  * @brief       Big Number Shift Left
1187  *
1188  * @param       BN_Dst          [out]destination
1189  * @param       BN_Src          [in]source
1190  * @param       NumOfShift      [in]shift amount
1191  *
1192  * @return      CRYPTO_SUCCESS if no error occured
1193  */
1194 int SDRM_BN_SHL(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, cc_u32 NumOfShift)
1195 {
1196         cc_u32  t;
1197
1198         if (!BN_Src->Length)
1199         {
1200                 SDRM_BN_Copy(BN_Dst, BN_Zero);
1201                 return CRYPTO_SUCCESS;
1202         }
1203
1204         BN_Dst->sign = BN_Src->sign;
1205
1206         t = NumOfShift % SDRM_BitsInDWORD;
1207         if (t)
1208         {
1209                 BN_Dst->Length = BN_Src->Length;
1210                 t = SDRM_DWD_SHL(BN_Dst->pData, BN_Src->pData, BN_Src->Length, t);
1211                 if (t)
1212                 {
1213                         BN_Dst->pData[BN_Dst->Length++] = t;
1214                 }
1215         }
1216         else
1217         {
1218                 SDRM_BN_Copy(BN_Dst, BN_Src);
1219         }
1220
1221         t = NumOfShift / SDRM_BitsInDWORD;
1222         if (t)
1223         {
1224                 BN_Dst->Length += t;
1225
1226                 memmove((BN_Dst->pData) + t, BN_Dst->pData, (BN_Dst->Length - t) * SDRM_SIZE_OF_DWORD);
1227
1228                 memset(BN_Dst->pData, 0, t * SDRM_SIZE_OF_DWORD);
1229         }
1230
1231         SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1232
1233         return CRYPTO_SUCCESS;
1234 }
1235
1236 /*
1237  * @fn          SDRM_BN_SHR
1238  * @brief       Big Number Shift Right
1239  *
1240  * @param       BN_Dst          [out]destination
1241  * @param       BN_Src          [in]source
1242  * @param       NumOfShift      [in]shift amount
1243  *
1244  * @return      CRYPTO_SUCCESS if no error occured
1245  */
1246 int SDRM_BN_SHR(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, cc_u32 NumOfShift)
1247 {
1248         cc_u32  t;
1249
1250         if (!BN_Src->Length)
1251         {
1252                 SDRM_BN_Copy(BN_Dst, BN_Src);
1253                 return CRYPTO_SUCCESS;
1254         }
1255
1256         t = NumOfShift / SDRM_BitsInDWORD;
1257         if (t)
1258         {
1259                 if (t >= BN_Src->Length)
1260                 {
1261                         SDRM_BN_Copy(BN_Dst, BN_Zero);
1262                         return CRYPTO_SUCCESS;
1263                 }
1264
1265                 memcpy(BN_Dst->pData, (BN_Src->pData) + t, (BN_Src->Length - t) * SDRM_SIZE_OF_DWORD);
1266
1267                 BN_Dst->Length = BN_Src->Length - t;
1268                 BN_Dst->sign = BN_Src->sign;
1269                 SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1270         }
1271         else
1272         {
1273                 SDRM_BN_Copy(BN_Dst, BN_Src);
1274         }
1275
1276         t = NumOfShift % SDRM_BitsInDWORD;
1277         if (t)
1278         {
1279                 SDRM_DWD_SHR(BN_Dst->pData, BN_Dst->pData, BN_Dst->Length, t);
1280         }
1281
1282         SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1283
1284         return CRYPTO_SUCCESS;
1285 }
1286
1287 /*
1288  * @fn          SDRM_BN_Add
1289  * @brief       Big Number Addition
1290  *
1291  * @param       BN_Dst          [out]destination
1292  * @param       BN_Src1         [in]first element
1293  * @param       BN_Src2         [in]second element
1294  *
1295  * @return      CRYPTO_SUCCESS                          if no error occured
1296  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
1297  */
1298 int SDRM_BN_Add(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
1299 {
1300         cc_u32                  carry, dSize, dAllocSize;
1301         SDRM_BIG_NUM    *temp, *temp_Src1, *temp_Src2;
1302         cc_u8                   *pbBuf;
1303
1304         dSize = MAX2(BN_Src1->Size, BN_Src2->Size);
1305         dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1306
1307         pbBuf = (cc_u8*)malloc(dAllocSize * 2);
1308
1309         if (!pbBuf)
1310         {
1311                 return CRYPTO_MEMORY_ALLOC_FAIL;
1312         }
1313
1314         temp_Src1 = SDRM_BN_Alloc(pbBuf, dSize);
1315         temp_Src2 = SDRM_BN_Alloc(pbBuf + dAllocSize, dSize);
1316
1317         if (!BN_Src1->Length)
1318         {
1319                 SDRM_BN_Copy(BN_Dst, BN_Src2);
1320                 free(pbBuf);
1321
1322                 return CRYPTO_SUCCESS;
1323         }
1324
1325         if (!BN_Src2->Length) {
1326                 SDRM_BN_Copy(BN_Dst, BN_Src1);
1327                 free(pbBuf);
1328
1329                 return CRYPTO_SUCCESS;
1330         }
1331
1332         SDRM_BN_Copy(temp_Src1, BN_Src1);
1333         SDRM_BN_Copy(temp_Src2, BN_Src2);
1334
1335         if (temp_Src1->sign ^ temp_Src2->sign)
1336         {
1337                 if (temp_Src1->sign)
1338                 {
1339                         temp = temp_Src1;
1340                         temp_Src1 = temp_Src2;
1341                         temp_Src2 = temp;
1342                 }
1343
1344                 if (SDRM_BN_Cmp(temp_Src1, temp_Src2) < 0)
1345                 {
1346                         SDRM_DWD_Sub(BN_Dst->pData, temp_Src2->pData, temp_Src2->Length, temp_Src1->pData, temp_Src1->Length);
1347                         BN_Dst->sign = 1;
1348                         BN_Dst->Length = temp_Src2->Length;
1349                 }
1350                 else
1351                 {
1352                         SDRM_DWD_Sub(BN_Dst->pData, temp_Src1->pData, temp_Src1->Length, temp_Src2->pData, temp_Src2->Length);
1353                         BN_Dst->sign = 0;
1354                         BN_Dst->Length = temp_Src1->Length;
1355                 }
1356
1357                 free(pbBuf);
1358
1359                 return CRYPTO_SUCCESS;
1360         }
1361
1362         if (temp_Src1->sign)
1363         {
1364                 BN_Dst->sign = 1;
1365         }
1366         else
1367         {
1368                 BN_Dst->sign = 0;
1369         }
1370
1371         if (temp_Src1->Length > temp_Src2->Length)
1372         {
1373                 BN_Dst->Length = temp_Src1->Length;
1374                 carry = SDRM_DWD_Add(BN_Dst->pData, temp_Src1->pData, temp_Src1->Length, temp_Src2->pData, temp_Src2->Length);
1375                 if (carry)
1376                 {
1377                         BN_Dst->pData[BN_Dst->Length++] = carry;
1378                 }
1379         }
1380         else
1381         {
1382                 BN_Dst->Length = temp_Src2->Length;
1383                 carry = SDRM_DWD_Add(BN_Dst->pData, temp_Src2->pData, temp_Src2->Length, temp_Src1->pData, temp_Src1->Length);
1384                 if ( carry )
1385                 {
1386                         BN_Dst->pData[BN_Dst->Length++] = carry;
1387                 }
1388         }
1389
1390         SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1391
1392         free(pbBuf);
1393
1394         return CRYPTO_SUCCESS;
1395 }
1396
1397 /*
1398  * @fn          SDRM_BN_Sub
1399  * @brief       Big Number Subtraction
1400  *
1401  * @param       BN_Dst          [out]destination
1402  * @param       BN_Src1         [in]first element
1403  * @param       BN_Src2         [in]second element
1404  *
1405  * @return      CRYPTO_SUCCESS if no error occured
1406  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
1407  */
1408 int SDRM_BN_Sub(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
1409 {
1410         int                             i, add = 0, dSize, dAllocSize;
1411         SDRM_BIG_NUM    *temp, *temp_Src1, *temp_Src2;
1412         cc_u8                   *pbBuf;
1413
1414         dSize = MAX2(BN_Src1->Size, BN_Src2->Size);
1415         dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1416         pbBuf = (cc_u8*)malloc(dAllocSize * 2);
1417
1418         if (!pbBuf)
1419         {
1420                 return CRYPTO_MEMORY_ALLOC_FAIL;
1421         }
1422
1423         temp_Src1 = SDRM_BN_Alloc(pbBuf, dSize);
1424         temp_Src2 = SDRM_BN_Alloc(pbBuf + dAllocSize, dSize);
1425
1426         SDRM_BN_Copy(temp_Src1, BN_Src1);
1427         SDRM_BN_Copy(temp_Src2, BN_Src2);
1428
1429         if (BN_Src1 == BN_Src2)
1430         {
1431                 SDRM_BN_Clr(BN_Dst);
1432                 free(pbBuf);
1433
1434                 return CRYPTO_SUCCESS;
1435         }
1436
1437         //to process sign
1438         if (temp_Src1->sign)
1439         {
1440                 if (temp_Src2->sign)
1441                 {
1442                         temp = temp_Src1;
1443                         temp_Src1 = temp_Src2;
1444                         temp_Src2 = temp;
1445                 }
1446                 else
1447                 {
1448                         add = 1;
1449                         temp_Src2->sign = 1;
1450                 }
1451         }
1452         else
1453         {
1454                 if (temp_Src2->sign)
1455                 {
1456                         add = 1;
1457                         temp_Src2->sign = 0;
1458                 }
1459         }
1460
1461         if (add)
1462         {
1463                 i = (temp_Src1->Length | temp_Src2->Length) +1;
1464                 if (i)
1465                 {
1466                         SDRM_BN_Add(BN_Dst, temp_Src1, temp_Src2);
1467                 }
1468                 else
1469                 {
1470                         SDRM_BN_Add(BN_Dst, temp_Src2, temp_Src1);
1471                 }
1472
1473                 free(pbBuf);
1474
1475                 return CRYPTO_SUCCESS;
1476         }
1477
1478         if (SDRM_BN_Cmp(temp_Src1, temp_Src2) < 0)
1479         {
1480                 SDRM_DWD_Sub(BN_Dst->pData, temp_Src2->pData, temp_Src2->Length, temp_Src1->pData, temp_Src1->Length);
1481                 BN_Dst->sign = 1;
1482                 BN_Dst->Length = temp_Src2->Length;
1483         }
1484         else
1485         {
1486                 SDRM_DWD_Sub(BN_Dst->pData, temp_Src1->pData, temp_Src1->Length, temp_Src2->pData, temp_Src2->Length);
1487                 BN_Dst->sign = 0;
1488                 BN_Dst->Length = temp_Src1->Length;
1489         }
1490         SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1491
1492         free(pbBuf);
1493
1494         return CRYPTO_SUCCESS;
1495 }
1496
1497 /*
1498  * @fn          SDRM_BN_Mul
1499  * @brief       Big Number Multiplication
1500  *
1501  * @param       BN_Dst                  [out]destination
1502  * @param       BN_Multiplicand [in]first element
1503  * @param       BN_Multiplier   [in]second element
1504  *
1505  * @return      CRYPTO_SUCCESS if no error occured
1506  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
1507  */
1508 int SDRM_BN_Mul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Multiplicand, SDRM_BIG_NUM *BN_Multiplier)
1509 {
1510         SDRM_BIG_NUM    *Dst;
1511
1512         if ((BN_Multiplicand->Length == 0) || (BN_Multiplier->Length == 0))
1513         {
1514                 SDRM_BN_Clr(BN_Dst);
1515                 return CRYPTO_SUCCESS;
1516         }
1517
1518         Dst = SDRM_BN_Init(BN_Dst->Size * 2);
1519         if (Dst == NULL)
1520         {
1521                 return CRYPTO_MEMORY_ALLOC_FAIL;
1522         }
1523
1524         Dst->Length = BN_Multiplicand->Length + BN_Multiplier->Length;
1525
1526         if (BN_Multiplicand->sign != BN_Multiplier->sign)
1527         {
1528                 Dst->sign = 1;
1529         }
1530         else
1531         {
1532                 Dst->sign = 0;
1533         }
1534
1535         if (BN_Multiplicand->Length > BN_Multiplier->Length)
1536         {
1537                 SDRM_DWD_Mul(Dst->pData, BN_Multiplicand->pData, BN_Multiplicand->Length, BN_Multiplier->pData, BN_Multiplier->Length);
1538         }
1539         else
1540         {
1541                 SDRM_DWD_Mul(Dst->pData, BN_Multiplier->pData, BN_Multiplier->Length, BN_Multiplicand->pData, BN_Multiplicand->Length);
1542         }
1543
1544         SDRM_BN_OPTIMIZE_LENGTH(Dst);
1545
1546         SDRM_BN_Copy(BN_Dst, Dst);
1547         SDRM_BN_FREE(Dst);
1548
1549         return CRYPTO_SUCCESS;
1550 }
1551
1552 /*
1553  * @fn          SDRM_BN_Div
1554  * @brief       Big Number Division
1555  *
1556  * @param       BN_Quotient             [out]quotient
1557  * @param       BN_Remainder    [out]remainder
1558  * @param       BN_Dividend             [in]dividend
1559  * @param       BN_Divisor              [in]divisor
1560  *
1561  * @return      CRYPTO_SUCCESS if no error occured
1562  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
1563  */
1564 int SDRM_BN_Div(SDRM_BIG_NUM *BN_Quotient, SDRM_BIG_NUM *BN_Remainder, SDRM_BIG_NUM *BN_Dividend, SDRM_BIG_NUM *BN_Divisor)
1565 {
1566         cc_u32                  tmp, dSize, dAllocSize;
1567         SDRM_BIG_NUM    *temp_Dividend, *temp_Divisor;
1568         cc_u32                  *bnTmp;
1569         cc_u8                   *pbBuf;
1570
1571         if (BN_Quotient != NULL)
1572         {
1573                 dSize = MAX2(BN_Quotient->Size, BN_Dividend->Size);
1574         }
1575         else
1576         {
1577                 dSize = BN_Dividend->Size;
1578         }
1579
1580         dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1581         pbBuf = (cc_u8*)malloc(dAllocSize * 3 + 2 * SDRM_SIZE_OF_DWORD);
1582         if (!pbBuf)
1583         {
1584                 return CRYPTO_MEMORY_ALLOC_FAIL;
1585         }
1586
1587         temp_Dividend   = SDRM_BN_Alloc(pbBuf, dSize);
1588         temp_Divisor    = SDRM_BN_Alloc(pbBuf + dAllocSize, dSize);
1589         bnTmp = (cc_u32*)(void*)(pbBuf + dSize + dAllocSize);
1590
1591         SDRM_BN_Copy(temp_Dividend, BN_Dividend);
1592         SDRM_BN_Copy(temp_Divisor, BN_Divisor);
1593
1594         if (SDRM_BN_Cmp(temp_Dividend, temp_Divisor) < 0)
1595         {
1596                 if (BN_Remainder != NULL)
1597                 {
1598                         SDRM_BN_Copy(BN_Remainder, temp_Dividend);
1599                         //free(pbBuf);
1600                         //return CRYPTO_SUCCESS; modify by Chalyi Aleksandr: it is not correct
1601                 }
1602
1603                 if (BN_Quotient != NULL)
1604                 {
1605                         SDRM_BN_Clr(BN_Quotient);
1606                 }
1607                 free(pbBuf);
1608
1609                 return CRYPTO_SUCCESS;
1610         }
1611
1612         if (BN_Quotient == NULL)
1613         {
1614                 BN_Remainder->Length = temp_Divisor->Length;
1615                 tmp = SDRM_DWD_Div(bnTmp, BN_Remainder->pData, temp_Dividend->pData, temp_Dividend->Length, temp_Divisor->pData, temp_Divisor->Length);
1616                 SDRM_BN_OPTIMIZE_LENGTH(BN_Remainder);
1617                 BN_Remainder->sign = BN_Dividend->sign;
1618         }
1619         else if (BN_Remainder == NULL)
1620         {
1621                 BN_Quotient->Length = temp_Dividend->Length - temp_Divisor->Length + 1;
1622                 tmp = SDRM_DWD_Div(BN_Quotient->pData, bnTmp, temp_Dividend->pData, temp_Dividend->Length, temp_Divisor->pData, temp_Divisor->Length);
1623                 SDRM_BN_OPTIMIZE_LENGTH(BN_Quotient);
1624                 BN_Quotient->sign= (BN_Dividend->sign^BN_Divisor->sign);
1625         }
1626         else
1627         {
1628                 BN_Quotient->Length = temp_Dividend->Length - temp_Divisor->Length + 1;
1629                 BN_Remainder->Length = temp_Divisor->Length;
1630                 BN_Quotient->sign= (BN_Dividend->sign^BN_Divisor->sign);
1631                 BN_Remainder->sign = BN_Dividend->sign;
1632
1633                 tmp = SDRM_DWD_Div(BN_Quotient->pData, BN_Remainder->pData, BN_Dividend->pData, BN_Dividend->Length, BN_Divisor->pData, BN_Divisor->Length);
1634
1635                 SDRM_BN_OPTIMIZE_LENGTH(BN_Quotient);
1636                 SDRM_BN_OPTIMIZE_LENGTH(BN_Remainder);
1637         }
1638
1639         free(pbBuf);
1640
1641         if (!(tmp == 0 || tmp == 1))
1642         {
1643                 return CRYPTO_ERROR;
1644         }
1645
1646         return CRYPTO_SUCCESS;
1647 }
1648
1649 /*
1650  * @fn          SDRM_BN_ModAdd
1651  * @brief       Big Number Modular Addition
1652  *
1653  * @param       BN_Dst          [out]destination
1654  * @param       BN_Src1         [in]first element of addition
1655  * @param       BN_Src2         [in]second element of addition
1656  * @param       BN_Modulus      [in]modular m
1657  *
1658  * @return      CRYPTO_SUCCESS if no error occured
1659  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
1660  */
1661 int SDRM_BN_ModAdd(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
1662 {
1663         SDRM_BIG_NUM    *BN_Src1_temp, *BN_Src2_temp;
1664         cc_u8                   *pbBuf;
1665         cc_u32                  tmp = 0, dSize, AllocSize;
1666
1667         dSize = MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size);
1668         AllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1669
1670         pbBuf = (cc_u8*)malloc(AllocSize * 2);
1671
1672         if (!pbBuf)
1673         {
1674                 return CRYPTO_MEMORY_ALLOC_FAIL;
1675         }
1676
1677         BN_Src1_temp = SDRM_BN_Alloc(pbBuf, dSize);
1678         BN_Src2_temp = SDRM_BN_Alloc(pbBuf + AllocSize, dSize);
1679
1680         SDRM_BN_Copy(BN_Src1_temp, BN_Src1);
1681         SDRM_BN_Copy(BN_Src2_temp, BN_Src2);
1682
1683         if ((SDRM_BN_Cmp(BN_Src1, BN_Modulus)>=0))
1684         {
1685                 SDRM_BN_ModRed(BN_Src1_temp, BN_Src1, BN_Modulus);
1686         }
1687
1688         if ((SDRM_BN_Cmp(BN_Src2, BN_Modulus)>=0))
1689         {
1690                 SDRM_BN_ModRed(BN_Src2_temp, BN_Src2, BN_Modulus);
1691         }
1692
1693         if (BN_Src1_temp->Length >= BN_Src2_temp->Length)
1694         {
1695                 BN_Dst->Length = BN_Src1_temp->Length;
1696                 BN_Dst->sign = BN_Src1_temp->sign;
1697                 tmp = SDRM_DWD_Add(BN_Dst->pData, BN_Src1_temp->pData, BN_Src1_temp->Length, BN_Src2_temp->pData, BN_Src2_temp->Length);
1698         }
1699         else
1700         {
1701                 BN_Dst->Length = BN_Src2_temp->Length;
1702                 BN_Dst->sign = BN_Src2_temp->sign;
1703                 tmp = SDRM_DWD_Add(BN_Dst->pData, BN_Src2_temp->pData, BN_Src2_temp->Length,
1704                                                                          BN_Src1_temp->pData, BN_Src1_temp->Length);
1705         }
1706
1707         if (tmp)
1708         {
1709                 BN_Dst->pData[BN_Dst->Length++] = tmp;
1710         }
1711
1712         SDRM_BN_ModRed(BN_Dst, BN_Dst, BN_Modulus);
1713
1714         if (SDRM_DWD_Cmp(BN_Dst->pData, BN_Dst->Length, BN_Modulus->pData, BN_Modulus->Length) >= 0)
1715         {
1716                 SDRM_DWD_Sub(BN_Dst->pData, BN_Dst->pData, BN_Dst->Length, BN_Modulus->pData, BN_Modulus->Length);
1717         }
1718
1719         SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1720         free(pbBuf);
1721
1722         return CRYPTO_SUCCESS;
1723 }
1724
1725 /*
1726  * @fn          SDRM_BN_ModSub
1727  * @brief       Big Number Modular Subtraction
1728  *
1729  * @param       BN_Dst          [out]destination
1730  * @param       BN_Src1         [in]first element of subtraction
1731  * @param       BN_Src2         [in]second element of subtraction
1732  * @param       BN_Modulus      [in]modular m
1733  *
1734  * @return      CRYPTO_SUCCESS if no error occured
1735  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
1736  */
1737 int SDRM_BN_ModSub(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
1738 {
1739         cc_u32                  tmp = 0, dSize, AllocSize;
1740         SDRM_BIG_NUM    *BN_Src1_temp, *BN_Src2_temp;
1741         cc_u8                   *pbBuf;
1742
1743         dSize = MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size);
1744         AllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1745
1746         pbBuf = (cc_u8*)malloc(AllocSize * 2);
1747
1748         if (!pbBuf)
1749         {
1750                 return CRYPTO_MEMORY_ALLOC_FAIL;
1751         }
1752
1753         BN_Src1_temp = SDRM_BN_Alloc(pbBuf, dSize);
1754         BN_Src2_temp = SDRM_BN_Alloc(pbBuf + AllocSize, dSize);
1755
1756         SDRM_BN_Copy(BN_Src1_temp, BN_Src1);
1757         SDRM_BN_Copy(BN_Src2_temp, BN_Src2);
1758
1759         if ((SDRM_BN_Cmp(BN_Src1, BN_Modulus) >= 0))
1760         {
1761                 SDRM_BN_ModRed(BN_Src1_temp, BN_Src1, BN_Modulus);
1762         }
1763
1764         if ((SDRM_BN_Cmp(BN_Src2, BN_Modulus) >= 0))
1765         {
1766                 SDRM_BN_ModRed(BN_Src2_temp, BN_Src2, BN_Modulus);
1767         }
1768
1769         if (SDRM_DWD_Cmp(BN_Src1_temp->pData, BN_Src1_temp->Length, BN_Src2_temp->pData, BN_Src2_temp->Length) >= 0)
1770         {
1771                 BN_Dst->Length = BN_Src1_temp->Length;
1772                 BN_Dst->sign = BN_Src1_temp->sign;
1773
1774                 tmp = SDRM_DWD_Sub(BN_Dst->pData, BN_Src1_temp->pData, BN_Src1_temp->Length, BN_Src2_temp->pData, BN_Src2_temp->Length);
1775         }
1776         else
1777         {
1778                 BN_Dst->Length = BN_Modulus->Length;
1779                 BN_Dst->sign = BN_Modulus->sign;
1780                 SDRM_DWD_Add(BN_Dst->pData, BN_Modulus->pData, BN_Modulus->Length, BN_Src1_temp->pData, BN_Src1_temp->Length);
1781                 SDRM_DWD_Sub(BN_Dst->pData, BN_Dst->pData, BN_Dst->Length, BN_Src2_temp->pData, BN_Src2_temp->Length);
1782         }
1783
1784         SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1785         free(pbBuf);
1786
1787         if (tmp != 0)
1788         {
1789                 return CRYPTO_ERROR;
1790         }
1791
1792         return CRYPTO_SUCCESS;
1793 }
1794
1795 /*
1796  * @fn          SDRM_BN_ModRed
1797  * @brief       Big Number Modular Reduction
1798  *
1799  * @param       BN_Dst          [out]destination
1800  * @param       BN_Src          [in]source
1801  * @param       BN_Modulus      [in]modular m
1802  *
1803  * @return      CRYPTO_SUCCESS if no error occured
1804  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
1805  */
1806 int SDRM_BN_ModRed(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, SDRM_BIG_NUM *BN_Modulus)
1807 {
1808         int                     ret;
1809         cc_u32          *Value = (cc_u32*)malloc(SDRM_SIZE_OF_DWORD * 2 * (sizeof(SDRM_BIG_NUM) + MAX2(BN_Src->Size, BN_Modulus->Size) + 2));
1810
1811         if (!Value)
1812         {
1813                 return CRYPTO_MEMORY_ALLOC_FAIL;
1814         }
1815
1816         if (SDRM_BN_Cmp(BN_Src, BN_Modulus) < 0)
1817         {
1818                 SDRM_BN_Copy(BN_Dst, BN_Src);
1819                 free(Value);
1820                 return CRYPTO_SUCCESS;
1821         }
1822
1823         memcpy(Value, BN_Src->pData, BN_Src->Length * SDRM_SIZE_OF_DWORD);
1824
1825         ret = SDRM_DWD_Classical_REDC(Value, BN_Src->Length,    BN_Modulus->pData, BN_Modulus->Length);
1826
1827         if (ret != CRYPTO_SUCCESS)
1828         {
1829                 free(Value);
1830                 return ret;
1831         }
1832
1833         memcpy(BN_Dst->pData, Value, BN_Modulus->Length * SDRM_SIZE_OF_DWORD);
1834
1835         BN_Dst->Length = BN_Modulus->Length;
1836         BN_Dst->sign = BN_Modulus->sign;
1837         SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
1838
1839         free(Value);
1840
1841         return CRYPTO_SUCCESS;
1842 }
1843
1844 /*
1845  * @fn          SDRM_BN_ModMul
1846  * @brief       Big Number Modular Multiplication
1847  *
1848  * @param       BN_Dst          [out]destination
1849  * @param       BN_Src1         [in]first element of multiplication
1850  * @param       BN_Src2         [in]second element of multipliation
1851  * @param       BN_Modulus      [in]modular m
1852  *
1853  * @return      CRYPTO_SUCCESS if no error occured
1854  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
1855  */
1856 int SDRM_BN_ModMul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
1857 {
1858         int             ret;
1859         SDRM_BIG_NUM Dest;
1860         cc_u32  *Value = (cc_u32*)malloc(SDRM_SIZE_OF_DWORD * (MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size) + 2));
1861
1862         if (!Value)
1863         {
1864                 return CRYPTO_MEMORY_ALLOC_FAIL;
1865         }
1866
1867         memset(Value, 0x00, SDRM_SIZE_OF_DWORD * (MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size) + 2));
1868
1869         SDRM_DWD_Mul(Value, BN_Src1->pData, BN_Src1->Length, BN_Src2->pData, BN_Src2->Length);
1870
1871         ret = SDRM_DWD_Classical_REDC(Value, BN_Src1->Length + BN_Src2->Length, BN_Modulus->pData, BN_Modulus->Length);
1872         if (ret != CRYPTO_SUCCESS)
1873         {
1874                 free(Value);
1875
1876                 return ret;
1877         }
1878
1879         Dest.sign = (BN_Src1->sign == BN_Src2->sign)? 0 : 1;
1880         Dest.Length = BN_Modulus->Length;
1881         Dest.pData = Value;
1882
1883         SDRM_BN_OPTIMIZE_LENGTH(&Dest);
1884
1885         SDRM_BN_Copy(BN_Dst, &Dest);
1886
1887         free(Value);
1888
1889         return CRYPTO_SUCCESS;
1890 }
1891
1892 /*
1893  * @fn          SDRM_BN_ModInv
1894  * @brief       Big Number Modular Inverse
1895  *
1896  * @param       BN_Dest         [out]destination
1897  * @param       BN_Src          [in]soure
1898  * @param       BN_Modulus      [in]modular m
1899  *
1900  * @return      CRYPTO_SUCCESS if no error occured
1901  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
1902  * \n           CRYPTO_NEGATIVE_INPUT           if source is negative value
1903  * \n           CRYPTO_INVERSE_NOT_EXIST        if inverse is not exists
1904  */
1905 int SDRM_BN_ModInv(SDRM_BIG_NUM *BN_Dest, SDRM_BIG_NUM *BN_Src, SDRM_BIG_NUM *BN_Modulus)
1906 {
1907         SDRM_BIG_NUM    *BN_G0, *BN_G1, *BN_V0, *BN_V1, *BN_Y, *BN_Temp1, *BN_Temp2;
1908         cc_u8                   *pbBuf = NULL;
1909         cc_u32                  dSize, dAllocSize;
1910
1911         dSize = MAX2(BN_Src->Size, BN_Modulus->Size);
1912         dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
1913
1914         pbBuf = (cc_u8*)malloc(dAllocSize * 7);
1915
1916         if (!pbBuf)
1917         {
1918                 return CRYPTO_MEMORY_ALLOC_FAIL;
1919         }
1920
1921         BN_G0 =    SDRM_BN_Alloc(pbBuf, dSize);
1922         BN_G1 =    SDRM_BN_Alloc((cc_u8*)BN_G0    + dAllocSize, dSize);
1923         BN_V0 =    SDRM_BN_Alloc((cc_u8*)BN_G1    + dAllocSize, dSize);
1924         BN_V1 =    SDRM_BN_Alloc((cc_u8*)BN_V0    + dAllocSize, dSize);
1925         BN_Y =     SDRM_BN_Alloc((cc_u8*)BN_V1    + dAllocSize, dSize);
1926         BN_Temp1 = SDRM_BN_Alloc((cc_u8*)BN_Y     + dAllocSize, dSize);
1927         BN_Temp2 = SDRM_BN_Alloc((cc_u8*)BN_Temp1 + dAllocSize, dSize);
1928
1929         if (BN_Src->sign)
1930         {
1931                 free(pbBuf);
1932                 return CRYPTO_NEGATIVE_INPUT;
1933         }
1934
1935         //Extended Euclid Algorithm
1936         SDRM_BN_Copy(BN_G0, BN_Modulus);
1937         SDRM_BN_ModRed(BN_G1, BN_Src, BN_Modulus);
1938
1939         SDRM_BN_Copy(BN_V0, BN_Zero);
1940         SDRM_BN_Copy(BN_V1, BN_One);
1941
1942         SDRM_BN_Clr(BN_Y);
1943         SDRM_BN_Clr(BN_Dest);
1944
1945         while(SDRM_BN_Cmp(BN_G1, BN_Zero))
1946         {
1947                 if (!SDRM_BN_Cmp(BN_G1, BN_One))
1948                 {
1949                         SDRM_BN_Copy(BN_Dest, BN_V1);
1950                         SDRM_BN_OPTIMIZE_LENGTH(BN_Dest);
1951                         free(pbBuf);
1952
1953                         return CRYPTO_SUCCESS;
1954                 }
1955
1956                 SDRM_BN_Clr(BN_Y);
1957                 SDRM_BN_Clr(BN_Temp1);
1958                 SDRM_DWD_Div(BN_Y->pData, BN_Temp1->pData, BN_G0->pData, BN_G0->Length, BN_G1->pData, BN_G1->Length);
1959
1960                 BN_Y->Length = BN_G0->Length;
1961                 SDRM_BN_OPTIMIZE_LENGTH(BN_Y);
1962
1963                 BN_Temp1->Length = BN_G1->Length;
1964                 SDRM_BN_Copy(BN_G0, BN_Temp1);
1965                 SDRM_BN_OPTIMIZE_LENGTH(BN_G0);
1966
1967                 SDRM_BN_Clr(BN_Temp1);
1968                 SDRM_DWD_Mul(BN_Temp1->pData, BN_Y->pData, BN_Y->Length, BN_V1->pData, BN_V1->Length);
1969                 BN_Temp1->Length = BN_Y->Length + BN_V1->Length;
1970                 SDRM_BN_OPTIMIZE_LENGTH(BN_Temp1);
1971
1972                 SDRM_BN_Clr(BN_Temp2);
1973                 if (SDRM_BN_Cmp(BN_V0, BN_Temp1) >= 0)
1974                 {
1975                         SDRM_BN_Add(BN_Temp2, BN_V0, BN_Temp1);
1976                 }
1977                 else
1978                 {
1979                         SDRM_BN_Add(BN_Temp2, BN_Temp1, BN_V0);
1980                 }
1981
1982                 SDRM_BN_Copy(BN_V0, BN_Temp2);
1983
1984                 if (!SDRM_BN_Cmp(BN_G0, BN_Zero))
1985                 {
1986                         break;
1987                 }
1988
1989                 if (!SDRM_BN_Cmp(BN_G0, BN_One))
1990                 {
1991                         SDRM_BN_Sub(BN_Dest, BN_Modulus, BN_V0);
1992                         SDRM_BN_OPTIMIZE_LENGTH(BN_Dest);
1993                         free(pbBuf);
1994
1995                         return CRYPTO_SUCCESS;
1996                 }
1997
1998                 SDRM_BN_Clr(BN_Y);
1999                 SDRM_BN_Clr(BN_Temp1);
2000                 SDRM_DWD_Div(BN_Y->pData, BN_Temp1->pData, BN_G1->pData, BN_G1->Length, BN_G0->pData, BN_G0->Length);
2001
2002                 BN_Y->Length = BN_G1->Length;
2003                 SDRM_BN_OPTIMIZE_LENGTH(BN_Y);
2004
2005                 BN_Temp1->Length = BN_G0->Length;
2006                 SDRM_BN_Copy(BN_G1, BN_Temp1);
2007                 SDRM_BN_OPTIMIZE_LENGTH(BN_G1);
2008
2009                 SDRM_BN_Clr(BN_Temp1);
2010                 SDRM_DWD_Mul(BN_Temp1->pData, BN_Y->pData, BN_Y->Length, BN_V0->pData, BN_V0->Length);
2011                 BN_Temp1->Length = BN_Y->Length + BN_V0->Length;
2012                 SDRM_BN_OPTIMIZE_LENGTH(BN_Temp1);
2013
2014                 SDRM_BN_Clr(BN_Temp2);
2015                 if (SDRM_BN_Cmp(BN_V1, BN_Temp1) >= 0)
2016                 {
2017                         SDRM_BN_Add(BN_Temp2, BN_V1, BN_Temp1);
2018                 }
2019                 else
2020                 {
2021                         SDRM_BN_Add(BN_Temp2, BN_Temp1, BN_V1);
2022                 }
2023
2024                 SDRM_BN_Copy(BN_V1, BN_Temp2);
2025         }
2026
2027         SDRM_BN_Copy(BN_Dest, BN_Zero);
2028         free(pbBuf);
2029
2030         return CRYPTO_INVERSE_NOT_EXIST;
2031 }
2032
2033 /*
2034  * @fn          SDRM_MONT_Rzn2zn
2035  * @brief       Convert Montgomery number to noraml number
2036  *
2037  * @param       BN_Dst          [out]destination, normal number
2038  * @param       BN_Src1         [in]source, montgomery number
2039  * @param       Mont            [in]montgomery parameters
2040  *
2041  * @return      CRYPTO_SUCCESS if no error occured
2042  */
2043 int SDRM_MONT_Rzn2zn(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_MONT *Mont)
2044 {
2045         cc_u32                  Src1_Len, Mod_Len, ri, i;
2046         cc_u32                  carry;
2047         SDRM_BIG_NUM    *Src1 = NULL;
2048
2049         if (!BN_Src1->Length)
2050         {
2051                 BN_Dst->Length = 0;
2052
2053                 return CRYPTO_SUCCESS;
2054         }
2055
2056         Src1_Len = ri = Mont->ri / SDRM_BitsInDWORD;
2057         Mod_Len = Mont->Mod->Length + 1;
2058
2059         Src1 = SDRM_BN_Init(BN_Src1->Size + Mod_Len);
2060     if(Src1 == NULL)//fixed prevent cid=89093 by guoxing.xu
2061     {
2062         return CRYPTO_ERROR;
2063     }
2064         SDRM_BN_Copy(Src1, BN_Src1);
2065
2066         if (!Src1_Len || !Mod_Len)
2067         {
2068                 BN_Dst->Length = 0;
2069                 BN_Dst->pData[0] = 0;
2070                 SDRM_BN_FREE(Src1);
2071
2072                 return CRYPTO_SUCCESS;
2073         }
2074
2075         Src1->sign = BN_Src1->sign ^ Mont->Mod->sign;
2076
2077         memset(Src1->pData + Src1->Length, 0, (Mod_Len + BN_Src1->Length - Src1->Length) * SDRM_SIZE_OF_DWORD);
2078
2079         Src1->Length = Mod_Len + BN_Src1->Length;
2080
2081         for (i = 0; i < Mod_Len; i++)
2082         {
2083                 if ((carry = SDRM_DWD_MulAdd(Src1->pData + i, Src1->Length - i, Mont->Mod->pData, Mod_Len, (cc_u32)Src1->pData[i] * Mont->N0)))
2084                 {
2085                         Src1->pData[Src1->Length++] = carry;                                                            //Added by Park Ji soon, 05-03-2006
2086                 }                                                                                                                                               // (cc_u32)A.pData[i]*modulus_p   <== u=a[i]*m' mod b
2087                                                                                                                                                                 //  A=A+ (A.pData[i]*modulus_p* modulus[i])*b^i;
2088         }
2089         SDRM_BN_OPTIMIZE_LENGTH(Src1);
2090
2091         SDRM_BN_SHR(BN_Dst, Src1, (Mod_Len) * 32);
2092         //BN_Dst->Length = Src1->Length - ri;
2093         BN_Dst->Length = Src1->Length - ri- 1;//Added by yhhwang
2094
2095         //if (SDRM_BN_Cmp(BN_Dst, Mont->Mod) >= 0)
2096         while (SDRM_BN_Cmp(BN_Dst, Mont->Mod) >= 0)
2097         {
2098                 SDRM_BN_Sub(BN_Dst, BN_Dst, Mont->Mod);
2099         }
2100
2101         SDRM_BN_FREE(Src1);
2102
2103         return CRYPTO_SUCCESS;
2104 }
2105
2106 /*
2107  * @fn          SDRM_MONT_Mul
2108  * @brief       Montgomery Multiplication
2109  *
2110  * @param       BN_Dst          [out]destination, montgomery number
2111  * @param       BN_Src1         [in]first element, montgomery number
2112  * @param       BN_Src2         [in]second element, montgomery number
2113  * @param       Mont            [in]montgomery parameters
2114  *
2115  * @return      CRYPTO_SUCCESS if no error occured
2116  */
2117 int SDRM_MONT_Mul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_MONT *Mont)
2118 {
2119         int ret;
2120
2121         /* Begin - Add to test input range by Yong Ho Hwang (20120809) */
2122         /*
2123         if (SDRM_BN_Cmp(BN_Src1, Mont->Mod) >= 0)
2124         {
2125                 ret = SDRM_BN_ModRed(BN_Src1, BN_Src1, Mont->Mod);
2126                 if (ret != CRYPTO_SUCCESS)
2127                 {
2128                         return ret;
2129                 }
2130         } else if ( BN_Src1->sign == 1)
2131         {
2132                 printf("Minus Value\n");
2133                 ret = SDRM_BN_Add(BN_Src1, BN_Src1, Mont->Mod);
2134                 if (BN_Src1->sign == 1)
2135                 {
2136                         printf("Value Fail.\n");
2137                         return CRYPTO_ERROR;
2138                 }
2139         }
2140
2141         if (SDRM_BN_Cmp(BN_Src2, Mont->Mod) >= 0)
2142         {
2143                 ret = SDRM_BN_ModRed(BN_Src2, BN_Src2, Mont->Mod);
2144                 if (ret != CRYPTO_SUCCESS)
2145                 {
2146                         return ret;
2147                 }
2148         } else if ( BN_Src2->sign == 1)
2149         {
2150                 printf("Minus Value\n");
2151                 ret = SDRM_BN_Add(BN_Src2, BN_Src2, Mont->Mod);
2152                 if (BN_Src2->sign == 1)
2153                 {
2154                         printf("Value Fail.\n");
2155                         return CRYPTO_ERROR;
2156                 }
2157         }
2158         */
2159         /* End - Add to test input range by Yong Ho Hwang (20120809) */
2160
2161         ret = SDRM_BN_Mul(BN_Dst, BN_Src1, BN_Src2);
2162         if (ret != CRYPTO_SUCCESS)
2163         {
2164                 return ret;
2165         }
2166
2167         ret = SDRM_MONT_Rzn2zn(BN_Dst, BN_Dst, Mont);
2168
2169         /* Begin - Add to test input range by Yong Ho Hwang (20120809) */
2170         /*
2171         if (SDRM_BN_Cmp(BN_Dst, Mont->Mod) >= 0)
2172         {
2173                 printf("Output is bigger than Mod\n");
2174         } else if ( BN_Dst->sign == 1)
2175         {
2176                 printf("Minus Value\n");
2177         }
2178         */
2179         /* End - Add to test input range by Yong Ho Hwang (20120809) */
2180
2181         return ret;
2182 }
2183
2184 /*
2185  * @fn          SDRM_MONT_Set
2186  * @brief       Set Montgomery parameters
2187  *
2188  * @param       Mont            [out]montgomery parameter
2189  * @param       BN_Modulus      [in]modular m
2190  *
2191  * @return      CRYPTO_SUCCESS if no error occured
2192  * \n           BN_NOT_ENOUGHT_BUFFER if malloc is failed
2193  * \n           CRYPTO_INVERSE_NOT_EXIST if inverse is not exists
2194  */
2195 int SDRM_MONT_Set(SDRM_BIG_MONT *Mont, SDRM_BIG_NUM *BN_Modulus)
2196 {
2197         SDRM_BIG_NUM    *Ri, *R;
2198         SDRM_BIG_NUM    *temp, *Rsquare;
2199         cc_u8                   *pbBuf;
2200         cc_u32                  buf[2], dSize, dAllocSize, r2Size;
2201
2202         if ((Mont == NULL) || (BN_Modulus == NULL))
2203         {
2204                 return CRYPTO_INVALID_ARGUMENT;
2205         }
2206
2207         if (Mont->R == NULL)
2208         {
2209                 Mont->R = SDRM_BN_Init(BN_Modulus->Size);
2210         }
2211     if (Mont->R == NULL)//fix prevent 89095 by guoxing.xu
2212     {
2213         return CRYPTO_MEMORY_ALLOC_FAIL;
2214     }
2215         if (Mont->Mod == NULL)
2216         {
2217                 Mont->Mod = SDRM_BN_Init(BN_Modulus->Size);
2218         }
2219         if (Mont->Mod == NULL)//fix prevent 89-95 by guoxing.xu
2220     {
2221         SDRM_BN_FREE(Mont->R);
2222         return CRYPTO_MEMORY_ALLOC_FAIL;
2223     }
2224         if (SDRM_BN_Cmp(Mont->Mod, BN_Modulus) == 0)
2225         {
2226                 return CRYPTO_SUCCESS;
2227         }
2228
2229         dSize = BN_Modulus->Size + 1;
2230         dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
2231         if (!(pbBuf = (cc_u8*)malloc(dAllocSize * 3)))
2232         {
2233                 return CRYPTO_MEMORY_ALLOC_FAIL;
2234         }
2235
2236         Ri =   SDRM_BN_Alloc( pbBuf,                             dSize);
2237         R =    SDRM_BN_Alloc((cc_u8*)Ri + dAllocSize, dSize);
2238         temp = SDRM_BN_Alloc((cc_u8*)R  + dAllocSize, dSize);
2239
2240 //++ 2012.08.20 - modified by yhhwang to apply R=2^(160+32)
2241 /* == DELETED ==
2242         SDRM_BN_Copy(Mont->Mod, BN_Modulus);
2243
2244         Mont->ri = (SDRM_BN_num_bits(BN_Modulus) + (SDRM_BitsInDWORD - 1)) / SDRM_BitsInDWORD * SDRM_BitsInDWORD;
2245
2246         SDRM_BN_SHL(R, BN_One, SDRM_BitsInDWORD);
2247
2248         buf[0] = BN_Modulus->pData[0];
2249         buf[1] = 0;
2250         temp->pData[0] = buf[0];
2251         temp->Length = 1;
2252         temp->sign = BN_Modulus->sign;
2253
2254         SDRM_BN_ModInv(Ri, R, temp);
2255         if (Ri == NULL)
2256         {
2257                 free(pbBuf);
2258
2259                 return CRYPTO_INVERSE_NOT_EXIST;
2260         }
2261
2262         SDRM_BN_SHL(Ri, Ri, SDRM_BitsInDWORD);
2263         SDRM_BN_Sub(Ri, Ri, BN_One);
2264         SDRM_BN_Div(Ri, NULL, Ri, temp);
2265         SDRM_BN_Copy(Mont->Inv_Mod, Ri);
2266         Mont->N0 = Ri->pData[0];
2267
2268         SDRM_BN_SHL(Mont->R, BN_One, 2 * (32 + Mont->ri));
2269         SDRM_BN_ModRed(Mont->R, Mont->R, Mont->Mod);
2270 */
2271
2272 // == NEW CODE ==
2273         SDRM_BN_Copy(Mont->Mod, BN_Modulus);
2274         Mont->Mod->pData[Mont->Mod->Length] = 0;
2275
2276         Mont->ri = (SDRM_BN_num_bits(BN_Modulus) + (SDRM_BitsInDWORD - 1)) / SDRM_BitsInDWORD * SDRM_BitsInDWORD;
2277
2278         SDRM_BN_SHL(R, BN_One, SDRM_BitsInDWORD);
2279
2280         // Compute -m^-1 mod b
2281         buf[0] = BN_Modulus->pData[0];
2282         buf[1] = 0;
2283         temp->pData[0] = buf[0];
2284         temp->Length = 1;
2285         temp->sign = BN_Modulus->sign;
2286
2287         SDRM_BN_ModInv(Ri, temp, R);
2288         Ri->sign = 1;
2289         SDRM_BN_Add(Ri, Ri, R);
2290         Mont->N0 = Ri->pData[0];
2291
2292         r2Size = 2 * (SDRM_BitsInDWORD + Mont->ri);
2293         Rsquare = SDRM_BN_Init(r2Size / SDRM_BitsInDWORD + 1);
2294         if (Rsquare == NULL)
2295         {
2296                 free(pbBuf);
2297                 return CRYPTO_MEMORY_ALLOC_FAIL;
2298         }
2299
2300         // Compute R and R^2 mod M
2301         SDRM_BN_SHL(Rsquare, BN_One, r2Size);
2302         SDRM_BN_ModRed(Mont->R, Rsquare, BN_Modulus);
2303 //-- 2012.08.20 - modified by yhhwang
2304
2305         free(pbBuf);
2306         free(Rsquare);
2307
2308         return CRYPTO_SUCCESS;
2309 }
2310
2311 /*
2312  * @fn          SDRM_MONT_Init
2313  * @brief       Allocate new momory for Montgomery parameter
2314  *
2315  * @param       dSize   [in]size of buffer of big number
2316  *
2317  * @return      Pointer to created structure
2318  * \n           NULL if malloc failed
2319  */
2320 SDRM_BIG_MONT *SDRM_MONT_Init(cc_u32 dSize)
2321 {
2322         SDRM_BIG_MONT   *Mont;
2323         cc_u32                  AllocSiz = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
2324
2325         Mont = (SDRM_BIG_MONT *)malloc(sizeof(SDRM_BIG_MONT) + AllocSiz * 3);
2326         if (Mont == NULL)
2327         {
2328                 return NULL;
2329         }
2330
2331         Mont->ri          = 0;
2332         Mont->R           = SDRM_BN_Alloc((cc_u8*)Mont + sizeof(SDRM_BIG_MONT), dSize);
2333         Mont->Mod         = SDRM_BN_Alloc((cc_u8*)Mont->R + AllocSiz,              dSize);
2334         Mont->Inv_Mod = SDRM_BN_Alloc((cc_u8*)Mont->Mod + AllocSiz,                dSize);
2335
2336         return Mont;
2337 }
2338
2339 /*
2340  * @fn          SDRM_MONT_Free
2341  * @brief       Free allocated memory for montgomery paramter
2342  *
2343  * @param       Mont    [in]montgomery parameters
2344  *
2345  * @return      void
2346  */
2347 void SDRM_MONT_Free(SDRM_BIG_MONT *Mont)
2348 {
2349         if (Mont != NULL) {
2350                 free(Mont);
2351         }
2352 }
2353
2354 int SDRM_BN_num_bits_index(SDRM_BIG_NUM *BN_Src, cc_u32 bitIndex)
2355 {
2356         cc_u32  l;
2357         int j;
2358
2359         if (BN_Src->Length == 0)
2360         {
2361                 return 0;
2362         }
2363
2364         int div = bitIndex / (sizeof(cc_u32) * 8);
2365         int rem = bitIndex % (sizeof(cc_u32) * 8);
2366
2367         l = BN_Src->pData[div];
2368         j = SDRM_UINT32_num_bits_index(&l, rem);
2369         return j;
2370 }
2371
2372 int SDRM_UINT32_num_bits_index(cc_u32 *pdSrc, cc_u32 bitIndex)
2373 {
2374         cc_u32  i = 0;
2375         cc_u32  temp;
2376
2377         temp = *pdSrc;
2378
2379         if (!temp)
2380         {
2381                 return 0;
2382         }
2383
2384         while(temp)
2385         {
2386                 if(bitIndex == i) {
2387                         break;
2388                 }
2389                 temp >>= 1;
2390                 i++;
2391         }
2392         return temp & 0x00000001;
2393 }
2394
2395
2396
2397 /*
2398  * @fn          SDRM_BN_num_bits
2399  * @brief       Calc bit-length of Big Number
2400  *
2401  * @param       BN_Src  [in]source
2402  *
2403  * @return      bit-length
2404  */
2405 int SDRM_BN_num_bits(SDRM_BIG_NUM *BN_Src)
2406 {
2407         cc_u32  l;
2408         int             i, j;
2409
2410         if (BN_Src->Length == 0)
2411         {
2412                 return 0;
2413         }
2414
2415         l = BN_Src->pData[BN_Src->Length - 1];
2416         i = (BN_Src->Length-1) * SDRM_BitsInDWORD;
2417
2418         j = SDRM_UINT32_num_bits(&l);
2419
2420         return(i + j);
2421 }
2422
2423 /*
2424  * @fn          SDRM_UINT32_num_bits
2425  * @brief       Calc bit-length of cc_u32
2426  *
2427  * @param       pdSrc   [in]source
2428  *
2429  * @return      bit-length
2430  */
2431 int     SDRM_UINT32_num_bits(cc_u32 *pdSrc)
2432 {
2433         int             i = 0;
2434         cc_u32  temp;
2435
2436         temp = *pdSrc;
2437
2438         if (!temp)
2439         {
2440                 return 0;
2441         }
2442
2443         while(temp)
2444         {
2445                 temp >>= 1;
2446                 i++;
2447         }
2448
2449         return i;
2450 }
2451
2452 /*
2453  * @fn          SDRM_INT_num_bits
2454  * @brief       Calc bit-length of integer
2455  *
2456  * @param       Src     [in]source
2457  *
2458  * @return      bit-length
2459  */
2460 int     SDRM_INT_num_bits(int Src)
2461 {
2462         int i = 0;
2463
2464         if (!Src)
2465         {
2466                 return 0;
2467         }
2468
2469         while(Src)
2470         {
2471                 Src >>= 1;
2472                 i++;
2473         }
2474
2475         return i;
2476 }
2477
2478 /*
2479  * @fn          SDRM_BN_ModExp
2480  * @brief       Big Number Modular Exponentiation
2481  *
2482  * @param       BN_Dst          [out]destination
2483  * @param       BN_Base         [in]base
2484  * @param       BN_Exponent     [in]exponent
2485  * @param       BN_Modulus      [in]modular m
2486  *
2487  * @return      CRYPTO_SUCCESS if no error occured
2488  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
2489  * \n           CRYPTO_ERROR    if evaluation is failed
2490  */
2491 int SDRM_BN_ModExp(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Base, SDRM_BIG_NUM *BN_Exponent, SDRM_BIG_NUM *BN_Modulus)
2492 {
2493         SDRM_BIG_NUM    *c_, *a_, *BN_Temp;
2494         SDRM_BIG_MONT   *Mont;
2495         int                             i, m;
2496         cc_u8                   *pbBuf;
2497         cc_u32                  dSize, dAllocSize;
2498
2499         dSize = MAX3(BN_Base->Size, BN_Exponent->Size, BN_Modulus->Size);
2500         dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
2501
2502         pbBuf = (cc_u8*)malloc(dAllocSize * 3);
2503         if (pbBuf == NULL)
2504         {
2505                 return CRYPTO_MEMORY_ALLOC_FAIL;
2506         }
2507
2508         c_ = SDRM_BN_Alloc(pbBuf, dSize);
2509         a_ = SDRM_BN_Alloc((cc_u8*)c_ + dAllocSize, dSize);
2510         BN_Temp = SDRM_BN_Alloc((cc_u8*)a_ + dAllocSize, dSize);
2511
2512         if (SDRM_BN_Cmp(BN_Base, BN_Modulus) >= 0)
2513         {
2514                 SDRM_BN_ModRed(BN_Temp, BN_Base, BN_Modulus);
2515         }
2516         else
2517         {
2518                 BN_Temp = BN_Base;
2519         }
2520
2521         if (SDRM_BN_Cmp(BN_Temp, BN_Zero) == 0)
2522         {
2523                 SDRM_BN_Copy(BN_Dst, BN_Zero);
2524
2525                 free(pbBuf);
2526                 return CRYPTO_SUCCESS;
2527         }
2528
2529         Mont = SDRM_MONT_Init(dSize);
2530         SDRM_MONT_Set(Mont, BN_Modulus);
2531
2532         SDRM_MONT_Zn2rzn(a_, BN_Temp, Mont);
2533         SDRM_MONT_Zn2rzn(c_, BN_One, Mont);
2534
2535         m = SDRM_BN_num_bits(BN_Exponent);
2536
2537         for (i = m - 1; i >= 0; i--)
2538         {
2539                 SDRM_MONT_Mul(c_, c_, c_, Mont);
2540
2541                 if (SDRM_CheckBitUINT32(BN_Exponent->pData, i) == 1)
2542                 {
2543                         SDRM_MONT_Mul(c_, c_, a_, Mont);
2544                 }
2545         }
2546
2547         SDRM_MONT_Rzn2zn(BN_Dst, c_, Mont);
2548
2549         SDRM_MONT_Free(Mont);
2550
2551         free(pbBuf);
2552
2553         return CRYPTO_SUCCESS;
2554 }
2555
2556 /*
2557  * @fn          SDRM_BN_ModExp2
2558  * @brief       Big Number Modular Exponentiation2 - Karen's method
2559  *
2560  * @param       BN_Dst          [out]destination
2561  * @param       BN_Base         [in]base
2562  * @param       BN_Exponent     [in]exponent
2563  * @param       BN_Modulus      [in]modular m
2564  *
2565  * @return      CRYPTO_SUCCESS if no error occured
2566  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
2567  * \n           CRYPTO_ERROR    if evaluation is failed
2568  */
2569 int SDRM_BN_ModExp2(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Base, SDRM_BIG_NUM *BN_Exponent, SDRM_BIG_NUM *BN_Modulus)
2570 {
2571         int retVal;
2572         SDRM_BIG_NUM *BN_Temp;
2573
2574         if ((BN_Dst != BN_Base) && (BN_Dst != BN_Exponent) && (BN_Dst != BN_Modulus))
2575         {
2576                 SDRM_BN_Clr(BN_Dst);
2577         }
2578
2579         if (SDRM_BN_Cmp(BN_Base, BN_Modulus) >= 0)
2580         {
2581                 BN_Temp = SDRM_BN_Init(MAX3(BN_Base->Size, BN_Exponent->Size, BN_Modulus->Size));
2582                 if (BN_Temp == NULL)
2583                 {
2584                         return CRYPTO_MEMORY_ALLOC_FAIL;
2585                 }
2586
2587                 if (BN_Temp == BN_Base)
2588                 {
2589                         free(BN_Temp);
2590                         return CRYPTO_ERROR;
2591                 }
2592
2593                 SDRM_BN_ModRed(BN_Temp, BN_Base, BN_Modulus);
2594         }
2595         else
2596         {
2597                 BN_Temp = BN_Base;
2598         }
2599
2600         if (SDRM_BN_Cmp(BN_Temp, BN_Zero) == 0)
2601         {
2602                 SDRM_BN_Clr(BN_Dst);
2603
2604                 if (BN_Temp != BN_Base)
2605                 {
2606                         free(BN_Temp);
2607                 }
2608
2609                 return CRYPTO_SUCCESS;
2610         }
2611
2612         retVal = SDRM_ll_ExpMod(BN_Temp->pData, BN_Temp->Length * 4, BN_Exponent->pData, BN_Exponent->Length * 4, BN_Modulus->pData, BN_Modulus->Length * 4, BN_Dst->pData);
2613         if (retVal != CRYPTO_SUCCESS)
2614         {
2615                 if (BN_Temp != BN_Base)
2616                 {
2617                         free(BN_Temp);
2618                 }
2619
2620                 return retVal;
2621         }
2622
2623         BN_Dst->Length = BN_Dst->Size;
2624
2625         while(BN_Dst->pData[BN_Dst->Length - 1] == 0)
2626         {
2627                 BN_Dst->Length--;
2628         }
2629
2630         if (BN_Temp != BN_Base)
2631         {
2632                 free(BN_Temp);
2633         }
2634
2635         return CRYPTO_SUCCESS;
2636 }
2637
2638 /*
2639  * @fn          SDRM_BN_CheckRelativelyPrime
2640  * @brief       get gcd of two big number
2641  *
2642  * @param       BN_Src1                                         [in]first element
2643  * @param       BN_Src2                                         [in]second element
2644  *
2645  * @return      CRYPTO_ISPRIME                          if two elements are relatively prime
2646  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
2647  * \n           CRYPTO_ERROR    otherwise
2648  */
2649 int SDRM_BN_CheckRelativelyPrime(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
2650 {
2651         SDRM_BIG_NUM    *Temp, *S1, *S2;
2652         cc_u8                   *pbBuf;
2653         cc_u32                  dSize, dAllocSize;
2654
2655         dSize = MAX2(BN_Src1->Size, BN_Src2->Size);
2656         dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
2657
2658         if (!(pbBuf = (cc_u8*)malloc(dAllocSize * 3)))
2659         {
2660                 return CRYPTO_MEMORY_ALLOC_FAIL;
2661         }
2662
2663         S1       = SDRM_BN_Alloc(pbBuf,                                 dSize);
2664         S2       = SDRM_BN_Alloc((cc_u8*)S1 + dAllocSize, dSize);
2665         Temp = SDRM_BN_Alloc((cc_u8*)S2 + dAllocSize, dSize);
2666
2667         if (SDRM_BN_Cmp(BN_Src1, BN_Src2) >= 0)
2668         {
2669                 SDRM_BN_Copy(S1, BN_Src1);
2670                 SDRM_BN_Copy(S2, BN_Src2);
2671         }
2672         else
2673         {
2674                 SDRM_BN_Copy(S1, BN_Src2);
2675                 SDRM_BN_Copy(S2, BN_Src1);
2676         }
2677
2678         SDRM_BN_OPTIMIZE_LENGTH(S1);
2679         SDRM_BN_OPTIMIZE_LENGTH(S2);
2680
2681         while(S2->Length)
2682         {
2683                 SDRM_BN_ModRed(Temp, S1, S2);
2684                 SDRM_BN_Copy(S1, S2);
2685                 SDRM_BN_Copy(S2, Temp);
2686         }
2687
2688         if (SDRM_BN_Cmp(S1, BN_One) == 0)
2689         {
2690                 free(pbBuf);
2691
2692                 return CRYPTO_ISPRIME;
2693         }
2694
2695         free(pbBuf);
2696
2697         return CRYPTO_ERROR;
2698 }
2699
2700 //small primes for pre-testing
2701 static cc_u32 miniPrimes[] = {
2702         0xC8E15F2A, 0x16FA4227, 0x87B81DA9, 0xDA38C071, 0xFDB17C23, 0xFE5E796B,
2703         0xC7E4CBF5, 0x7EB0F0B1, 0xB72EFC93, 0xF46CEE57, 0x80B2C2BB, 0x34A77199,
2704         0x447D1BD5, 0xEA4C7C31, 0xF046D45B, 0xFF55A7BF, 0x9B287041, 0x85663BEF,
2705         0x7856625B, 0
2706 };
2707
2708 /*
2709  * @fn          SDRM_BN_MILLER_RABIN
2710  * @brief       MILLER_RABIN Test
2711  *
2712  * @param       n                                       [in]value to test
2713  * @param       t                                       [in]security parameter
2714  *
2715  * @return      CRYPTO_ISPRIME                  if n is (probably) prime
2716  * \n           CRYPTO_INVALID_ARGUMENT if n is composite
2717  */
2718 int SDRM_BN_MILLER_RABIN(SDRM_BIG_NUM* n, cc_u32 t)
2719 {
2720         SDRM_BIG_NUM    *r, *a, *y, *n1;
2721         cc_u32                  i, j, tmp, srcLen, s = 1;
2722         cc_u8                   *pbBuf;
2723         cc_u32                  dSize, dAllocSize;
2724
2725         dSize = n->Size;
2726         dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
2727
2728         if (n->Length == 0)
2729         {
2730                 return CRYPTO_INVALID_ARGUMENT;
2731         }
2732
2733         if ((n->pData[0] & 0x01) == 0)
2734         {
2735                 return CRYPTO_INVALID_ARGUMENT;
2736         }
2737
2738         for (i = 0; miniPrimes[i] != 0; i++)
2739         {
2740                 tmp = 0;
2741                 for (j = n->Length - 1; j != (cc_u32)-1; j--)
2742                 {
2743                         tmp = SDRM_DIGIT_Mod(tmp, n->pData[j], miniPrimes[i]);
2744                 }
2745
2746                 if(SDRM_DIGIT_Gcd(miniPrimes[i], tmp) != 1)
2747                 {
2748                         return CRYPTO_INVALID_ARGUMENT;
2749                 }
2750         }
2751
2752         while(SDRM_CheckBitUINT32(n->pData, s) == 0) {
2753                 s++;
2754         }
2755
2756         pbBuf = (cc_u8*)malloc(dAllocSize * 4);
2757         if (pbBuf == NULL)
2758         {
2759                 return CRYPTO_MEMORY_ALLOC_FAIL;
2760         }
2761
2762         r  = SDRM_BN_Alloc( pbBuf,                               dSize);
2763         a  = SDRM_BN_Alloc((cc_u8*)r + dAllocSize, dSize);
2764         y  = SDRM_BN_Alloc((cc_u8*)a + dAllocSize, dSize);
2765         n1 = SDRM_BN_Alloc((cc_u8*)y + dAllocSize, dSize);
2766
2767         SDRM_BN_Sub(n1, n, BN_One);
2768         SDRM_BN_SHR(r, n1, s);
2769
2770         srcLen = SDRM_BN_num_bits(n);
2771
2772         for (i = 1; i <= t; i++)
2773         {
2774                 SDRM_BN_Rand(a, srcLen);
2775                 a->pData[n->Length - 1] %= n->pData[n->Length - 1];
2776
2777                 SDRM_BN_ModExp(y, a, r, n);
2778                 if ((SDRM_BN_Cmp(y, BN_One) == 0) || (SDRM_BN_Cmp(y, n1) == 0))
2779                 {
2780                         continue;
2781                 }
2782
2783                 for (j = 1; (j < s) && SDRM_BN_Cmp(y, n1) != 0; j++)
2784                 {
2785                         SDRM_BN_ModMul(y, y, y, n);
2786
2787                         if (SDRM_BN_Cmp(y, BN_One) == 0)
2788                         {
2789                                 free(pbBuf);
2790                                 return CRYPTO_INVALID_ARGUMENT;
2791                         }
2792                 }
2793
2794                 if (SDRM_BN_Cmp(y, n1) != 0)
2795                 {
2796                         free(pbBuf);
2797
2798                         return CRYPTO_INVALID_ARGUMENT;
2799                 }
2800
2801         }
2802         free(pbBuf);
2803
2804         return CRYPTO_ISPRIME;
2805 }
2806
2807 /*
2808  * @fn          int     SDRM_HEX2BN(cc_u8* pbSrc, SDRM_BIG_NUM *BN_Dst)
2809  * @brief       Convert Hex String to Big Number
2810  *
2811  * @param       pbSrc   [in]source hex string
2812  * @param       BN_Dst  [out]output big number
2813  *
2814  * @return      CRYPTO_SUCCESS  if no error is occured
2815  * \n           CRYPTO_MEMORY_ALLOC_FAIL        if arrary is too small
2816  */
2817 int     SDRM_HEX2BN(cc_u8* pbSrc, SDRM_BIG_NUM *BN_Dst)
2818 {
2819         cc_u32 i, n, k, j;
2820         cc_u8 * bufferHex = NULL;
2821
2822         n = (cc_u32)strlen((const char*)pbSrc);
2823
2824         if (!BN_Dst)
2825         {
2826                 BN_Dst = SDRM_BN_Init((n / SDRM_SIZE_BLOCK) * SDRM_SIZE_OF_DWORD * 8);
2827                 if(BN_Dst == NULL)
2828                 {
2829                         return CRYPTO_MEMORY_ALLOC_FAIL;
2830                 }
2831         }
2832         if(pbSrc[0] == '-')
2833         {
2834                 BN_Dst->sign = 1;
2835                 pbSrc[0] = '0';
2836         }
2837
2838         BN_Dst->Length = n / SDRM_SIZE_BLOCK;
2839         //normalize length
2840         if( n % SDRM_SIZE_BLOCK != 0 ) {
2841                 BN_Dst->Length+=1;
2842         }
2843 #if 0 //fix prevent problem by guoxing.xu 20140826. move to before
2844         if (!BN_Dst)
2845         {
2846                 BN_Dst = SDRM_BN_Init(BN_Dst->Length * SDRM_SIZE_OF_DWORD * 8);
2847         }
2848 #endif
2849         for(i = 0; i < BN_Dst->Length ; i++)
2850         {
2851                 BN_Dst->pData[i] = 0;
2852         }
2853
2854         //full string: bufferHex mod Length = 0
2855         bufferHex = (cc_u8 *)malloc( sizeof(cc_u8) * (BN_Dst->Length * SDRM_SIZE_BLOCK));
2856
2857         //init byffer by 0
2858         for(i = 0; i < BN_Dst->Length * SDRM_SIZE_BLOCK; i++)
2859         {
2860                 bufferHex[i] = '0';
2861         }
2862
2863         k = n - 1;
2864         for(i = (BN_Dst->Length * SDRM_SIZE_BLOCK) - 1; (int)k >= 0; i--, k--)
2865         {
2866                 bufferHex[i] = pbSrc[k];
2867         }
2868
2869         for(i = 0; i < BN_Dst->Length; i++)
2870         {
2871                 for(j = (BN_Dst->Length * SDRM_SIZE_BLOCK) - (i * SDRM_SIZE_BLOCK) - SDRM_SIZE_BLOCK; j < (BN_Dst->Length * SDRM_SIZE_BLOCK) - (i * SDRM_SIZE_BLOCK) ; j++)
2872                 {
2873                         switch(bufferHex[j])
2874                         {
2875                                 case '0':
2876                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2877                                         BN_Dst->pData[i] |= 0x0;
2878                                         break;
2879                                 case '1':
2880                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2881                                         BN_Dst->pData[i] |= 0x1;
2882                                         break;
2883                                 case '2':
2884                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2885                                         BN_Dst->pData[i] |= 0x2;
2886                                         break;
2887                                 case '3':
2888                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2889                                         BN_Dst->pData[i] |= 0x3;
2890                                         break;
2891                                 case '4':
2892                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2893                                         BN_Dst->pData[i] |= 0x4;
2894                                         break;
2895                                 case '5':
2896                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2897                                         BN_Dst->pData[i] |= 0x5;
2898                                         break;
2899                                 case '6':
2900                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2901                                         BN_Dst->pData[i] |= 0x6;
2902                                         break;
2903                                 case '7':
2904                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2905                                         BN_Dst->pData[i] |= 0x7;
2906                                         break;
2907                                 case '8':
2908                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2909                                         BN_Dst->pData[i] |= 0x8;
2910                                         break;
2911                                 case '9':
2912                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2913                                         BN_Dst->pData[i] |= 0x9;
2914                                         break;
2915                                 case 'a':
2916                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2917                                         BN_Dst->pData[i] |= 0xa;
2918                                         break;
2919                                 case 'A':
2920                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2921                                         BN_Dst->pData[i] |= 0xa;
2922                                         break;
2923                                 case 'b':
2924                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2925                                         BN_Dst->pData[i] |= 0xb;
2926                                         break;
2927                                 case 'B':
2928                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2929                                         BN_Dst->pData[i] |= 0xb;
2930                                         break;
2931                                 case 'c':
2932                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2933                                         BN_Dst->pData[i] |= 0xc;
2934                                         break;
2935                                 case 'C':
2936                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2937                                         BN_Dst->pData[i] |= 0xc;
2938                                         break;
2939                                 case 'd':
2940                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2941                                         BN_Dst->pData[i] |= 0xd;
2942                                         break;
2943                                 case 'D':
2944                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2945                                         BN_Dst->pData[i] |= 0xd;
2946                                         break;
2947                                 case 'e':
2948                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2949                                         BN_Dst->pData[i] |= 0xe;
2950                                         break;
2951                                 case 'E':
2952                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2953                                         BN_Dst->pData[i] |= 0xe;
2954                                         break;
2955                                 case 'f':
2956                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2957                                         BN_Dst->pData[i] |= 0xf;
2958                                         break;
2959                                 case 'F':
2960                                         BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
2961                                         BN_Dst->pData[i] |= 0xf;
2962                                         break;
2963                                 default:
2964                                 {
2965                                         free(bufferHex);
2966                                         return CRYPTO_INVALID_ARGUMENT;
2967                                 }
2968                         }
2969                 }
2970         }
2971
2972         //clear time buffer
2973         free(bufferHex);
2974
2975         return CRYPTO_SUCCESS;
2976 }
2977
2978 /*
2979  * @fn          cc_u8 * SDRM_BN2STRBIN(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src);
2980  * @brief       Convert Big Number to binary String
2981  *
2982  * @param       pbSrc   [in]source big number
2983  * @param       BN_Dst  [out]output numberBits of uot string
2984  *
2985  * @return      (cc_u8 *) binary string
2986  */
2987 cc_u8 * SDRM_BN2STRBIN(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src)
2988 {
2989         cc_u32 i,j,k;
2990         cc_u32 mask = 0x80000000;
2991         cc_u32 temp, check;
2992         cc_u8 *tempC, *tempR;
2993         (*numberBits) = sizeof(cc_u8) * BN_Src->Length * SDRM_SIZE_OF_DWORD * 8 + 1;
2994         tempC = (cc_u8*)malloc(*numberBits);
2995         tempR = (cc_u8*)malloc(*numberBits);
2996         tempC[(*numberBits) - 1] = '\0';
2997         for(i = BN_Src->Length - 1; (int)i >= 0 ; i--)
2998         {
2999                 temp = BN_Src->pData[i];
3000                 for(j = 0; j < (SDRM_SIZE_OF_DWORD * 8); j++)
3001                 {
3002                         if((temp & mask) > 0) {
3003                                 tempC[(((BN_Src->Length - 1) - i) * (SDRM_SIZE_OF_DWORD * 8)) + j] = '1';
3004                         }
3005                         else {
3006                                 tempC[(((BN_Src->Length - 1) - i) * (SDRM_SIZE_OF_DWORD * 8)) + j] = '0';
3007                         }
3008
3009                         temp = temp << 1;
3010                 }
3011         }
3012
3013         //next block for normalize length string (eg 0111 = 111)
3014         check = 0; k = 0;
3015         for(i = 0; i < (*numberBits); i++)
3016         {
3017                 if(tempC[i] == '0' && check == 0) {
3018                         continue;
3019                 }
3020                 else {
3021                         check = 1;
3022                 }
3023
3024                 tempR[k] = tempC[i];
3025                 k++;
3026
3027         }
3028         tempR[k] = '\0';
3029         (*numberBits) = k - 1;
3030
3031         free(tempC);
3032
3033         return tempR;
3034 }
3035
3036 /*
3037  * @fn          int SDRM_BN_SetWord(SDRM_BIG_NUM *BN_Dst, cc_u32 t);
3038  * @brief       Set word to Big Number
3039  *
3040  * @param       pbSrc   [in]source word
3041  * @param       BN_Dst  [out]output Big Nubmer
3042  *
3043  * @return      CRYPTO_SUCCESS  if no error is occuredg
3044  */
3045 int SDRM_BN_SetWord(SDRM_BIG_NUM *BN_Dst, cc_u32 t)
3046 {
3047         if((int)t >= 0)
3048         {
3049                 BN_Dst->Length = 1;
3050                 BN_Dst->sign = 0;
3051                 BN_Dst->pData[0] = t;
3052         }
3053         else
3054         {
3055                 BN_Dst->Length = 1;
3056                 BN_Dst->sign = 1;
3057                 BN_Dst->pData[0] = t * (-1);
3058         }
3059
3060         return CRYPTO_SUCCESS;
3061 }
3062
3063 /*
3064  * @fn          int SDRM_BN_isZero(SDRM_BIG_NUM *BN_Src);
3065  * @brief       check big number is zero
3066  *
3067  * @param       pbSrc   [in]source big number
3068  *
3069  * @return      0 - false, 1 - true
3070  */
3071 int SDRM_BN_isZero(SDRM_BIG_NUM *BN_Src)
3072 {
3073         return ((BN_Src)->Length == 0)?1:0;
3074 }
3075
3076 /*
3077  * @fn          cc_u8 * SDRM_BN2STRFOUR(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src);
3078  * @brief       Convert Big Number to four String
3079  *
3080  * @param       pbSrc   [in]source big number
3081  * @param       BN_Dst  [out]output numberBits of four string
3082  *
3083  * @return      (cc_u8 *) four string
3084  */
3085 cc_u8 * SDRM_BN2STRFOUR(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src)
3086 {
3087         SDRM_BIG_NUM *d, *tempREM, *num;
3088         cc_u32 i;
3089         cc_u32 sLength = (2 * SDRM_SIZE_OF_DWORD) * BN_Src->Length;
3090         cc_u8 * strDestTemp = (cc_u8*)malloc(sLength * 10);
3091         cc_u8 * strDest;
3092         cc_u8 tempChar[10];
3093         (*numberBits) = 0;
3094
3095         if(strDestTemp == NULL)
3096         {
3097                 return NULL;
3098         }
3099
3100         d = SDRM_BN_Init(BN_Src->Size);
3101     if( d == NULL)// fix prevent cid =89093 by guoxing.xu
3102     {
3103                 free(strDestTemp);
3104         return NULL;
3105     }
3106         tempREM = SDRM_BN_Init(BN_Src->Size);
3107         num = SDRM_BN_Init(BN_Src->Size);
3108     if( num == NULL)//fix prevent cid = 89093 by guoxing.xu
3109     {
3110                 free(num);
3111                 free(strDestTemp);
3112         SDRM_BN_FREE(d);
3113         return NULL;
3114     }
3115         SDRM_BN_Copy(num, BN_Src);
3116         SDRM_BN_SetWord(d, 4);
3117
3118         while (!SDRM_BN_isZero(num))
3119         {
3120                 SDRM_BN_Div(num, tempREM, num, d);
3121                 //itoa(tempREM->pData[0], (char *)tempChar, 10);
3122                 //sprintf((char*)tempChar, "%d", tempREM->pData[0]);
3123                 snprintf((char*)tempChar, sizeof(tempChar), "%d", tempREM->pData[0]);// fix prevnet 60199 by guoxing.xu
3124                 strDestTemp[(*numberBits)] = tempChar[0];
3125                 (*numberBits)++;
3126
3127         }
3128         if((*numberBits) != 0)
3129         {
3130                 strDest = (cc_u8*)malloc((*numberBits) + 1);
3131                 for(i = 0; i < (*numberBits); i++) {
3132                         strDest[i] = strDestTemp[((*numberBits) - 1) - i];
3133                 }
3134                 strDest[(*numberBits)] = '\0';
3135         }
3136         else
3137         {
3138                 (*numberBits) = 1;
3139                 strDest = (cc_u8*)malloc((*numberBits) + 1);
3140                 strDest[0] = '0';
3141                 strDest[(*numberBits)] = '\0';
3142         }
3143
3144         free(strDestTemp);
3145         SDRM_BN_FREE(d);
3146         SDRM_BN_FREE(tempREM);
3147         SDRM_BN_FREE(num);
3148
3149         return strDest;
3150 }
3151
3152 /*
3153  * @fn          SDRM_BN_MassInit
3154  * @brief       Allocate a series of big number object
3155  *
3156  * @param       dBufSize        [in]buffer size of each big number
3157  * @param       count           [in]number BigNumbers
3158  *
3159  * @return      double pointer of SDRM_BIG_NUM structure
3160  * \n           NULL if memory allocation is failed
3161  */
3162 SDRM_BIG_NUM **SDRM_BN_MassInit(cc_u32 dBufSize, cc_u32 count)
3163 {
3164         cc_u32 i;
3165         cc_u32 bnsiz = sizeof(SDRM_BIG_NUM) + dBufSize * SDRM_SIZE_OF_DWORD;
3166         cc_u8* ptr;
3167     void * tmp;
3168
3169         SDRM_BIG_NUM** BN_Buf = (SDRM_BIG_NUM**)malloc((sizeof(SDRM_BIG_NUM*) + bnsiz) * count);
3170
3171         if (BN_Buf == NULL)
3172         {
3173                 return NULL;
3174         }
3175
3176         memset(BN_Buf, 0x00, (sizeof(SDRM_BIG_NUM*) + bnsiz) * count);
3177
3178         ptr = (cc_u8*)BN_Buf + sizeof(SDRM_BIG_NUM*) * count;
3179         for(i = 0; i < count; i++)
3180         {
3181             //add by guoxing.xu to avoid warning. 2/15/2014
3182             tmp = ptr;
3183         BN_Buf[i] = (SDRM_BIG_NUM*)tmp;
3184                 //BN_Buf[i] = (SDRM_BIG_NUM*)ptr;
3185                 BN_Buf[i]->Size = dBufSize;
3186         tmp = (ptr + sizeof(SDRM_BIG_NUM));
3187         BN_Buf[i]->pData =  (cc_u32*)tmp;
3188                 //BN_Buf[i]->pData = (cc_u32*)(ptr + sizeof(SDRM_BIG_NUM));
3189                 ptr += bnsiz;
3190         }
3191
3192         return BN_Buf;
3193 }
3194
3195 /*
3196  * @fn          SDRM_BN_IntInit
3197  * @brief       Allocate a big number object and assign an integer value
3198  *
3199  * @param       dSize           [in]buffer size of each big number
3200  * @param       data            [in]integer value
3201  *
3202  * @return      double pointer of SDRM_BIG_NUM structure
3203  * \n           NULL if memory allocation is failed
3204  */
3205 SDRM_BIG_NUM *SDRM_BN_IntInit(cc_u32 dSize, cc_u32 data)
3206 {
3207         SDRM_BIG_NUM* BN_Buf = SDRM_BN_Init(dSize);
3208         if (BN_Buf == NULL)
3209         {
3210                 return NULL;
3211         }
3212
3213         BN_Buf->pData[0] = data;
3214         BN_Buf->Length = 1;
3215
3216         return BN_Buf;
3217 }
3218
3219 /***************************** End of File *****************************/