summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/md5
diff options
context:
space:
mode:
authormarkus <>2002-09-05 12:51:50 +0000
committermarkus <>2002-09-05 12:51:50 +0000
commit15b5d84f9da2ce4bfae8580e56e34a859f74ad71 (patch)
treebf939e82d7fd73cc8a01cf6959002209972091bc /src/lib/libcrypto/md5
parent027351f729b9e837200dae6e1520cda6577ab930 (diff)
downloadopenbsd-15b5d84f9da2ce4bfae8580e56e34a859f74ad71.tar.gz
openbsd-15b5d84f9da2ce4bfae8580e56e34a859f74ad71.tar.bz2
openbsd-15b5d84f9da2ce4bfae8580e56e34a859f74ad71.zip
import openssl-0.9.7-beta1
Diffstat (limited to 'src/lib/libcrypto/md5')
-rw-r--r--src/lib/libcrypto/md5/asm/md5-586.pl40
-rw-r--r--src/lib/libcrypto/md5/md5.h57
-rw-r--r--src/lib/libcrypto/md5/md5_dgst.c398
-rw-r--r--src/lib/libcrypto/md5/md5_locl.h167
-rw-r--r--src/lib/libcrypto/md5/md5_one.c28
5 files changed, 291 insertions, 399 deletions
diff --git a/src/lib/libcrypto/md5/asm/md5-586.pl b/src/lib/libcrypto/md5/asm/md5-586.pl
index 2c7fb7dd98..5fc6a205ce 100644
--- a/src/lib/libcrypto/md5/asm/md5-586.pl
+++ b/src/lib/libcrypto/md5/asm/md5-586.pl
@@ -1,4 +1,4 @@
1#!/usr/bin/perl 1#!/usr/local/bin/perl
2 2
3# Normal is the 3# Normal is the
4# md5_block_x86(MD5_CTX *c, ULONG *X); 4# md5_block_x86(MD5_CTX *c, ULONG *X);
@@ -29,7 +29,7 @@ $X="esi";
29 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, # R3 29 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, # R3
30 ); 30 );
31 31
32&md5_block("md5_block_x86"); 32&md5_block("md5_block_asm_host_order");
33&asm_finish(); 33&asm_finish();
34 34
35sub Np 35sub Np
@@ -44,7 +44,7 @@ sub R0
44 local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_; 44 local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_;
45 45
46 &mov($tmp1,$C) if $pos < 0; 46 &mov($tmp1,$C) if $pos < 0;
47 &mov($tmp2,&DWP($xo[$ki]*4,$K,"",0)) if $pos < 0; # very first one 47 &mov($tmp2,&DWP($xo[$ki]*4,$K,"",0)) if $pos < 0; # very first one
48 48
49 # body proper 49 # body proper
50 50
@@ -54,7 +54,6 @@ sub R0
54 &and($tmp1,$b); # F function - part 3 54 &and($tmp1,$b); # F function - part 3
55 &lea($a,&DWP($t,$a,$tmp2,1)); 55 &lea($a,&DWP($t,$a,$tmp2,1));
56 56
57 &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
58 &xor($tmp1,$d); # F function - part 4 57 &xor($tmp1,$d); # F function - part 4
59 58
60 &add($a,$tmp1); 59 &add($a,$tmp1);
@@ -62,8 +61,10 @@ sub R0
62 &mov($tmp1,&Np($c)) if $pos == 1; # next tmp1 for R1 61 &mov($tmp1,&Np($c)) if $pos == 1; # next tmp1 for R1
63 62
64 &rotl($a,$s); 63 &rotl($a,$s);
65 &add($a,$b);
66 64
65 &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
66
67 &add($a,$b);
67 } 68 }
68 69
69sub R1 70sub R1
@@ -100,16 +101,16 @@ if (($n & 1) == 0)
100 # make sure to do 'D' first, not 'B', else we clash with 101 # make sure to do 'D' first, not 'B', else we clash with
101 # the last add from the previous round. 102 # the last add from the previous round.
102 103
103 &xor($tmp1,$d); # H function - part 2 104 &xor($tmp1,$d); # H function - part 2
104 105
105 &xor($tmp1,$b); # H function - part 3 106 &xor($tmp1,$b); # H function - part 3
106 &lea($a,&DWP($t,$a,$tmp2,1)); 107 &lea($a,&DWP($t,$a,$tmp2,1));
107 108
108 &add($a,$tmp1); 109 &add($a,$tmp1);
109 &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0));
110 110
111 &rotl($a,$s); 111 &rotl($a,$s);
112 112
113 &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0));
113 &mov($tmp1,&Np($c)); 114 &mov($tmp1,&Np($c));
114 } 115 }
115else 116else
@@ -118,17 +119,17 @@ else
118 # make sure to do 'D' first, not 'B', else we clash with 119 # make sure to do 'D' first, not 'B', else we clash with
119 # the last add from the previous round. 120 # the last add from the previous round.
120 121
121 &lea($a,&DWP($t,$a,$tmp2,1)); 122 &lea($a,&DWP($t,$a,$tmp2,1));
122 123
123 &add($b,$c); # MOVED FORWARD 124 &add($b,$c); # MOVED FORWARD
124 &xor($tmp1,$d); # H function - part 2 125 &xor($tmp1,$d); # H function - part 2
125 126
126 &xor($tmp1,$b); # H function - part 3 127 &xor($tmp1,$b); # H function - part 3
127 &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2); 128 &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2);
128 129
129 &add($a,$tmp1); 130 &add($a,$tmp1);
130 &mov($tmp1,&Np($c)) if $pos < 1; # H function - part 1 131 &mov($tmp1,&Np($c)) if $pos < 1; # H function - part 1
131 &mov($tmp1,-1) if $pos == 1; # I function - part 1 132 &mov($tmp1,-1) if $pos == 1; # I function - part 1
132 133
133 &rotl($a,$s); 134 &rotl($a,$s);
134 135
@@ -146,21 +147,21 @@ sub R3
146 &xor($tmp1,$d) if $pos < 0; # I function - part 2 147 &xor($tmp1,$d) if $pos < 0; # I function - part 2
147 148
148 &or($tmp1,$b); # I function - part 3 149 &or($tmp1,$b); # I function - part 3
149 &lea($a,&DWP($t,$a,$tmp2,1)); 150 &lea($a,&DWP($t,$a,$tmp2,1));
150 151
151 &xor($tmp1,$c); # I function - part 4 152 &xor($tmp1,$c); # I function - part 4
152 &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if $pos != 2; # load X/k value 153 &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if $pos != 2; # load X/k value
153 &mov($tmp2,&wparam(0)) if $pos == 2; 154 &mov($tmp2,&wparam(0)) if $pos == 2;
154 155
155 &add($a,$tmp1); 156 &add($a,$tmp1);
156 &mov($tmp1,-1) if $pos < 1; # H function - part 1 157 &mov($tmp1,-1) if $pos < 1; # H function - part 1
157 &add($K,64) if $pos >=1 && !$normal; 158 &add($K,64) if $pos >=1 && !$normal;
158 159
159 &rotl($a,$s); 160 &rotl($a,$s);
160 161
161 &xor($tmp1,&Np($d)) if $pos <= 0; # I function - part = first time 162 &xor($tmp1,&Np($d)) if $pos <= 0; # I function - part = first time
162 &mov($tmp1,&DWP( 0,$tmp2,"",0)) if $pos > 0; 163 &mov($tmp1,&DWP( 0,$tmp2,"",0)) if $pos > 0;
163 &add($a,$b); 164 &add($a,$b);
164 } 165 }
165 166
166 167
@@ -182,6 +183,7 @@ sub md5_block
182 &mov($X, &wparam(1)); # esi 183 &mov($X, &wparam(1)); # esi
183 &mov($C, &wparam(2)); 184 &mov($C, &wparam(2));
184 &push("ebp"); 185 &push("ebp");
186 &shl($C, 6);
185 &push("ebx"); 187 &push("ebx");
186 &add($C, $X); # offset we end at 188 &add($C, $X); # offset we end at
187 &sub($C, 64); 189 &sub($C, 64);
diff --git a/src/lib/libcrypto/md5/md5.h b/src/lib/libcrypto/md5/md5.h
index 357c6c625d..52cb753e6a 100644
--- a/src/lib/libcrypto/md5/md5.h
+++ b/src/lib/libcrypto/md5/md5.h
@@ -63,35 +63,50 @@
63extern "C" { 63extern "C" {
64#endif 64#endif
65 65
66#ifdef OPENSSL_NO_MD5
67#error MD5 is disabled.
68#endif
69
70/*
71 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
72 * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then !
73 * ! MD5_LONG_LOG2 has to be defined along. !
74 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
75 */
76
77#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
78#define MD5_LONG unsigned long
79#elif defined(OENSSL_SYS_CRAY) || defined(__ILP64__)
80#define MD5_LONG unsigned long
81#define MD5_LONG_LOG2 3
82/*
83 * _CRAY note. I could declare short, but I have no idea what impact
84 * does it have on performance on none-T3E machines. I could declare
85 * int, but at least on C90 sizeof(int) can be chosen at compile time.
86 * So I've chosen long...
87 * <appro@fy.chalmers.se>
88 */
89#else
90#define MD5_LONG unsigned int
91#endif
92
66#define MD5_CBLOCK 64 93#define MD5_CBLOCK 64
67#define MD5_LBLOCK 16 94#define MD5_LBLOCK (MD5_CBLOCK/4)
68#define MD5_BLOCK 16
69#define MD5_LAST_BLOCK 56
70#define MD5_LENGTH_BLOCK 8
71#define MD5_DIGEST_LENGTH 16 95#define MD5_DIGEST_LENGTH 16
72 96
73typedef struct MD5state_st 97typedef struct MD5state_st
74 { 98 {
75 unsigned long A,B,C,D; 99 MD5_LONG A,B,C,D;
76 unsigned long Nl,Nh; 100 MD5_LONG Nl,Nh;
77 unsigned long data[MD5_LBLOCK]; 101 MD5_LONG data[MD5_LBLOCK];
78 int num; 102 int num;
79 } MD5_CTX; 103 } MD5_CTX;
80 104
81#ifndef NOPROTO 105int MD5_Init(MD5_CTX *c);
82void MD5_Init(MD5_CTX *c); 106int MD5_Update(MD5_CTX *c, const void *data, unsigned long len);
83void MD5_Update(MD5_CTX *c, unsigned char *data, unsigned long len); 107int MD5_Final(unsigned char *md, MD5_CTX *c);
84void MD5_Final(unsigned char *md, MD5_CTX *c); 108unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md);
85unsigned char *MD5(unsigned char *d, unsigned long n, unsigned char *md); 109void MD5_Transform(MD5_CTX *c, const unsigned char *b);
86void MD5_Transform(MD5_CTX *c, unsigned char *b);
87#else
88void MD5_Init();
89void MD5_Update();
90void MD5_Final();
91unsigned char *MD5();
92void MD5_Transform();
93#endif
94
95#ifdef __cplusplus 110#ifdef __cplusplus
96} 111}
97#endif 112#endif
diff --git a/src/lib/libcrypto/md5/md5_dgst.c b/src/lib/libcrypto/md5/md5_dgst.c
index 43b3498d92..c38a3f021e 100644
--- a/src/lib/libcrypto/md5/md5_dgst.c
+++ b/src/lib/libcrypto/md5/md5_dgst.c
@@ -58,8 +58,9 @@
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include "md5_locl.h" 60#include "md5_locl.h"
61#include <openssl/opensslv.h>
61 62
62char *MD5_version="MD5 part of SSLeay 0.9.0b 29-Jun-1998"; 63const char *MD5_version="MD5" OPENSSL_VERSION_PTEXT;
63 64
64/* Implemented from RFC1321 The MD5 Message-Digest Algorithm 65/* Implemented from RFC1321 The MD5 Message-Digest Algorithm
65 */ 66 */
@@ -69,24 +70,7 @@ char *MD5_version="MD5 part of SSLeay 0.9.0b 29-Jun-1998";
69#define INIT_DATA_C (unsigned long)0x98badcfeL 70#define INIT_DATA_C (unsigned long)0x98badcfeL
70#define INIT_DATA_D (unsigned long)0x10325476L 71#define INIT_DATA_D (unsigned long)0x10325476L
71 72
72#ifndef NOPROTO 73int MD5_Init(MD5_CTX *c)
73# ifdef MD5_ASM
74 void md5_block_x86(MD5_CTX *c, unsigned long *p,int num);
75# define md5_block md5_block_x86
76# else
77 static void md5_block(MD5_CTX *c, unsigned long *p,int num);
78# endif
79#else
80# ifdef MD5_ASM
81 void md5_block_x86();
82# define md5_block md5_block_x86
83# else
84 static void md5_block();
85# endif
86#endif
87
88void MD5_Init(c)
89MD5_CTX *c;
90 { 74 {
91 c->A=INIT_DATA_A; 75 c->A=INIT_DATA_A;
92 c->B=INIT_DATA_B; 76 c->B=INIT_DATA_B;
@@ -95,192 +79,35 @@ MD5_CTX *c;
95 c->Nl=0; 79 c->Nl=0;
96 c->Nh=0; 80 c->Nh=0;
97 c->num=0; 81 c->num=0;
82 return 1;
98 } 83 }
99 84
100void MD5_Update(c, data, len) 85#ifndef md5_block_host_order
101MD5_CTX *c; 86void md5_block_host_order (MD5_CTX *c, const void *data, int num)
102register unsigned char *data;
103unsigned long len;
104 {
105 register ULONG *p;
106 int sw,sc;
107 ULONG l;
108
109 if (len == 0) return;
110
111 l=(c->Nl+(len<<3))&0xffffffffL;
112 /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
113 * Wei Dai <weidai@eskimo.com> for pointing it out. */
114 if (l < c->Nl) /* overflow */
115 c->Nh++;
116 c->Nh+=(len>>29);
117 c->Nl=l;
118
119 if (c->num != 0)
120 {
121 p=c->data;
122 sw=c->num>>2;
123 sc=c->num&0x03;
124
125 if ((c->num+len) >= MD5_CBLOCK)
126 {
127 l= p[sw];
128 p_c2l(data,l,sc);
129 p[sw++]=l;
130 for (; sw<MD5_LBLOCK; sw++)
131 {
132 c2l(data,l);
133 p[sw]=l;
134 }
135 len-=(MD5_CBLOCK-c->num);
136
137 md5_block(c,p,64);
138 c->num=0;
139 /* drop through and do the rest */
140 }
141 else
142 {
143 int ew,ec;
144
145 c->num+=(int)len;
146 if ((sc+len) < 4) /* ugly, add char's to a word */
147 {
148 l= p[sw];
149 p_c2l_p(data,l,sc,len);
150 p[sw]=l;
151 }
152 else
153 {
154 ew=(c->num>>2);
155 ec=(c->num&0x03);
156 l= p[sw];
157 p_c2l(data,l,sc);
158 p[sw++]=l;
159 for (; sw < ew; sw++)
160 { c2l(data,l); p[sw]=l; }
161 if (ec)
162 {
163 c2l_p(data,l,ec);
164 p[sw]=l;
165 }
166 }
167 return;
168 }
169 }
170 /* we now can process the input data in blocks of MD5_CBLOCK
171 * chars and save the leftovers to c->data. */
172#ifdef L_ENDIAN
173 if ((((unsigned long)data)%sizeof(ULONG)) == 0)
174 {
175 sw=(int)len/MD5_CBLOCK;
176 if (sw > 0)
177 {
178 sw*=MD5_CBLOCK;
179 md5_block(c,(ULONG *)data,sw);
180 data+=sw;
181 len-=sw;
182 }
183 }
184#endif
185 p=c->data;
186 while (len >= MD5_CBLOCK)
187 {
188#if defined(L_ENDIAN) || defined(B_ENDIAN)
189 if (p != (unsigned long *)data)
190 memcpy(p,data,MD5_CBLOCK);
191 data+=MD5_CBLOCK;
192#ifdef B_ENDIAN
193 for (sw=(MD5_LBLOCK/4); sw; sw--)
194 {
195 Endian_Reverse32(p[0]);
196 Endian_Reverse32(p[1]);
197 Endian_Reverse32(p[2]);
198 Endian_Reverse32(p[3]);
199 p+=4;
200 }
201#endif
202#else
203 for (sw=(MD5_LBLOCK/4); sw; sw--)
204 {
205 c2l(data,l); *(p++)=l;
206 c2l(data,l); *(p++)=l;
207 c2l(data,l); *(p++)=l;
208 c2l(data,l); *(p++)=l;
209 }
210#endif
211 p=c->data;
212 md5_block(c,p,64);
213 len-=MD5_CBLOCK;
214 }
215 sc=(int)len;
216 c->num=sc;
217 if (sc)
218 {
219 sw=sc>>2; /* words to copy */
220#ifdef L_ENDIAN
221 p[sw]=0;
222 memcpy(p,data,sc);
223#else
224 sc&=0x03;
225 for ( ; sw; sw--)
226 { c2l(data,l); *(p++)=l; }
227 c2l_p(data,l,sc);
228 *p=l;
229#endif
230 }
231 }
232
233void MD5_Transform(c,b)
234MD5_CTX *c;
235unsigned char *b;
236 {
237 ULONG p[16];
238#if !defined(L_ENDIAN)
239 ULONG *q;
240 int i;
241#endif
242
243#if defined(B_ENDIAN) || defined(L_ENDIAN)
244 memcpy(p,b,64);
245#ifdef B_ENDIAN
246 q=p;
247 for (i=(MD5_LBLOCK/4); i; i--)
248 {
249 Endian_Reverse32(q[0]);
250 Endian_Reverse32(q[1]);
251 Endian_Reverse32(q[2]);
252 Endian_Reverse32(q[3]);
253 q+=4;
254 }
255#endif
256#else
257 q=p;
258 for (i=(MD5_LBLOCK/4); i; i--)
259 {
260 ULONG l;
261 c2l(b,l); *(q++)=l;
262 c2l(b,l); *(q++)=l;
263 c2l(b,l); *(q++)=l;
264 c2l(b,l); *(q++)=l;
265 }
266#endif
267 md5_block(c,p,64);
268 }
269
270#ifndef MD5_ASM
271
272static void md5_block(c, X, num)
273MD5_CTX *c;
274register ULONG *X;
275int num;
276 { 87 {
277 register ULONG A,B,C,D; 88 const MD5_LONG *X=data;
89 register unsigned long A,B,C,D;
90 /*
91 * In case you wonder why A-D are declared as long and not
92 * as MD5_LONG. Doing so results in slight performance
93 * boost on LP64 architectures. The catch is we don't
94 * really care if 32 MSBs of a 64-bit register get polluted
95 * with eventual overflows as we *save* only 32 LSBs in
96 * *either* case. Now declaring 'em long excuses the compiler
97 * from keeping 32 MSBs zeroed resulting in 13% performance
98 * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
99 * Well, to be honest it should say that this *prevents*
100 * performance degradation.
101 *
102 * <appro@fy.chalmers.se>
103 */
278 104
279 A=c->A; 105 A=c->A;
280 B=c->B; 106 B=c->B;
281 C=c->C; 107 C=c->C;
282 D=c->D; 108 D=c->D;
283 for (;;) 109
110 for (;num--;X+=HASH_LBLOCK)
284 { 111 {
285 /* Round 0 */ 112 /* Round 0 */
286 R0(A,B,C,D,X[ 0], 7,0xd76aa478L); 113 R0(A,B,C,D,X[ 0], 7,0xd76aa478L);
@@ -351,80 +178,133 @@ int num;
351 R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL); 178 R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL);
352 R3(B,C,D,A,X[ 9],21,0xeb86d391L); 179 R3(B,C,D,A,X[ 9],21,0xeb86d391L);
353 180
354 A+=c->A&0xffffffffL; 181 A = c->A += A;
355 B+=c->B&0xffffffffL; 182 B = c->B += B;
356 c->A=A; 183 C = c->C += C;
357 c->B=B; 184 D = c->D += D;
358 C+=c->C&0xffffffffL;
359 D+=c->D&0xffffffffL;
360 c->C=C;
361 c->D=D;
362 X+=16;
363 num-=64;
364 if (num <= 0) break;
365 } 185 }
366 } 186 }
367#endif 187#endif
368 188
369void MD5_Final(md, c) 189#ifndef md5_block_data_order
370unsigned char *md; 190#ifdef X
371MD5_CTX *c; 191#undef X
192#endif
193void md5_block_data_order (MD5_CTX *c, const void *data_, int num)
372 { 194 {
373 register int i,j; 195 const unsigned char *data=data_;
374 register ULONG l; 196 register unsigned long A,B,C,D,l;
375 register ULONG *p; 197 /*
376 static unsigned char end[4]={0x80,0x00,0x00,0x00}; 198 * In case you wonder why A-D are declared as long and not
377 unsigned char *cp=end; 199 * as MD5_LONG. Doing so results in slight performance
200 * boost on LP64 architectures. The catch is we don't
201 * really care if 32 MSBs of a 64-bit register get polluted
202 * with eventual overflows as we *save* only 32 LSBs in
203 * *either* case. Now declaring 'em long excuses the compiler
204 * from keeping 32 MSBs zeroed resulting in 13% performance
205 * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
206 * Well, to be honest it should say that this *prevents*
207 * performance degradation.
208 *
209 * <appro@fy.chalmers.se>
210 */
211#ifndef MD32_XARRAY
212 /* See comment in crypto/sha/sha_locl.h for details. */
213 unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
214 XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
215# define X(i) XX##i
216#else
217 MD5_LONG XX[MD5_LBLOCK];
218# define X(i) XX[i]
219#endif
378 220
379 /* c->num should definitly have room for at least one more byte. */ 221 A=c->A;
380 p=c->data; 222 B=c->B;
381 j=c->num; 223 C=c->C;
382 i=j>>2; 224 D=c->D;
383 225
384 /* purify often complains about the following line as an 226 for (;num--;)
385 * Uninitialized Memory Read. While this can be true, the
386 * following p_c2l macro will reset l when that case is true.
387 * This is because j&0x03 contains the number of 'valid' bytes
388 * already in p[i]. If and only if j&0x03 == 0, the UMR will
389 * occur but this is also the only time p_c2l will do
390 * l= *(cp++) instead of l|= *(cp++)
391 * Many thanks to Alex Tang <altitude@cic.net> for pickup this
392 * 'potential bug' */
393#ifdef PURIFY
394 if ((j&0x03) == 0) p[i]=0;
395#endif
396 l=p[i];
397 p_c2l(cp,l,j&0x03);
398 p[i]=l;
399 i++;
400 /* i is the next 'undefined word' */
401 if (c->num >= MD5_LAST_BLOCK)
402 { 227 {
403 for (; i<MD5_LBLOCK; i++) 228 HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l;
404 p[i]=0; 229 /* Round 0 */
405 md5_block(c,p,64); 230 R0(A,B,C,D,X( 0), 7,0xd76aa478L); HOST_c2l(data,l); X( 2)=l;
406 i=0; 231 R0(D,A,B,C,X( 1),12,0xe8c7b756L); HOST_c2l(data,l); X( 3)=l;
407 } 232 R0(C,D,A,B,X( 2),17,0x242070dbL); HOST_c2l(data,l); X( 4)=l;
408 for (; i<(MD5_LBLOCK-2); i++) 233 R0(B,C,D,A,X( 3),22,0xc1bdceeeL); HOST_c2l(data,l); X( 5)=l;
409 p[i]=0; 234 R0(A,B,C,D,X( 4), 7,0xf57c0fafL); HOST_c2l(data,l); X( 6)=l;
410 p[MD5_LBLOCK-2]=c->Nl; 235 R0(D,A,B,C,X( 5),12,0x4787c62aL); HOST_c2l(data,l); X( 7)=l;
411 p[MD5_LBLOCK-1]=c->Nh; 236 R0(C,D,A,B,X( 6),17,0xa8304613L); HOST_c2l(data,l); X( 8)=l;
412 md5_block(c,p,64); 237 R0(B,C,D,A,X( 7),22,0xfd469501L); HOST_c2l(data,l); X( 9)=l;
413 cp=md; 238 R0(A,B,C,D,X( 8), 7,0x698098d8L); HOST_c2l(data,l); X(10)=l;
414 l=c->A; l2c(l,cp); 239 R0(D,A,B,C,X( 9),12,0x8b44f7afL); HOST_c2l(data,l); X(11)=l;
415 l=c->B; l2c(l,cp); 240 R0(C,D,A,B,X(10),17,0xffff5bb1L); HOST_c2l(data,l); X(12)=l;
416 l=c->C; l2c(l,cp); 241 R0(B,C,D,A,X(11),22,0x895cd7beL); HOST_c2l(data,l); X(13)=l;
417 l=c->D; l2c(l,cp); 242 R0(A,B,C,D,X(12), 7,0x6b901122L); HOST_c2l(data,l); X(14)=l;
243 R0(D,A,B,C,X(13),12,0xfd987193L); HOST_c2l(data,l); X(15)=l;
244 R0(C,D,A,B,X(14),17,0xa679438eL);
245 R0(B,C,D,A,X(15),22,0x49b40821L);
246 /* Round 1 */
247 R1(A,B,C,D,X( 1), 5,0xf61e2562L);
248 R1(D,A,B,C,X( 6), 9,0xc040b340L);
249 R1(C,D,A,B,X(11),14,0x265e5a51L);
250 R1(B,C,D,A,X( 0),20,0xe9b6c7aaL);
251 R1(A,B,C,D,X( 5), 5,0xd62f105dL);
252 R1(D,A,B,C,X(10), 9,0x02441453L);
253 R1(C,D,A,B,X(15),14,0xd8a1e681L);
254 R1(B,C,D,A,X( 4),20,0xe7d3fbc8L);
255 R1(A,B,C,D,X( 9), 5,0x21e1cde6L);
256 R1(D,A,B,C,X(14), 9,0xc33707d6L);
257 R1(C,D,A,B,X( 3),14,0xf4d50d87L);
258 R1(B,C,D,A,X( 8),20,0x455a14edL);
259 R1(A,B,C,D,X(13), 5,0xa9e3e905L);
260 R1(D,A,B,C,X( 2), 9,0xfcefa3f8L);
261 R1(C,D,A,B,X( 7),14,0x676f02d9L);
262 R1(B,C,D,A,X(12),20,0x8d2a4c8aL);
263 /* Round 2 */
264 R2(A,B,C,D,X( 5), 4,0xfffa3942L);
265 R2(D,A,B,C,X( 8),11,0x8771f681L);
266 R2(C,D,A,B,X(11),16,0x6d9d6122L);
267 R2(B,C,D,A,X(14),23,0xfde5380cL);
268 R2(A,B,C,D,X( 1), 4,0xa4beea44L);
269 R2(D,A,B,C,X( 4),11,0x4bdecfa9L);
270 R2(C,D,A,B,X( 7),16,0xf6bb4b60L);
271 R2(B,C,D,A,X(10),23,0xbebfbc70L);
272 R2(A,B,C,D,X(13), 4,0x289b7ec6L);
273 R2(D,A,B,C,X( 0),11,0xeaa127faL);
274 R2(C,D,A,B,X( 3),16,0xd4ef3085L);
275 R2(B,C,D,A,X( 6),23,0x04881d05L);
276 R2(A,B,C,D,X( 9), 4,0xd9d4d039L);
277 R2(D,A,B,C,X(12),11,0xe6db99e5L);
278 R2(C,D,A,B,X(15),16,0x1fa27cf8L);
279 R2(B,C,D,A,X( 2),23,0xc4ac5665L);
280 /* Round 3 */
281 R3(A,B,C,D,X( 0), 6,0xf4292244L);
282 R3(D,A,B,C,X( 7),10,0x432aff97L);
283 R3(C,D,A,B,X(14),15,0xab9423a7L);
284 R3(B,C,D,A,X( 5),21,0xfc93a039L);
285 R3(A,B,C,D,X(12), 6,0x655b59c3L);
286 R3(D,A,B,C,X( 3),10,0x8f0ccc92L);
287 R3(C,D,A,B,X(10),15,0xffeff47dL);
288 R3(B,C,D,A,X( 1),21,0x85845dd1L);
289 R3(A,B,C,D,X( 8), 6,0x6fa87e4fL);
290 R3(D,A,B,C,X(15),10,0xfe2ce6e0L);
291 R3(C,D,A,B,X( 6),15,0xa3014314L);
292 R3(B,C,D,A,X(13),21,0x4e0811a1L);
293 R3(A,B,C,D,X( 4), 6,0xf7537e82L);
294 R3(D,A,B,C,X(11),10,0xbd3af235L);
295 R3(C,D,A,B,X( 2),15,0x2ad7d2bbL);
296 R3(B,C,D,A,X( 9),21,0xeb86d391L);
418 297
419 /* clear stuff, md5_block may be leaving some stuff on the stack 298 A = c->A += A;
420 * but I'm not worried :-) */ 299 B = c->B += B;
421 c->num=0; 300 C = c->C += C;
422/* memset((char *)&c,0,sizeof(c));*/ 301 D = c->D += D;
302 }
423 } 303 }
304#endif
424 305
425#ifdef undef 306#ifdef undef
426int printit(l) 307int printit(unsigned long *l)
427unsigned long *l;
428 { 308 {
429 int i,ii; 309 int i,ii;
430 310
diff --git a/src/lib/libcrypto/md5/md5_locl.h b/src/lib/libcrypto/md5/md5_locl.h
index dbbe1b71ca..34c5257306 100644
--- a/src/lib/libcrypto/md5/md5_locl.h
+++ b/src/lib/libcrypto/md5/md5_locl.h
@@ -56,109 +56,94 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58 58
59/* On sparc, this actually slows things down :-( */
60#if defined(sun)
61#undef B_ENDIAN
62#endif
63
64#include <stdlib.h> 59#include <stdlib.h>
65#include <string.h> 60#include <string.h>
66#include "md5.h" 61#include <openssl/opensslconf.h>
67 62#include <openssl/md5.h>
68#define ULONG unsigned long
69#define UCHAR unsigned char
70#define UINT unsigned int
71 63
72#if defined(NOCONST) 64#ifndef MD5_LONG_LOG2
73#define const 65#define MD5_LONG_LOG2 2 /* default to 32 bits */
74#endif 66#endif
75 67
76#undef c2l 68#ifdef MD5_ASM
77#define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \ 69# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
78 l|=(((unsigned long)(*((c)++)))<< 8), \ 70# define md5_block_host_order md5_block_asm_host_order
79 l|=(((unsigned long)(*((c)++)))<<16), \ 71# elif defined(__sparc) && defined(OPENSSL_SYS_ULTRASPARC)
80 l|=(((unsigned long)(*((c)++)))<<24)) 72 void md5_block_asm_data_order_aligned (MD5_CTX *c, const MD5_LONG *p,int num);
81 73# define HASH_BLOCK_DATA_ORDER_ALIGNED md5_block_asm_data_order_aligned
82#undef p_c2l 74# endif
83#define p_c2l(c,l,n) { \ 75#endif
84 switch (n) { \
85 case 0: l =((unsigned long)(*((c)++))); \
86 case 1: l|=((unsigned long)(*((c)++)))<< 8; \
87 case 2: l|=((unsigned long)(*((c)++)))<<16; \
88 case 3: l|=((unsigned long)(*((c)++)))<<24; \
89 } \
90 }
91 76
92/* NOTE the pointer is not incremented at the end of this */ 77void md5_block_host_order (MD5_CTX *c, const void *p,int num);
93#undef c2l_p 78void md5_block_data_order (MD5_CTX *c, const void *p,int num);
94#define c2l_p(c,l,n) { \
95 l=0; \
96 (c)+=n; \
97 switch (n) { \
98 case 3: l =((unsigned long)(*(--(c))))<<16; \
99 case 2: l|=((unsigned long)(*(--(c))))<< 8; \
100 case 1: l|=((unsigned long)(*(--(c)))) ; \
101 } \
102 }
103 79
104#undef p_c2l_p 80#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
105#define p_c2l_p(c,l,sc,len) { \ 81/*
106 switch (sc) \ 82 * *_block_host_order is expected to handle aligned data while
107 { \ 83 * *_block_data_order - unaligned. As algorithm and host (x86)
108 case 0: l =((unsigned long)(*((c)++))); \ 84 * are in this case of the same "endianness" these two are
109 if (--len == 0) break; \ 85 * otherwise indistinguishable. But normally you don't want to
110 case 1: l|=((unsigned long)(*((c)++)))<< 8; \ 86 * call the same function because unaligned access in places
111 if (--len == 0) break; \ 87 * where alignment is expected is usually a "Bad Thing". Indeed,
112 case 2: l|=((unsigned long)(*((c)++)))<<16; \ 88 * on RISCs you get punished with BUS ERROR signal or *severe*
113 } \ 89 * performance degradation. Intel CPUs are in turn perfectly
114 } 90 * capable of loading unaligned data without such drastic side
91 * effect. Yes, they say it's slower than aligned load, but no
92 * exception is generated and therefore performance degradation
93 * is *incomparable* with RISCs. What we should weight here is
94 * costs of unaligned access against costs of aligning data.
95 * According to my measurements allowing unaligned access results
96 * in ~9% performance improvement on Pentium II operating at
97 * 266MHz. I won't be surprised if the difference will be higher
98 * on faster systems:-)
99 *
100 * <appro@fy.chalmers.se>
101 */
102#define md5_block_data_order md5_block_host_order
103#endif
115 104
116#undef l2c 105#define DATA_ORDER_IS_LITTLE_ENDIAN
117#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ 106
118 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ 107#define HASH_LONG MD5_LONG
119 *((c)++)=(unsigned char)(((l)>>16)&0xff), \ 108#define HASH_LONG_LOG2 MD5_LONG_LOG2
120 *((c)++)=(unsigned char)(((l)>>24)&0xff)) 109#define HASH_CTX MD5_CTX
110#define HASH_CBLOCK MD5_CBLOCK
111#define HASH_LBLOCK MD5_LBLOCK
112#define HASH_UPDATE MD5_Update
113#define HASH_TRANSFORM MD5_Transform
114#define HASH_FINAL MD5_Final
115#define HASH_MAKE_STRING(c,s) do { \
116 unsigned long ll; \
117 ll=(c)->A; HOST_l2c(ll,(s)); \
118 ll=(c)->B; HOST_l2c(ll,(s)); \
119 ll=(c)->C; HOST_l2c(ll,(s)); \
120 ll=(c)->D; HOST_l2c(ll,(s)); \
121 } while (0)
122#define HASH_BLOCK_HOST_ORDER md5_block_host_order
123#if !defined(L_ENDIAN) || defined(md5_block_data_order)
124#define HASH_BLOCK_DATA_ORDER md5_block_data_order
125/*
126 * Little-endians (Intel and Alpha) feel better without this.
127 * It looks like memcpy does better job than generic
128 * md5_block_data_order on copying-n-aligning input data.
129 * But frankly speaking I didn't expect such result on Alpha.
130 * On the other hand I've got this with egcs-1.0.2 and if
131 * program is compiled with another (better?) compiler it
132 * might turn out other way around.
133 *
134 * <appro@fy.chalmers.se>
135 */
136#endif
121 137
122/* NOTE - c is not incremented as per l2c */ 138#include "md32_common.h"
123#undef l2cn
124#define l2cn(l1,l2,c,n) { \
125 c+=n; \
126 switch (n) { \
127 case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
128 case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
129 case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
130 case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
131 case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
132 case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
133 case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
134 case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
135 } \
136 }
137 139
138/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
139#if defined(WIN32)
140/* 5 instructions with rotate instruction, else 9 */
141#define Endian_Reverse32(a) \
142 { \
143 unsigned long l=(a); \
144 (a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \
145 }
146#else
147/* 6 instructions with rotate instruction, else 8 */
148#define Endian_Reverse32(a) \
149 { \
150 unsigned long l=(a); \
151 l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \
152 (a)=ROTATE(l,16L); \
153 }
154#endif
155/* 140/*
156#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) 141#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
157#define G(x,y,z) (((x) & (z)) | ((y) & (~(z)))) 142#define G(x,y,z) (((x) & (z)) | ((y) & (~(z))))
158*/ 143*/
159 144
160/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be 145/* As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
161 * simplified to the code below. Wei attributes these optimisations 146 * simplified to the code below. Wei attributes these optimizations
162 * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. 147 * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
163 */ 148 */
164#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) 149#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
@@ -166,14 +151,6 @@
166#define H(b,c,d) ((b) ^ (c) ^ (d)) 151#define H(b,c,d) ((b) ^ (c) ^ (d))
167#define I(b,c,d) (((~(d)) | (b)) ^ (c)) 152#define I(b,c,d) (((~(d)) | (b)) ^ (c))
168 153
169#undef ROTATE
170#if defined(WIN32)
171#define ROTATE(a,n) _lrotl(a,n)
172#else
173#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
174#endif
175
176
177#define R0(a,b,c,d,k,s,t) { \ 154#define R0(a,b,c,d,k,s,t) { \
178 a+=((k)+(t)+F((b),(c),(d))); \ 155 a+=((k)+(t)+F((b),(c),(d))); \
179 a=ROTATE(a,s); \ 156 a=ROTATE(a,s); \
diff --git a/src/lib/libcrypto/md5/md5_one.c b/src/lib/libcrypto/md5/md5_one.c
index ab6bb435f9..b89dec850d 100644
--- a/src/lib/libcrypto/md5/md5_one.c
+++ b/src/lib/libcrypto/md5/md5_one.c
@@ -57,19 +57,37 @@
57 */ 57 */
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include "md5_locl.h" 60#include <string.h>
61#include <openssl/md5.h>
61 62
62unsigned char *MD5(d, n, md) 63#ifdef CHARSET_EBCDIC
63unsigned char *d; 64#include <openssl/ebcdic.h>
64unsigned long n; 65#endif
65unsigned char *md; 66
67unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md)
66 { 68 {
67 MD5_CTX c; 69 MD5_CTX c;
68 static unsigned char m[MD5_DIGEST_LENGTH]; 70 static unsigned char m[MD5_DIGEST_LENGTH];
69 71
70 if (md == NULL) md=m; 72 if (md == NULL) md=m;
71 MD5_Init(&c); 73 MD5_Init(&c);
74#ifndef CHARSET_EBCDIC
72 MD5_Update(&c,d,n); 75 MD5_Update(&c,d,n);
76#else
77 {
78 char temp[1024];
79 unsigned long chunk;
80
81 while (n > 0)
82 {
83 chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
84 ebcdic2ascii(temp, d, chunk);
85 MD5_Update(&c,temp,chunk);
86 n -= chunk;
87 d += chunk;
88 }
89 }
90#endif
73 MD5_Final(md,&c); 91 MD5_Final(md,&c);
74 memset(&c,0,sizeof(c)); /* security consideration */ 92 memset(&c,0,sizeof(c)); /* security consideration */
75 return(md); 93 return(md);