Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/libbb/md5.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 15  Line 15 
15    
16  #include "libbb.h"  #include "libbb.h"
17    
18  #if CONFIG_MD5_SIZE_VS_SPEED < 0 || CONFIG_MD5_SIZE_VS_SPEED > 3  /* 0: fastest, 3: smallest */
19  # define MD5_SIZE_VS_SPEED 2  #if CONFIG_MD5_SIZE_VS_SPEED < 0
20    # define MD5_SIZE_VS_SPEED 0
21    #elif CONFIG_MD5_SIZE_VS_SPEED > 3
22    # define MD5_SIZE_VS_SPEED 3
23  #else  #else
24  # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED  # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED
25  #endif  #endif
# Line 30  void FAST_FUNC md5_begin(md5_ctx_t *ctx) Line 33  void FAST_FUNC md5_begin(md5_ctx_t *ctx)
33   ctx->B = 0xefcdab89;   ctx->B = 0xefcdab89;
34   ctx->C = 0x98badcfe;   ctx->C = 0x98badcfe;
35   ctx->D = 0x10325476;   ctx->D = 0x10325476;
   
36   ctx->total = 0;   ctx->total = 0;
37   ctx->buflen = 0;   ctx->buflen = 0;
38  }  }
# Line 40  void FAST_FUNC md5_begin(md5_ctx_t *ctx) Line 42  void FAST_FUNC md5_begin(md5_ctx_t *ctx)
42   * (as found in Colin Plumbs public domain implementation).   * (as found in Colin Plumbs public domain implementation).
43   * #define FF(b, c, d) ((b & c) | (~b & d))   * #define FF(b, c, d) ((b & c) | (~b & d))
44   */   */
45  # define FF(b, c, d) (d ^ (b & (c ^ d)))  #define FF(b, c, d) (d ^ (b & (c ^ d)))
46  # define FG(b, c, d) FF (d, b, c)  #define FG(b, c, d) FF(d, b, c)
47  # define FH(b, c, d) (b ^ c ^ d)  #define FH(b, c, d) (b ^ c ^ d)
48  # define FI(b, c, d) (c ^ (b | ~d))  #define FI(b, c, d) (c ^ (b | ~d))
49    
50    #define rotl32(w, s) (((w) << (s)) | ((w) >> (32 - (s))))
51    
52  /* Hash a single block, 64 bytes long and 4-byte aligned. */  /* Hash a single block, 64 bytes long and 4-byte aligned. */
53  static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)  static void md5_hash_block(const void *buffer, md5_ctx_t *ctx)
# Line 51  static void md5_hash_block(const void *b Line 55  static void md5_hash_block(const void *b
55   uint32_t correct_words[16];   uint32_t correct_words[16];
56   const uint32_t *words = buffer;   const uint32_t *words = buffer;
57    
58  # if MD5_SIZE_VS_SPEED > 0  #if MD5_SIZE_VS_SPEED > 0
59   static const uint32_t C_array[] = {   static const uint32_t C_array[] = {
60   /* round 1 */   /* round 1 */
61   0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,   0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
# Line 74  static void md5_hash_block(const void *b Line 78  static void md5_hash_block(const void *b
78   0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,   0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
79   0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391   0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
80   };   };
   
81   static const char P_array[] ALIGN1 = {   static const char P_array[] ALIGN1 = {
82  #  if MD5_SIZE_VS_SPEED > 1  # if MD5_SIZE_VS_SPEED > 1
83   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
84  #  endif /* MD5_SIZE_VS_SPEED > 1 */  # endif
85   1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */   1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
86   5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */   5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
87   0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */   0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */
88   };   };
89    # if MD5_SIZE_VS_SPEED > 1
 #  if MD5_SIZE_VS_SPEED > 1  
90   static const char S_array[] ALIGN1 = {   static const char S_array[] ALIGN1 = {
91   7, 12, 17, 22,   7, 12, 17, 22,
92   5, 9, 14, 20,   5, 9, 14, 20,
93   4, 11, 16, 23,   4, 11, 16, 23,
94   6, 10, 15, 21   6, 10, 15, 21
95   };   };
96  #  endif /* MD5_SIZE_VS_SPEED > 1 */  # endif /* MD5_SIZE_VS_SPEED > 1 */
97  # endif  #endif
   
