00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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 },
00047 { 5, 9, 14, 20 },
00048 { 4, 11, 16, 23 },
00049 { 6, 10, 15, 21 }
00050 };
00051
00052 static const uint32_t T[64] = {
00053 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
00054 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
00055 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
00056 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
00057
00058 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
00059 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
00060 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
00061 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
00062
00063 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
00064 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
00065 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
00066 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
00067
00068 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
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