removed the condition in alpm_db_set_servers since FREELIST is NULL safe
[pacman-ng.git] / lib / libalpm / md5.c
blob0d5ed9e0a4098e847a611d0b0086a146fb8aaa8f
1 /*
2 * RFC 1321 compliant MD5 implementation
4 * Copyright (C) 2006-2010, Brainspark B.V.
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
9 * All rights reserved.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 * The MD5 algorithm was designed by Ron Rivest in 1991.
27 * http://www.ietf.org/rfc/rfc1321.txt
30 * Pacman Notes:
32 * Taken from the PolarSSL project at http://polarssl.org under terms of the
33 * GPL. This is from version 1.0.0 of the library, and has been modified
34 * as following, which may be helpful for future updates:
35 * * remove "polarssl/config.h" include
36 * * change include from "polarssl/md5.h" to "md5.h"
37 * * removal of HMAC code
38 * * removal of SELF_TEST code
39 * * removal of ipad and opad from the md5_context struct in md5.h
40 * * increase the size of buffer for performance reasons
41 * * change 'unsigned long' to uint32_t
44 #include <stdio.h>
45 #include <stdint.h>
47 #include "md5.h"
50 * 32-bit integer manipulation macros (little endian)
52 #ifndef GET_U32_LE
53 #define GET_U32_LE(n,b,i) \
54 { \
55 (n) = ( (uint32_t) (b)[(i) ] ) \
56 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
57 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
58 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
60 #endif
62 #ifndef PUT_U32_LE
63 #define PUT_U32_LE(n,b,i) \
64 { \
65 (b)[(i) ] = (unsigned char) ( (n) ); \
66 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
67 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
68 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
70 #endif
73 * MD5 context setup
75 static void md5_starts( md5_context *ctx )
77 ctx->total[0] = 0;
78 ctx->total[1] = 0;
80 ctx->state[0] = 0x67452301;
81 ctx->state[1] = 0xEFCDAB89;
82 ctx->state[2] = 0x98BADCFE;
83 ctx->state[3] = 0x10325476;
86 static void md5_process( md5_context *ctx, const unsigned char data[64] )
88 uint32_t X[16], A, B, C, D;
90 GET_U32_LE( X[ 0], data, 0 );
91 GET_U32_LE( X[ 1], data, 4 );
92 GET_U32_LE( X[ 2], data, 8 );
93 GET_U32_LE( X[ 3], data, 12 );
94 GET_U32_LE( X[ 4], data, 16 );
95 GET_U32_LE( X[ 5], data, 20 );
96 GET_U32_LE( X[ 6], data, 24 );
97 GET_U32_LE( X[ 7], data, 28 );
98 GET_U32_LE( X[ 8], data, 32 );
99 GET_U32_LE( X[ 9], data, 36 );
100 GET_U32_LE( X[10], data, 40 );
101 GET_U32_LE( X[11], data, 44 );
102 GET_U32_LE( X[12], data, 48 );
103 GET_U32_LE( X[13], data, 52 );
104 GET_U32_LE( X[14], data, 56 );
105 GET_U32_LE( X[15], data, 60 );
107 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
109 #define P(a,b,c,d,k,s,t) \
111 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
114 A = ctx->state[0];
115 B = ctx->state[1];
116 C = ctx->state[2];
117 D = ctx->state[3];
119 #define F(x,y,z) (z ^ (x & (y ^ z)))
121 P( A, B, C, D, 0, 7, 0xD76AA478 );
122 P( D, A, B, C, 1, 12, 0xE8C7B756 );
123 P( C, D, A, B, 2, 17, 0x242070DB );
124 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
125 P( A, B, C, D, 4, 7, 0xF57C0FAF );
126 P( D, A, B, C, 5, 12, 0x4787C62A );
127 P( C, D, A, B, 6, 17, 0xA8304613 );
128 P( B, C, D, A, 7, 22, 0xFD469501 );
129 P( A, B, C, D, 8, 7, 0x698098D8 );
130 P( D, A, B, C, 9, 12, 0x8B44F7AF );
131 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
132 P( B, C, D, A, 11, 22, 0x895CD7BE );
133 P( A, B, C, D, 12, 7, 0x6B901122 );
134 P( D, A, B, C, 13, 12, 0xFD987193 );
135 P( C, D, A, B, 14, 17, 0xA679438E );
136 P( B, C, D, A, 15, 22, 0x49B40821 );
138 #undef F
140 #define F(x,y,z) (y ^ (z & (x ^ y)))
142 P( A, B, C, D, 1, 5, 0xF61E2562 );
143 P( D, A, B, C, 6, 9, 0xC040B340 );
144 P( C, D, A, B, 11, 14, 0x265E5A51 );
145 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
146 P( A, B, C, D, 5, 5, 0xD62F105D );
147 P( D, A, B, C, 10, 9, 0x02441453 );
148 P( C, D, A, B, 15, 14, 0xD8A1E681 );
149 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
150 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
151 P( D, A, B, C, 14, 9, 0xC33707D6 );
152 P( C, D, A, B, 3, 14, 0xF4D50D87 );
153 P( B, C, D, A, 8, 20, 0x455A14ED );
154 P( A, B, C, D, 13, 5, 0xA9E3E905 );
155 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
156 P( C, D, A, B, 7, 14, 0x676F02D9 );
157 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
159 #undef F
161 #define F(x,y,z) (x ^ y ^ z)
163 P( A, B, C, D, 5, 4, 0xFFFA3942 );
164 P( D, A, B, C, 8, 11, 0x8771F681 );
165 P( C, D, A, B, 11, 16, 0x6D9D6122 );
166 P( B, C, D, A, 14, 23, 0xFDE5380C );
167 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
168 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
169 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
170 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
171 P( A, B, C, D, 13, 4, 0x289B7EC6 );
172 P( D, A, B, C, 0, 11, 0xEAA127FA );
173 P( C, D, A, B, 3, 16, 0xD4EF3085 );
174 P( B, C, D, A, 6, 23, 0x04881D05 );
175 P( A, B, C, D, 9, 4, 0xD9D4D039 );
176 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
177 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
178 P( B, C, D, A, 2, 23, 0xC4AC5665 );
180 #undef F
182 #define F(x,y,z) (y ^ (x | ~z))
184 P( A, B, C, D, 0, 6, 0xF4292244 );
185 P( D, A, B, C, 7, 10, 0x432AFF97 );
186 P( C, D, A, B, 14, 15, 0xAB9423A7 );
187 P( B, C, D, A, 5, 21, 0xFC93A039 );
188 P( A, B, C, D, 12, 6, 0x655B59C3 );
189 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
190 P( C, D, A, B, 10, 15, 0xFFEFF47D );
191 P( B, C, D, A, 1, 21, 0x85845DD1 );
192 P( A, B, C, D, 8, 6, 0x6FA87E4F );
193 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
194 P( C, D, A, B, 6, 15, 0xA3014314 );
195 P( B, C, D, A, 13, 21, 0x4E0811A1 );
196 P( A, B, C, D, 4, 6, 0xF7537E82 );
197 P( D, A, B, C, 11, 10, 0xBD3AF235 );
198 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
199 P( B, C, D, A, 9, 21, 0xEB86D391 );
201 #undef F
203 ctx->state[0] += A;
204 ctx->state[1] += B;
205 ctx->state[2] += C;
206 ctx->state[3] += D;
210 * MD5 process buffer
212 static void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
214 size_t fill;
215 uint32_t left;
217 if( ilen <= 0 )
218 return;
220 left = ctx->total[0] & 0x3F;
221 fill = 64 - left;
223 ctx->total[0] += (uint32_t) ilen;
224 ctx->total[0] &= 0xFFFFFFFF;
226 if( ctx->total[0] < (uint32_t) ilen )
227 ctx->total[1]++;
229 if( left && ilen >= fill )
231 memcpy( (void *) (ctx->buffer + left),
232 (void *) input, fill );
233 md5_process( ctx, ctx->buffer );
234 input += fill;
235 ilen -= fill;
236 left = 0;
239 while( ilen >= 64 )
241 md5_process( ctx, input );
242 input += 64;
243 ilen -= 64;
246 if( ilen > 0 )
248 memcpy( (void *) (ctx->buffer + left),
249 (void *) input, ilen );
253 static const unsigned char md5_padding[64] =
255 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
262 * MD5 final digest
264 static void md5_finish( md5_context *ctx, unsigned char output[16] )
266 uint32_t last, padn;
267 uint32_t high, low;
268 unsigned char msglen[8];
270 high = ( ctx->total[0] >> 29 )
271 | ( ctx->total[1] << 3 );
272 low = ( ctx->total[0] << 3 );
274 PUT_U32_LE( low, msglen, 0 );
275 PUT_U32_LE( high, msglen, 4 );
277 last = ctx->total[0] & 0x3F;
278 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
280 md5_update( ctx, (unsigned char *) md5_padding, padn );
281 md5_update( ctx, msglen, 8 );
283 PUT_U32_LE( ctx->state[0], output, 0 );
284 PUT_U32_LE( ctx->state[1], output, 4 );
285 PUT_U32_LE( ctx->state[2], output, 8 );
286 PUT_U32_LE( ctx->state[3], output, 12 );
290 * output = MD5( input buffer )
292 void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
294 md5_context ctx;
296 md5_starts( &ctx );
297 md5_update( &ctx, input, ilen );
298 md5_finish( &ctx, output );
300 memset( &ctx, 0, sizeof( md5_context ) );
304 * output = MD5( file contents )
306 int md5_file( const char *path, unsigned char output[16] )
308 FILE *f;
309 size_t n;
310 md5_context ctx;
311 unsigned char buf[4096];
313 if( ( f = fopen( path, "rb" ) ) == NULL )
314 return( 1 );
316 md5_starts( &ctx );
318 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
319 md5_update( &ctx, buf, n );
321 md5_finish( &ctx, output );
323 memset( &ctx, 0, sizeof( md5_context ) );
325 if( ferror( f ) != 0 )
327 fclose( f );
328 return( 2 );
331 fclose( f );
332 return( 0 );