ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ssl_calls.c
Go to the documentation of this file.
00001 /*
00002    This program is free software; you can redistribute it and/or modify
00003    it under the terms of the GNU General Public License as published by
00004    the Free Software Foundation; either version 2 of the License, or
00005    (at your option) any later version.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License along
00013    with this program; if not, write to the Free Software Foundation, Inc.,
00014    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00015 
00016    xrdp: A Remote Desktop Protocol server.
00017    Copyright (C) Jay Sorg 2004-2005
00018 
00019    ssl calls
00020 
00021 */
00022 
00023 #include <precomp.h>
00024 
00025 #define APP_CC
00026 
00027 /*****************************************************************************/
00028 static void * g_malloc(int size, int zero)
00029 {
00030   void * p;
00031 
00032   p = xmalloc(size);
00033   if (zero)
00034   {
00035     memset(p, 0, size);
00036   }
00037   return p;
00038 }
00039 
00040 /*****************************************************************************/
00041 static void g_free(void * in)
00042 {
00043   xfree(in);
00044 }
00045 
00046 /*****************************************************************************/
00047 /*****************************************************************************/
00048 /* rc4 stuff */
00049 /* An implementation of the ARC4 algorithm
00050  *
00051  * Copyright (C) 2001-2003  Christophe Devine
00052  */
00053 struct rc4_state
00054 {
00055   int x;
00056   int y;
00057   int m[256];
00058 };
00059 
00060 /*****************************************************************************/
00061 void* APP_CC
00062 ssl_rc4_info_create(void)
00063 {
00064   return g_malloc(sizeof(struct rc4_state), 1);
00065 }
00066 
00067 /*****************************************************************************/
00068 void APP_CC
00069 ssl_rc4_info_delete(void* rc4_info)
00070 {
00071   g_free(rc4_info);
00072 }
00073 
00074 /*****************************************************************************/
00075 void APP_CC
00076 ssl_rc4_set_key(void* rc4_info, char* key, int len)
00077 {
00078   int i;
00079   int j;
00080   int k;
00081   int a;
00082   int* m;
00083   struct rc4_state* s;
00084 
00085   s = (struct rc4_state*)rc4_info;
00086   s->x = 0;
00087   s->y = 0;
00088   m = s->m;
00089   for (i = 0; i < 256; i++)
00090   {
00091     m[i] = i;
00092   }
00093   j = 0;
00094   k = 0;
00095   for (i = 0; i < 256; i++)
00096   {
00097     a = m[i];
00098     j = (unsigned char)(j + a + key[k]);
00099     m[i] = m[j];
00100     m[j] = a;
00101     k++;
00102     if (k >= len)
00103     {
00104       k = 0;
00105     }
00106   }
00107 }
00108 
00109 /*****************************************************************************/
00110 void APP_CC
00111 ssl_rc4_crypt(void* rc4_info, char* in_data, char* out_data, int len)
00112 {
00113   int i;
00114   int x;
00115   int y;
00116   int a;
00117   int b;
00118   int* m;
00119   struct rc4_state* s;
00120 
00121   s = (struct rc4_state*)rc4_info;
00122   x = s->x;
00123   y = s->y;
00124   m = s->m;
00125   for (i = 0; i < len; i++)
00126   {
00127     x = (unsigned char)(x + 1);
00128     a = m[x];
00129     y = (unsigned char)(y + a);
00130     b = m[y];
00131     m[x] = b;
00132     m[y] = a;
00133     out_data[i] = in_data[i] ^ (m[(unsigned char)(a + b)]);
00134   }
00135   s->x = x;
00136   s->y = y;
00137 }
00138 
00139 /*****************************************************************************/
00140 /*****************************************************************************/
00141 /* sha1 stuff */
00142 /* FIPS-180-1 compliant SHA-1 implementation
00143  *
00144  * Copyright (C) 2001-2003  Christophe Devine
00145  */
00146 struct sha1_context
00147 {
00148   int total[2];
00149   int state[5];
00150   char buffer[64];
00151 };
00152 
00153 /*****************************************************************************/
00154 void* APP_CC
00155 ssl_sha1_info_create(void)
00156 {
00157   return g_malloc(sizeof(struct sha1_context), 1);
00158 }
00159 
00160 /*****************************************************************************/
00161 void APP_CC
00162 ssl_sha1_info_delete(void* sha1_info)
00163 {
00164   g_free(sha1_info);
00165 }
00166 
00167 /*****************************************************************************/
00168 void APP_CC
00169 ssl_sha1_clear(void* sha1_info)
00170 {
00171   struct sha1_context* ctx;
00172 
00173   ctx = (struct sha1_context*)sha1_info;
00174   memset(ctx, 0, sizeof(struct sha1_context));
00175   ctx->state[0] = 0x67452301;
00176   ctx->state[1] = 0xEFCDAB89;
00177   ctx->state[2] = 0x98BADCFE;
00178   ctx->state[3] = 0x10325476;
00179   ctx->state[4] = 0xC3D2E1F0;
00180 }
00181 
00182 #undef GET_UINT32
00183 #define GET_UINT32(n, b, i)          \
00184 {                                    \
00185   (n) = ((b)[(i) + 0] << 24) |       \
00186         ((b)[(i) + 1] << 16) |       \
00187         ((b)[(i) + 2] << 8) |        \
00188         ((b)[(i) + 3] << 0);         \
00189 }
00190 
00191 #undef PUT_UINT32
00192 #define PUT_UINT32(n, b, i)         \
00193 {                                   \
00194   (b)[(i) + 0] = ((n) >> 24);       \
00195   (b)[(i) + 1] = ((n) >> 16);       \
00196   (b)[(i) + 2] = ((n) >> 8);        \
00197   (b)[(i) + 3] = ((n) >> 0);        \
00198 }
00199 
00200 /*****************************************************************************/
00201 static void APP_CC
00202 sha1_process(struct sha1_context* ctx, char* in_data)
00203 {
00204   int temp;
00205   int W[16];
00206   int A;
00207   int B;
00208   int C;
00209   int D;
00210   int E;
00211   unsigned char* data;
00212 
00213   data = (unsigned char*)in_data;
00214 
00215   GET_UINT32(W[0], data, 0);
00216   GET_UINT32(W[1], data, 4);
00217   GET_UINT32(W[2], data, 8);
00218   GET_UINT32(W[3], data, 12);
00219   GET_UINT32(W[4], data, 16);
00220   GET_UINT32(W[5], data, 20);
00221   GET_UINT32(W[6], data, 24);
00222   GET_UINT32(W[7], data, 28);
00223   GET_UINT32(W[8], data, 32);
00224   GET_UINT32(W[9], data, 36);
00225   GET_UINT32(W[10], data, 40);
00226   GET_UINT32(W[11], data, 44);
00227   GET_UINT32(W[12], data, 48);
00228   GET_UINT32(W[13], data, 52);
00229   GET_UINT32(W[14], data, 56);
00230   GET_UINT32(W[15], data, 60);
00231 
00232 #define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00233 
00234 #define R(t)                        \
00235 (                                   \
00236   temp = W[(t - 3) & 0x0F] ^        \
00237          W[(t - 8) & 0x0F] ^        \
00238          W[(t - 14) & 0x0F] ^       \
00239          W[(t - 0) & 0x0F],         \
00240          (W[t & 0x0F] = S(temp, 1)) \
00241 )
00242 
00243 #undef P
00244 #define P(a, b, c, d, e, x)          \
00245 {                                    \
00246   e += S(a, 5) + F(b, c, d) + K + x; \
00247   b = S(b, 30);                      \
00248 }
00249 
00250   A = ctx->state[0];
00251   B = ctx->state[1];
00252   C = ctx->state[2];
00253   D = ctx->state[3];
00254   E = ctx->state[4];
00255 
00256 #define F(x, y, z) (z ^ (x & (y ^ z)))
00257 #define K 0x5A827999
00258 
00259   P(A, B, C, D, E, W[0]);
00260   P(E, A, B, C, D, W[1]);
00261   P(D, E, A, B, C, W[2]);
00262   P(C, D, E, A, B, W[3]);
00263   P(B, C, D, E, A, W[4]);
00264   P(A, B, C, D, E, W[5]);
00265   P(E, A, B, C, D, W[6]);
00266   P(D, E, A, B, C, W[7]);
00267   P(C, D, E, A, B, W[8]);
00268   P(B, C, D, E, A, W[9]);
00269   P(A, B, C, D, E, W[10]);
00270   P(E, A, B, C, D, W[11]);
00271   P(D, E, A, B, C, W[12]);
00272   P(C, D, E, A, B, W[13]);
00273   P(B, C, D, E, A, W[14]);
00274   P(A, B, C, D, E, W[15]);
00275   P(E, A, B, C, D, R(16));
00276   P(D, E, A, B, C, R(17));
00277   P(C, D, E, A, B, R(18));
00278   P(B, C, D, E, A, R(19));
00279 
00280 #undef K
00281 #undef F
00282 
00283 #define F(x, y, z) (x ^ y ^ z)
00284 #define K 0x6ED9EBA1
00285 
00286   P(A, B, C, D, E, R(20));
00287   P(E, A, B, C, D, R(21));
00288   P(D, E, A, B, C, R(22));
00289   P(C, D, E, A, B, R(23));
00290   P(B, C, D, E, A, R(24));
00291   P(A, B, C, D, E, R(25));
00292   P(E, A, B, C, D, R(26));
00293   P(D, E, A, B, C, R(27));
00294   P(C, D, E, A, B, R(28));
00295   P(B, C, D, E, A, R(29));
00296   P(A, B, C, D, E, R(30));
00297   P(E, A, B, C, D, R(31));
00298   P(D, E, A, B, C, R(32));
00299   P(C, D, E, A, B, R(33));
00300   P(B, C, D, E, A, R(34));
00301   P(A, B, C, D, E, R(35));
00302   P(E, A, B, C, D, R(36));
00303   P(D, E, A, B, C, R(37));
00304   P(C, D, E, A, B, R(38));
00305   P(B, C, D, E, A, R(39));
00306 
00307 #undef K
00308 #undef F
00309 
00310 #define F(x, y, z) ((x & y) | (z & (x | y)))
00311 #define K 0x8F1BBCDC
00312 
00313   P(A, B, C, D, E, R(40));
00314   P(E, A, B, C, D, R(41));
00315   P(D, E, A, B, C, R(42));
00316   P(C, D, E, A, B, R(43));
00317   P(B, C, D, E, A, R(44));
00318   P(A, B, C, D, E, R(45));
00319   P(E, A, B, C, D, R(46));
00320   P(D, E, A, B, C, R(47));
00321   P(C, D, E, A, B, R(48));
00322   P(B, C, D, E, A, R(49));
00323   P(A, B, C, D, E, R(50));
00324   P(E, A, B, C, D, R(51));
00325   P(D, E, A, B, C, R(52));
00326   P(C, D, E, A, B, R(53));
00327   P(B, C, D, E, A, R(54));
00328   P(A, B, C, D, E, R(55));
00329   P(E, A, B, C, D, R(56));
00330   P(D, E, A, B, C, R(57));
00331   P(C, D, E, A, B, R(58));
00332   P(B, C, D, E, A, R(59));
00333 
00334 #undef K
00335 #undef F
00336 
00337 #define F(x, y, z) (x ^ y ^ z)
00338 #define K 0xCA62C1D6
00339 
00340   P(A, B, C, D, E, R(60));
00341   P(E, A, B, C, D, R(61));
00342   P(D, E, A, B, C, R(62));
00343   P(C, D, E, A, B, R(63));
00344   P(B, C, D, E, A, R(64));
00345   P(A, B, C, D, E, R(65));
00346   P(E, A, B, C, D, R(66));
00347   P(D, E, A, B, C, R(67));
00348   P(C, D, E, A, B, R(68));
00349   P(B, C, D, E, A, R(69));
00350   P(A, B, C, D, E, R(70));
00351   P(E, A, B, C, D, R(71));
00352   P(D, E, A, B, C, R(72));
00353   P(C, D, E, A, B, R(73));
00354   P(B, C, D, E, A, R(74));
00355   P(A, B, C, D, E, R(75));
00356   P(E, A, B, C, D, R(76));
00357   P(D, E, A, B, C, R(77));
00358   P(C, D, E, A, B, R(78));
00359   P(B, C, D, E, A, R(79));
00360 
00361 #undef K
00362 #undef F
00363 
00364   ctx->state[0] += A;
00365   ctx->state[1] += B;
00366   ctx->state[2] += C;
00367   ctx->state[3] += D;
00368   ctx->state[4] += E;
00369 }
00370 
00371 /*****************************************************************************/
00372 void APP_CC
00373 ssl_sha1_transform(void* sha1_info, char* data, int len)
00374 {
00375   int left;
00376   int fill;
00377   struct sha1_context* ctx;
00378 
00379   ctx = (struct sha1_context*)sha1_info;
00380   if (len == 0)
00381   {
00382     return;
00383   }
00384   left = ctx->total[0] & 0x3F;
00385   fill = 64 - left;
00386   ctx->total[0] += len;
00387   ctx->total[0] &= 0xFFFFFFFF;
00388   if (ctx->total[0] < len)
00389   {
00390     ctx->total[1]++;
00391   }
00392   if (left && (len >= fill))
00393   {
00394     memcpy(ctx->buffer + left, data, fill);
00395     sha1_process(ctx, ctx->buffer);
00396     len -= fill;
00397     data += fill;
00398     left = 0;
00399   }
00400   while (len >= 64)
00401   {
00402     sha1_process(ctx, data);
00403     len -= 64;
00404     data += 64;
00405   }
00406   if (len != 0)
00407   {
00408     memcpy(ctx->buffer + left, data, len);
00409   }
00410 }
00411 
00412 static unsigned char sha1_padding[64] =
00413 {
00414   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00415      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00416      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00417      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00418 };
00419 
00420 /*****************************************************************************/
00421 void APP_CC
00422 ssl_sha1_complete(void* sha1_info, char* data)
00423 {
00424   int last;
00425   int padn;
00426   int high;
00427   int low;
00428   char msglen[8];
00429   struct sha1_context* ctx;
00430 
00431   ctx = (struct sha1_context*)sha1_info;
00432   high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
00433   low = (ctx->total[0] << 3);
00434   PUT_UINT32(high, msglen, 0);
00435   PUT_UINT32(low, msglen, 4);
00436   last = ctx->total[0] & 0x3F;
00437   padn = (last < 56) ? (56 - last) : (120 - last);
00438   ssl_sha1_transform(ctx, (char *)sha1_padding, padn);
00439   ssl_sha1_transform(ctx, msglen, 8);
00440   PUT_UINT32(ctx->state[0], data, 0);
00441   PUT_UINT32(ctx->state[1], data, 4);
00442   PUT_UINT32(ctx->state[2], data, 8);
00443   PUT_UINT32(ctx->state[3], data, 12);
00444   PUT_UINT32(ctx->state[4], data, 16);
00445 }
00446 
00447 /*****************************************************************************/
00448 /*****************************************************************************/
00449 /* md5 stuff */
00450 /* RFC 1321 compliant MD5 implementation
00451  *
00452  * Copyright (C) 2001-2003  Christophe Devine
00453  */
00454 
00455 struct md5_context
00456 {
00457   int total[2];
00458   int state[4];
00459   char buffer[64];
00460 };
00461 
00462 /*****************************************************************************/
00463 void* APP_CC
00464 ssl_md5_info_create(void)
00465 {
00466   return g_malloc(sizeof(struct md5_context), 1);
00467 }
00468 
00469 /*****************************************************************************/
00470 void APP_CC
00471 ssl_md5_info_delete(void* md5_info)
00472 {
00473   g_free(md5_info);
00474 }
00475 
00476 /*****************************************************************************/
00477 void APP_CC
00478 ssl_md5_clear(void* md5_info)
00479 {
00480   struct md5_context* ctx;
00481 
00482   ctx = (struct md5_context*)md5_info;
00483   memset(ctx, 0, sizeof(struct md5_context));
00484   ctx->state[0] = 0x67452301;
00485   ctx->state[1] = 0xEFCDAB89;
00486   ctx->state[2] = 0x98BADCFE;
00487   ctx->state[3] = 0x10325476;
00488 }
00489 
00490 #undef GET_UINT32
00491 #define GET_UINT32(n, b, i)          \
00492 {                                    \
00493   (n) = ((b)[(i) + 0] << 0) |        \
00494         ((b)[(i) + 1] << 8) |        \
00495         ((b)[(i) + 2] << 16) |       \
00496         ((b)[(i) + 3] << 24);        \
00497 }
00498 
00499 #undef PUT_UINT32
00500 #define PUT_UINT32(n, b, i)          \
00501 {                                    \
00502   (b)[(i) + 0] = ((n) >> 0);         \
00503   (b)[(i) + 1] = ((n) >> 8);         \
00504   (b)[(i) + 2] = ((n) >> 16);        \
00505   (b)[(i) + 3] = ((n) >> 24);        \
00506 }
00507 
00508 /*****************************************************************************/
00509 static void
00510 md5_process(struct md5_context* ctx, char* in_data)
00511 {
00512   int X[16];
00513   int A;
00514   int B;
00515   int C;
00516   int D;
00517   unsigned char* data;
00518 
00519   data = (unsigned char*)in_data;
00520   GET_UINT32(X[0], data, 0);
00521   GET_UINT32(X[1], data, 4);
00522   GET_UINT32(X[2], data, 8);
00523   GET_UINT32(X[3], data, 12);
00524   GET_UINT32(X[4], data, 16);
00525   GET_UINT32(X[5], data, 20);
00526   GET_UINT32(X[6], data, 24);
00527   GET_UINT32(X[7], data, 28);
00528   GET_UINT32(X[8], data, 32);
00529   GET_UINT32(X[9], data, 36);
00530   GET_UINT32(X[10], data, 40);
00531   GET_UINT32(X[11], data, 44);
00532   GET_UINT32(X[12], data, 48);
00533   GET_UINT32(X[13], data, 52);
00534   GET_UINT32(X[14], data, 56);
00535   GET_UINT32(X[15], data, 60);
00536 
00537 #define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00538 
00539 #undef P
00540 #define P(a, b, c, d, k, s, t) \
00541 {                              \
00542   a += F(b, c, d) + X[k] + t;  \
00543   a = S(a, s) + b;             \
00544 }
00545 
00546   A = ctx->state[0];
00547   B = ctx->state[1];
00548   C = ctx->state[2];
00549   D = ctx->state[3];
00550 
00551 #define F(x, y, z) (z ^ (x & (y ^ z)))
00552 
00553   P(A, B, C, D,  0,  7, 0xD76AA478);
00554   P(D, A, B, C,  1, 12, 0xE8C7B756);
00555   P(C, D, A, B,  2, 17, 0x242070DB);
00556   P(B, C, D, A,  3, 22, 0xC1BDCEEE);
00557   P(A, B, C, D,  4,  7, 0xF57C0FAF);
00558   P(D, A, B, C,  5, 12, 0x4787C62A);
00559   P(C, D, A, B,  6, 17, 0xA8304613);
00560   P(B, C, D, A,  7, 22, 0xFD469501);
00561   P(A, B, C, D,  8,  7, 0x698098D8);
00562   P(D, A, B, C,  9, 12, 0x8B44F7AF);
00563   P(C, D, A, B, 10, 17, 0xFFFF5BB1);
00564   P(B, C, D, A, 11, 22, 0x895CD7BE);
00565   P(A, B, C, D, 12,  7, 0x6B901122);
00566   P(D, A, B, C, 13, 12, 0xFD987193);
00567   P(C, D, A, B, 14, 17, 0xA679438E);
00568   P(B, C, D, A, 15, 22, 0x49B40821);
00569 
00570 #undef F
00571 
00572 #define F(x, y, z) (y ^ (z & (x ^ y)))
00573 
00574   P(A, B, C, D,  1,  5, 0xF61E2562);
00575   P(D, A, B, C,  6,  9, 0xC040B340);
00576   P(C, D, A, B, 11, 14, 0x265E5A51);
00577   P(B, C, D, A,  0, 20, 0xE9B6C7AA);
00578   P(A, B, C, D,  5,  5, 0xD62F105D);
00579   P(D, A, B, C, 10,  9, 0x02441453);
00580   P(C, D, A, B, 15, 14, 0xD8A1E681);
00581   P(B, C, D, A,  4, 20, 0xE7D3FBC8);
00582   P(A, B, C, D,  9,  5, 0x21E1CDE6);
00583   P(D, A, B, C, 14,  9, 0xC33707D6);
00584   P(C, D, A, B,  3, 14, 0xF4D50D87);
00585   P(B, C, D, A,  8, 20, 0x455A14ED);
00586   P(A, B, C, D, 13,  5, 0xA9E3E905);
00587   P(D, A, B, C,  2,  9, 0xFCEFA3F8);
00588   P(C, D, A, B,  7, 14, 0x676F02D9);
00589   P(B, C, D, A, 12, 20, 0x8D2A4C8A);
00590 
00591 #undef F
00592 
00593 #define F(x, y, z) (x ^ y ^ z)
00594 
00595   P(A, B, C, D,  5,  4, 0xFFFA3942);
00596   P(D, A, B, C,  8, 11, 0x8771F681);
00597   P(C, D, A, B, 11, 16, 0x6D9D6122);
00598   P(B, C, D, A, 14, 23, 0xFDE5380C);
00599   P(A, B, C, D,  1,  4, 0xA4BEEA44);
00600   P(D, A, B, C,  4, 11, 0x4BDECFA9);
00601   P(C, D, A, B,  7, 16, 0xF6BB4B60);
00602   P(B, C, D, A, 10, 23, 0xBEBFBC70);
00603   P(A, B, C, D, 13,  4, 0x289B7EC6);
00604   P(D, A, B, C,  0, 11, 0xEAA127FA);
00605   P(C, D, A, B,  3, 16, 0xD4EF3085);
00606   P(B, C, D, A,  6, 23, 0x04881D05);
00607   P(A, B, C, D,  9,  4, 0xD9D4D039);
00608   P(D, A, B, C, 12, 11, 0xE6DB99E5);
00609   P(C, D, A, B, 15, 16, 0x1FA27CF8);
00610   P(B, C, D, A,  2, 23, 0xC4AC5665);
00611 
00612 #undef F
00613 
00614 #define F(x, y, z) (y ^ (x | ~z))
00615 
00616   P(A, B, C, D,  0,  6, 0xF4292244);
00617   P(D, A, B, C,  7, 10, 0x432AFF97);
00618   P(C, D, A, B, 14, 15, 0xAB9423A7);
00619   P(B, C, D, A,  5, 21, 0xFC93A039);
00620   P(A, B, C, D, 12,  6, 0x655B59C3);
00621   P(D, A, B, C,  3, 10, 0x8F0CCC92);
00622   P(C, D, A, B, 10, 15, 0xFFEFF47D);
00623   P(B, C, D, A,  1, 21, 0x85845DD1);
00624   P(A, B, C, D,  8,  6, 0x6FA87E4F);
00625   P(D, A, B, C, 15, 10, 0xFE2CE6E0);
00626   P(C, D, A, B,  6, 15, 0xA3014314);
00627   P(B, C, D, A, 13, 21, 0x4E0811A1);
00628   P(A, B, C, D,  4,  6, 0xF7537E82);
00629   P(D, A, B, C, 11, 10, 0xBD3AF235);
00630   P(C, D, A, B,  2, 15, 0x2AD7D2BB);
00631   P(B, C, D, A,  9, 21, 0xEB86D391);
00632 
00633 #undef F
00634 
00635   ctx->state[0] += A;
00636   ctx->state[1] += B;
00637   ctx->state[2] += C;
00638   ctx->state[3] += D;
00639 }
00640 
00641 /*****************************************************************************/
00642 void APP_CC
00643 ssl_md5_transform(void* md5_info, char* data, int len)
00644 {
00645   int left;
00646   int fill;
00647   struct md5_context* ctx;
00648 
00649   ctx = (struct md5_context*)md5_info;
00650   if (len == 0)
00651   {
00652     return;
00653   }
00654   left = ctx->total[0] & 0x3F;
00655   fill = 64 - left;
00656   ctx->total[0] += len;
00657   ctx->total[0] &= 0xFFFFFFFF;
00658   if (ctx->total[0] < len)
00659   {
00660     ctx->total[1]++;
00661   }
00662   if (left && (len >= fill))
00663   {
00664     memcpy(ctx->buffer + left, data, fill);
00665     md5_process(ctx, ctx->buffer);
00666     len -= fill;
00667     data += fill;
00668     left = 0;
00669   }
00670   while (len >= 64)
00671   {
00672     md5_process(ctx, data);
00673     len -= 64;
00674     data += 64;
00675   }
00676   if (len != 0)
00677   {
00678     memcpy(ctx->buffer + left, data, len);
00679   }
00680 }
00681 
00682 static unsigned char md5_padding[64] =
00683 {
00684   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00685      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00686      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00687      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00688 };
00689 
00690 /*****************************************************************************/
00691 void APP_CC
00692 ssl_md5_complete(void* md5_info, char* data)
00693 {
00694   int last;
00695   int padn;
00696   int high;
00697   int low;
00698   char msglen[8];
00699   struct md5_context* ctx;
00700 
00701   ctx = (struct md5_context*)md5_info;
00702   high = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
00703   low = (ctx->total[0] << 3);
00704   PUT_UINT32(low, msglen, 0);
00705   PUT_UINT32(high, msglen, 4);
00706   last = ctx->total[0] & 0x3F;
00707   padn = (last < 56) ? (56 - last) : (120 - last);
00708   ssl_md5_transform(ctx, (char *)md5_padding, padn);
00709   ssl_md5_transform(ctx, msglen, 8);
00710   PUT_UINT32(ctx->state[0], data, 0);
00711   PUT_UINT32(ctx->state[1], data, 4);
00712   PUT_UINT32(ctx->state[2], data, 8);
00713   PUT_UINT32(ctx->state[3], data, 12);
00714 }
00715 
00716 /*****************************************************************************/
00717 /*****************************************************************************/
00718 /* big number stuff */
00719 /******************* SHORT COPYRIGHT NOTICE*************************
00720 This source code is part of the BigDigits multiple-precision
00721 arithmetic library Version 1.0 originally written by David Ireland,
00722 copyright (c) 2001 D.I. Management Services Pty Limited, all rights
00723 reserved. It is provided "as is" with no warranties. You may use
00724 this software under the terms of the full copyright notice
00725 "bigdigitsCopyright.txt" that should have been included with
00726 this library. To obtain a copy send an email to
00727 <code@di-mgt.com.au> or visit <www.di-mgt.com.au/crypto.html>.
00728 This notice must be retained in any copy.
00729 ****************** END OF COPYRIGHT NOTICE*************************/
00730 /************************* COPYRIGHT NOTICE*************************
00731 This source code is part of the BigDigits multiple-precision
00732 arithmetic library Version 1.0 originally written by David Ireland,
00733 copyright (c) 2001 D.I. Management Services Pty Limited, all rights
00734 reserved. You are permitted to use compiled versions of this code as
00735 part of your own executable files and to distribute unlimited copies
00736 of such executable files for any purposes including commercial ones
00737 provided you keep the copyright notices intact in the source code
00738 and that you ensure that the following characters remain in any
00739 object or executable files you distribute:
00740 
00741 "Contains multiple-precision arithmetic code originally written
00742 by David Ireland, copyright (c) 2001 by D.I. Management Services
00743 Pty Limited <www.di-mgt.com.au>, and is used with permission."
00744 
00745 David Ireland and DI Management Services Pty Limited make no
00746 representations concerning either the merchantability of this
00747 software or the suitability of this software for any particular
00748 purpose. It is provided "as is" without express or implied warranty
00749 of any kind.
00750 
00751 Please forward any comments and bug reports to <code@di-mgt.com.au>.
00752 The latest version of the source code can be downloaded from
00753 www.di-mgt.com.au/crypto.html.
00754 ****************** END OF COPYRIGHT NOTICE*************************/
00755 
00756 typedef unsigned int DIGIT_T;
00757 #define HIBITMASK 0x80000000
00758 #define MAX_DIG_LEN 51
00759 #define MAX_DIGIT 0xffffffff
00760 #define BITS_PER_DIGIT 32
00761 #define MAX_HALF_DIGIT 0xffff
00762 #define B_J (MAX_HALF_DIGIT + 1)
00763 #define LOHALF(x) ((DIGIT_T)((x) & 0xffff))
00764 #define HIHALF(x) ((DIGIT_T)((x) >> 16 & 0xffff))
00765 #define TOHIGH(x) ((DIGIT_T)((x) << 16))
00766 
00767 #define mpNEXTBITMASK(mask, n) \
00768 { \
00769   if (mask == 1) \
00770   { \
00771     mask = HIBITMASK; \
00772     n--; \
00773   } \
00774   else \
00775   { \
00776     mask >>= 1; \
00777   } \
00778 }
00779 
00780 /*****************************************************************************/
00781 static DIGIT_T APP_CC
00782 mpAdd(DIGIT_T* w, DIGIT_T* u, DIGIT_T* v, unsigned int ndigits)
00783 {
00784   /* Calculates w = u + v
00785      where w, u, v are multiprecision integers of ndigits each
00786      Returns carry if overflow. Carry = 0 or 1.
00787 
00788      Ref: Knuth Vol 2 Ch 4.3.1 p 266 Algorithm A. */
00789   DIGIT_T k;
00790   unsigned int j;
00791 
00792   /* Step A1. Initialise */
00793   k = 0;
00794   for (j = 0; j < ndigits; j++)
00795   {
00796     /* Step A2. Add digits w_j = (u_j + v_j + k)
00797        Set k = 1 if carry (overflow) occurs */
00798     w[j] = u[j] + k;
00799     if (w[j] < k)
00800     {
00801       k = 1;
00802     }
00803     else
00804     {
00805       k = 0;
00806     }
00807     w[j] += v[j];
00808     if (w[j] < v[j])
00809     {
00810       k++;
00811     }
00812   } /* Step A3. Loop on j */
00813   return k; /* w_n = k */
00814 }
00815 
00816 /*****************************************************************************/
00817 static void APP_CC
00818 mpSetDigit(DIGIT_T* a, DIGIT_T d, unsigned int ndigits)
00819 { /* Sets a = d where d is a single digit */
00820   unsigned int i;
00821 
00822   for (i = 1; i < ndigits; i++)
00823   {
00824     a[i] = 0;
00825   }
00826   a[0] = d;
00827 }
00828 
00829 /*****************************************************************************/
00830 static int APP_CC
00831 mpCompare(DIGIT_T* a, DIGIT_T* b, unsigned int ndigits)
00832 {
00833   /* Returns sign of (a - b) */
00834   if (ndigits == 0)
00835   {
00836     return 0;
00837   }
00838   while (ndigits--)
00839   {
00840     if (a[ndigits] > b[ndigits])
00841     {
00842       return 1; /* GT */
00843     }
00844     if (a[ndigits] < b[ndigits])
00845     {
00846       return -1; /* LT */
00847     }
00848   }
00849   return 0; /* EQ */
00850 }
00851 
00852 /*****************************************************************************/
00853 static void APP_CC
00854 mpSetZero(DIGIT_T* a, unsigned int ndigits)
00855 { /* Sets a = 0 */
00856   unsigned int i;
00857 
00858   for (i = 0; i < ndigits; i++)
00859   {
00860     a[i] = 0;
00861   }
00862 }
00863 
00864 /*****************************************************************************/
00865 static void APP_CC
00866 mpSetEqual(DIGIT_T* a, DIGIT_T* b, unsigned int ndigits)
00867 {  /* Sets a = b */
00868   unsigned int i;
00869 
00870   for (i = 0; i < ndigits; i++)
00871   {
00872     a[i] = b[i];
00873   }
00874 }
00875 
00876 /*****************************************************************************/
00877 static unsigned int APP_CC
00878 mpSizeof(DIGIT_T* a, unsigned int ndigits)
00879 {  /* Returns size of significant digits in a */
00880   while (ndigits--)
00881   {
00882     if (a[ndigits] != 0)
00883     {
00884       return (++ndigits);
00885     }
00886   }
00887   return 0;
00888 }
00889 
00890 /*****************************************************************************/
00891 static DIGIT_T APP_CC
00892 mpShiftLeft(DIGIT_T* a, DIGIT_T* b, unsigned int x, unsigned int ndigits)
00893 { /* Computes a = b << x */
00894   unsigned int i;
00895   unsigned int y;
00896   DIGIT_T mask;
00897   DIGIT_T carry;
00898   DIGIT_T nextcarry;
00899 
00900   /* Check input - NB unspecified result */
00901   if (x >= BITS_PER_DIGIT)
00902   {
00903     return 0;
00904   }
00905   /* Construct mask */
00906   mask = HIBITMASK;
00907   for (i = 1; i < x; i++)
00908   {
00909     mask = (mask >> 1) | mask;
00910   }
00911   if (x == 0)
00912   {
00913     mask = 0x0;
00914   }
00915   y = BITS_PER_DIGIT - x;
00916   carry = 0;
00917   for (i = 0; i < ndigits; i++)
00918   {
00919     nextcarry = (b[i] & mask) >> y;
00920     a[i] = b[i] << x | carry;
00921     carry = nextcarry;
00922   }
00923   return carry;
00924 }
00925 
00926 /*****************************************************************************/
00927 static DIGIT_T APP_CC
00928 mpShiftRight(DIGIT_T* a, DIGIT_T* b, unsigned int x, unsigned int ndigits)
00929 { /* Computes a = b >> x */
00930   unsigned int i;
00931   unsigned int y;
00932   DIGIT_T mask;
00933   DIGIT_T carry;
00934   DIGIT_T nextcarry;
00935 
00936   /* Check input  - NB unspecified result */
00937   if (x >= BITS_PER_DIGIT)
00938   {
00939     return 0;
00940   }
00941   /* Construct mask */
00942   mask = 0x1;
00943   for (i = 1; i < x; i++)
00944   {
00945     mask = (mask << 1) | mask;
00946   }
00947   if (x == 0)
00948   {
00949     mask = 0x0;
00950   }
00951   y = BITS_PER_DIGIT - x;
00952   carry = 0;
00953   i = ndigits;
00954   while (i--)
00955   {
00956     nextcarry = (b[i] & mask) << y;
00957     a[i] = b[i] >> x | carry;
00958     carry = nextcarry;
00959   }
00960   return carry;
00961 }
00962 
00963 /*****************************************************************************/
00964 static void APP_CC
00965 spMultSub(DIGIT_T* uu, DIGIT_T qhat, DIGIT_T v1, DIGIT_T v0)
00966 {
00967   /* Compute uu = uu - q(v1v0)
00968      where uu = u3u2u1u0, u3 = 0
00969      and u_n, v_n are all half-digits
00970      even though v1, v2 are passed as full digits. */
00971   DIGIT_T p0;
00972   DIGIT_T p1;
00973   DIGIT_T t;
00974 
00975   p0 = qhat * v0;
00976   p1 = qhat * v1;
00977   t = p0 + TOHIGH(LOHALF(p1));
00978   uu[0] -= t;
00979   if (uu[0] > MAX_DIGIT - t)
00980   {
00981     uu[1]--; /* Borrow */
00982   }
00983   uu[1] -= HIHALF(p1);
00984 }
00985 
00986 /*****************************************************************************/
00987 static int APP_CC
00988 spMultiply(DIGIT_T* p, DIGIT_T x, DIGIT_T y)
00989 { /* Computes p = x * y */
00990   /* Ref: Arbitrary Precision Computation
00991      http://numbers.computation.free.fr/Constants/constants.html
00992 
00993          high    p1                p0     low
00994         +--------+--------+--------+--------+
00995         |      x1*y1      |      x0*y0      |
00996         +--------+--------+--------+--------+
00997                +-+--------+--------+
00998                |1| (x0*y1 + x1*y1) |
00999                +-+--------+--------+
01000                 ^carry from adding (x0*y1+x1*y1) together
01001                         +-+
01002                         |1|< carry from adding LOHALF t
01003                         +-+  to high half of p0 */
01004   DIGIT_T x0;
01005   DIGIT_T y0;
01006   DIGIT_T x1;
01007   DIGIT_T y1;
01008   DIGIT_T t;
01009   DIGIT_T u;
01010   DIGIT_T carry;
01011 
01012   /* Split each x,y into two halves
01013      x = x0 + B * x1
01014      y = y0 + B * y1
01015      where B = 2^16, half the digit size
01016      Product is
01017         xy = x0y0 + B(x0y1 + x1y0) + B^2(x1y1) */
01018 
01019   x0 = LOHALF(x);
01020   x1 = HIHALF(x);
01021   y0 = LOHALF(y);
01022   y1 = HIHALF(y);
01023 
01024   /* Calc low part - no carry */
01025   p[0] = x0 * y0;
01026 
01027   /* Calc middle part */
01028   t = x0 * y1;
01029   u = x1 * y0;
01030   t += u;
01031   if (t < u)
01032   {
01033     carry = 1;
01034   }
01035   else
01036   {
01037     carry = 0;
01038   }
01039   /* This carry will go to high half of p[1]
01040      + high half of t into low half of p[1] */
01041   carry = TOHIGH(carry) + HIHALF(t);
01042 
01043   /* Add low half of t to high half of p[0] */
01044   t = TOHIGH(t);
01045   p[0] += t;
01046   if (p[0] < t)
01047   {
01048     carry++;
01049   }
01050 
01051   p[1] = x1 * y1;
01052   p[1] += carry;
01053 
01054   return 0;
01055 }
01056 
01057 /*****************************************************************************/
01058 static DIGIT_T APP_CC
01059 spDivide(DIGIT_T* q, DIGIT_T* r, DIGIT_T* u, DIGIT_T v)
01060 { /* Computes quotient q = u / v, remainder r = u mod v
01061      where u is a double digit
01062      and q, v, r are single precision digits.
01063      Returns high digit of quotient (max value is 1)
01064      Assumes normalised such that v1 >= b/2
01065      where b is size of HALF_DIGIT
01066      i.e. the most significant bit of v should be one
01067 
01068      In terms of half-digits in Knuth notation:
01069      (q2q1q0) = (u4u3u2u1u0) / (v1v0)
01070      (r1r0) = (u4u3u2u1u0) mod (v1v0)
01071      for m = 2, n = 2 where u4 = 0
01072      q2 is either 0 or 1.
01073      We set q = (q1q0) and return q2 as "overflow' */
01074   DIGIT_T qhat;
01075   DIGIT_T rhat;
01076   DIGIT_T t;
01077   DIGIT_T v0;
01078   DIGIT_T v1;
01079   DIGIT_T u0;
01080   DIGIT_T u1;
01081   DIGIT_T u2;
01082   DIGIT_T u3;
01083   DIGIT_T uu[2];
01084   DIGIT_T q2;
01085 
01086   /* Check for normalisation */
01087   if (!(v & HIBITMASK))
01088   {
01089     *q = *r = 0;
01090     return MAX_DIGIT;
01091   }
01092 
01093   /* Split up into half-digits */
01094   v0 = LOHALF(v);
01095   v1 = HIHALF(v);
01096   u0 = LOHALF(u[0]);
01097   u1 = HIHALF(u[0]);
01098   u2 = LOHALF(u[1]);
01099   u3 = HIHALF(u[1]);
01100 
01101   /* Do three rounds of Knuth Algorithm D Vol 2 p272 */
01102 
01103   /* ROUND 1. Set j = 2 and calculate q2 */
01104   /* Estimate qhat = (u4u3)/v1  = 0 or 1
01105      then set (u4u3u2) -= qhat(v1v0)
01106      where u4 = 0. */
01107   qhat = u3 / v1;
01108   if (qhat > 0)
01109   {
01110     rhat = u3 - qhat * v1;
01111     t = TOHIGH(rhat) | u2;
01112     if (qhat * v0 > t)
01113     {
01114       qhat--;
01115     }
01116   }
01117   uu[1] = 0; /* (u4) */
01118   uu[0] = u[1]; /* (u3u2) */
01119   if (qhat > 0)
01120   {
01121     /* (u4u3u2) -= qhat(v1v0) where u4 = 0 */
01122     spMultSub(uu, qhat, v1, v0);
01123     if (HIHALF(uu[1]) != 0)
01124     { /* Add back */
01125       qhat--;
01126       uu[0] += v;
01127       uu[1] = 0;
01128     }
01129   }
01130   q2 = qhat;
01131   /* ROUND 2. Set j = 1 and calculate q1 */
01132   /* Estimate qhat = (u3u2) / v1
01133      then set (u3u2u1) -= qhat(v1v0) */
01134   t = uu[0];
01135   qhat = t / v1;
01136   rhat = t - qhat * v1;
01137   /* Test on v0 */
01138   t = TOHIGH(rhat) | u1;
01139   if ((qhat == B_J) || (qhat * v0 > t))
01140   {
01141     qhat--;
01142     rhat += v1;
01143     t = TOHIGH(rhat) | u1;
01144     if ((rhat < B_J) && (qhat * v0 > t))
01145     {
01146       qhat--;
01147     }
01148   }
01149   /* Multiply and subtract
01150      (u3u2u1)' = (u3u2u1) - qhat(v1v0) */
01151   uu[1] = HIHALF(uu[0]); /* (0u3) */
01152   uu[0] = TOHIGH(LOHALF(uu[0])) | u1; /* (u2u1) */
01153   spMultSub(uu, qhat, v1, v0);
01154   if (HIHALF(uu[1]) != 0)
01155   { /* Add back */
01156     qhat--;
01157     uu[0] += v;
01158     uu[1] = 0;
01159   }
01160   /* q1 = qhat */
01161   *q = TOHIGH(qhat);
01162   /* ROUND 3. Set j = 0 and calculate q0 */
01163   /* Estimate qhat = (u2u1) / v1
01164      then set (u2u1u0) -= qhat(v1v0) */
01165   t = uu[0];
01166   qhat = t / v1;
01167   rhat = t - qhat * v1;
01168   /* Test on v0 */
01169   t = TOHIGH(rhat) | u0;
01170   if ((qhat == B_J) || (qhat * v0 > t))
01171   {
01172     qhat--;
01173     rhat += v1;
01174     t = TOHIGH(rhat) | u0;
01175     if ((rhat < B_J) && (qhat * v0 > t))
01176     {
01177       qhat--;
01178     }
01179   }
01180   /* Multiply and subtract
01181      (u2u1u0)" = (u2u1u0)' - qhat(v1v0) */
01182   uu[1] = HIHALF(uu[0]); /* (0u2) */
01183   uu[0] = TOHIGH(LOHALF(uu[0])) | u0; /* (u1u0) */
01184   spMultSub(uu, qhat, v1, v0);
01185   if (HIHALF(uu[1]) != 0)
01186   { /* Add back */
01187     qhat--;
01188     uu[0] += v;
01189     uu[1] = 0;
01190   }
01191   /* q0 = qhat */
01192   *q |= LOHALF(qhat);
01193   /* Remainder is in (u1u0) i.e. uu[0] */
01194   *r = uu[0];
01195   return q2;
01196 }
01197 
01198 /*****************************************************************************/
01199 static int APP_CC
01200 QhatTooBig(DIGIT_T qhat, DIGIT_T rhat, DIGIT_T vn2, DIGIT_T ujn2)
01201 { /* Returns true if Qhat is too big
01202      i.e. if (Qhat * Vn-2) > (b.Rhat + Uj+n-2) */
01203   DIGIT_T t[2];
01204 
01205   spMultiply(t, qhat, vn2);
01206   if (t[1] < rhat)
01207   {
01208     return 0;
01209   }
01210   else if (t[1] > rhat)
01211   {
01212     return 1;
01213   }
01214   else if (t[0] > ujn2)
01215   {
01216     return 1;
01217   }
01218   return 0;
01219 }
01220 
01221 /*****************************************************************************/
01222 static DIGIT_T APP_CC
01223 mpShortDiv(DIGIT_T* q, DIGIT_T* u, DIGIT_T v, unsigned int ndigits)
01224 {
01225   /* Calculates quotient q = u div v
01226      Returns remainder r = u mod v
01227      where q, u are multiprecision integers of ndigits each
01228      and d, v are single precision digits.
01229 
01230      Makes no assumptions about normalisation.
01231 
01232      Ref: Knuth Vol 2 Ch 4.3.1 Exercise 16 p625 */
01233   unsigned int j;
01234   unsigned int shift;
01235   DIGIT_T t[2];
01236   DIGIT_T r;
01237   DIGIT_T bitmask;
01238   DIGIT_T overflow;
01239   DIGIT_T* uu;
01240 
01241   if (ndigits == 0)
01242   {
01243     return 0;
01244   }
01245   if (v == 0)
01246   {
01247     return 0; /* Divide by zero error */
01248   }
01249   /* Normalise first */
01250   /* Requires high bit of V
01251      to be set, so find most signif. bit then shift left,
01252      i.e. d = 2^shift, u' = u * d, v' = v * d. */
01253   bitmask = HIBITMASK;
01254   for (shift = 0; shift < BITS_PER_DIGIT; shift++)
01255   {
01256     if (v & bitmask)
01257     {
01258       break;
01259     }
01260     bitmask >>= 1;
01261   }
01262   v <<= shift;
01263   overflow = mpShiftLeft(q, u, shift, ndigits);
01264   uu = q;
01265   /* Step S1 - modified for extra digit. */
01266   r = overflow; /* New digit Un */
01267   j = ndigits;
01268   while (j--)
01269   {
01270     /* Step S2. */
01271     t[1] = r;
01272     t[0] = uu[j];
01273     overflow = spDivide(&q[j], &r, t, v);
01274   }
01275   /* Unnormalise */
01276   r >>= shift;
01277   return r;
01278 }
01279 
01280 /*****************************************************************************/
01281 static DIGIT_T APP_CC
01282 mpMultSub(DIGIT_T wn, DIGIT_T* w, DIGIT_T* v, DIGIT_T q, unsigned int n)
01283 { /* Compute w = w - qv
01284      where w = (WnW[n-1]...W[0])
01285      return modified Wn. */
01286   DIGIT_T k;
01287   DIGIT_T t[2];
01288   unsigned int i;
01289 
01290   if (q == 0) /* No change */
01291   {
01292     return wn;
01293   }
01294   k = 0;
01295   for (i = 0; i < n; i++)
01296   {
01297     spMultiply(t, q, v[i]);
01298     w[i] -= k;
01299     if (w[i] > MAX_DIGIT - k)
01300     {
01301       k = 1;
01302     }
01303     else
01304     {
01305       k = 0;
01306     }
01307     w[i] -= t[0];
01308     if (w[i] > MAX_DIGIT - t[0])
01309     {
01310       k++;
01311     }
01312     k += t[1];
01313   }
01314   /* Cope with Wn not stored in array w[0..n-1] */
01315   wn -= k;
01316   return wn;
01317 }
01318 
01319 /*****************************************************************************/
01320 static int APP_CC
01321 mpDivide(DIGIT_T* q, DIGIT_T* r, DIGIT_T* u, unsigned int udigits,
01322          DIGIT_T* v, unsigned int vdigits)
01323 { /* Computes quotient q = u / v and remainder r = u mod v
01324      where q, r, u are multiple precision digits
01325      all of udigits and the divisor v is vdigits.
01326 
01327      Ref: Knuth Vol 2 Ch 4.3.1 p 272 Algorithm D.
01328 
01329      Do without extra storage space, i.e. use r[] for
01330      normalised u[], unnormalise v[] at end, and cope with
01331      extra digit Uj+n added to u after normalisation.
01332 
01333      WARNING: this trashes q and r first, so cannot do
01334      u = u / v or v = u mod v. */
01335   unsigned int shift;
01336   int n;
01337   int m;
01338   int j;
01339   int qhatOK;
01340   int cmp;
01341   DIGIT_T bitmask;
01342   DIGIT_T overflow;
01343   DIGIT_T qhat;
01344   DIGIT_T rhat;
01345   DIGIT_T t[2];
01346   DIGIT_T* uu;
01347   DIGIT_T* ww;
01348 
01349   /* Clear q and r */
01350   mpSetZero(q, udigits);
01351   mpSetZero(r, udigits);
01352   /* Work out exact sizes of u and v */
01353   n = (int)mpSizeof(v, vdigits);
01354   m = (int)mpSizeof(u, udigits);
01355   m -= n;
01356   /* Catch special cases */
01357   if (n == 0)
01358   {
01359     return -1;  /* Error: divide by zero */
01360   }
01361   if (n == 1)
01362   { /* Use short division instead */
01363     r[0] = mpShortDiv(q, u, v[0], udigits);
01364     return 0;
01365   }
01366   if (m < 0)
01367   { /* v > u, so just set q = 0 and r = u */
01368     mpSetEqual(r, u, udigits);
01369     return 0;
01370   }
01371   if (m == 0)
01372   { /* u and v are the same length */
01373     cmp = mpCompare(u, v, (unsigned int)n);
01374     if (cmp < 0)
01375     { /* v > u, as above */
01376       mpSetEqual(r, u, udigits);
01377       return 0;
01378     }
01379     else if (cmp == 0)
01380     { /* v == u, so set q = 1 and r = 0 */
01381       mpSetDigit(q, 1, udigits);
01382       return 0;
01383     }
01384   }
01385   /* In Knuth notation, we have:
01386      Given
01387      u = (Um+n-1 ... U1U0)
01388      v = (Vn-1 ... V1V0)
01389      Compute
01390      q = u/v = (QmQm-1 ... Q0)
01391      r = u mod v = (Rn-1 ... R1R0) */
01392   /* Step D1. Normalise */
01393   /* Requires high bit of Vn-1
01394      to be set, so find most signif. bit then shift left,
01395      i.e. d = 2^shift, u' = u * d, v' = v * d. */
01396   bitmask = HIBITMASK;
01397   for (shift = 0; shift < BITS_PER_DIGIT; shift++)
01398   {
01399     if (v[n - 1] & bitmask)
01400     {
01401       break;
01402     }
01403     bitmask >>= 1;
01404   }
01405   /* Normalise v in situ - NB only shift non-zero digits */
01406   overflow = mpShiftLeft(v, v, shift, n);
01407   /* Copy normalised dividend u*d into r */
01408   overflow = mpShiftLeft(r, u, shift, n + m);
01409   uu = r; /* Use ptr to keep notation constant */
01410   t[0] = overflow; /* New digit Um+n */
01411   /* Step D2. Initialise j. Set j = m */
01412   for (j = m; j >= 0; j--)
01413   {
01414     /* Step D3. Calculate Qhat = (b.Uj+n + Uj+n-1)/Vn-1 */
01415     qhatOK = 0;
01416     t[1] = t[0]; /* This is Uj+n */
01417     t[0] = uu[j+n-1];
01418     overflow = spDivide(&qhat, &rhat, t, v[n - 1]);
01419     /* Test Qhat */
01420     if (overflow)
01421     { /* Qhat = b */
01422       qhat = MAX_DIGIT;
01423       rhat = uu[j + n - 1];
01424       rhat += v[n - 1];
01425       if (rhat < v[n - 1]) /* Overflow */
01426       {
01427         qhatOK = 1;
01428       }
01429     }
01430     if (!qhatOK && QhatTooBig(qhat, rhat, v[n - 2], uu[j + n - 2]))
01431     { /* Qhat.Vn-2 > b.Rhat + Uj+n-2 */
01432       qhat--;
01433       rhat += v[n - 1];
01434       if (!(rhat < v[n - 1]))
01435       {
01436         if (QhatTooBig(qhat, rhat, v[n - 2], uu[j + n - 2]))
01437         {
01438           qhat--;
01439         }
01440       }
01441     }
01442     /* Step D4. Multiply and subtract */
01443     ww = &uu[j];
01444     overflow = mpMultSub(t[1], ww, v, qhat, (unsigned int)n);
01445     /* Step D5. Test remainder. Set Qj = Qhat */
01446     q[j] = qhat;
01447     if (overflow)
01448     { /* Step D6. Add back if D4 was negative */
01449       q[j]--;
01450       overflow = mpAdd(ww, ww, v, (unsigned int)n);
01451     }
01452     t[0] = uu[j + n - 1]; /* Uj+n on next round */
01453   } /* Step D7. Loop on j */
01454   /* Clear high digits in uu */
01455   for (j = n; j < m+n; j++)
01456   {
01457     uu[j] = 0;
01458   }
01459   /* Step D8. Unnormalise. */
01460   mpShiftRight(r, r, shift, n);
01461   mpShiftRight(v, v, shift, n);
01462   return 0;
01463 }
01464 
01465 /*****************************************************************************/
01466 static int APP_CC
01467 mpModulo(DIGIT_T* r, DIGIT_T* u, unsigned int udigits,
01468          DIGIT_T* v, unsigned int vdigits)
01469 {
01470   /* Calculates r = u mod v
01471      where r, v are multiprecision integers of length vdigits
01472      and u is a multiprecision integer of length udigits.
01473      r may overlap v.
01474 
01475      Note that r here is only vdigits long,
01476      whereas in mpDivide it is udigits long.
01477 
01478      Use remainder from mpDivide function. */
01479   /* Double-length temp variable for divide fn */
01480   DIGIT_T qq[MAX_DIG_LEN * 2];
01481   /* Use a double-length temp for r to allow overlap of r and v */
01482   DIGIT_T rr[MAX_DIG_LEN * 2];
01483 
01484   /* rr[2n] = u[2n] mod v[n] */
01485   mpDivide(qq, rr, u, udigits, v, vdigits);
01486   mpSetEqual(r, rr, vdigits);
01487   mpSetZero(rr, udigits);
01488   mpSetZero(qq, udigits);
01489   return 0;
01490 }
01491 
01492 /*****************************************************************************/
01493 static int APP_CC
01494 mpMultiply(DIGIT_T* w, DIGIT_T* u, DIGIT_T* v, unsigned int ndigits)
01495 {
01496   /* Computes product w = u * v
01497      where u, v are multiprecision integers of ndigits each
01498      and w is a multiprecision integer of 2*ndigits
01499      Ref: Knuth Vol 2 Ch 4.3.1 p 268 Algorithm M. */
01500   DIGIT_T k;
01501   DIGIT_T t[2];
01502   unsigned int i;
01503   unsigned int j;
01504   unsigned int m;
01505   unsigned int n;
01506 
01507   n = ndigits;
01508   m = n;
01509   /* Step M1. Initialise */
01510   for (i = 0; i < 2 * m; i++)
01511   {
01512     w[i] = 0;
01513   }
01514   for (j = 0; j < n; j++)
01515   {
01516     /* Step M2. Zero multiplier? */
01517     if (v[j] == 0)
01518     {
01519       w[j + m] = 0;
01520     }
01521     else
01522     {
01523       /* Step M3. Initialise i */
01524       k = 0;
01525       for (i = 0; i < m; i++)
01526       {
01527         /* Step M4. Multiply and add */
01528         /* t = u_i * v_j + w_(i+j) + k */
01529         spMultiply(t, u[i], v[j]);
01530         t[0] += k;
01531         if (t[0] < k)
01532         {
01533           t[1]++;
01534         }
01535         t[0] += w[i + j];
01536         if (t[0] < w[i+j])
01537         {
01538           t[1]++;
01539         }
01540         w[i + j] = t[0];
01541         k = t[1];
01542       }
01543       /* Step M5. Loop on i, set w_(j+m) = k */
01544       w[j + m] = k;
01545     }
01546   } /* Step M6. Loop on j */
01547   return 0;
01548 }
01549 
01550 /*****************************************************************************/
01551 static int APP_CC
01552 mpModMult(DIGIT_T* a, DIGIT_T* x, DIGIT_T* y,
01553           DIGIT_T* m, unsigned int ndigits)
01554 { /* Computes a = (x * y) mod m */
01555   /* Double-length temp variable */
01556   DIGIT_T p[MAX_DIG_LEN * 2];
01557 
01558   /* Calc p[2n] = x * y */
01559   mpMultiply(p, x, y, ndigits);
01560   /* Then modulo */
01561   mpModulo(a, p, ndigits * 2, m, ndigits);
01562   mpSetZero(p, ndigits * 2);
01563   return 0;
01564 }
01565 
01566 /*****************************************************************************/
01567 int APP_CC
01568 ssl_mod_exp(char* out, int out_len, char* in, int in_len,
01569             char* mod, int mod_len, char* exp, int exp_len)
01570 {
01571   /* Computes y = x ^ e mod m */
01572   /* Binary left-to-right method */
01573   DIGIT_T mask;
01574   DIGIT_T* e;
01575   DIGIT_T* x;
01576   DIGIT_T* y;
01577   DIGIT_T* m;
01578   unsigned int n;
01579   int max_size;
01580   char* l_out;
01581   char* l_in;
01582   char* l_mod;
01583   char* l_exp;
01584 
01585   if (in_len > out_len || in_len == 0 ||
01586       out_len == 0 || mod_len == 0 || exp_len == 0)
01587   {
01588     return 0;
01589   }
01590   max_size = out_len;
01591   if (in_len > max_size)
01592   {
01593     max_size = in_len;
01594   }
01595   if (mod_len > max_size)
01596   {
01597     max_size = mod_len;
01598   }
01599   if (exp_len > max_size)
01600   {
01601     max_size = exp_len;
01602   }
01603   l_out = (char*)g_malloc(max_size, 1);
01604   l_in = (char*)g_malloc(max_size, 1);
01605   l_mod = (char*)g_malloc(max_size, 1);
01606   l_exp = (char*)g_malloc(max_size, 1);
01607   memcpy(l_in, in, in_len);
01608   memcpy(l_mod, mod, mod_len);
01609   memcpy(l_exp, exp, exp_len);
01610   e = (DIGIT_T*)l_exp;
01611   x = (DIGIT_T*)l_in;
01612   y = (DIGIT_T*)l_out;
01613   m = (DIGIT_T*)l_mod;
01614   /* Find second-most significant bit in e */
01615   n = mpSizeof(e, max_size / 4);
01616   for (mask = HIBITMASK; mask > 0; mask >>= 1)
01617   {
01618     if (e[n - 1] & mask)
01619     {
01620       break;
01621     }
01622   }
01623   mpNEXTBITMASK(mask, n);
01624   /* Set y = x */
01625   mpSetEqual(y, x, max_size / 4);
01626   /* For bit j = k - 2 downto 0 step -1 */
01627   while (n)
01628   {
01629     mpModMult(y, y, y, m, max_size / 4); /* Square */
01630     if (e[n - 1] & mask)
01631     {
01632       mpModMult(y, y, x, m, max_size / 4); /* Multiply */
01633     }
01634     /* Move to next bit */
01635     mpNEXTBITMASK(mask, n);
01636   }
01637   memcpy(out, l_out, out_len);
01638   g_free(l_out);
01639   g_free(l_in);
01640   g_free(l_mod);
01641   g_free(l_exp);
01642   return out_len;
01643 }
01644 

Generated on Sun May 27 2012 04:17:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.