Ignore:
Timestamp:
Nov 18, 2005 12:16:43 AM (18 years ago)
Author:
bennylp
Message:

Pretty comments

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/src/pjlib-util/md5.c

    r49 r51  
    1 /* $Id$ 
    2  */ 
     1/* $Id$ */ 
    32/*  
    4  * PJLIB - PJ Foundation Library 
    5  * (C)2003-2005 Benny Prijono <bennylp@bulukucing.org> 
    6  * 
    7  * Author: 
    8  *  Benny Prijono <bennylp@bulukucing.org> 
    9  * 
    10  * This library is free software; you can redistribute it and/or 
    11  * modify it under the terms of the GNU Lesser General Public 
    12  * License as published by the Free Software Foundation; either 
    13  * version 2.1 of the License, or (at your option) any later version. 
    14  *  
    15  * This library is distributed in the hope that it will be useful, 
     3 * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org> 
     4 * 
     5 * This program is free software; you can redistribute it and/or modify 
     6 * it under the terms of the GNU General Public License as published by 
     7 * the Free Software Foundation; either version 2 of the License, or 
     8 * (at your option) any later version. 
     9 * 
     10 * This program is distributed in the hope that it will be useful, 
    1611 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
    18  * Lesser General Public License for more details. 
    19  *  
    20  * You should have received a copy of the GNU Lesser General Public 
    21  * License along with this library; if not, write to the Free Software 
    22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
    23  */ 
    24 /* 
    25   Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved. 
    26  
    27   This software is provided 'as-is', without any express or implied 
    28   warranty.  In no event will the authors be held liable for any damages 
    29   arising from the use of this software. 
    30  
    31   Permission is granted to anyone to use this software for any purpose, 
    32   including commercial applications, and to alter it and redistribute it 
    33   freely, subject to the following restrictions: 
    34  
    35   1. The origin of this software must not be misrepresented; you must not 
    36      claim that you wrote the original software. If you use this software 
    37      in a product, an acknowledgment in the product documentation would be 
    38      appreciated but is not required. 
    39   2. Altered source versions must be plainly marked as such, and must not be 
    40      misrepresented as being the original software. 
    41   3. This notice may not be removed or altered from any source distribution. 
    42  
    43   L. Peter Deutsch 
    44   ghost@aladdin.com 
    45  
    46  */ 
    47 /* Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp */ 
    48 /* 
    49   Independent implementation of MD5 (RFC 1321). 
    50  
    51   This code implements the MD5 Algorithm defined in RFC 1321, whose 
    52   text is available at 
    53         http://www.ietf.org/rfc/rfc1321.txt 
    54   The code is derived from the text of the RFC, including the test suite 
    55   (section A.5) but excluding the rest of Appendix A.  It does not include 
    56   any code or documentation that is identified in the RFC as being 
    57   copyrighted. 
    58  
    59   The original and principal author of md5.c is L. Peter Deutsch 
    60   <ghost@aladdin.com>.  Other authors are noted in the change history 
    61   that follows (in reverse chronological order): 
    62  
    63   2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order 
    64         either statically or dynamically; added missing #include <string.h> 
    65         in library. 
    66   2002-03-11 lpd Corrected argument list for main(), and added int return 
    67         type, in test program and T value program. 
    68   2002-02-21 lpd Added missing #include <stdio.h> in test program. 
    69   2000-07-03 lpd Patched to eliminate warnings about "constant is 
    70         unsigned in ANSI C, signed in traditional"; made test program 
    71         self-checking. 
    72   1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 
    73   1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 
    74   1999-05-03 lpd Original version. 
    75  */ 
    76  
     12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     13 * GNU General Public License for more details. 
     14 * 
     15 * You should have received a copy of the GNU General Public License 
     16 * along with this program; if not, write to the Free Software 
     17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  
     18 */ 
    7719#include <pjlib-util/md5.h> 
    78 #include <pj/string.h> 
    79 #include <pj/os.h> 
    80  
    81 #undef BYTE_ORDER       /* 1 = big-endian, -1 = little-endian, 0 = unknown */ 
    82  
    83 /* 
    84 #ifdef ARCH_IS_BIG_ENDIAN 
    85 #  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) 
     20#include <pj/string.h>          /* pj_memcpy */ 
     21/* 
     22 * This code implements the MD5 message-digest algorithm. 
     23 * The algorithm is due to Ron Rivest.  This code was 
     24 * written by Colin Plumb in 1993, no copyright is claimed. 
     25 * This code is in the public domain; do with it what you wish. 
     26 * 
     27 * Equivalent code is available from RSA Data Security, Inc. 
     28 * This code has been tested against that, and is equivalent, 
     29 * except that you don't need to include two pages of legalese 
     30 * with every copy. 
     31 * 
     32 * To compute the message digest of a chunk of bytes, declare an 
     33 * MD5Context structure, pass it to MD5Init, call MD5Update as 
     34 * needed on buffers full of bytes, and then call MD5Final, which 
     35 * will fill a supplied 16-byte array with the digest. 
     36 */ 
     37 
     38#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN != 0 
     39#define HIGHFIRST 1 
     40#endif 
     41 
     42#ifndef HIGHFIRST 
     43#define byteReverse(buf, len)   /* Nothing */ 
    8644#else 
    87 #  define BYTE_ORDER 0 
    88 #endif 
    89 */ 
    90 /* pjlib: */ 
    91 #include <pj/config.h> 
    92 #if PJ_IS_LITTLE_ENDIAN 
    93 #  define BYTE_ORDER -1 
    94 #elif PJ_IS_BIG_ENDIAN 
    95 #  define BYTE_ORDER 1 
    96 #else 
    97 #  error Endianess is not known! 
    98 #endif 
    99  
    100  
    101 #define T_MASK ((md5_word_t)~0) 
    102 #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) 
    103 #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) 
    104 #define T3    0x242070db 
    105 #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) 
    106 #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) 
    107 #define T6    0x4787c62a 
    108 #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) 
    109 #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) 
    110 #define T9    0x698098d8 
    111 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) 
    112 #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) 
    113 #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) 
    114 #define T13    0x6b901122 
    115 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) 
    116 #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) 
    117 #define T16    0x49b40821 
    118 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) 
    119 #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) 
    120 #define T19    0x265e5a51 
    121 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) 
    122 #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) 
    123 #define T22    0x02441453 
    124 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) 
    125 #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) 
    126 #define T25    0x21e1cde6 
    127 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) 
    128 #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) 
    129 #define T28    0x455a14ed 
    130 #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) 
    131 #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) 
    132 #define T31    0x676f02d9 
    133 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) 
    134 #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) 
    135 #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) 
    136 #define T35    0x6d9d6122 
    137 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) 
    138 #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) 
    139 #define T38    0x4bdecfa9 
    140 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) 
    141 #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) 
    142 #define T41    0x289b7ec6 
    143 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) 
    144 #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) 
    145 #define T44    0x04881d05 
    146 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) 
    147 #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) 
    148 #define T47    0x1fa27cf8 
    149 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) 
    150 #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) 
    151 #define T50    0x432aff97 
    152 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) 
    153 #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) 
    154 #define T53    0x655b59c3 
    155 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) 
    156 #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) 
    157 #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) 
    158 #define T57    0x6fa87e4f 
    159 #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) 
    160 #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) 
    161 #define T60    0x4e0811a1 
    162 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) 
    163 #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) 
    164 #define T63    0x2ad7d2bb 
    165 #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) 
    166  
    167  
    168 static void 
    169 md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) 
    170 { 
    171     md5_word_t 
    172         a = pms->abcd[0], b = pms->abcd[1], 
    173         c = pms->abcd[2], d = pms->abcd[3]; 
    174     md5_word_t t; 
    175 #if BYTE_ORDER > 0 
    176     /* Define storage only for big-endian CPUs. */ 
    177     md5_word_t X[16]; 
    178 #else 
    179     /* Define storage for little-endian or both types of CPUs. */ 
    180     md5_word_t xbuf[16]; 
    181     const md5_word_t *X; 
    182 #endif 
    183  
    184     PJ_CHECK_STACK(); 
    185  
    186     { 
    187 #if BYTE_ORDER == 0 
    188         /* 
    189          * Determine dynamically whether this is a big-endian or 
    190          * little-endian machine, since we can use a more efficient 
    191          * algorithm on the latter. 
    192          */ 
    193         static const int w = 1; 
    194  
    195         if (*((const md5_byte_t *)&w)) /* dynamic little-endian */ 
    196 #endif 
    197 #if BYTE_ORDER <= 0             /* little-endian */ 
    198         { 
    199             /* 
    200              * On little-endian machines, we can process properly aligned 
    201              * data without copying it. 
    202              */ 
    203             if (!((data - (const md5_byte_t *)0) & 3)) { 
    204                 /* data are properly aligned */ 
    205                 X = (const md5_word_t *)data; 
    206             } else { 
    207                 /* not aligned */ 
    208                 memcpy(xbuf, data, 64); 
    209                 X = xbuf; 
    210             } 
     45void byteReverse(unsigned char *buf, unsigned longs); 
     46 
     47#ifndef ASM_MD5 
     48/* 
     49 * Note: this code is harmless on little-endian machines. 
     50 */ 
     51void byteReverse(unsigned char *buf, unsigned longs) 
     52{ 
     53    pj_uint32_t t; 
     54    do { 
     55        t = (pj_uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | 
     56            ((unsigned) buf[1] << 8 | buf[0]); 
     57        *(pj_uint32_t *) buf = t; 
     58        buf += 4; 
     59    } while (--longs); 
     60} 
     61#endif 
     62#endif 
     63 
     64static void MD5Transform(pj_uint32_t buf[4], pj_uint32_t const in[16]); 
     65 
     66 
     67/* 
     68 * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious 
     69 * initialization constants. 
     70 */ 
     71PJ_DEF(void) pj_md5_init(pj_md5_context *ctx) 
     72{ 
     73    ctx->buf[0] = 0x67452301; 
     74    ctx->buf[1] = 0xefcdab89; 
     75    ctx->buf[2] = 0x98badcfe; 
     76    ctx->buf[3] = 0x10325476; 
     77 
     78    ctx->bits[0] = 0; 
     79    ctx->bits[1] = 0; 
     80} 
     81 
     82/* 
     83 * Update context to reflect the concatenation of another buffer full 
     84 * of bytes. 
     85 */ 
     86PJ_DEF(void) pj_md5_update( pj_md5_context *ctx,  
     87                            unsigned char const *buf, unsigned len) 
     88{ 
     89    pj_uint32_t t; 
     90 
     91    /* Update bitcount */ 
     92 
     93    t = ctx->bits[0]; 
     94    if ((ctx->bits[0] = t + ((pj_uint32_t) len << 3)) < t) 
     95        ctx->bits[1]++;         /* Carry from low to high */ 
     96    ctx->bits[1] += len >> 29; 
     97 
     98    t = (t >> 3) & 0x3f;        /* Bytes already in shsInfo->data */ 
     99 
     100    /* Handle any leading odd-sized chunks */ 
     101 
     102    if (t) { 
     103        unsigned char *p = (unsigned char *) ctx->in + t; 
     104 
     105        t = 64 - t; 
     106        if (len < t) { 
     107            pj_memcpy(p, buf, len); 
     108            return; 
    211109        } 
    212 #endif 
    213 #if BYTE_ORDER == 0 
    214         else                    /* dynamic big-endian */ 
    215 #endif 
    216 #if BYTE_ORDER >= 0             /* big-endian */ 
    217         { 
    218             /* 
    219              * On big-endian machines, we must arrange the bytes in the 
    220              * right order. 
    221              */ 
    222             const md5_byte_t *xp = data; 
    223             int i; 
    224  
    225 #  if BYTE_ORDER == 0 
    226             X = xbuf;           /* (dynamic only) */ 
    227 #  else 
    228 #    define xbuf X              /* (static only) */ 
    229 #  endif 
    230             for (i = 0; i < 16; ++i, xp += 4) 
    231                 xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); 
    232         } 
    233 #endif 
     110        pj_memcpy(p, buf, t); 
     111        byteReverse(ctx->in, 16); 
     112        MD5Transform(ctx->buf, (pj_uint32_t *) ctx->in); 
     113        buf += t; 
     114        len -= t; 
    234115    } 
    235  
    236 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) 
    237  
    238     /* Round 1. */ 
    239     /* Let [abcd k s i] denote the operation 
    240        a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ 
    241 #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) 
    242 #define SET(a, b, c, d, k, s, Ti)\ 
    243   t = a + F(b,c,d) + X[k] + Ti;\ 
    244   a = ROTATE_LEFT(t, s) + b 
    245     /* Do the following 16 operations. */ 
    246     SET(a, b, c, d,  0,  7,  T1); 
    247     SET(d, a, b, c,  1, 12,  T2); 
    248     SET(c, d, a, b,  2, 17,  T3); 
    249     SET(b, c, d, a,  3, 22,  T4); 
    250     SET(a, b, c, d,  4,  7,  T5); 
    251     SET(d, a, b, c,  5, 12,  T6); 
    252     SET(c, d, a, b,  6, 17,  T7); 
    253     SET(b, c, d, a,  7, 22,  T8); 
    254     SET(a, b, c, d,  8,  7,  T9); 
    255     SET(d, a, b, c,  9, 12, T10); 
    256     SET(c, d, a, b, 10, 17, T11); 
    257     SET(b, c, d, a, 11, 22, T12); 
    258     SET(a, b, c, d, 12,  7, T13); 
    259     SET(d, a, b, c, 13, 12, T14); 
    260     SET(c, d, a, b, 14, 17, T15); 
    261     SET(b, c, d, a, 15, 22, T16); 
    262 #undef SET 
    263  
    264      /* Round 2. */ 
    265      /* Let [abcd k s i] denote the operation 
    266           a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ 
    267 #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) 
    268 #define SET(a, b, c, d, k, s, Ti)\ 
    269   t = a + G(b,c,d) + X[k] + Ti;\ 
    270   a = ROTATE_LEFT(t, s) + b 
    271      /* Do the following 16 operations. */ 
    272     SET(a, b, c, d,  1,  5, T17); 
    273     SET(d, a, b, c,  6,  9, T18); 
    274     SET(c, d, a, b, 11, 14, T19); 
    275     SET(b, c, d, a,  0, 20, T20); 
    276     SET(a, b, c, d,  5,  5, T21); 
    277     SET(d, a, b, c, 10,  9, T22); 
    278     SET(c, d, a, b, 15, 14, T23); 
    279     SET(b, c, d, a,  4, 20, T24); 
    280     SET(a, b, c, d,  9,  5, T25); 
    281     SET(d, a, b, c, 14,  9, T26); 
    282     SET(c, d, a, b,  3, 14, T27); 
    283     SET(b, c, d, a,  8, 20, T28); 
    284     SET(a, b, c, d, 13,  5, T29); 
    285     SET(d, a, b, c,  2,  9, T30); 
    286     SET(c, d, a, b,  7, 14, T31); 
    287     SET(b, c, d, a, 12, 20, T32); 
    288 #undef SET 
    289  
    290      /* Round 3. */ 
    291      /* Let [abcd k s t] denote the operation 
    292           a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ 
    293 #define H(x, y, z) ((x) ^ (y) ^ (z)) 
    294 #define SET(a, b, c, d, k, s, Ti)\ 
    295   t = a + H(b,c,d) + X[k] + Ti;\ 
    296   a = ROTATE_LEFT(t, s) + b 
    297      /* Do the following 16 operations. */ 
    298     SET(a, b, c, d,  5,  4, T33); 
    299     SET(d, a, b, c,  8, 11, T34); 
    300     SET(c, d, a, b, 11, 16, T35); 
    301     SET(b, c, d, a, 14, 23, T36); 
    302     SET(a, b, c, d,  1,  4, T37); 
    303     SET(d, a, b, c,  4, 11, T38); 
    304     SET(c, d, a, b,  7, 16, T39); 
    305     SET(b, c, d, a, 10, 23, T40); 
    306     SET(a, b, c, d, 13,  4, T41); 
    307     SET(d, a, b, c,  0, 11, T42); 
    308     SET(c, d, a, b,  3, 16, T43); 
    309     SET(b, c, d, a,  6, 23, T44); 
    310     SET(a, b, c, d,  9,  4, T45); 
    311     SET(d, a, b, c, 12, 11, T46); 
    312     SET(c, d, a, b, 15, 16, T47); 
    313     SET(b, c, d, a,  2, 23, T48); 
    314 #undef SET 
    315  
    316      /* Round 4. */ 
    317      /* Let [abcd k s t] denote the operation 
    318           a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ 
    319 #define I(x, y, z) ((y) ^ ((x) | ~(z))) 
    320 #define SET(a, b, c, d, k, s, Ti)\ 
    321   t = a + I(b,c,d) + X[k] + Ti;\ 
    322   a = ROTATE_LEFT(t, s) + b 
    323      /* Do the following 16 operations. */ 
    324     SET(a, b, c, d,  0,  6, T49); 
    325     SET(d, a, b, c,  7, 10, T50); 
    326     SET(c, d, a, b, 14, 15, T51); 
    327     SET(b, c, d, a,  5, 21, T52); 
    328     SET(a, b, c, d, 12,  6, T53); 
    329     SET(d, a, b, c,  3, 10, T54); 
    330     SET(c, d, a, b, 10, 15, T55); 
    331     SET(b, c, d, a,  1, 21, T56); 
    332     SET(a, b, c, d,  8,  6, T57); 
    333     SET(d, a, b, c, 15, 10, T58); 
    334     SET(c, d, a, b,  6, 15, T59); 
    335     SET(b, c, d, a, 13, 21, T60); 
    336     SET(a, b, c, d,  4,  6, T61); 
    337     SET(d, a, b, c, 11, 10, T62); 
    338     SET(c, d, a, b,  2, 15, T63); 
    339     SET(b, c, d, a,  9, 21, T64); 
    340 #undef SET 
    341  
    342      /* Then perform the following additions. (That is increment each 
    343         of the four registers by the value it had before this block 
    344         was started.) */ 
    345     pms->abcd[0] += a; 
    346     pms->abcd[1] += b; 
    347     pms->abcd[2] += c; 
    348     pms->abcd[3] += d; 
    349 } 
    350  
    351 void 
    352 md5_init(md5_state_t *pms) 
    353 { 
    354     PJ_CHECK_STACK(); 
    355  
    356     pms->count[0] = pms->count[1] = 0; 
    357     pms->abcd[0] = 0x67452301; 
    358     pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; 
    359     pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; 
    360     pms->abcd[3] = 0x10325476; 
    361 } 
    362  
    363 void 
    364 md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) 
    365 { 
    366     const md5_byte_t *p = data; 
    367     int left = nbytes; 
    368     int offset = (pms->count[0] >> 3) & 63; 
    369     md5_word_t nbits = (md5_word_t)(nbytes << 3); 
    370  
    371     PJ_CHECK_STACK(); 
    372  
    373     if (nbytes <= 0) 
    374         return; 
    375  
    376     /* Update the message length. */ 
    377     pms->count[1] += nbytes >> 29; 
    378     pms->count[0] += nbits; 
    379     if (pms->count[0] < nbits) 
    380         pms->count[1]++; 
    381  
    382     /* Process an initial partial block. */ 
    383     if (offset) { 
    384         int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); 
    385  
    386         memcpy(pms->buf + offset, p, copy); 
    387         if (offset + copy < 64) 
    388             return; 
    389         p += copy; 
    390         left -= copy; 
    391         md5_process(pms, pms->buf); 
     116    /* Process data in 64-byte chunks */ 
     117 
     118    while (len >= 64) { 
     119        pj_memcpy(ctx->in, buf, 64); 
     120        byteReverse(ctx->in, 16); 
     121        MD5Transform(ctx->buf, (pj_uint32_t *) ctx->in); 
     122        buf += 64; 
     123        len -= 64; 
    392124    } 
    393125 
    394     /* Process full blocks. */ 
    395     for (; left >= 64; p += 64, left -= 64) 
    396         md5_process(pms, p); 
    397  
    398     /* Process a final partial block. */ 
    399     if (left) 
    400         memcpy(pms->buf, p, left); 
    401 } 
    402  
    403 void 
    404 md5_finish(md5_state_t *pms, md5_byte_t digest[16]) 
    405 { 
    406     static const md5_byte_t pad[64] = { 
    407         0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    408         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    409         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    410         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
    411     }; 
    412     md5_byte_t data[8]; 
    413     int i; 
    414  
    415     PJ_CHECK_STACK(); 
    416  
    417     /* Save the length before padding. */ 
    418     for (i = 0; i < 8; ++i) 
    419         data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); 
    420     /* Pad to 56 bytes mod 64. */ 
    421     md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); 
    422     /* Append the length. */ 
    423     md5_append(pms, data, 8); 
    424     for (i = 0; i < 16; ++i) 
    425         digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); 
    426 } 
    427  
     126    /* Handle any remaining bytes of data. */ 
     127 
     128    pj_memcpy(ctx->in, buf, len); 
     129} 
     130 
     131/* 
     132 * Final wrapup - pad to 64-byte boundary with the bit pattern  
     133 * 1 0* (64-bit count of bits processed, MSB-first) 
     134 */ 
     135PJ_DEF(void) pj_md5_final(pj_md5_context *ctx, unsigned char digest[16]) 
     136{ 
     137    unsigned count; 
     138    unsigned char *p; 
     139 
     140    /* Compute number of bytes mod 64 */ 
     141    count = (ctx->bits[0] >> 3) & 0x3F; 
     142 
     143    /* Set the first char of padding to 0x80.  This is safe since there is 
     144       always at least one byte free */ 
     145    p = ctx->in + count; 
     146    *p++ = 0x80; 
     147 
     148    /* Bytes of padding needed to make 64 bytes */ 
     149    count = 64 - 1 - count; 
     150 
     151    /* Pad out to 56 mod 64 */ 
     152    if (count < 8) { 
     153        /* Two lots of padding:  Pad the first block to 64 bytes */ 
     154        pj_memset(p, 0, count); 
     155        byteReverse(ctx->in, 16); 
     156        MD5Transform(ctx->buf, (pj_uint32_t *) ctx->in); 
     157 
     158        /* Now fill the next block with 56 bytes */ 
     159        pj_memset(ctx->in, 0, 56); 
     160    } else { 
     161        /* Pad block to 56 bytes */ 
     162        pj_memset(p, 0, count - 8); 
     163    } 
     164    byteReverse(ctx->in, 14); 
     165 
     166    /* Append length in bits and transform */ 
     167    ((pj_uint32_t *) ctx->in)[14] = ctx->bits[0]; 
     168    ((pj_uint32_t *) ctx->in)[15] = ctx->bits[1]; 
     169 
     170    MD5Transform(ctx->buf, (pj_uint32_t *) ctx->in); 
     171    byteReverse((unsigned char *) ctx->buf, 4); 
     172    pj_memcpy(digest, ctx->buf, 16); 
     173    pj_memset(ctx, 0, sizeof(ctx));     /* In case it's sensitive */ 
     174} 
     175 
     176#ifndef ASM_MD5 
     177 
     178/* The four core functions - F1 is optimized somewhat */ 
     179 
     180/* #define F1(x, y, z) (x & y | ~x & z) */ 
     181#define F1(x, y, z) (z ^ (x & (y ^ z))) 
     182#define F2(x, y, z) F1(z, x, y) 
     183#define F3(x, y, z) (x ^ y ^ z) 
     184#define F4(x, y, z) (y ^ (x | ~z)) 
     185 
     186/* This is the central step in the MD5 algorithm. */ 
     187#define MD5STEP(f, w, x, y, z, data, s) \ 
     188        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x ) 
     189 
     190/* 
     191 * The core of the MD5 algorithm, this alters an existing MD5 hash to 
     192 * reflect the addition of 16 longwords of new data.  MD5Update blocks 
     193 * the data and converts bytes into longwords for this routine. 
     194 */ 
     195static void MD5Transform(pj_uint32_t buf[4], pj_uint32_t const in[16]) 
     196{ 
     197    register pj_uint32_t a, b, c, d; 
     198 
     199    a = buf[0]; 
     200    b = buf[1]; 
     201    c = buf[2]; 
     202    d = buf[3]; 
     203 
     204    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 
     205    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 
     206    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 
     207    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 
     208    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 
     209    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 
     210    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 
     211    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 
     212    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 
     213    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 
     214    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 
     215    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 
     216    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 
     217    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 
     218    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 
     219    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 
     220 
     221    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 
     222    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 
     223    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 
     224    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 
     225    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 
     226    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 
     227    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 
     228    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 
     229    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 
     230    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 
     231    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 
     232    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 
     233    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 
     234    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 
     235    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 
     236    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 
     237 
     238    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 
     239    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 
     240    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 
     241    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 
     242    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 
     243    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 
     244    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 
     245    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 
     246    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 
     247    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 
     248    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 
     249    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 
     250    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 
     251    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 
     252    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 
     253    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 
     254 
     255    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 
     256    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 
     257    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 
     258    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 
     259    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 
     260    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 
     261    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 
     262    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 
     263    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 
     264    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 
     265    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 
     266    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 
     267    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 
     268    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 
     269    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 
     270    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 
     271 
     272    buf[0] += a; 
     273    buf[1] += b; 
     274    buf[2] += c; 
     275    buf[3] += d; 
     276} 
     277 
     278#endif 
     279 
Note: See TracChangeset for help on using the changeset viewer.