98   uint32_t A = ctx->A;   uint32_t A = ctx->A;
99   uint32_t B = ctx->B;   uint32_t B = ctx->B;
100   uint32_t C = ctx->C;   uint32_t C = ctx->C;
# Line 101  static void md5_hash_block(const void *b Line 102  static void md5_hash_block(const void *b
102    
103   /* Process all bytes in the buffer with 64 bytes in each round of   /* Process all bytes in the buffer with 64 bytes in each round of
104     the loop.  */     the loop.  */
105   uint32_t *cwp = correct_words;   uint32_t *cwp = correct_words;
106   uint32_t A_save = A;   uint32_t A_save = A;
107   uint32_t B_save = B;   uint32_t B_save = B;
108   uint32_t C_save = C;   uint32_t C_save = C;
109   uint32_t D_save = D;   uint32_t D_save = D;
110    
111  # if MD5_SIZE_VS_SPEED > 1  #if MD5_SIZE_VS_SPEED > 1
112  #  define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))   const uint32_t *pc;
113     const char *pp;
114   const uint32_t *pc;   const char *ps;
115   const char *pp;   int i;
116   const char *ps;   uint32_t temp;
  int i;  
  uint32_t temp;  
   
  for (i = 0; i < 16; i++) {  
  cwp[i] = SWAP_LE32(words[i]);  
  }  
  words += 16;  
   
 #  if MD5_SIZE_VS_SPEED > 2  
  pc = C_array;  
  pp = P_array;  
  ps = S_array - 4;  
   
  for (i = 0; i < 64; i++) {  
  if ((i & 0x0f) == 0)  
  ps += 4;  
  temp = A;  
  switch (i >> 4) {  
  case 0:  
  temp += FF(B, C, D);  
  break;  
  case 1:  
  temp += FG(B, C, D);  
  break;  
  case 2:  
  temp += FH(B, C, D);  
  break;  
  case 3:  
  temp += FI(B, C, D);  
  }  
  temp += cwp[(int) (*pp++)] + *pc++;  
  CYCLIC(temp, ps[i & 3]);  
  temp += B;  
  A = D;  
  D = C;  
  C = B;  
  B = temp;  
  }  
 #  else  
  pc = C_array;  
  pp = P_array;  
  ps = S_array;  
   
  for (i = 0; i < 16; i++) {  
  temp = A + FF(B, C, D) + cwp[(int) (*pp++)] + *pc++;  
  CYCLIC(temp, ps[i & 3]);  
  temp += B;  
  A = D;  
  D = C;  
  C = B;  
  B = temp;  
  }  
   
  ps += 4;  
  for (i = 0; i < 16; i++) {  
  temp = A + FG(B, C, D) + cwp[(int) (*pp++)] + *pc++;  
  CYCLIC(temp, ps[i & 3]);  
  temp += B;  
  A = D;  
  D = C;  
  C = B;  
  B = temp;  
  }  
  ps += 4;  
  for (i = 0; i < 16; i++) {  
  temp = A + FH(B, C, D) + cwp[(int) (*pp++)] + *pc++;  
  CYCLIC(temp, ps[i & 3]);  
  temp += B;  
  A = D;  
  D = C;  
  C = B;  
  B = temp;  
  }  
  ps += 4;  
  for (i = 0; i < 16; i++) {  
  temp = A + FI(B, C, D) + cwp[(int) (*pp++)] + *pc++;  
  CYCLIC(temp, ps[i & 3]);  
  temp += B;  
  A = D;  
  D = C;  
  C = B;  
  B = temp;  
  }  
