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 <stdint.h>
00034 #include "bswap.h"
00035 #include "intreadwrite.h"
00036 #include "md5.h"
00037 #include "mem.h"
00038
00039 typedef struct AVMD5{
00040 uint64_t len;
00041 uint8_t block[64];
00042 uint32_t ABCD[4];
00043 } AVMD5;
00044
00045 const int av_md5_size = sizeof(AVMD5);
00046
00047 struct AVMD5 *av_md5_alloc(void)
00048 {
00049 return av_mallocz(sizeof(struct AVMD5));
00050 }
00051
00052 static const uint8_t S[4][4] = {
00053 { 7, 12, 17, 22 },
00054 { 5, 9, 14, 20 },
00055 { 4, 11, 16, 23 },
00056 { 6, 10, 15, 21 }
00057 };
00058
00059 static const uint32_t T[64] = {
00060 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
00061 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
00062 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
00063 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
00064
00065 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
00066 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
00067 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
00068 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
00069
00070 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
00071 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
00072 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
00073 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
00074
00075 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
00076 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
00077 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
00078 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
00079 };
00080
00081 #define CORE(i, a, b, c, d) do { \
00082 t = S[i >> 4][i & 3]; \
00083 a += T[i]; \
00084 \
00085 if (i < 32) { \
00086 if (i < 16) a += (d ^ (b & (c ^ d))) + X[ i & 15]; \
00087 else a += (c ^ (d & (c ^ b))) + X[(1 + 5*i) & 15]; \
00088 } else { \
00089 if (i < 48) a += (b ^ c ^ d) + X[(5 + 3*i) & 15]; \
00090 else a += (c ^ (b | ~d)) + X[( 7*i) & 15]; \
00091 } \
00092 a = b + (a << t | a >> (32 - t)); \
00093 } while (0)
00094
00095 static void body(uint32_t ABCD[4], uint32_t X[16])
00096 {
00097 int i av_unused;
00098 uint32_t t;
00099 uint32_t a = ABCD[3];
00100 uint32_t b = ABCD[2];
00101 uint32_t c = ABCD[1];
00102 uint32_t d = ABCD[0];
00103
00104 #if HAVE_BIGENDIAN
00105 for (i = 0; i < 16; i++)
00106 X[i] = av_bswap32(X[i]);
00107 #endif
00108
00109 #if CONFIG_SMALL
00110 for (i = 0; i < 64; i++) {
00111 CORE(i, a, b, c, d);
00112 t = d;
00113 d = c;
00114 c = b;
00115 b = a;
00116 a = t;
00117 }
00118 #else
00119 #define CORE2(i) \
00120 CORE( i, a,b,c,d); CORE((i+1),d,a,b,c); \
00121 CORE((i+2),c,d,a,b); CORE((i+3),b,c,d,a)
00122 #define CORE4(i) CORE2(i); CORE2((i+4)); CORE2((i+8)); CORE2((i+12))
00123 CORE4(0); CORE4(16); CORE4(32); CORE4(48);
00124 #endif
00125
00126 ABCD[0] += d;
00127 ABCD[1] += c;
00128 ABCD[2] += b;
00129 ABCD[3] += a;
00130 }
00131
00132 void av_md5_init(AVMD5 *ctx)
00133 {
00134 ctx->len = 0;
00135
00136 ctx->ABCD[0] = 0x10325476;
00137 ctx->ABCD[1] = 0x98badcfe;
00138 ctx->ABCD[2] = 0xefcdab89;
00139 ctx->ABCD[3] = 0x67452301;
00140 }
00141
00142 void av_md5_update(AVMD5 *ctx, const uint8_t *src, const int len)
00143 {
00144 int i, j;
00145
00146 j = ctx->len & 63;
00147 ctx->len += len;
00148
00149 for (i = 0; i < len; i++) {
00150 ctx->block[j++] = src[i];
00151 if (j == 64) {
00152 body(ctx->ABCD, (uint32_t *) ctx->block);
00153 j = 0;
00154 }
00155 }
00156 }
00157
00158 void av_md5_final(AVMD5 *ctx, uint8_t *dst)
00159 {
00160 int i;
00161 uint64_t finalcount = av_le2ne64(ctx->len << 3);
00162
00163 av_md5_update(ctx, "\200", 1);
00164 while ((ctx->len & 63) != 56)
00165 av_md5_update(ctx, "", 1);
00166
00167 av_md5_update(ctx, (uint8_t *)&finalcount, 8);
00168
00169 for (i = 0; i < 4; i++)
00170 AV_WL32(dst + 4*i, ctx->ABCD[3 - i]);
00171 }
00172
00173 void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len)
00174 {
00175 AVMD5 ctx;
00176
00177 av_md5_init(&ctx);
00178 av_md5_update(&ctx, src, len);
00179 av_md5_final(&ctx, dst);
00180 }
00181
00182 #ifdef TEST
00183 #include <stdio.h>
00184
00185 static void print_md5(uint8_t *md5)
00186 {
00187 int i;
00188 for (i = 0; i < 16; i++)
00189 printf("%02x", md5[i]);
00190 printf("\n");
00191 }
00192
00193 int main(void){
00194 uint8_t md5val[16];
00195 int i;
00196 uint8_t in[1000];
00197
00198 for (i = 0; i < 1000; i++)
00199 in[i] = i * i;
00200 av_md5_sum(md5val, in, 1000); print_md5(md5val);
00201 av_md5_sum(md5val, in, 63); print_md5(md5val);
00202 av_md5_sum(md5val, in, 64); print_md5(md5val);
00203 av_md5_sum(md5val, in, 65); print_md5(md5val);
00204 for (i = 0; i < 1000; i++)
00205 in[i] = i % 127;
00206 av_md5_sum(md5val, in, 999); print_md5(md5val);
00207
00208 return 0;
00209 }
00210 #endif