Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenssl_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
1.7.6.1
|