117    
118  #  endif /* MD5_SIZE_VS_SPEED > 2 */   for (i = 0; i < 16; i++)
119     cwp[i] = SWAP_LE32(words[i]);
120     words += 16;
121    
122    # if MD5_SIZE_VS_SPEED > 2
123     pc = C_array;
124     pp = P_array;
125     ps = S_array - 4;
126    
127     for (i = 0; i < 64; i++) {
128     if ((i & 0x0f) == 0)
129     ps += 4;
130     temp = A;
131     switch (i >> 4) {
132     case 0:
133     temp += FF(B, C, D);
134     break;
135     case 1:
136     temp += FG(B, C, D);
137     break;
138     case 2:
139     temp += FH(B, C, D);
140     break;
141     case 3:
142     temp += FI(B, C, D);
143     }
144     temp += cwp[(int) (*pp++)] + *pc++;
145     temp = rotl32(temp, ps[i & 3]);
146     temp += B;
147     A = D;
148     D = C;
149     C = B;
150     B = temp;
151     }
152  # else  # else
153   /* First round: using the given function, the context and a constant   pc = C_array;
154     the next context is computed.  Because the algorithms processing   pp = P_array;
155     unit is a 32-bit word and it is determined to work on words in   ps = S_array;
156     little endian byte order we perhaps have to change the byte order  
157     before the computation.  To reduce the work for the next steps   for (i = 0; i < 16; i++) {
158     we store the swapped words in the array CORRECT_WORDS.  */   temp = A + FF(B, C, D) + cwp[(int) (*pp++)] + *pc++;
159     temp = rotl32(temp, ps[i & 3]);
160     temp += B;
161     A = D;
162     D = C;
163     C = B;
164     B = temp;
165     }
166     ps += 4;
167     for (i = 0; i < 16; i++) {
168     temp = A + FG(B, C, D) + cwp[(int) (*pp++)] + *pc++;
169     temp = rotl32(temp, ps[i & 3]);
170     temp += B;
171     A = D;
172     D = C;
173     C = B;
174     B = temp;
175     }
176     ps += 4;
177     for (i = 0; i < 16; i++) {
178     temp = A + FH(B, C, D) + cwp[(int) (*pp++)] + *pc++;
179     temp = rotl32(temp, ps[i & 3]);
180     temp += B;
181     A = D;
182     D = C;
183     C = B;
184     B = temp;
185     }
186     ps += 4;
187     for (i = 0; i < 16; i++) {
188     temp = A + FI(B, C, D) + cwp[(int) (*pp++)] + *pc++;
189     temp = rotl32(temp, ps[i & 3]);
190     temp += B;
191     A = D;
192     D = C;
193     C = B;
194     B = temp;
195     }
196    
197  #  define OP(a, b, c, d, s, T) \  # endif /* MD5_SIZE_VS_SPEED > 2 */
198    #else
199     /* First round: using the given function, the context and a constant
200       the next context is computed.  Because the algorithms processing
201       unit is a 32-bit word and it is determined to work on words in
202       little endian byte order we perhaps have to change the byte order
203       before the computation.  To reduce the work for the next steps
204       we store the swapped words in the array CORRECT_WORDS.  */
205    # define OP(a, b, c, d, s, T) \
206   do { \   do { \
207   a += FF (b, c, d) + (*cwp++ = SWAP_LE32(*words)) + T; \   a += FF(b, c, d) + (*cwp++ = SWAP_LE32(*words)) + T; \
208   ++words; \   ++words; \
209   CYCLIC (a, s); \   a = rotl32(a, s); \
210   a += b; \   a += b; \
211   } while (0)   } while (0)
212    
213   /* It is unfortunate that C does not provide an operator for   /* Before we start, one word to the strange constants.
214     cyclic rotation.  Hope the C compiler is smart enough.  */     They are defined in RFC 1321 as
215   /* gcc 2.95.4 seems to be --aaronl */     T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
216  #  define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))   */
217    
218   /* Before we start, one word to the strange constants.  # if MD5_SIZE_VS_SPEED == 1
219     They are defined in RFC 1321 as   const uint32_t *pc;
220     const char *pp;
221     T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64   int i;
222   */  # endif /* MD5_SIZE_VS_SPEED */
223    
224  #  if MD5_SIZE_VS_SPEED == 1   /* Round 1.  */
225   const uint32_t *pc;  # if MD5_SIZE_VS_SPEED == 1
226   const char *pp;   pc = C_array;
227   int i;   for (i = 0; i < 4; i++) {
228  #  endif /* MD5_SIZE_VS_SPEED */   OP(A, B, C, D, 7, *pc++);
229     OP(D, A, B, C, 12, *pc++);
230   /* Round 1.  */   OP(C, D, A, B, 17, *pc++);
231  #  if MD5_SIZE_VS_SPEED == 1   OP(B, C, D, A, 22, *pc++);
232   pc = C_array;   }
233   for (i = 0; i < 4; i++) {  # else
234   OP(A, B, C, D, 7, *pc++);   OP(A, B, C, D, 7, 0xd76aa478);
235   OP(D, A, B, C, 12, *pc++);   OP(D, A, B, C, 12, 0xe8c7b756);
236   OP(C, D, A, B, 17, *pc++);   OP(C, D, A, B, 17, 0x242070db);
237   OP(B, C, D, A, 22, *pc++);   OP(B, C, D, A, 22, 0xc1bdceee);
238   }   OP(A, B, C, D, 7, 0xf57c0faf);
239  #  else   OP(D, A, B, C, 12, 0x4787c62a);
240   OP(A, B, C, D, 7, 0xd76aa478);   OP(C, D, A, B, 17, 0xa8304613);
241   OP(D, A, B, C, 12, 0xe8c7b756);   OP(B, C, D, A, 22, 0xfd469501);
242   OP(C, D, A, B, 17, 0x242070db);   OP(A, B, C, D, 7, 0x698098d8);
243   OP(B, C, D, A, 22, 0xc1bdceee);   OP(D, A, B, C, 12, 0x8b44f7af);
244   OP(A, B, C, D, 7, 0xf57c0faf);   OP(C, D, A, B, 17, 0xffff5bb1);
245   OP(D, A, B, C, 12, 0x4787c62a);   OP(B, C, D, A, 22, 0x895cd7be);
246   OP(C, D, A, B, 17, 0xa8304613);   OP(A, B, C, D, 7, 0x6b901122);
247   OP(B, C, D, A, 22, 0xfd469501);   OP(D, A, B, C, 12, 0xfd987193);
248   OP(A, B, C, D, 7, 0x698098d8);   OP(C, D, A, B, 17, 0xa679438e);
249   OP(D, A, B, C, 12, 0x8b44f7af);   OP(B, C, D, A, 22, 0x49b40821);
250   OP(C, D, A, B, 17, 0xffff5bb1);  # endif/* MD5_SIZE_VS_SPEED == 1 */
251   OP(B, C, D, A, 22, 0x895cd7be);  
252   OP(A, B, C, D, 7, 0x6b901122);   /* For the second to fourth round we have the possibly swapped words
253   OP(D, A, B, C, 12, 0xfd987193);     in CORRECT_WORDS.  Redefine the macro to take an additional first
254   OP(C, D, A, B, 17, 0xa679438e);     argument specifying the function to use.  */
255   OP(B, C, D, A, 22, 0x49b40821);  # undef OP
256  #  endif /* MD5_SIZE_VS_SPEED == 1 */  # define OP(f, a, b, c, d, k, s, T) \
   
  /* For the second to fourth round we have the possibly swapped words  
    in CORRECT_WORDS.  Redefine the macro to take an additional first  
    argument specifying the function to use.  */  
 #  undef OP  
 #  define OP(f, a, b, c, d, k, s, T) \  
