French translation update by Mustapha Senhaji.
[Rockbox.git] / rbutil / md5sum.cpp
blob9c253beed2a38b735b0e519c1a924f80b30bd5b2
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Module: rbutil
9 * File: md5sum.cpp
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
43 #include "md5sum.h"
46 #define GET_UINT32(n,b,i) \
47 { \
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) \
55 { \
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 )
64 ctx->total[0] = 0;
65 ctx->total[1] = 0;
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) \
97 { \
98 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
101 A = ctx->state[0];
102 B = ctx->state[1];
103 C = ctx->state[2];
104 D = ctx->state[3];
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 );
125 #undef F
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 );
146 #undef F
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 );
167 #undef F
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 );
188 #undef F
189 #undef S
190 #undef P
193 ctx->state[0] += A;
194 ctx->state[1] += B;
195 ctx->state[2] += C;
196 ctx->state[3] += D;
199 void md5_update( md5_context *ctx, uint8 *input, uint32 length )
201 uint32 left, fill;
203 if( ! length ) return;
205 left = ctx->total[0] & 0x3F;
206 fill = 64 - left;
208 ctx->total[0] += length;
209 ctx->total[0] &= 0xFFFFFFFF;
211 if( ctx->total[0] < length )
212 ctx->total[1]++;
214 if( left && length >= fill )
216 memcpy( (void *) (ctx->buffer + left),
217 (void *) input, fill );
218 md5_process( ctx, ctx->buffer );
219 length -= fill;
220 input += fill;
221 left = 0;
224 while( length >= 64 )
226 md5_process( ctx, input );
227 length -= 64;
228 input += 64;
231 if( length )
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] )
248 uint32 last, padn;
249 uint32 high, low;
250 uint8 msglen[8];
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,wxString *md5)
273 int i, read;
274 md5_context ctx;
275 unsigned char md5sum[16];
276 unsigned char block[32768];
278 char temp[255];
279 wxFile file;
281 file.Open(name);
283 if (!file.IsOpened()) {
284 ERR_DIALOG("Could not open patched firmware for checksum check", _("Open Firmware"));
285 return 0;
287 md5_starts(&ctx);
288 while ( !file.Eof() ) {
289 read = file.Read(block, sizeof(block));
290 md5_update(&ctx, block, read);
292 file.Close();
293 md5_finish(&ctx, md5sum);
294 for (i = 0; i < 16; ++i)
296 sprintf(temp + 2*i, "%02x", md5sum[i]);
298 md5->Append(temp);
299 return 1;