| OLD | NEW |
| (Empty) |
| 1 /* crypto/md32_common.h */ | |
| 2 /* ==================================================================== | |
| 3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. | |
| 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 */ | |
| 51 | |
| 52 /* | |
| 53 * This is a generic 32 bit "collector" for message digest algorithms. | |
| 54 * Whenever needed it collects input character stream into chunks of | |
| 55 * 32 bit values and invokes a block function that performs actual hash | |
| 56 * calculations. | |
| 57 * | |
| 58 * Porting guide. | |
| 59 * | |
| 60 * Obligatory macros: | |
| 61 * | |
| 62 * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN | |
| 63 * this macro defines byte order of input stream. | |
| 64 * HASH_CBLOCK | |
| 65 * size of a unit chunk HASH_BLOCK operates on. | |
| 66 * HASH_LONG | |
| 67 * has to be at lest 32 bit wide, if it's wider, then | |
| 68 * HASH_LONG_LOG2 *has to* be defined along | |
| 69 * HASH_CTX | |
| 70 * context structure that at least contains following | |
| 71 * members: | |
| 72 * typedef struct { | |
| 73 * ... | |
| 74 * HASH_LONG Nl,Nh; | |
| 75 * either { | |
| 76 * HASH_LONG data[HASH_LBLOCK]; | |
| 77 * unsigned char data[HASH_CBLOCK]; | |
| 78 * }; | |
| 79 * unsigned int num; | |
| 80 * ... | |
| 81 * } HASH_CTX; | |
| 82 * data[] vector is expected to be zeroed upon first call to | |
| 83 * HASH_UPDATE. | |
| 84 * HASH_UPDATE | |
| 85 * name of "Update" function, implemented here. | |
| 86 * HASH_TRANSFORM | |
| 87 * name of "Transform" function, implemented here. | |
| 88 * HASH_FINAL | |
| 89 * name of "Final" function, implemented here. | |
| 90 * HASH_BLOCK_DATA_ORDER | |
| 91 * name of "block" function capable of treating *unaligned* input | |
| 92 * message in original (data) byte order, implemented externally. | |
| 93 * HASH_MAKE_STRING | |
| 94 * macro convering context variables to an ASCII hash string. | |
| 95 * | |
| 96 * MD5 example: | |
| 97 * | |
| 98 * #define DATA_ORDER_IS_LITTLE_ENDIAN | |
| 99 * | |
| 100 * #define HASH_LONG MD5_LONG | |
| 101 * #define HASH_LONG_LOG2 MD5_LONG_LOG2 | |
| 102 * #define HASH_CTX MD5_CTX | |
| 103 * #define HASH_CBLOCK MD5_CBLOCK | |
| 104 * #define HASH_UPDATE MD5_Update | |
| 105 * #define HASH_TRANSFORM MD5_Transform | |
| 106 * #define HASH_FINAL MD5_Final | |
| 107 * #define HASH_BLOCK_DATA_ORDER md5_block_data_order | |
| 108 * | |
| 109 * <appro@fy.chalmers.se> | |
| 110 */ | |
| 111 | |
| 112 #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) | |
| 113 #error "DATA_ORDER must be defined!" | |
| 114 #endif | |
| 115 | |
| 116 #ifndef HASH_CBLOCK | |
| 117 #error "HASH_CBLOCK must be defined!" | |
| 118 #endif | |
| 119 #ifndef HASH_LONG | |
| 120 #error "HASH_LONG must be defined!" | |
| 121 #endif | |
| 122 #ifndef HASH_CTX | |
| 123 #error "HASH_CTX must be defined!" | |
| 124 #endif | |
| 125 | |
| 126 #ifndef HASH_UPDATE | |
| 127 #error "HASH_UPDATE must be defined!" | |
| 128 #endif | |
| 129 #ifndef HASH_TRANSFORM | |
| 130 #error "HASH_TRANSFORM must be defined!" | |
| 131 #endif | |
| 132 #ifndef HASH_FINAL | |
| 133 #error "HASH_FINAL must be defined!" | |
| 134 #endif | |
| 135 | |
| 136 #ifndef HASH_BLOCK_DATA_ORDER | |
| 137 #error "HASH_BLOCK_DATA_ORDER must be defined!" | |
| 138 #endif | |
| 139 | |
| 140 /* | |
| 141 * Engage compiler specific rotate intrinsic function if available. | |
| 142 */ | |
| 143 #undef ROTATE | |
| 144 #ifndef PEDANTIC | |
| 145 # if defined(_MSC_VER) || defined(__ICC) | |
| 146 # define ROTATE(a,n) _lrotl(a,n) | |
| 147 # elif defined(__MWERKS__) | |
| 148 # if defined(__POWERPC__) | |
| 149 # define ROTATE(a,n) __rlwinm(a,n,0,31) | |
| 150 # elif defined(__MC68K__) | |
| 151 /* Motorola specific tweak. <appro@fy.chalmers.se> */ | |
| 152 # define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) ) | |
| 153 # else | |
| 154 # define ROTATE(a,n) __rol(a,n) | |
| 155 # endif | |
| 156 # elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(
OPENSSL_NO_INLINE_ASM) | |
| 157 /* | |
| 158 * Some GNU C inline assembler templates. Note that these are | |
| 159 * rotates by *constant* number of bits! But that's exactly | |
| 160 * what we need here... | |
| 161 * <appro@fy.chalmers.se> | |
| 162 */ | |
| 163 # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86
_64__) | |
| 164 # define ROTATE(a,n) ({ register unsigned int ret; \ | |
| 165 asm ( \ | |
| 166 "roll %1,%0" \ | |
| 167 : "=r"(ret) \ | |
| 168 : "I"(n), "0"((unsigned int)(a)) \ | |
| 169 : "cc"); \ | |
| 170 ret; \ | |
| 171 }) | |
| 172 # elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ | |
| 173 defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) | |
| 174 # define ROTATE(a,n) ({ register unsigned int ret; \ | |
| 175 asm ( \ | |
| 176 "rlwinm %0,%1,%2,0,31" \ | |
| 177 : "=r"(ret) \ | |
| 178 : "r"(a), "I"(n)); \ | |
| 179 ret; \ | |
| 180 }) | |
| 181 # elif defined(__s390x__) | |
| 182 # define ROTATE(a,n) ({ register unsigned int ret; \ | |
| 183 asm ("rll %0,%1,%2" \ | |
| 184 : "=r"(ret) \ | |
| 185 : "r"(a), "I"(n)); \ | |
| 186 ret; \ | |
| 187 }) | |
| 188 # endif | |
| 189 # endif | |
| 190 #endif /* PEDANTIC */ | |
| 191 | |
| 192 #ifndef ROTATE | |
| 193 #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) | |
| 194 #endif | |
| 195 | |
| 196 #if defined(DATA_ORDER_IS_BIG_ENDIAN) | |
| 197 | |
| 198 #ifndef PEDANTIC | |
| 199 # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OP
ENSSL_NO_INLINE_ASM) | |
| 200 # if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \ | |
| 201 (defined(__x86_64) || defined(__x86_64__)) | |
| 202 # if !defined(B_ENDIAN) | |
| 203 /* | |
| 204 * This gives ~30-40% performance improvement in SHA-256 compiled | |
| 205 * with gcc [on P4]. Well, first macro to be frank. We can pull | |
| 206 * this trick on x86* platforms only, because these CPUs can fetch | |
| 207 * unaligned data without raising an exception. | |
| 208 */ | |
| 209 # define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c));
\ | |
| 210 asm ("bswapl %0":"=r"(r):"0"(r)); \ | |
| 211 (c)+=4; (l)=r; }) | |
| 212 # define HOST_l2c(l,c) ({ unsigned int r=(l); \ | |
| 213 asm ("bswapl %0":"=r"(r):"0"(r)); \ | |
| 214 *((unsigned int *)(c))=r; (c)+=4; r; }) | |
| 215 # endif | |
| 216 # endif | |
| 217 # endif | |
| 218 #endif | |
| 219 #if defined(__s390__) || defined(__s390x__) | |
| 220 # define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l)) | |
| 221 # define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l)) | |
| 222 #endif | |
| 223 | |
| 224 #ifndef HOST_c2l | |
| 225 #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ | |
| 226 l|=(((unsigned long)(*((c)++)))<<16), \ | |
| 227 l|=(((unsigned long)(*((c)++)))<< 8), \ | |
| 228 l|=(((unsigned long)(*((c)++))) ), \ | |
| 229 l) | |
| 230 #endif | |
| 231 #ifndef HOST_l2c | |
| 232 #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ | |
| 233 *((c)++)=(unsigned char)(((l)>>16)&0xff), \ | |
| 234 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ | |
| 235 *((c)++)=(unsigned char)(((l) )&0xff), \ | |
| 236 l) | |
| 237 #endif | |
| 238 | |
| 239 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) | |
| 240 | |
| 241 #ifndef PEDANTIC | |
| 242 # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OP
ENSSL_NO_INLINE_ASM) | |
| 243 # if defined(__s390x__) | |
| 244 # define HOST_c2l(c,l) ({ asm ("lrv %0,%1" \ | |
| 245 :"=d"(l) :"m"(*(const unsigned int *)(c)));\ | |
| 246 (c)+=4; (l); }) | |
| 247 # define HOST_l2c(l,c) ({ asm ("strv %1,%0" \ | |
| 248 :"=m"(*(unsigned int *)(c)) :"d"(l));\ | |
| 249 (c)+=4; (l); }) | |
| 250 # endif | |
| 251 # endif | |
| 252 #endif | |
| 253 #if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_6
4__) | |
| 254 # ifndef B_ENDIAN | |
| 255 /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */ | |
| 256 # define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l) | |
| 257 # define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l) | |
| 258 # endif | |
| 259 #endif | |
| 260 | |
| 261 #ifndef HOST_c2l | |
| 262 #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ | |
| 263 l|=(((unsigned long)(*((c)++)))<< 8), \ | |
| 264 l|=(((unsigned long)(*((c)++)))<<16), \ | |
| 265 l|=(((unsigned long)(*((c)++)))<<24), \ | |
| 266 l) | |
| 267 #endif | |
| 268 #ifndef HOST_l2c | |
| 269 #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ | |
| 270 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ | |
| 271 *((c)++)=(unsigned char)(((l)>>16)&0xff), \ | |
| 272 *((c)++)=(unsigned char)(((l)>>24)&0xff), \ | |
| 273 l) | |
| 274 #endif | |
| 275 | |
| 276 #endif | |
| 277 | |
| 278 /* | |
| 279 * Time for some action:-) | |
| 280 */ | |
| 281 | |
| 282 int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len) | |
| 283 { | |
| 284 const unsigned char *data=data_; | |
| 285 unsigned char *p; | |
| 286 HASH_LONG l; | |
| 287 size_t n; | |
| 288 | |
| 289 if (len==0) return 1; | |
| 290 | |
| 291 l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL; | |
| 292 /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to | |
| 293 * Wei Dai <weidai@eskimo.com> for pointing it out. */ | |
| 294 if (l < c->Nl) /* overflow */ | |
| 295 c->Nh++; | |
| 296 c->Nh+=(HASH_LONG)(len>>29); /* might cause compiler warning on 16-bi
t */ | |
| 297 c->Nl=l; | |
| 298 | |
| 299 n = c->num; | |
| 300 if (n != 0) | |
| 301 { | |
| 302 p=(unsigned char *)c->data; | |
| 303 | |
| 304 if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK) | |
| 305 { | |
| 306 memcpy (p+n,data,HASH_CBLOCK-n); | |
| 307 HASH_BLOCK_DATA_ORDER (c,p,1); | |
| 308 n = HASH_CBLOCK-n; | |
| 309 data += n; | |
| 310 len -= n; | |
| 311 c->num = 0; | |
| 312 memset (p,0,HASH_CBLOCK); /* keep it zeroed */ | |
| 313 } | |
| 314 else | |
| 315 { | |
| 316 memcpy (p+n,data,len); | |
| 317 c->num += (unsigned int)len; | |
| 318 return 1; | |
| 319 } | |
| 320 } | |
| 321 | |
| 322 n = len/HASH_CBLOCK; | |
| 323 if (n > 0) | |
| 324 { | |
| 325 HASH_BLOCK_DATA_ORDER (c,data,n); | |
| 326 n *= HASH_CBLOCK; | |
| 327 data += n; | |
| 328 len -= n; | |
| 329 } | |
| 330 | |
| 331 if (len != 0) | |
| 332 { | |
| 333 p = (unsigned char *)c->data; | |
| 334 c->num = (unsigned int)len; | |
| 335 memcpy (p,data,len); | |
| 336 } | |
| 337 return 1; | |
| 338 } | |
| 339 | |
| 340 | |
| 341 void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data) | |
| 342 { | |
| 343 HASH_BLOCK_DATA_ORDER (c,data,1); | |
| 344 } | |
| 345 | |
| 346 | |
| 347 int HASH_FINAL (unsigned char *md, HASH_CTX *c) | |
| 348 { | |
| 349 unsigned char *p = (unsigned char *)c->data; | |
| 350 size_t n = c->num; | |
| 351 | |
| 352 p[n] = 0x80; /* there is always room for one */ | |
| 353 n++; | |
| 354 | |
| 355 if (n > (HASH_CBLOCK-8)) | |
| 356 { | |
| 357 memset (p+n,0,HASH_CBLOCK-n); | |
| 358 n=0; | |
| 359 HASH_BLOCK_DATA_ORDER (c,p,1); | |
| 360 } | |
| 361 memset (p+n,0,HASH_CBLOCK-8-n); | |
| 362 | |
| 363 p += HASH_CBLOCK-8; | |
| 364 #if defined(DATA_ORDER_IS_BIG_ENDIAN) | |
| 365 (void)HOST_l2c(c->Nh,p); | |
| 366 (void)HOST_l2c(c->Nl,p); | |
| 367 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) | |
| 368 (void)HOST_l2c(c->Nl,p); | |
| 369 (void)HOST_l2c(c->Nh,p); | |
| 370 #endif | |
| 371 p -= HASH_CBLOCK; | |
| 372 HASH_BLOCK_DATA_ORDER (c,p,1); | |
| 373 c->num=0; | |
| 374 memset (p,0,HASH_CBLOCK); | |
| 375 | |
| 376 #ifndef HASH_MAKE_STRING | |
| 377 #error "HASH_MAKE_STRING must be defined!" | |
| 378 #else | |
| 379 HASH_MAKE_STRING(c,md); | |
| 380 #endif | |
| 381 | |
| 382 return 1; | |
| 383 } | |
| 384 | |
| 385 #ifndef MD32_REG_T | |
| 386 #if defined(__alpha) || defined(__sparcv9) || defined(__mips) | |
| 387 #define MD32_REG_T long | |
| 388 /* | |
| 389 * This comment was originaly written for MD5, which is why it | |
| 390 * discusses A-D. But it basically applies to all 32-bit digests, | |
| 391 * which is why it was moved to common header file. | |
| 392 * | |
| 393 * In case you wonder why A-D are declared as long and not | |
| 394 * as MD5_LONG. Doing so results in slight performance | |
| 395 * boost on LP64 architectures. The catch is we don't | |
| 396 * really care if 32 MSBs of a 64-bit register get polluted | |
| 397 * with eventual overflows as we *save* only 32 LSBs in | |
| 398 * *either* case. Now declaring 'em long excuses the compiler | |
| 399 * from keeping 32 MSBs zeroed resulting in 13% performance | |
| 400 * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. | |
| 401 * Well, to be honest it should say that this *prevents* | |
| 402 * performance degradation. | |
| 403 * <appro@fy.chalmers.se> | |
| 404 */ | |
| 405 #else | |
| 406 /* | |
| 407 * Above is not absolute and there are LP64 compilers that | |
| 408 * generate better code if MD32_REG_T is defined int. The above | |
| 409 * pre-processor condition reflects the circumstances under which | |
| 410 * the conclusion was made and is subject to further extension. | |
| 411 * <appro@fy.chalmers.se> | |
| 412 */ | |
| 413 #define MD32_REG_T int | |
| 414 #endif | |
| 415 #endif | |
| OLD | NEW |