257   do { \   do { \
258   a += f (b, c, d) + correct_words[k] + T; \   a += f(b, c, d) + correct_words[k] + T; \
259   CYCLIC (a, s); \   a = rotl32(a, s); \
260   a += b; \   a += b; \
261   } while (0)   } while (0)
262    
263   /* Round 2.  */   /* Round 2.  */
264  #  if MD5_SIZE_VS_SPEED == 1  # if MD5_SIZE_VS_SPEED == 1
265   pp = P_array;   pp = P_array;
266   for (i = 0; i < 4; i++) {   for (i = 0; i < 4; i++) {
267   OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++);   OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++);
268   OP(FG, D, A, B, C, (int) (*pp++), 9, *pc++);   OP(FG, D, A, B, C, (int) (*pp++), 9, *pc++);
269   OP(FG, C, D, A, B, (int) (*pp++), 14, *pc++);   OP(FG, C, D, A, B, (int) (*pp++), 14, *pc++);
270   OP(FG, B, C, D, A, (int) (*pp++), 20, *pc++);   OP(FG, B, C, D, A, (int) (*pp++), 20, *pc++);
271   }   }
272  #  else  # else
273   OP(FG, A, B, C, D, 1, 5, 0xf61e2562);   OP(FG, A, B, C, D, 1, 5, 0xf61e2562);
274   OP(FG, D, A, B, C, 6, 9, 0xc040b340);   OP(FG, D, A, B, C, 6, 9, 0xc040b340);
275   OP(FG, C, D, A, B, 11, 14, 0x265e5a51);   OP(FG, C, D, A, B, 11, 14, 0x265e5a51);
276   OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);   OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
277   OP(FG, A, B, C, D, 5, 5, 0xd62f105d);   OP(FG, A, B, C, D, 5, 5, 0xd62f105d);
278   OP(FG, D, A, B, C, 10, 9, 0x02441453);   OP(FG, D, A, B, C, 10, 9, 0x02441453);
279   OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);   OP(FG, C, D, A, B, 15, 14, 0xd8a1e681);
280   OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);   OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
281   OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);   OP(FG, A, B, C, D, 9, 5, 0x21e1cde6);
282   OP(FG, D, A, B, C, 14, 9, 0xc33707d6);   OP(FG, D, A, B, C, 14, 9, 0xc33707d6);
283   OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);   OP(FG, C, D, A, B, 3, 14, 0xf4d50d87);
284   OP(FG, B, C, D, A, 8, 20, 0x455a14ed);   OP(FG, B, C, D, A, 8, 20, 0x455a14ed);
285   OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);   OP(FG, A, B, C, D, 13, 5, 0xa9e3e905);
286   OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);   OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8);
287   OP(FG, C, D, A, B, 7, 14, 0x676f02d9);   OP(FG, C, D, A, B, 7, 14, 0x676f02d9);
288   OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);   OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
289  #  endif /* MD5_SIZE_VS_SPEED == 1 */  # endif/* MD5_SIZE_VS_SPEED == 1 */
290    
291   /* Round 3.  */   /* Round 3.  */
292  #  if MD5_SIZE_VS_SPEED == 1  # if MD5_SIZE_VS_SPEED == 1
293   for (i = 0; i < 4; i++) {   for (i = 0; i < 4; i++) {
294   OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++);   OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++);
295   OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++);   OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++);
296   OP(FH, C, D, A, B, (int) (*pp++), 16, *pc++);   OP(FH, C, D, A, B, (int) (*pp++), 16, *pc++);
297   OP(FH, B, C, D, A, (int) (*pp++), 23, *pc++);   OP(FH, B, C, D, A, (int) (*pp++), 23, *pc++);
298   }   }
299  #  else  # else
300   OP(FH, A, B, C, D, 5, 4, 0xfffa3942);   OP(FH, A, B, C, D, 5, 4, 0xfffa3942);
301   OP(FH, D, A, B, C, 8, 11, 0x8771f681);   OP(FH, D, A, B, C, 8, 11, 0x8771f681);
302   OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);   OP(FH, C, D, A, B, 11, 16, 0x6d9d6122);
303   OP(FH, B, C, D, A, 14, 23, 0xfde5380c);   OP(FH, B, C, D, A, 14, 23, 0xfde5380c);
304   OP(FH, A, B, C, D, 1, 4, 0xa4beea44);   OP(FH, A, B, C, D, 1, 4, 0xa4beea44);
305   OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);   OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9);
306   OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);   OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60);
307   OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);   OP(FH, B, C, D, A, 10, 23, 0xbebfbc70);
308   OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);   OP(FH, A, B, C, D, 13, 4, 0x289b7ec6);
309   OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);   OP(FH, D, A, B, C, 0, 11, 0xeaa127fa);
310   OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);   OP(FH, C, D, A, B, 3, 16, 0xd4ef3085);
311   OP(FH, B, C, D, A, 6, 23, 0x04881d05);   OP(FH, B, C, D, A, 6, 23, 0x04881d05);
312   OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);   OP(FH, A, B, C, D, 9, 4, 0xd9d4d039);
313   OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);   OP(FH, D, A, B, C, 12, 11, 0xe6db99e5);
314   OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);   OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8);
315   OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);   OP(FH, B, C, D, A, 2, 23, 0xc4ac5665);
316  #  endif /* MD5_SIZE_VS_SPEED == 1 */  # endif/* MD5_SIZE_VS_SPEED == 1 */
317    
318   /* Round 4.  */   /* Round 4.  */
319  #  if MD5_SIZE_VS_SPEED == 1  # if MD5_SIZE_VS_SPEED == 1
320   for (i = 0; i < 4; i++) {   for (i = 0; i < 4; i++) {
321   OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++);   OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++);
322   OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++);   OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++);
323   OP(FI, C, D, A, B, (int) (*pp++), 15, *pc++);   OP(FI, C, D, A, B, (int) (*pp++), 15, *pc++);
324   OP(FI, B, C, D, A, (int) (*pp++), 21, *pc++);   OP(FI, B, C, D, A, (int) (*pp++), 21, *pc++);
325   }   }
326  #  else  # else
327   OP(FI, A, B, C, D, 0, 6, 0xf4292244);   OP(FI, A, B, C, D, 0, 6, 0xf4292244);
328   OP(FI, D, A, B, C, 7, 10, 0x432aff97);   OP(FI, D, A, B, C, 7, 10, 0x432aff97);
329   OP(FI, C, D, A, B, 14, 15, 0xab9423a7);   OP(FI, C, D, A, B, 14, 15, 0xab9423a7);
330   OP(FI, B, C, D, A, 5, 21, 0xfc93a039);   OP(FI, B, C, D, A, 5, 21, 0xfc93a039);
331   OP(FI, A, B, C, D, 12, 6, 0x655b59c3);   OP(FI, A, B, C, D, 12, 6, 0x655b59c3);
332   OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);   OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92);
333   OP(FI, C, D, A, B, 10, 15, 0xffeff47d);   OP(FI, C, D, A, B, 10, 15, 0xffeff47d);
334   OP(FI, B, C, D, A, 1, 21, 0x85845dd1);   OP(FI, B, C, D, A, 1, 21, 0x85845dd1);
335   OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);   OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f);
336   OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);   OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
337   OP(FI, C, D, A, B, 6, 15, 0xa3014314);   OP(FI, C, D, A, B, 6, 15, 0xa3014314);
338   OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);   OP(FI, B, C, D, A, 13, 21, 0x4e0811a1);
339   OP(FI, A, B, C, D, 4, 6, 0xf7537e82);   OP(FI, A, B, C, D, 4, 6, 0xf7537e82);
340   OP(FI, D, A, B, C, 11, 10, 0xbd3af235);   OP(FI, D, A, B, C, 11, 10, 0xbd3af235);
341   OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);   OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
342   OP(FI, B, C, D, A, 9, 21, 0xeb86d391);   OP(FI, B, C, D, A, 9, 21, 0xeb86d391);
343  #  endif /* MD5_SIZE_VS_SPEED == 1 */  # endif /* MD5_SIZE_VS_SPEED == 1 */
344  # endif /* MD5_SIZE_VS_SPEED > 1 */  #endif /* MD5_SIZE_VS_SPEED > 1 */
345    
346   /* Add the starting values of the context.  */   /* Add the starting values of the context.  */
347   A += A_save;   A += A_save;
348   B += B_save;   B += B_save;
349   C += C_save;   C += C_save;
350   D += D_save;   D += D_save;
351    
352   /* Put checksum in context given as argument.  */   /* Put checksum in context given as argument.  */
353   ctx->A = A;   ctx->A = A;
# Line 370  static void md5_hash_block(const void *b Line 360  static void md5_hash_block(const void *b
360   * with chunks of data that are 4-byte aligned and a multiple of 64 bytes.   * with chunks of data that are 4-byte aligned and a multiple of 64 bytes.
361   * This function's internal buffer remembers previous data until it has 64   * This function's internal buffer remembers previous data until it has 64
362   * bytes worth to pass on.  Call md5_end() to flush this buffer. */   * bytes worth to pass on.  Call md5_end() to flush this buffer. */
   
