diff options
author | Dave Chapman <dave@dchapman.com> | 2005-02-16 19:33:19 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2005-02-16 19:33:19 +0000 |
commit | aa97e4d4981d61808a558c5ab36be6d3bcc2c4f6 (patch) | |
tree | a66b2fcd87f37b26e2d4f360e6c2a9db53eb1b5b /apps/codecs/libFLAC/md5.c | |
parent | 9b32a1988f848145d96ba2be8cba86e837196df3 (diff) | |
download | rockbox-aa97e4d4981d61808a558c5ab36be6d3bcc2c4f6.tar.gz rockbox-aa97e4d4981d61808a558c5ab36be6d3bcc2c4f6.zip |
Initial import of libFLAC from flac-1.1.2.tar.gz
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5983 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libFLAC/md5.c')
-rw-r--r-- | apps/codecs/libFLAC/md5.c | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/apps/codecs/libFLAC/md5.c b/apps/codecs/libFLAC/md5.c new file mode 100644 index 0000000000..9679387db9 --- /dev/null +++ b/apps/codecs/libFLAC/md5.c | |||
@@ -0,0 +1,315 @@ | |||
1 | /* | ||
2 | * This code implements the MD5 message-digest algorithm. | ||
3 | * The algorithm is due to Ron Rivest. This code was | ||
4 | * written by Colin Plumb in 1993, no copyright is claimed. | ||
5 | * This code is in the public domain; do with it what you wish. | ||
6 | * | ||
7 | * Equivalent code is available from RSA Data Security, Inc. | ||
8 | * This code has been tested against that, and is equivalent, | ||
9 | * except that you don't need to include two pages of legalese | ||
10 | * with every copy. | ||
11 | * | ||
12 | * To compute the message digest of a chunk of bytes, declare an | ||
13 | * MD5Context structure, pass it to MD5Init, call MD5Update as | ||
14 | * needed on buffers full of bytes, and then call MD5Final, which | ||
15 | * will fill a supplied 16-byte array with the digest. | ||
16 | * | ||
17 | * Changed so as no longer to depend on Colin Plumb's `usual.h' header | ||
18 | * definitions; now uses stuff from dpkg's config.h. | ||
19 | * - Ian Jackson <ijackson@nyx.cs.du.edu>. | ||
20 | * Still in the public domain. | ||
21 | * | ||
22 | * Josh Coalson: made some changes to integrate with libFLAC. | ||
23 | * Still in the public domain. | ||
24 | */ | ||
25 | |||
26 | #include <stdlib.h> /* for malloc() */ | ||
27 | #include <string.h> /* for memcpy() */ | ||
28 | |||
29 | #include "private/md5.h" | ||
30 | |||
31 | #ifdef HAVE_CONFIG_H | ||
32 | #include <config.h> | ||
33 | #endif | ||
34 | |||
35 | #ifndef FLaC__INLINE | ||
36 | #define FLaC__INLINE | ||
37 | #endif | ||
38 | |||
39 | static FLAC__bool is_big_endian_host_; | ||
40 | |||
41 | #ifndef ASM_MD5 | ||
42 | |||
43 | /* The four core functions - F1 is optimized somewhat */ | ||
44 | |||
45 | /* #define F1(x, y, z) (x & y | ~x & z) */ | ||
46 | #define F1(x, y, z) (z ^ (x & (y ^ z))) | ||
47 | #define F2(x, y, z) F1(z, x, y) | ||
48 | #define F3(x, y, z) (x ^ y ^ z) | ||
49 | #define F4(x, y, z) (y ^ (x | ~z)) | ||
50 | |||
51 | /* This is the central step in the MD5 algorithm. */ | ||
52 | #define MD5STEP(f,w,x,y,z,in,s) \ | ||
53 | (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x) | ||
54 | |||
55 | /* | ||
56 | * The core of the MD5 algorithm, this alters an existing MD5 hash to | ||
57 | * reflect the addition of 16 longwords of new data. MD5Update blocks | ||
58 | * the data and converts bytes into longwords for this routine. | ||
59 | */ | ||
60 | FLaC__INLINE | ||
61 | void | ||
62 | FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16]) | ||
63 | { | ||
64 | register FLAC__uint32 a, b, c, d; | ||
65 | |||
66 | a = buf[0]; | ||
67 | b = buf[1]; | ||
68 | c = buf[2]; | ||
69 | d = buf[3]; | ||
70 | |||
71 | MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); | ||
72 | MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); | ||
73 | MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); | ||
74 | MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); | ||
75 | MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); | ||
76 | MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); | ||
77 | MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); | ||
78 | MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); | ||
79 | MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); | ||
80 | MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); | ||
81 | MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); | ||
82 | MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); | ||
83 | MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); | ||
84 | MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); | ||
85 | MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); | ||
86 | MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); | ||
87 | |||
88 | MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); | ||
89 | MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); | ||
90 | MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); | ||
91 | MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); | ||
92 | MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); | ||
93 | MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); | ||
94 | MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); | ||
95 | MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); | ||
96 | MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); | ||
97 | MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); | ||
98 | MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); | ||
99 | MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); | ||
100 | MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); | ||
101 | MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); | ||
102 | MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); | ||
103 | MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); | ||
104 | |||
105 | MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); | ||
106 | MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); | ||
107 | MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); | ||
108 | MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); | ||
109 | MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); | ||
110 | MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); | ||
111 | MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); | ||
112 | MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); | ||
113 | MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); | ||
114 | MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); | ||
115 | MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); | ||
116 | MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); | ||
117 | MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); | ||
118 | MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); | ||
119 | MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); | ||
120 | MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); | ||
121 | |||
122 | MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); | ||
123 | MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); | ||
124 | MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); | ||
125 | MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); | ||
126 | MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); | ||
127 | MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); | ||
128 | MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); | ||
129 | MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); | ||
130 | MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); | ||
131 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); | ||
132 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); | ||
133 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); | ||
134 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); | ||
135 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); | ||
136 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); | ||
137 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); | ||
138 | |||
139 | buf[0] += a; | ||
140 | buf[1] += b; | ||
141 | buf[2] += c; | ||
142 | buf[3] += d; | ||
143 | } | ||
144 | |||
145 | #endif | ||
146 | |||
147 | FLaC__INLINE | ||
148 | void | ||
149 | byteSwap(FLAC__uint32 *buf, unsigned words) | ||
150 | { | ||
151 | md5byte *p = (md5byte *)buf; | ||
152 | |||
153 | if(!is_big_endian_host_) | ||
154 | return; | ||
155 | do { | ||
156 | *buf++ = (FLAC__uint32)((unsigned)p[3] << 8 | p[2]) << 16 | ((unsigned)p[1] << 8 | p[0]); | ||
157 | p += 4; | ||
158 | } while (--words); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious | ||
163 | * initialization constants. | ||
164 | */ | ||
165 | void | ||
166 | FLAC__MD5Init(struct FLAC__MD5Context *ctx) | ||
167 | { | ||
168 | FLAC__uint32 test = 1; | ||
169 | |||
170 | is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true; | ||
171 | |||
172 | ctx->buf[0] = 0x67452301; | ||
173 | ctx->buf[1] = 0xefcdab89; | ||
174 | ctx->buf[2] = 0x98badcfe; | ||
175 | ctx->buf[3] = 0x10325476; | ||
176 | |||
177 | ctx->bytes[0] = 0; | ||
178 | ctx->bytes[1] = 0; | ||
179 | |||
180 | ctx->internal_buf = 0; | ||
181 | ctx->capacity = 0; | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * Update context to reflect the concatenation of another buffer full | ||
186 | * of bytes. | ||
187 | */ | ||
188 | void | ||
189 | FLAC__MD5Update(struct FLAC__MD5Context *ctx, md5byte const *buf, unsigned len) | ||
190 | { | ||
191 | FLAC__uint32 t; | ||
192 | |||
193 | /* Update byte count */ | ||
194 | |||
195 | t = ctx->bytes[0]; | ||
196 | if ((ctx->bytes[0] = t + len) < t) | ||
197 | ctx->bytes[1]++; /* Carry from low to high */ | ||
198 | |||
199 | t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ | ||
200 | if (t > len) { | ||
201 | memcpy((md5byte *)ctx->in + 64 - t, buf, len); | ||
202 | return; | ||
203 | } | ||
204 | /* First chunk is an odd size */ | ||
205 | memcpy((md5byte *)ctx->in + 64 - t, buf, t); | ||
206 | byteSwap(ctx->in, 16); | ||
207 | FLAC__MD5Transform(ctx->buf, ctx->in); | ||
208 | buf += t; | ||
209 | len -= t; | ||
210 | |||
211 | /* Process data in 64-byte chunks */ | ||
212 | while (len >= 64) { | ||
213 | memcpy(ctx->in, buf, 64); | ||
214 | byteSwap(ctx->in, 16); | ||
215 | FLAC__MD5Transform(ctx->buf, ctx->in); | ||
216 | buf += 64; | ||
217 | len -= 64; | ||
218 | } | ||
219 | |||
220 | /* Handle any remaining bytes of data. */ | ||
221 | memcpy(ctx->in, buf, len); | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Convert the incoming audio signal to a byte stream and FLAC__MD5Update it. | ||
226 | */ | ||
227 | FLAC__bool | ||
228 | FLAC__MD5Accumulate(struct FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample) | ||
229 | { | ||
230 | unsigned channel, sample, a_byte; | ||
231 | FLAC__int32 a_word; | ||
232 | FLAC__byte *buf_; | ||
233 | const unsigned bytes_needed = channels * samples * bytes_per_sample; | ||
234 | |||
235 | if(ctx->capacity < bytes_needed) { | ||
236 | FLAC__byte *tmp = (FLAC__byte*)realloc(ctx->internal_buf, bytes_needed); | ||
237 | if(0 == tmp) { | ||
238 | free(ctx->internal_buf); | ||
239 | if(0 == (ctx->internal_buf = (FLAC__byte*)malloc(bytes_needed))) | ||
240 | return false; | ||
241 | } | ||
242 | ctx->internal_buf = tmp; | ||
243 | ctx->capacity = bytes_needed; | ||
244 | } | ||
245 | |||
246 | buf_ = ctx->internal_buf; | ||
247 | |||
248 | #ifdef FLAC__CPU_IA32 | ||
249 | if(channels == 2 && bytes_per_sample == 2) { | ||
250 | memcpy(buf_, signal[0], sizeof(FLAC__int32) * samples); | ||
251 | buf_ += sizeof(FLAC__int16); | ||
252 | for(sample = 0; sample < samples; sample++) | ||
253 | ((FLAC__int16 *)buf_)[2 * sample] = (FLAC__int16)signal[1][sample]; | ||
254 | } | ||
255 | else if(channels == 1 && bytes_per_sample == 2) { | ||
256 | for(sample = 0; sample < samples; sample++) | ||
257 | ((FLAC__int16 *)buf_)[sample] = (FLAC__int16)signal[0][sample]; | ||
258 | } | ||
259 | else | ||
260 | #endif | ||
261 | for(sample = 0; sample < samples; sample++) { | ||
262 | for(channel = 0; channel < channels; channel++) { | ||
263 | a_word = signal[channel][sample]; | ||
264 | for(a_byte = 0; a_byte < bytes_per_sample; a_byte++) { | ||
265 | *buf_++ = (FLAC__byte)(a_word & 0xff); | ||
266 | a_word >>= 8; | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | |||
271 | FLAC__MD5Update(ctx, ctx->internal_buf, bytes_needed); | ||
272 | |||
273 | return true; | ||
274 | } | ||
275 | |||
276 | /* | ||
277 | * Final wrapup - pad to 64-byte boundary with the bit pattern | ||
278 | * 1 0* (64-bit count of bits processed, MSB-first) | ||
279 | */ | ||
280 | void | ||
281 | FLAC__MD5Final(md5byte digest[16], struct FLAC__MD5Context *ctx) | ||
282 | { | ||
283 | int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ | ||
284 | md5byte *p = (md5byte *)ctx->in + count; | ||
285 | |||
286 | /* Set the first char of padding to 0x80. There is always room. */ | ||
287 | *p++ = 0x80; | ||
288 | |||
289 | /* Bytes of padding needed to make 56 bytes (-8..55) */ | ||
290 | count = 56 - 1 - count; | ||
291 | |||
292 | if (count < 0) { /* Padding forces an extra block */ | ||
293 | memset(p, 0, count + 8); | ||
294 | byteSwap(ctx->in, 16); | ||
295 | FLAC__MD5Transform(ctx->buf, ctx->in); | ||
296 | p = (md5byte *)ctx->in; | ||
297 | count = 56; | ||
298 | } | ||
299 | memset(p, 0, count); | ||
300 | byteSwap(ctx->in, 14); | ||
301 | |||
302 | /* Append length in bits and transform */ | ||
303 | ctx->in[14] = ctx->bytes[0] << 3; | ||
304 | ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; | ||
305 | FLAC__MD5Transform(ctx->buf, ctx->in); | ||
306 | |||
307 | byteSwap(ctx->buf, 4); | ||
308 | memcpy(digest, ctx->buf, 16); | ||
309 | memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ | ||
310 | if(0 != ctx->internal_buf) { | ||
311 | free(ctx->internal_buf); | ||
312 | ctx->internal_buf = 0; | ||
313 | ctx->capacity = 0; | ||
314 | } | ||
315 | } | ||