]>
Commit | Line | Data |
---|---|---|
bd3576d2 UM |
1 | /* crypto/md32_common.h */ |
2 | /* ==================================================================== | |
8a09b386 | 3 | * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. |
bd3576d2 UM |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * | |
9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in | |
14 | * the documentation and/or other materials provided with the | |
15 | * distribution. | |
16 | * | |
17 | * 3. All advertising materials mentioning features or use of this | |
18 | * software must display the following acknowledgment: | |
19 | * "This product includes software developed by the OpenSSL Project | |
20 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | |
21 | * | |
22 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | |
23 | * endorse or promote products derived from this software without | |
24 | * prior written permission. For written permission, please contact | |
25 | * licensing@OpenSSL.org. | |
26 | * | |
27 | * 5. Products derived from this software may not be called "OpenSSL" | |
28 | * nor may "OpenSSL" appear in their names without prior written | |
29 | * permission of the OpenSSL Project. | |
30 | * | |
31 | * 6. Redistributions of any form whatsoever must retain the following | |
32 | * acknowledgment: | |
33 | * "This product includes software developed by the OpenSSL Project | |
34 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | |
35 | * | |
36 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | |
37 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
38 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
39 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | |
40 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
41 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
42 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
43 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
44 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
45 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
46 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
47 | * OF THE POSSIBILITY OF SUCH DAMAGE. | |
48 | * ==================================================================== | |
49 | * | |
50 | * This product includes cryptographic software written by Eric Young | |
51 | * (eay@cryptsoft.com). This product includes software written by Tim | |
52 | * Hudson (tjh@cryptsoft.com). | |
53 | * | |
54 | */ | |
55 | ||
56 | /* | |
57 | * This is a generic 32 bit "collector" for message digest algorithms. | |
58 | * Whenever needed it collects input character stream into chunks of | |
59 | * 32 bit values and invokes a block function that performs actual hash | |
60 | * calculations. | |
61 | * | |
62 | * Porting guide. | |
63 | * | |
64 | * Obligatory macros: | |
65 | * | |
66 | * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN | |
67 | * this macro defines byte order of input stream. | |
68 | * HASH_CBLOCK | |
69 | * size of a unit chunk HASH_BLOCK operates on. | |
70 | * HASH_LONG | |
71 | * has to be at lest 32 bit wide, if it's wider, then | |
72 | * HASH_LONG_LOG2 *has to* be defined along | |
73 | * HASH_CTX | |
74 | * context structure that at least contains following | |
75 | * members: | |
76 | * typedef struct { | |
77 | * ... | |
78 | * HASH_LONG Nl,Nh; | |
79 | * HASH_LONG data[HASH_LBLOCK]; | |
16ab8a93 | 80 | * unsigned int num; |
bd3576d2 UM |
81 | * ... |
82 | * } HASH_CTX; | |
83 | * HASH_UPDATE | |
84 | * name of "Update" function, implemented here. | |
85 | * HASH_TRANSFORM | |
86 | * name of "Transform" function, implemented here. | |
87 | * HASH_FINAL | |
88 | * name of "Final" function, implemented here. | |
89 | * HASH_BLOCK_HOST_ORDER | |
90 | * name of "block" function treating *aligned* input message | |
91 | * in host byte order, implemented externally. | |
92 | * HASH_BLOCK_DATA_ORDER | |
93 | * name of "block" function treating *unaligned* input message | |
94 | * in original (data) byte order, implemented externally (it | |
95 | * actually is optional if data and host are of the same | |
96 | * "endianess"). | |
1cbde6e4 AP |
97 | * HASH_MAKE_STRING |
98 | * macro convering context variables to an ASCII hash string. | |
bd3576d2 UM |
99 | * |
100 | * Optional macros: | |
101 | * | |
102 | * B_ENDIAN or L_ENDIAN | |
103 | * defines host byte-order. | |
104 | * HASH_LONG_LOG2 | |
105 | * defaults to 2 if not states otherwise. | |
106 | * HASH_LBLOCK | |
107 | * assumed to be HASH_CBLOCK/4 if not stated otherwise. | |
108 | * HASH_BLOCK_DATA_ORDER_ALIGNED | |
109 | * alternative "block" function capable of treating | |
110 | * aligned input message in original (data) order, | |
111 | * implemented externally. | |
112 | * | |
113 | * MD5 example: | |
114 | * | |
115 | * #define DATA_ORDER_IS_LITTLE_ENDIAN | |
116 | * | |
117 | * #define HASH_LONG MD5_LONG | |
118 | * #define HASH_LONG_LOG2 MD5_LONG_LOG2 | |
119 | * #define HASH_CTX MD5_CTX | |
120 | * #define HASH_CBLOCK MD5_CBLOCK | |
121 | * #define HASH_LBLOCK MD5_LBLOCK | |
122 | * #define HASH_UPDATE MD5_Update | |
123 | * #define HASH_TRANSFORM MD5_Transform | |
124 | * #define HASH_FINAL MD5_Final | |
125 | * #define HASH_BLOCK_HOST_ORDER md5_block_host_order | |
126 | * #define HASH_BLOCK_DATA_ORDER md5_block_data_order | |
127 | * | |
128 | * <appro@fy.chalmers.se> | |
129 | */ | |
130 | ||
131 | #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) | |
132 | #error "DATA_ORDER must be defined!" | |
133 | #endif | |
134 | ||
135 | #ifndef HASH_CBLOCK | |
136 | #error "HASH_CBLOCK must be defined!" | |
137 | #endif | |
138 | #ifndef HASH_LONG | |
139 | #error "HASH_LONG must be defined!" | |
140 | #endif | |
141 | #ifndef HASH_CTX | |
142 | #error "HASH_CTX must be defined!" | |
143 | #endif | |
144 | ||
145 | #ifndef HASH_UPDATE | |
146 | #error "HASH_UPDATE must be defined!" | |
147 | #endif | |
148 | #ifndef HASH_TRANSFORM | |
149 | #error "HASH_TRANSFORM must be defined!" | |
150 | #endif | |
151 | #ifndef HASH_FINAL | |
152 | #error "HASH_FINAL must be defined!" | |
153 | #endif | |
154 | ||
155 | #ifndef HASH_BLOCK_HOST_ORDER | |
156 | #error "HASH_BLOCK_HOST_ORDER must be defined!" | |
157 | #endif | |
158 | ||
159 | #if 0 | |
160 | /* | |
161 | * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED | |
162 | * isn't defined. | |
163 | */ | |
164 | #ifndef HASH_BLOCK_DATA_ORDER | |
165 | #error "HASH_BLOCK_DATA_ORDER must be defined!" | |
166 | #endif | |
167 | #endif | |
168 | ||
169 | #ifndef HASH_LBLOCK | |
170 | #define HASH_LBLOCK (HASH_CBLOCK/4) | |
171 | #endif | |
172 | ||
173 | #ifndef HASH_LONG_LOG2 | |
174 | #define HASH_LONG_LOG2 2 | |
175 | #endif | |
176 | ||
177 | /* | |
178 | * Engage compiler specific rotate intrinsic function if available. | |
179 | */ | |
180 | #undef ROTATE | |
181 | #ifndef PEDANTIC | |
1a979201 | 182 | # if defined(_MSC_VER) || defined(__ICC) |
1cbde6e4 AP |
183 | # define ROTATE(a,n) _lrotl(a,n) |
184 | # elif defined(__MWERKS__) | |
1eab9a1f | 185 | # if defined(__POWERPC__) |
a7c5241f | 186 | # define ROTATE(a,n) __rlwinm(a,n,0,31) |
1eab9a1f AP |
187 | # elif defined(__MC68K__) |
188 | /* Motorola specific tweak. <appro@fy.chalmers.se> */ | |
189 | # define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) ) | |
9a1e34e5 AP |
190 | # else |
191 | # define ROTATE(a,n) __rol(a,n) | |
192 | # endif | |
cf1b7d96 | 193 | # elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) |
bd3576d2 UM |
194 | /* |
195 | * Some GNU C inline assembler templates. Note that these are | |
196 | * rotates by *constant* number of bits! But that's exactly | |
197 | * what we need here... | |
bd3576d2 UM |
198 | * <appro@fy.chalmers.se> |
199 | */ | |
2f98abbc | 200 | # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) |
bd3576d2 | 201 | # define ROTATE(a,n) ({ register unsigned int ret; \ |
0fad6cb7 | 202 | asm ( \ |
bd3576d2 UM |
203 | "roll %1,%0" \ |
204 | : "=r"(ret) \ | |
205 | : "I"(n), "0"(a) \ | |
206 | : "cc"); \ | |
207 | ret; \ | |
208 | }) | |
76ef6ac9 | 209 | # elif defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) |
bd3576d2 | 210 | # define ROTATE(a,n) ({ register unsigned int ret; \ |
0fad6cb7 | 211 | asm ( \ |
bd3576d2 UM |
212 | "rlwinm %0,%1,%2,0,31" \ |
213 | : "=r"(ret) \ | |
214 | : "r"(a), "I"(n)); \ | |
215 | ret; \ | |
216 | }) | |
217 | # endif | |
218 | # endif | |
bd3576d2 UM |
219 | #endif /* PEDANTIC */ |
220 | ||
221 | #if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */ | |
222 | /* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */ | |
223 | #ifdef ROTATE | |
224 | /* 5 instructions with rotate instruction, else 9 */ | |
225 | #define REVERSE_FETCH32(a,l) ( \ | |
226 | l=*(const HASH_LONG *)(a), \ | |
227 | ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \ | |
228 | ) | |
229 | #else | |
230 | /* 6 instructions with rotate instruction, else 8 */ | |
231 | #define REVERSE_FETCH32(a,l) ( \ | |
232 | l=*(const HASH_LONG *)(a), \ | |
233 | l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \ | |
234 | ROTATE(l,16) \ | |
235 | ) | |
236 | /* | |
237 | * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|... | |
238 | * It's rewritten as above for two reasons: | |
239 | * - RISCs aren't good at long constants and have to explicitely | |
240 | * compose 'em with several (well, usually 2) instructions in a | |
241 | * register before performing the actual operation and (as you | |
242 | * already realized:-) having same constant should inspire the | |
243 | * compiler to permanently allocate the only register for it; | |
244 | * - most modern CPUs have two ALUs, but usually only one has | |
245 | * circuitry for shifts:-( this minor tweak inspires compiler | |
246 | * to schedule shift instructions in a better way... | |
247 | * | |
248 | * <appro@fy.chalmers.se> | |
249 | */ | |
250 | #endif | |
251 | #endif | |
252 | ||
253 | #ifndef ROTATE | |
254 | #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) | |
255 | #endif | |
256 | ||
257 | /* | |
258 | * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED | |
259 | * and HASH_BLOCK_HOST_ORDER ought to be the same if input data | |
260 | * and host are of the same "endianess". It's possible to mask | |
261 | * this with blank #define HASH_BLOCK_DATA_ORDER though... | |
262 | * | |
263 | * <appro@fy.chalmers.se> | |
264 | */ | |
265 | #if defined(B_ENDIAN) | |
266 | # if defined(DATA_ORDER_IS_BIG_ENDIAN) | |
267 | # if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 | |
268 | # define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER | |
269 | # endif | |
bd3576d2 UM |
270 | # endif |
271 | #elif defined(L_ENDIAN) | |
272 | # if defined(DATA_ORDER_IS_LITTLE_ENDIAN) | |
273 | # if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 | |
274 | # define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER | |
275 | # endif | |
bd3576d2 UM |
276 | # endif |
277 | #endif | |
278 | ||
0a78c297 | 279 | #if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) |
bd3576d2 UM |
280 | #ifndef HASH_BLOCK_DATA_ORDER |
281 | #error "HASH_BLOCK_DATA_ORDER must be defined!" | |
282 | #endif | |
283 | #endif | |
284 | ||
285 | #if defined(DATA_ORDER_IS_BIG_ENDIAN) | |
286 | ||
a2eb9688 AP |
287 | #ifndef PEDANTIC |
288 | # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) | |
6d9c46b8 | 289 | # if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \ |
af2c2823 | 290 | (defined(__x86_64) || defined(__x86_64__)) |
6c1fc273 | 291 | # if !defined(B_ENDIAN) |
a2eb9688 AP |
292 | /* |
293 | * This gives ~30-40% performance improvement in SHA-256 compiled | |
294 | * with gcc [on P4]. Well, first macro to be frank. We can pull | |
295 | * this trick on x86* platforms only, because these CPUs can fetch | |
296 | * unaligned data without raising an exception. | |
297 | */ | |
385c8e89 AP |
298 | # define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \ |
299 | asm ("bswapl %0":"=r"(r):"0"(r)); \ | |
300 | (c)+=4; (l)=r; }) | |
a2eb9688 AP |
301 | # define HOST_l2c(l,c) ({ unsigned int r=(l); \ |
302 | asm ("bswapl %0":"=r"(r):"0"(r)); \ | |
303 | *((unsigned int *)(c))=r; (c)+=4; r; }) | |
6c1fc273 | 304 | # endif |
a2eb9688 AP |
305 | # endif |
306 | # endif | |
307 | #endif | |
308 | ||
309 | #ifndef HOST_c2l | |
bd3576d2 UM |
310 | #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ |
311 | l|=(((unsigned long)(*((c)++)))<<16), \ | |
312 | l|=(((unsigned long)(*((c)++)))<< 8), \ | |
313 | l|=(((unsigned long)(*((c)++))) ), \ | |
314 | l) | |
a2eb9688 | 315 | #endif |
bd3576d2 UM |
316 | #define HOST_p_c2l(c,l,n) { \ |
317 | switch (n) { \ | |
318 | case 0: l =((unsigned long)(*((c)++)))<<24; \ | |
319 | case 1: l|=((unsigned long)(*((c)++)))<<16; \ | |
320 | case 2: l|=((unsigned long)(*((c)++)))<< 8; \ | |
321 | case 3: l|=((unsigned long)(*((c)++))); \ | |
322 | } } | |
323 | #define HOST_p_c2l_p(c,l,sc,len) { \ | |
324 | switch (sc) { \ | |
325 | case 0: l =((unsigned long)(*((c)++)))<<24; \ | |
326 | if (--len == 0) break; \ | |
327 | case 1: l|=((unsigned long)(*((c)++)))<<16; \ | |
328 | if (--len == 0) break; \ | |
329 | case 2: l|=((unsigned long)(*((c)++)))<< 8; \ | |
330 | } } | |
331 | /* NOTE the pointer is not incremented at the end of this */ | |
332 | #define HOST_c2l_p(c,l,n) { \ | |
333 | l=0; (c)+=n; \ | |
334 | switch (n) { \ | |
335 | case 3: l =((unsigned long)(*(--(c))))<< 8; \ | |
336 | case 2: l|=((unsigned long)(*(--(c))))<<16; \ | |
337 | case 1: l|=((unsigned long)(*(--(c))))<<24; \ | |
338 | } } | |
a2eb9688 | 339 | #ifndef HOST_l2c |
bd3576d2 UM |
340 | #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ |
341 | *((c)++)=(unsigned char)(((l)>>16)&0xff), \ | |
342 | *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ | |
343 | *((c)++)=(unsigned char)(((l) )&0xff), \ | |
344 | l) | |
a2eb9688 | 345 | #endif |
bd3576d2 UM |
346 | |
347 | #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) | |
348 | ||
a2eb9688 | 349 | #if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) |
1110cea0 RL |
350 | # ifndef B_ENDIAN |
351 | /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */ | |
352 | # define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l) | |
353 | # define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l) | |
354 | # endif | |
a2eb9688 AP |
355 | #endif |
356 | ||
357 | #ifndef HOST_c2l | |
bd3576d2 UM |
358 | #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ |
359 | l|=(((unsigned long)(*((c)++)))<< 8), \ | |
360 | l|=(((unsigned long)(*((c)++)))<<16), \ | |
361 | l|=(((unsigned long)(*((c)++)))<<24), \ | |
362 | l) | |
a2eb9688 | 363 | #endif |
bd3576d2 UM |
364 | #define HOST_p_c2l(c,l,n) { \ |
365 | switch (n) { \ | |
366 | case 0: l =((unsigned long)(*((c)++))); \ | |
367 | case 1: l|=((unsigned long)(*((c)++)))<< 8; \ | |
368 | case 2: l|=((unsigned long)(*((c)++)))<<16; \ | |
369 | case 3: l|=((unsigned long)(*((c)++)))<<24; \ | |
370 | } } | |
371 | #define HOST_p_c2l_p(c,l,sc,len) { \ | |
372 | switch (sc) { \ | |
373 | case 0: l =((unsigned long)(*((c)++))); \ | |
374 | if (--len == 0) break; \ | |
375 | case 1: l|=((unsigned long)(*((c)++)))<< 8; \ | |
376 | if (--len == 0) break; \ | |
377 | case 2: l|=((unsigned long)(*((c)++)))<<16; \ | |
378 | } } | |
379 | /* NOTE the pointer is not incremented at the end of this */ | |
380 | #define HOST_c2l_p(c,l,n) { \ | |
381 | l=0; (c)+=n; \ | |
382 | switch (n) { \ | |
383 | case 3: l =((unsigned long)(*(--(c))))<<16; \ | |
384 | case 2: l|=((unsigned long)(*(--(c))))<< 8; \ | |
385 | case 1: l|=((unsigned long)(*(--(c)))); \ | |
386 | } } | |
a2eb9688 | 387 | #ifndef HOST_l2c |
bd3576d2 UM |
388 | #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ |
389 | *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ | |
390 | *((c)++)=(unsigned char)(((l)>>16)&0xff), \ | |
391 | *((c)++)=(unsigned char)(((l)>>24)&0xff), \ | |
392 | l) | |
a2eb9688 | 393 | #endif |
bd3576d2 UM |
394 | |
395 | #endif | |
396 | ||
397 | /* | |
398 | * Time for some action:-) | |
399 | */ | |
400 | ||
9e0aad9f | 401 | int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len) |
bd3576d2 | 402 | { |
bd445703 | 403 | const unsigned char *data=data_; |
bd3576d2 | 404 | register HASH_LONG * p; |
9e0aad9f | 405 | register HASH_LONG l; |
16ab8a93 | 406 | size_t sw,sc,ew,ec; |
bd3576d2 | 407 | |
2dc769a1 | 408 | if (len==0) return 1; |
bd3576d2 | 409 | |
9e0aad9f | 410 | l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL; |
bd3576d2 UM |
411 | /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to |
412 | * Wei Dai <weidai@eskimo.com> for pointing it out. */ | |
413 | if (l < c->Nl) /* overflow */ | |
414 | c->Nh++; | |
9e0aad9f | 415 | c->Nh+=(len>>29); /* might cause compiler warning on 16-bit */ |
bd3576d2 UM |
416 | c->Nl=l; |
417 | ||
418 | if (c->num != 0) | |
419 | { | |
420 | p=c->data; | |
421 | sw=c->num>>2; | |
422 | sc=c->num&0x03; | |
423 | ||
424 | if ((c->num+len) >= HASH_CBLOCK) | |
425 | { | |
426 | l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l; | |
427 | for (; sw<HASH_LBLOCK; sw++) | |
428 | { | |
429 | HOST_c2l(data,l); p[sw]=l; | |
430 | } | |
431 | HASH_BLOCK_HOST_ORDER (c,p,1); | |
432 | len-=(HASH_CBLOCK-c->num); | |
433 | c->num=0; | |
434 | /* drop through and do the rest */ | |
435 | } | |
436 | else | |
437 | { | |
16ab8a93 | 438 | c->num+=(unsigned int)len; |
bd3576d2 UM |
439 | if ((sc+len) < 4) /* ugly, add char's to a word */ |
440 | { | |
441 | l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l; | |
442 | } | |
443 | else | |
444 | { | |
445 | ew=(c->num>>2); | |
446 | ec=(c->num&0x03); | |
8a09b386 BM |
447 | if (sc) |
448 | l=p[sw]; | |
449 | HOST_p_c2l(data,l,sc); | |
450 | p[sw++]=l; | |
bd3576d2 UM |
451 | for (; sw < ew; sw++) |
452 | { | |
453 | HOST_c2l(data,l); p[sw]=l; | |
454 | } | |
455 | if (ec) | |
456 | { | |
457 | HOST_c2l_p(data,l,ec); p[sw]=l; | |
458 | } | |
459 | } | |
2dc769a1 | 460 | return 1; |
bd3576d2 UM |
461 | } |
462 | } | |
463 | ||
464 | sw=len/HASH_CBLOCK; | |
465 | if (sw > 0) | |
466 | { | |
0a78c297 | 467 | #if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) |
bd3576d2 UM |
468 | /* |
469 | * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined | |
470 | * only if sizeof(HASH_LONG)==4. | |
471 | */ | |
a2eb9688 | 472 | if ((((size_t)data)%4) == 0) |
bd3576d2 | 473 | { |
4d5d543e | 474 | /* data is properly aligned so that we can cast it: */ |
8087d8f7 | 475 | HASH_BLOCK_DATA_ORDER_ALIGNED (c,(const HASH_LONG *)data,sw); |
bd3576d2 UM |
476 | sw*=HASH_CBLOCK; |
477 | data+=sw; | |
478 | len-=sw; | |
479 | } | |
480 | else | |
481 | #if !defined(HASH_BLOCK_DATA_ORDER) | |
482 | while (sw--) | |
483 | { | |
484 | memcpy (p=c->data,data,HASH_CBLOCK); | |
485 | HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1); | |
486 | data+=HASH_CBLOCK; | |
487 | len-=HASH_CBLOCK; | |
488 | } | |
489 | #endif | |
490 | #endif | |
491 | #if defined(HASH_BLOCK_DATA_ORDER) | |
492 | { | |
531b2cf7 | 493 | HASH_BLOCK_DATA_ORDER(c,data,sw); |
bd3576d2 UM |
494 | sw*=HASH_CBLOCK; |
495 | data+=sw; | |
496 | len-=sw; | |
497 | } | |
498 | #endif | |
499 | } | |
500 | ||
501 | if (len!=0) | |
502 | { | |
503 | p = c->data; | |
504 | c->num = len; | |
505 | ew=len>>2; /* words to copy */ | |
506 | ec=len&0x03; | |
507 | for (; ew; ew--,p++) | |
508 | { | |
509 | HOST_c2l(data,l); *p=l; | |
510 | } | |
511 | HOST_c2l_p(data,l,ec); | |
512 | *p=l; | |
513 | } | |
2dc769a1 | 514 | return 1; |
bd3576d2 UM |
515 | } |
516 | ||
517 | ||
ac7d0785 | 518 | void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data) |
bd3576d2 | 519 | { |
0a78c297 | 520 | #if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) |
a2eb9688 | 521 | if ((((size_t)data)%4) == 0) |
4d5d543e | 522 | /* data is properly aligned so that we can cast it: */ |
8087d8f7 | 523 | HASH_BLOCK_DATA_ORDER_ALIGNED (c,(const HASH_LONG *)data,1); |
bd3576d2 UM |
524 | else |
525 | #if !defined(HASH_BLOCK_DATA_ORDER) | |
526 | { | |
527 | memcpy (c->data,data,HASH_CBLOCK); | |
528 | HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1); | |
529 | } | |
530 | #endif | |
531 | #endif | |
532 | #if defined(HASH_BLOCK_DATA_ORDER) | |
cdfb093f | 533 | HASH_BLOCK_DATA_ORDER (c,data,1); |
bd3576d2 UM |
534 | #endif |
535 | } | |
536 | ||
537 | ||
2dc769a1 | 538 | int HASH_FINAL (unsigned char *md, HASH_CTX *c) |
bd3576d2 UM |
539 | { |
540 | register HASH_LONG *p; | |
541 | register unsigned long l; | |
542 | register int i,j; | |
543 | static const unsigned char end[4]={0x80,0x00,0x00,0x00}; | |
544 | const unsigned char *cp=end; | |
545 | ||
546 | /* c->num should definitly have room for at least one more byte. */ | |
547 | p=c->data; | |
548 | i=c->num>>2; | |
549 | j=c->num&0x03; | |
550 | ||
551 | #if 0 | |
552 | /* purify often complains about the following line as an | |
553 | * Uninitialized Memory Read. While this can be true, the | |
554 | * following p_c2l macro will reset l when that case is true. | |
555 | * This is because j&0x03 contains the number of 'valid' bytes | |
556 | * already in p[i]. If and only if j&0x03 == 0, the UMR will | |
557 | * occur but this is also the only time p_c2l will do | |
558 | * l= *(cp++) instead of l|= *(cp++) | |
559 | * Many thanks to Alex Tang <altitude@cic.net> for pickup this | |
560 | * 'potential bug' */ | |
561 | #ifdef PURIFY | |
562 | if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */ | |
563 | #endif | |
564 | l=p[i]; | |
565 | #else | |
566 | l = (j==0) ? 0 : p[i]; | |
567 | #endif | |
568 | HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */ | |
569 | ||
570 | if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */ | |
571 | { | |
572 | if (i<HASH_LBLOCK) p[i]=0; | |
573 | HASH_BLOCK_HOST_ORDER (c,p,1); | |
574 | i=0; | |
575 | } | |
576 | for (; i<(HASH_LBLOCK-2); i++) | |
577 | p[i]=0; | |
578 | ||
579 | #if defined(DATA_ORDER_IS_BIG_ENDIAN) | |
580 | p[HASH_LBLOCK-2]=c->Nh; | |
581 | p[HASH_LBLOCK-1]=c->Nl; | |
582 | #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) | |
583 | p[HASH_LBLOCK-2]=c->Nl; | |
584 | p[HASH_LBLOCK-1]=c->Nh; | |
585 | #endif | |
586 | HASH_BLOCK_HOST_ORDER (c,p,1); | |
587 | ||
1cbde6e4 AP |
588 | #ifndef HASH_MAKE_STRING |
589 | #error "HASH_MAKE_STRING must be defined!" | |
590 | #else | |
591 | HASH_MAKE_STRING(c,md); | |
592 | #endif | |
bd3576d2 UM |
593 | |
594 | c->num=0; | |
595 | /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack | |
596 | * but I'm not worried :-) | |
4579924b | 597 | OPENSSL_cleanse((void *)c,sizeof(HASH_CTX)); |
bd3576d2 | 598 | */ |
2dc769a1 | 599 | return 1; |
bd3576d2 | 600 | } |
2f98abbc AP |
601 | |
602 | #ifndef MD32_REG_T | |
603 | #define MD32_REG_T long | |
604 | /* | |
605 | * This comment was originaly written for MD5, which is why it | |
606 | * discusses A-D. But it basically applies to all 32-bit digests, | |
607 | * which is why it was moved to common header file. | |
608 | * | |
609 | * In case you wonder why A-D are declared as long and not | |
610 | * as MD5_LONG. Doing so results in slight performance | |
611 | * boost on LP64 architectures. The catch is we don't | |
612 | * really care if 32 MSBs of a 64-bit register get polluted | |
613 | * with eventual overflows as we *save* only 32 LSBs in | |
614 | * *either* case. Now declaring 'em long excuses the compiler | |
615 | * from keeping 32 MSBs zeroed resulting in 13% performance | |
616 | * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. | |
617 | * Well, to be honest it should say that this *prevents* | |
618 | * performance degradation. | |
619 | * <appro@fy.chalmers.se> | |
620 | * Apparently there're LP64 compilers that generate better | |
621 | * code if A-D are declared int. Most notably GCC-x86_64 | |
622 | * generates better code. | |
623 | * <appro@fy.chalmers.se> | |
624 | */ | |
625 | #endif |