A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 246 lines 7.2 kB view raw
1/* 2 * RFC 1321 compliant MD5 implementation 3 * 4 * Copyright (C) 2001-2003 Christophe Devine 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21#include <string.h> 22 23#include "md5.h" 24 25#define GET_UINT32(n,b,i) \ 26{ \ 27 (n) = ( (uint32) (b)[(i) ] ) \ 28 | ( (uint32) (b)[(i) + 1] << 8 ) \ 29 | ( (uint32) (b)[(i) + 2] << 16 ) \ 30 | ( (uint32) (b)[(i) + 3] << 24 ); \ 31} 32 33#define PUT_UINT32(n,b,i) \ 34{ \ 35 (b)[(i) ] = (uint8) ( (n) ); \ 36 (b)[(i) + 1] = (uint8) ( (n) >> 8 ); \ 37 (b)[(i) + 2] = (uint8) ( (n) >> 16 ); \ 38 (b)[(i) + 3] = (uint8) ( (n) >> 24 ); \ 39} 40 41void md5_starts( md5_context *ctx ) 42{ 43 ctx->total[0] = 0; 44 ctx->total[1] = 0; 45 46 ctx->state[0] = 0x67452301; 47 ctx->state[1] = 0xEFCDAB89; 48 ctx->state[2] = 0x98BADCFE; 49 ctx->state[3] = 0x10325476; 50} 51 52void md5_process( md5_context *ctx, uint8 data[64] ) 53{ 54 uint32 X[16], A, B, C, D; 55 56 GET_UINT32( X[0], data, 0 ); 57 GET_UINT32( X[1], data, 4 ); 58 GET_UINT32( X[2], data, 8 ); 59 GET_UINT32( X[3], data, 12 ); 60 GET_UINT32( X[4], data, 16 ); 61 GET_UINT32( X[5], data, 20 ); 62 GET_UINT32( X[6], data, 24 ); 63 GET_UINT32( X[7], data, 28 ); 64 GET_UINT32( X[8], data, 32 ); 65 GET_UINT32( X[9], data, 36 ); 66 GET_UINT32( X[10], data, 40 ); 67 GET_UINT32( X[11], data, 44 ); 68 GET_UINT32( X[12], data, 48 ); 69 GET_UINT32( X[13], data, 52 ); 70 GET_UINT32( X[14], data, 56 ); 71 GET_UINT32( X[15], data, 60 ); 72 73#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 74 75#define P(a,b,c,d,k,s,t) \ 76{ \ 77 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ 78} 79 80 A = ctx->state[0]; 81 B = ctx->state[1]; 82 C = ctx->state[2]; 83 D = ctx->state[3]; 84 85#define F(x,y,z) (z ^ (x & (y ^ z))) 86 87 P( A, B, C, D, 0, 7, 0xD76AA478 ); 88 P( D, A, B, C, 1, 12, 0xE8C7B756 ); 89 P( C, D, A, B, 2, 17, 0x242070DB ); 90 P( B, C, D, A, 3, 22, 0xC1BDCEEE ); 91 P( A, B, C, D, 4, 7, 0xF57C0FAF ); 92 P( D, A, B, C, 5, 12, 0x4787C62A ); 93 P( C, D, A, B, 6, 17, 0xA8304613 ); 94 P( B, C, D, A, 7, 22, 0xFD469501 ); 95 P( A, B, C, D, 8, 7, 0x698098D8 ); 96 P( D, A, B, C, 9, 12, 0x8B44F7AF ); 97 P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); 98 P( B, C, D, A, 11, 22, 0x895CD7BE ); 99 P( A, B, C, D, 12, 7, 0x6B901122 ); 100 P( D, A, B, C, 13, 12, 0xFD987193 ); 101 P( C, D, A, B, 14, 17, 0xA679438E ); 102 P( B, C, D, A, 15, 22, 0x49B40821 ); 103 104#undef F 105 106#define F(x,y,z) (y ^ (z & (x ^ y))) 107 108 P( A, B, C, D, 1, 5, 0xF61E2562 ); 109 P( D, A, B, C, 6, 9, 0xC040B340 ); 110 P( C, D, A, B, 11, 14, 0x265E5A51 ); 111 P( B, C, D, A, 0, 20, 0xE9B6C7AA ); 112 P( A, B, C, D, 5, 5, 0xD62F105D ); 113 P( D, A, B, C, 10, 9, 0x02441453 ); 114 P( C, D, A, B, 15, 14, 0xD8A1E681 ); 115 P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); 116 P( A, B, C, D, 9, 5, 0x21E1CDE6 ); 117 P( D, A, B, C, 14, 9, 0xC33707D6 ); 118 P( C, D, A, B, 3, 14, 0xF4D50D87 ); 119 P( B, C, D, A, 8, 20, 0x455A14ED ); 120 P( A, B, C, D, 13, 5, 0xA9E3E905 ); 121 P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); 122 P( C, D, A, B, 7, 14, 0x676F02D9 ); 123 P( B, C, D, A, 12, 20, 0x8D2A4C8A ); 124 125#undef F 126 127#define F(x,y,z) (x ^ y ^ z) 128 129 P( A, B, C, D, 5, 4, 0xFFFA3942 ); 130 P( D, A, B, C, 8, 11, 0x8771F681 ); 131 P( C, D, A, B, 11, 16, 0x6D9D6122 ); 132 P( B, C, D, A, 14, 23, 0xFDE5380C ); 133 P( A, B, C, D, 1, 4, 0xA4BEEA44 ); 134 P( D, A, B, C, 4, 11, 0x4BDECFA9 ); 135 P( C, D, A, B, 7, 16, 0xF6BB4B60 ); 136 P( B, C, D, A, 10, 23, 0xBEBFBC70 ); 137 P( A, B, C, D, 13, 4, 0x289B7EC6 ); 138 P( D, A, B, C, 0, 11, 0xEAA127FA ); 139 P( C, D, A, B, 3, 16, 0xD4EF3085 ); 140 P( B, C, D, A, 6, 23, 0x04881D05 ); 141 P( A, B, C, D, 9, 4, 0xD9D4D039 ); 142 P( D, A, B, C, 12, 11, 0xE6DB99E5 ); 143 P( C, D, A, B, 15, 16, 0x1FA27CF8 ); 144 P( B, C, D, A, 2, 23, 0xC4AC5665 ); 145 146#undef F 147 148#define F(x,y,z) (y ^ (x | ~z)) 149 150 P( A, B, C, D, 0, 6, 0xF4292244 ); 151 P( D, A, B, C, 7, 10, 0x432AFF97 ); 152 P( C, D, A, B, 14, 15, 0xAB9423A7 ); 153 P( B, C, D, A, 5, 21, 0xFC93A039 ); 154 P( A, B, C, D, 12, 6, 0x655B59C3 ); 155 P( D, A, B, C, 3, 10, 0x8F0CCC92 ); 156 P( C, D, A, B, 10, 15, 0xFFEFF47D ); 157 P( B, C, D, A, 1, 21, 0x85845DD1 ); 158 P( A, B, C, D, 8, 6, 0x6FA87E4F ); 159 P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); 160 P( C, D, A, B, 6, 15, 0xA3014314 ); 161 P( B, C, D, A, 13, 21, 0x4E0811A1 ); 162 P( A, B, C, D, 4, 6, 0xF7537E82 ); 163 P( D, A, B, C, 11, 10, 0xBD3AF235 ); 164 P( C, D, A, B, 2, 15, 0x2AD7D2BB ); 165 P( B, C, D, A, 9, 21, 0xEB86D391 ); 166 167#undef F 168 169 ctx->state[0] += A; 170 ctx->state[1] += B; 171 ctx->state[2] += C; 172 ctx->state[3] += D; 173} 174 175void md5_update( md5_context *ctx, uint8 *input, uint32 length ) 176{ 177 uint32 left, fill; 178 179 if( ! length ) return; 180 181 left = ctx->total[0] & 0x3F; 182 fill = 64 - left; 183 184 ctx->total[0] += length; 185 ctx->total[0] &= 0xFFFFFFFF; 186 187 if( ctx->total[0] < length ) 188 ctx->total[1]++; 189 190 if( left && length >= fill ) 191 { 192 memcpy( (void *) (ctx->buffer + left), 193 (void *) input, fill ); 194 md5_process( ctx, ctx->buffer ); 195 length -= fill; 196 input += fill; 197 left = 0; 198 } 199 200 while( length >= 64 ) 201 { 202 md5_process( ctx, input ); 203 length -= 64; 204 input += 64; 205 } 206 207 if( length ) 208 { 209 memcpy( (void *) (ctx->buffer + left), 210 (void *) input, length ); 211 } 212} 213 214static uint8 md5_padding[64] = 215{ 216 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 220}; 221 222void md5_finish( md5_context *ctx, uint8 digest[16] ) 223{ 224 uint32 last, padn; 225 uint32 high, low; 226 uint8 msglen[8]; 227 228 high = ( ctx->total[0] >> 29 ) 229 | ( ctx->total[1] << 3 ); 230 low = ( ctx->total[0] << 3 ); 231 232 PUT_UINT32( low, msglen, 0 ); 233 PUT_UINT32( high, msglen, 4 ); 234 235 last = ctx->total[0] & 0x3F; 236 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 237 238 md5_update( ctx, md5_padding, padn ); 239 md5_update( ctx, msglen, 8 ); 240 241 PUT_UINT32( ctx->state[0], digest, 0 ); 242 PUT_UINT32( ctx->state[1], digest, 4 ); 243 PUT_UINT32( ctx->state[2], digest, 8 ); 244 PUT_UINT32( ctx->state[3], digest, 12 ); 245} 246