FFmpeg
md5.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006 Michael Niedermayer (michaelni@gmx.at)
3  * Copyright (C) 2003-2005 by Christopher R. Hertel (crh@ubiqx.mn.org)
4  *
5  * References:
6  * IETF RFC 1321: The MD5 Message-Digest Algorithm
7  * Ron Rivest. IETF, April, 1992
8  *
9  * based on http://ubiqx.org/libcifs/source/Auth/MD5.c
10  * from Christopher R. Hertel (crh@ubiqx.mn.org)
11  * Simplified, cleaned and IMO redundant comments removed by Michael.
12  *
13  * If you use gcc, then version 4.1 or later and -fomit-frame-pointer is
14  * strongly recommended.
15  *
16  * This file is part of FFmpeg.
17  *
18  * FFmpeg is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU Lesser General Public
20  * License as published by the Free Software Foundation; either
21  * version 2.1 of the License, or (at your option) any later version.
22  *
23  * FFmpeg is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26  * Lesser General Public License for more details.
27  *
28  * You should have received a copy of the GNU Lesser General Public
29  * License along with FFmpeg; if not, write to the Free Software
30  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
31  */
32 
33 #include <stdint.h>
34 
35 #include "bswap.h"
36 #include "intreadwrite.h"
37 #include "mem.h"
38 #include "md5.h"
39 
40 typedef struct AVMD5 {
41  uint64_t len;
43  uint32_t ABCD[4];
44 } AVMD5;
45 
46 const int av_md5_size = sizeof(AVMD5);
47 
48 struct AVMD5 *av_md5_alloc(void)
49 {
50  return av_mallocz(sizeof(struct AVMD5));
51 }
52 
53 static const uint8_t S[4][4] = {
54  { 7, 12, 17, 22 }, /* round 1 */
55  { 5, 9, 14, 20 }, /* round 2 */
56  { 4, 11, 16, 23 }, /* round 3 */
57  { 6, 10, 15, 21 } /* round 4 */
58 };
59 
60 static const uint32_t T[64] = { // T[i]= fabs(sin(i+1)<<32)
61  0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* round 1 */
62  0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
63  0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
64  0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
65 
66  0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* round 2 */
67  0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
68  0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
69  0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
70 
71  0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, /* round 3 */
72  0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
73  0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
74  0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
75 
76  0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, /* round 4 */
77  0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
78  0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
79  0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
80 };
81 
82 #define CORE(i, a, b, c, d) \
83  do { \
84  t = S[i >> 4][i & 3]; \
85  a += T[i]; \
86  \
87  if (i < 32) { \
88  if (i < 16) \
89  a += (d ^ (b & (c ^ d))) + AV_RL32(X+( i & 15));\
90  else \
91  a += ((d & b) | (~d & c)) + AV_RL32(X+((1 + 5*i) & 15));\
92  } else { \
93  if (i < 48) \
94  a += (b ^ c ^ d) + AV_RL32(X+((5 + 3*i) & 15));\
95  else \
96  a += (c ^ (b | ~d)) + AV_RL32(X+(( 7*i) & 15));\
97  } \
98  a = b + (a << t | a >> (32 - t)); \
99  } while (0)
100 
101 static void body(uint32_t ABCD[4], const uint8_t *src, int nblocks)
102 {
103  int i av_unused;
104  int n;
105  const uint32_t *X;
106  uint32_t a, b, c, d, t;
107 
108  for (n = 0; n < nblocks; n++) {
109  a = ABCD[3];
110  b = ABCD[2];
111  c = ABCD[1];
112  d = ABCD[0];
113 
114  X = (const uint32_t *)src + n * 16;
115 
116 #if CONFIG_SMALL
117  for (i = 0; i < 64; i++) {
118  CORE(i, a, b, c, d);
119  t = d;
120  d = c;
121  c = b;
122  b = a;
123  a = t;
124  }
125 #else
126 #define CORE2(i) \
127  CORE(i, a, b, c, d); CORE((i + 1), d, a, b, c); \
128  CORE((i + 2), c, d, a, b); CORE((i + 3), b, c, d, a)
129 #define CORE4(i) CORE2(i); CORE2((i + 4)); CORE2((i + 8)); CORE2((i + 12))
130  CORE4(0);
131  CORE4(16);
132  CORE4(32);
133  CORE4(48);
134 #endif
135 
136  ABCD[0] += d;
137  ABCD[1] += c;
138  ABCD[2] += b;
139  ABCD[3] += a;
140  }
141 }
142 
144 {
145  ctx->len = 0;
146 
147  ctx->ABCD[0] = 0x10325476;
148  ctx->ABCD[1] = 0x98badcfe;
149  ctx->ABCD[2] = 0xefcdab89;
150  ctx->ABCD[3] = 0x67452301;
151 }
152 
153 #if FF_API_CRYPTO_SIZE_T
154 void av_md5_update(AVMD5 *ctx, const uint8_t *src, int len)
155 #else
156 void av_md5_update(AVMD5 *ctx, const uint8_t *src, size_t len)
157 #endif
158 {
159  const uint8_t *end;
160  int j;
161 
162  j = ctx->len & 63;
163  ctx->len += len;
164 
165  if (j) {
166  int cnt = FFMIN(len, 64 - j);
167  memcpy(ctx->block + j, src, cnt);
168  src += cnt;
169  len -= cnt;
170  if (j + cnt < 64)
171  return;
172  body(ctx->ABCD, ctx->block, 1);
173  }
174 
175  end = src + (len & ~63);
176  if (!HAVE_FAST_UNALIGNED && ((intptr_t)src & 3)) {
177  while (src < end) {
178  memcpy(ctx->block, src, 64);
179  body(ctx->ABCD, ctx->block, 1);
180  src += 64;
181  }
182  } else {
183  int nblocks = len / 64;
184  body(ctx->ABCD, src, nblocks);
185  src = end;
186  }
187  len &= 63;
188  if (len > 0)
189  memcpy(ctx->block, src, len);
190 }
191 
193 {
194  int i;
195  uint64_t finalcount = av_le2ne64(ctx->len << 3);
196 
197  av_md5_update(ctx, "\200", 1);
198  while ((ctx->len & 63) != 56)
199  av_md5_update(ctx, "", 1);
200 
201  av_md5_update(ctx, (uint8_t *) &finalcount, 8);
202 
203  for (i = 0; i < 4; i++)
204  AV_WL32(dst + 4 * i, ctx->ABCD[3 - i]);
205 }
206 
207 #if FF_API_CRYPTO_SIZE_T
208 void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len)
209 #else
210 void av_md5_sum(uint8_t *dst, const uint8_t *src, size_t len)
211 #endif
212 {
213  AVMD5 ctx;
214 
215  av_md5_init(&ctx);
216  av_md5_update(&ctx, src, len);
217  av_md5_final(&ctx, dst);
218 }
AVMD5::ABCD
uint32_t ABCD[4]
Definition: md5.c:43
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
n
int n
Definition: avisynth_c.h:760
av_unused
#define av_unused
Definition: attributes.h:125
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
b
#define b
Definition: input.c:41
T
static const uint32_t T[64]
Definition: md5.c:60
body
static void body(uint32_t ABCD[4], const uint8_t *src, int nblocks)
Definition: md5.c:101
av_md5_sum
void av_md5_sum(uint8_t *dst, const uint8_t *src, const int len)
Hash an array of data.
Definition: md5.c:208
av_md5_size
const int av_md5_size
Definition: md5.c:46
AVMD5
Definition: md5.c:40
src
#define src
Definition: vp8dsp.c:254
intreadwrite.h
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AVMD5::block
uint8_t block[64]
Definition: md5.c:42
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
av_le2ne64
#define av_le2ne64(x)
Definition: bswap.h:97
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
CORE
#define CORE(i, a, b, c, d)
Definition: md5.c:82
av_md5_init
void av_md5_init(AVMD5 *ctx)
Initialize MD5 hashing.
Definition: md5.c:143
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
md5.h
uint8_t
uint8_t
Definition: audio_convert.c:194
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
len
int len
Definition: vorbis_enc_data.h:452
av_md5_final
void av_md5_final(AVMD5 *ctx, uint8_t *dst)
Finish hashing and output digest value.
Definition: md5.c:192
CORE4
#define CORE4(i)
bswap.h
av_md5_update
void av_md5_update(AVMD5 *ctx, const uint8_t *src, int len)
Update hash value.
Definition: md5.c:154
av_md5_alloc
struct AVMD5 * av_md5_alloc(void)
Allocate an AVMD5 context.
Definition: md5.c:48
AVMD5::len
uint64_t len
Definition: md5.c:41
mem.h
S
static const uint8_t S[4][4]
Definition: md5.c:53