1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
11 * Copyright (C) 2007 Dominik Wenger
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
23 * RFC 1321 compliant MD5 implementation
25 * Copyright (C) 2001-2003 Christophe Devine
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 2 of the License, or
30 * (at your option) any later version.
32 * This program is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
37 * You should have received a copy of the GNU General Public License
38 * along with this program; if not, write to the Free Software
39 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
46 #define GET_UINT32(n,b,i) \
48 (n) = ( (uint32) (b)[(i) ] ) \
49 | ( (uint32) (b)[(i) + 1] << 8 ) \
50 | ( (uint32) (b)[(i) + 2] << 16 ) \
51 | ( (uint32) (b)[(i) + 3] << 24 ); \
54 #define PUT_UINT32(n,b,i) \
56 (b)[(i) ] = (uint8) ( (n) ); \
57 (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \
58 (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \
59 (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \
62 void md5_starts( md5_context
*ctx
)
67 ctx
->state
[0] = 0x67452301;
68 ctx
->state
[1] = 0xEFCDAB89;
69 ctx
->state
[2] = 0x98BADCFE;
70 ctx
->state
[3] = 0x10325476;
73 void md5_process( md5_context
*ctx
, uint8 data
[64] )
75 uint32 X
[16], A
, B
, C
, D
;
77 GET_UINT32( X
[0], data
, 0 );
78 GET_UINT32( X
[1], data
, 4 );
79 GET_UINT32( X
[2], data
, 8 );
80 GET_UINT32( X
[3], data
, 12 );
81 GET_UINT32( X
[4], data
, 16 );
82 GET_UINT32( X
[5], data
, 20 );
83 GET_UINT32( X
[6], data
, 24 );
84 GET_UINT32( X
[7], data
, 28 );
85 GET_UINT32( X
[8], data
, 32 );
86 GET_UINT32( X
[9], data
, 36 );
87 GET_UINT32( X
[10], data
, 40 );
88 GET_UINT32( X
[11], data
, 44 );
89 GET_UINT32( X
[12], data
, 48 );
90 GET_UINT32( X
[13], data
, 52 );
91 GET_UINT32( X
[14], data
, 56 );
92 GET_UINT32( X
[15], data
, 60 );
94 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
96 #define P(a,b,c,d,k,s,t) \
98 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
106 #define F(x,y,z) (z ^ (x & (y ^ z)))
108 P( A
, B
, C
, D
, 0, 7, 0xD76AA478 );
109 P( D
, A
, B
, C
, 1, 12, 0xE8C7B756 );
110 P( C
, D
, A
, B
, 2, 17, 0x242070DB );
111 P( B
, C
, D
, A
, 3, 22, 0xC1BDCEEE );
112 P( A
, B
, C
, D
, 4, 7, 0xF57C0FAF );
113 P( D
, A
, B
, C
, 5, 12, 0x4787C62A );
114 P( C
, D
, A
, B
, 6, 17, 0xA8304613 );
115 P( B
, C
, D
, A
, 7, 22, 0xFD469501 );
116 P( A
, B
, C
, D
, 8, 7, 0x698098D8 );
117 P( D
, A
, B
, C
, 9, 12, 0x8B44F7AF );
118 P( C
, D
, A
, B
, 10, 17, 0xFFFF5BB1 );
119 P( B
, C
, D
, A
, 11, 22, 0x895CD7BE );
120 P( A
, B
, C
, D
, 12, 7, 0x6B901122 );
121 P( D
, A
, B
, C
, 13, 12, 0xFD987193 );
122 P( C
, D
, A
, B
, 14, 17, 0xA679438E );
123 P( B
, C
, D
, A
, 15, 22, 0x49B40821 );
127 #define F(x,y,z) (y ^ (z & (x ^ y)))
129 P( A
, B
, C
, D
, 1, 5, 0xF61E2562 );
130 P( D
, A
, B
, C
, 6, 9, 0xC040B340 );
131 P( C
, D
, A
, B
, 11, 14, 0x265E5A51 );
132 P( B
, C
, D
, A
, 0, 20, 0xE9B6C7AA );
133 P( A
, B
, C
, D
, 5, 5, 0xD62F105D );
134 P( D
, A
, B
, C
, 10, 9, 0x02441453 );
135 P( C
, D
, A
, B
, 15, 14, 0xD8A1E681 );
136 P( B
, C
, D
, A
, 4, 20, 0xE7D3FBC8 );
137 P( A
, B
, C
, D
, 9, 5, 0x21E1CDE6 );
138 P( D
, A
, B
, C
, 14, 9, 0xC33707D6 );
139 P( C
, D
, A
, B
, 3, 14, 0xF4D50D87 );
140 P( B
, C
, D
, A
, 8, 20, 0x455A14ED );
141 P( A
, B
, C
, D
, 13, 5, 0xA9E3E905 );
142 P( D
, A
, B
, C
, 2, 9, 0xFCEFA3F8 );
143 P( C
, D
, A
, B
, 7, 14, 0x676F02D9 );
144 P( B
, C
, D
, A
, 12, 20, 0x8D2A4C8A );
148 #define F(x,y,z) (x ^ y ^ z)
150 P( A
, B
, C
, D
, 5, 4, 0xFFFA3942 );
151 P( D
, A
, B
, C
, 8, 11, 0x8771F681 );
152 P( C
, D
, A
, B
, 11, 16, 0x6D9D6122 );
153 P( B
, C
, D
, A
, 14, 23, 0xFDE5380C );
154 P( A
, B
, C
, D
, 1, 4, 0xA4BEEA44 );
155 P( D
, A
, B
, C
, 4, 11, 0x4BDECFA9 );
156 P( C
, D
, A
, B
, 7, 16, 0xF6BB4B60 );
157 P( B
, C
, D
, A
, 10, 23, 0xBEBFBC70 );
158 P( A
, B
, C
, D
, 13, 4, 0x289B7EC6 );
159 P( D
, A
, B
, C
, 0, 11, 0xEAA127FA );
160 P( C
, D
, A
, B
, 3, 16, 0xD4EF3085 );
161 P( B
, C
, D
, A
, 6, 23, 0x04881D05 );
162 P( A
, B
, C
, D
, 9, 4, 0xD9D4D039 );
163 P( D
, A
, B
, C
, 12, 11, 0xE6DB99E5 );
164 P( C
, D
, A
, B
, 15, 16, 0x1FA27CF8 );
165 P( B
, C
, D
, A
, 2, 23, 0xC4AC5665 );
169 #define F(x,y,z) (y ^ (x | ~z))
171 P( A
, B
, C
, D
, 0, 6, 0xF4292244 );
172 P( D
, A
, B
, C
, 7, 10, 0x432AFF97 );
173 P( C
, D
, A
, B
, 14, 15, 0xAB9423A7 );
174 P( B
, C
, D
, A
, 5, 21, 0xFC93A039 );
175 P( A
, B
, C
, D
, 12, 6, 0x655B59C3 );
176 P( D
, A
, B
, C
, 3, 10, 0x8F0CCC92 );
177 P( C
, D
, A
, B
, 10, 15, 0xFFEFF47D );
178 P( B
, C
, D
, A
, 1, 21, 0x85845DD1 );
179 P( A
, B
, C
, D
, 8, 6, 0x6FA87E4F );
180 P( D
, A
, B
, C
, 15, 10, 0xFE2CE6E0 );
181 P( C
, D
, A
, B
, 6, 15, 0xA3014314 );
182 P( B
, C
, D
, A
, 13, 21, 0x4E0811A1 );
183 P( A
, B
, C
, D
, 4, 6, 0xF7537E82 );
184 P( D
, A
, B
, C
, 11, 10, 0xBD3AF235 );
185 P( C
, D
, A
, B
, 2, 15, 0x2AD7D2BB );
186 P( B
, C
, D
, A
, 9, 21, 0xEB86D391 );
199 void md5_update( md5_context
*ctx
, uint8
*input
, uint32 length
)
203 if( ! length
) return;
205 left
= ctx
->total
[0] & 0x3F;
208 ctx
->total
[0] += length
;
209 ctx
->total
[0] &= 0xFFFFFFFF;
211 if( ctx
->total
[0] < length
)
214 if( left
&& length
>= fill
)
216 memcpy( (void *) (ctx
->buffer
+ left
),
217 (void *) input
, fill
);
218 md5_process( ctx
, ctx
->buffer
);
224 while( length
>= 64 )
226 md5_process( ctx
, input
);
233 memcpy( (void *) (ctx
->buffer
+ left
),
234 (void *) input
, length
);
238 static uint8 md5_padding
[64] =
240 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
246 void md5_finish( md5_context
*ctx
, uint8 digest
[16] )
252 high
= ( ctx
->total
[0] >> 29 )
253 | ( ctx
->total
[1] << 3 );
254 low
= ( ctx
->total
[0] << 3 );
256 PUT_UINT32( low
, msglen
, 0 );
257 PUT_UINT32( high
, msglen
, 4 );
259 last
= ctx
->total
[0] & 0x3F;
260 padn
= ( last
< 56 ) ? ( 56 - last
) : ( 120 - last
);
262 md5_update( ctx
, md5_padding
, padn
);
263 md5_update( ctx
, msglen
, 8 );
265 PUT_UINT32( ctx
->state
[0], digest
, 0 );
266 PUT_UINT32( ctx
->state
[1], digest
, 4 );
267 PUT_UINT32( ctx
->state
[2], digest
, 8 );
268 PUT_UINT32( ctx
->state
[3], digest
, 12 );
271 int FileMD5(wxString name
, char *md5
)
275 unsigned char md5sum
[16];
276 unsigned char block
[32768];
282 if (!file
.IsOpened()) {
283 ERR_DIALOG(wxT("Could not open patched firmware for checksum check"), wxT("Open Firmware"));
287 while ( !file
.Eof() ) {
288 read
= file
.Read(block
, sizeof(block
));
289 md5_update(&ctx
, block
, read
);
292 md5_finish(&ctx
, md5sum
);
293 for (i
= 0; i
< 16; ++i
)
295 sprintf(md5
+ 2*i
, "%02x", md5sum
[i
]);