Libav
|
00001 /* 00002 * Copyright (C) 2006 Michael Niedermayer (michaelni@gmx.at) 00003 * Copyright (C) 2003-2005 by Christopher R. Hertel (crh@ubiqx.mn.org) 00004 * 00005 * References: 00006 * IETF RFC 1321: The MD5 Message-Digest Algorithm 00007 * Ron Rivest. IETF, April, 1992 00008 * 00009 * based on http://ubiqx.org/libcifs/source/Auth/MD5.c 00010 * from Christopher R. Hertel (crh@ubiqx.mn.org) 00011 * Simplified, cleaned and IMO redundant comments removed by michael. 00012 * 00013 * If you use gcc, then version 4.1 or later and -fomit-frame-pointer is 00014 * strongly recommended. 00015 * 00016 * This file is part of FFmpeg. 00017 * 00018 * FFmpeg is free software; you can redistribute it and/or 00019 * modify it under the terms of the GNU Lesser General Public 00020 * License as published by the Free Software Foundation; either 00021 * version 2.1 of the License, or (at your option) any later version. 00022 * 00023 * FFmpeg is distributed in the hope that it will be useful, 00024 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00025 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00026 * Lesser General Public License for more details. 00027 * 00028 * You should have received a copy of the GNU Lesser General Public 00029 * License along with FFmpeg; if not, write to the Free Software 00030 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00031 */ 00032 00033 #include <string.h> 00034 #include "bswap.h" 00035 #include "md5.h" 00036 00037 typedef struct AVMD5{ 00038 uint64_t len; 00039 uint8_t block[64]; 00040 uint32_t ABCD[4]; 00041 } AVMD5; 00042 00043 const int av_md5_size= sizeof(AVMD5); 00044 00045 static const uint8_t S[4][4] = { 00046 { 7, 12, 17, 22 }, /* round 1 */ 00047 { 5, 9, 14, 20 }, /* round 2 */ 00048 { 4, 11, 16, 23 }, /* round 3 */ 00049 { 6, 10, 15, 21 } /* round 4 */ 00050 }; 00051 00052 static const uint32_t T[64] = { // T[i]= fabs(sin(i+1)<<32) 00053 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* round 1 */ 00054 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 00055 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 00056 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 00057 00058 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* round 2 */ 00059 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 00060 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 00061 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 00062 00063 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, /* round 3 */ 00064 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 00065 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 00066 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 00067 00068 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, /* round 4 */ 00069 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 00070 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 00071 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, 00072 }; 00073 00074 #define CORE(i, a, b, c, d) \ 00075 t = S[i>>4][i&3];\ 00076 a += T[i];\ 00077 \ 00078 if(i<32){\ 00079 if(i<16) a += (d ^ (b&(c^d))) + X[ i &15 ];\ 00080 else a += (c ^ (d&(c^b))) + X[ (1+5*i)&15 ];\ 00081 }else{\ 00082 if(i<48) a += (b^c^d) + X[ (5+3*i)&15 ];\ 00083 else a += (c^(b|~d)) + X[ ( 7*i)&15 ];\ 00084 }\ 00085 a = b + (( a << t ) | ( a >> (32 - t) )); 00086 00087 static void body(uint32_t ABCD[4], uint32_t X[16]){ 00088 00089 int t; 00090 int i av_unused; 00091 unsigned int a= ABCD[3]; 00092 unsigned int b= ABCD[2]; 00093 unsigned int c= ABCD[1]; 00094 unsigned int d= ABCD[0]; 00095 00096 #if HAVE_BIGENDIAN 00097 for(i=0; i<16; i++) 00098 X[i]= bswap_32(X[i]); 00099 #endif 00100 00101 #if CONFIG_SMALL 00102 for( i = 0; i < 64; i++ ){ 00103 CORE(i,a,b,c,d) 00104 t=d; d=c; c=b; b=a; a=t; 00105 } 00106 #else 00107 #define CORE2(i) CORE(i,a,b,c,d) CORE((i+1),d,a,b,c) CORE((i+2),c,d,a,b) CORE((i+3),b,c,d,a) 00108 #define CORE4(i) CORE2(i) CORE2((i+4)) CORE2((i+8)) CORE2((i+12)) 00109 CORE4(0) CORE4(16) CORE4(32) CORE4(48) 00110 #endif 00111 00112 ABCD[0] += d; 00113 ABCD[1] += c; 00114 ABCD[2] += b; 00115 ABCD[3] += a; 00116 } 00117 00118 void av_md5_init(AVMD5 *ctx){ 00119 ctx->len = 0; 00120 00121 ctx->ABCD[0] = 0x10325476; 00122 ctx->ABCD[1] = 0x98badcfe; 00123 ctx->ABCD[2] = 0xefcdab89; 00124 ctx->ABCD[3] = 0x67452301; 00125 } 00126 00127 void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len){ 00128 int i, j; 00129 00130 j= ctx->len & 63; 00131 ctx->len += len; 00132 00133 for( i = 0; i < len; i++ ){ 00134 ctx->block[j++] = src[i]; 00135 if( 64 == j ){ 00136 body(ctx->ABCD, (uint32_t*) ctx->block); 00137 j = 0; 00138 } 00139 } 00140 } 00141 00142 void av_md5_final(AVMD5 *ctx, uint8_t *dst){ 00143 int i; 00144 uint64_t finalcount= le2me_64(ctx->len<<3); 00145 00146 av_md5_update(ctx, "\200", 1); 00147 while((ctx->len & 63)!=56) 00148 av_md5_update(ctx, "", 1); 00149 00150 av_md5_update(ctx, (uint8_t*)&finalcount, 8); 00151 00152 for(i=0; i<4; i++) 00153 ((uint32_t*)dst)[i]= le2me_32(ctx->ABCD[3-i]); 00154 } 00155 00156 void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len){ 00157 AVMD5 ctx[1]; 00158 00159 av_md5_init(ctx); 00160 av_md5_update(ctx, src, len); 00161 av_md5_final(ctx, dst); 00162 } 00163 00164 #ifdef TEST 00165 #include <stdio.h> 00166 #include <inttypes.h> 00167 #undef printf 00168 int main(void){ 00169 uint64_t md5val; 00170 int i; 00171 uint8_t in[1000]; 00172 00173 for(i=0; i<1000; i++) in[i]= i*i; 00174 av_md5_sum( (uint8_t*)&md5val, in, 1000); printf("%"PRId64"\n", md5val); 00175 av_md5_sum( (uint8_t*)&md5val, in, 63); printf("%"PRId64"\n", md5val); 00176 av_md5_sum( (uint8_t*)&md5val, in, 64); printf("%"PRId64"\n", md5val); 00177 av_md5_sum( (uint8_t*)&md5val, in, 65); printf("%"PRId64"\n", md5val); 00178 for(i=0; i<1000; i++) in[i]= i % 127; 00179 av_md5_sum( (uint8_t*)&md5val, in, 999); printf("%"PRId64"\n", md5val); 00180 00181 return 0; 00182 } 00183 #endif