363  void FAST_FUNC md5_hash(const void *buffer, size_t len, md5_ctx_t *ctx)  void FAST_FUNC md5_hash(const void *buffer, size_t len, md5_ctx_t *ctx)
364  {  {
365   char *buf=(char *)buffer;   char *buf = (char *)buffer;
366    
367   /* RFC 1321 specifies the possible length of the file up to 2^64 bits,   /* RFC 1321 specifies the possible length of the file up to 2^64 bits,
368   * Here we only track the number of bytes.  */   * Here we only track the number of bytes.  */
   
369   ctx->total += len;   ctx->total += len;
370    
371   // Process all input.   /* Process all input. */
   
372   while (len) {   while (len) {
373   unsigned i = 64 - ctx->buflen;   unsigned i = 64 - ctx->buflen;
374    
375   // Copy data into aligned buffer.   /* Copy data into aligned buffer. */
   
376   if (i > len) i = len;   if (i > len) i = len;
377   memcpy(ctx->buffer + ctx->buflen, buf, i);   memcpy(ctx->buffer + ctx->buflen, buf, i);
378   len -= i;   len -= i;
379   ctx->buflen += i;   ctx->buflen += i;
380   buf += i;   buf += i;
381    
382   // When buffer fills up, process it.   /* When buffer fills up, process it. */
   
383   if (ctx->buflen == 64) {   if (ctx->buflen == 64) {
384   md5_hash_block(ctx->buffer, ctx);   md5_hash_block(ctx->buffer, ctx);
385   ctx->buflen = 0;   ctx->buflen = 0;
# Line 410  void FAST_FUNC md5_hash(const void *buff Line 395  void FAST_FUNC md5_hash(const void *buff
395   * IMPORTANT: On some systems it is required that RESBUF is correctly   * IMPORTANT: On some systems it is required that RESBUF is correctly
396   * aligned for a 32 bits value.   * aligned for a 32 bits value.
397   */   */
398  void* FAST_FUNC md5_end(void *resbuf, md5_ctx_t *ctx)  void FAST_FUNC md5_end(void *resbuf, md5_ctx_t *ctx)
399  {  {
400   char *buf = ctx->buffer;   char *buf = ctx->buffer;
401   int i;   int i;
402    
403   /* Pad data to block size.  */   /* Pad data to block size.  */
   
404   buf[ctx->buflen++] = 0x80;   buf[ctx->buflen++] = 0x80;
405   memset(buf + ctx->buflen, 0, 128 - ctx->buflen);   memset(buf + ctx->buflen, 0, 128 - ctx->buflen);
406    
407   /* Put the 64-bit file length in *bits* at the end of the buffer.  */   /* Put the 64-bit file length in *bits* at the end of the buffer.  */
408   ctx->total <<= 3;   ctx->total <<= 3;
409   if (ctx->buflen > 56) buf += 64;   if (ctx->buflen > 56)
410   for (i = 0; i < 8; i++)  buf[56 + i] = ctx->total >> (i*8);   buf += 64;
411     for (i = 0; i < 8; i++)
412     buf[56 + i] = ctx->total >> (i*8);
413    
414   /* Process last bytes.  */   /* Process last bytes.  */
415   if (buf != ctx->buffer) md5_hash_block(ctx->buffer, ctx);   if (buf != ctx->buffer)
416     md5_hash_block(ctx->buffer, ctx);
417   md5_hash_block(buf, ctx);   md5_hash_block(buf, ctx);
418    
419   /* Put result from CTX in first 16 bytes following RESBUF.  The result is   /* The MD5 result is in little endian byte order.
420   * always in little endian byte order, so that a byte-wise output yields   * We (ab)use the fact that A-D are consecutive in memory.
  * to the wanted ASCII representation of the message digest.  
  *  
  * IMPORTANT: On some systems it is required that RESBUF is correctly  
  * aligned for a 32 bits value.  
421   */   */
422   ((uint32_t *) resbuf)[0] = SWAP_LE32(ctx->A);  #if BB_BIG_ENDIAN
423   ((uint32_t *) resbuf)[1] = SWAP_LE32(ctx->B);   ctx->A = SWAP_LE32(ctx->A);
424   ((uint32_t *) resbuf)[2] = SWAP_LE32(ctx->C);   ctx->B = SWAP_LE32(ctx->B);
425   ((uint32_t *) resbuf)[3] = SWAP_LE32(ctx->D);   ctx->C = SWAP_LE32(ctx->C);
426     ctx->D = SWAP_LE32(ctx->D);
427   return resbuf;  #endif
428     memcpy(resbuf, &ctx->A, sizeof(ctx->A) * 4);
429  }  }
   

Legend:
Removed from v.983  
changed lines
  Added in v.984