1 /* Functions to compute MD5 message digest of memory blocks according to the
2 definition of MD5 in RFC 1321 from April 1992.
3 Copyright (C) 2020, 2021 Antonio Diaz Diaz.
4
5 This library is free software. Redistribution and use in source and
6 binary forms, with or without modification, are permitted provided
7 that the following conditions are met:
8
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions, and the following disclaimer.
11
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions, and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 This library 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.
19 */
20
21 #define _FILE_OFFSET_BITS 64
22
23 #include <cstring>
24 #include <stdint.h>
25
26 #include "md5.h"
27
28
29 namespace {
30
31 /* These are the four functions used in the four steps of the MD5 algorithm
32 as defined in RFC 1321. */
33 #define F(x, y, z) ((x & y) | (~x & z))
34 #define G(x, y, z) ((x & z) | (y & ~z))
35 #define H(x, y, z) (x ^ y ^ z)
36 #define I(x, y, z) (y ^ (x | ~z))
37
38 /* Rotate x left n bits.
39 It is unfortunate that C++ does not provide an operator for rotation.
40 Hope the compiler is smart enough. */
41 #define ROTATE_LEFT(x, n) (x = (x << n) | (x >> (32 - n)))
42
43 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
44 #define FF(a, b, c, d, x, s, ac) \
45 { a += F(b, c, d) + x + ac; ROTATE_LEFT(a, s); a += b; }
46 #define GG(a, b, c, d, x, s, ac) \
47 { a += G(b, c, d) + x + ac; ROTATE_LEFT(a, s); a += b; }
48 #define HH(a, b, c, d, x, s, ac) \
49 { a += H(b, c, d) + x + ac; ROTATE_LEFT(a, s); a += b; }
50 #define II(a, b, c, d, x, s, ac) \
51 { a += I(b, c, d) + x + ac; ROTATE_LEFT(a, s); a += b; }
52
53 } // end namespace
54
55
md5_process_block(const uint8_t block[64])56 void MD5SUM::md5_process_block( const uint8_t block[64] )
57 {
58 uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
59
60 for( int i = 0, j = 0; i < 16; ++i, j += 4 ) // fill x in little endian
61 x[i] = block[j] | (block[j+1] << 8) | (block[j+2] << 16) | (block[j+3] << 24);
62
63 /* Round 1 */
64 FF (a, b, c, d, x[ 0], 7, 0xD76AA478); // 1
65 FF (d, a, b, c, x[ 1], 12, 0xE8C7B756); // 2
66 FF (c, d, a, b, x[ 2], 17, 0x242070DB); // 3
67 FF (b, c, d, a, x[ 3], 22, 0xC1BDCEEE); // 4
68 FF (a, b, c, d, x[ 4], 7, 0xF57C0FAF); // 5
69 FF (d, a, b, c, x[ 5], 12, 0x4787C62A); // 6
70 FF (c, d, a, b, x[ 6], 17, 0xA8304613); // 7
71 FF (b, c, d, a, x[ 7], 22, 0xFD469501); // 8
72 FF (a, b, c, d, x[ 8], 7, 0x698098D8); // 9
73 FF (d, a, b, c, x[ 9], 12, 0x8B44F7AF); // 10
74 FF (c, d, a, b, x[10], 17, 0xFFFF5BB1); // 11
75 FF (b, c, d, a, x[11], 22, 0x895CD7BE); // 12
76 FF (a, b, c, d, x[12], 7, 0x6B901122); // 13
77 FF (d, a, b, c, x[13], 12, 0xFD987193); // 14
78 FF (c, d, a, b, x[14], 17, 0xA679438E); // 15
79 FF (b, c, d, a, x[15], 22, 0x49B40821); // 16
80
81 /* Round 2 */
82 GG (a, b, c, d, x[ 1], 5, 0xF61E2562); // 17
83 GG (d, a, b, c, x[ 6], 9, 0xC040B340); // 18
84 GG (c, d, a, b, x[11], 14, 0x265E5A51); // 19
85 GG (b, c, d, a, x[ 0], 20, 0xE9B6C7AA); // 20
86 GG (a, b, c, d, x[ 5], 5, 0xD62F105D); // 21
87 GG (d, a, b, c, x[10], 9, 0x02441453); // 22
88 GG (c, d, a, b, x[15], 14, 0xD8A1E681); // 23
89 GG (b, c, d, a, x[ 4], 20, 0xE7D3FBC8); // 24
90 GG (a, b, c, d, x[ 9], 5, 0x21E1CDE6); // 25
91 GG (d, a, b, c, x[14], 9, 0xC33707D6); // 26
92 GG (c, d, a, b, x[ 3], 14, 0xF4D50D87); // 27
93 GG (b, c, d, a, x[ 8], 20, 0x455A14ED); // 28
94 GG (a, b, c, d, x[13], 5, 0xA9E3E905); // 29
95 GG (d, a, b, c, x[ 2], 9, 0xFCEFA3F8); // 30
96 GG (c, d, a, b, x[ 7], 14, 0x676F02D9); // 31
97 GG (b, c, d, a, x[12], 20, 0x8D2A4C8A); // 32
98
99 /* Round 3 */
100 HH (a, b, c, d, x[ 5], 4, 0xFFFA3942); // 33
101 HH (d, a, b, c, x[ 8], 11, 0x8771F681); // 34
102 HH (c, d, a, b, x[11], 16, 0x6D9D6122); // 35
103 HH (b, c, d, a, x[14], 23, 0xFDE5380C); // 36
104 HH (a, b, c, d, x[ 1], 4, 0xA4BEEA44); // 37
105 HH (d, a, b, c, x[ 4], 11, 0x4BDECFA9); // 38
106 HH (c, d, a, b, x[ 7], 16, 0xF6BB4B60); // 39
107 HH (b, c, d, a, x[10], 23, 0xBEBFBC70); // 40
108 HH (a, b, c, d, x[13], 4, 0x289B7EC6); // 41
109 HH (d, a, b, c, x[ 0], 11, 0xEAA127FA); // 42
110 HH (c, d, a, b, x[ 3], 16, 0xD4EF3085); // 43
111 HH (b, c, d, a, x[ 6], 23, 0x04881D05); // 44
112 HH (a, b, c, d, x[ 9], 4, 0xD9D4D039); // 45
113 HH (d, a, b, c, x[12], 11, 0xE6DB99E5); // 46
114 HH (c, d, a, b, x[15], 16, 0x1FA27CF8); // 47
115 HH (b, c, d, a, x[ 2], 23, 0xC4AC5665); // 48
116
117 /* Round 4 */
118 II (a, b, c, d, x[ 0], 6, 0xF4292244); // 49
119 II (d, a, b, c, x[ 7], 10, 0x432AFF97); // 50
120 II (c, d, a, b, x[14], 15, 0xAB9423A7); // 51
121 II (b, c, d, a, x[ 5], 21, 0xFC93A039); // 52
122 II (a, b, c, d, x[12], 6, 0x655B59C3); // 53
123 II (d, a, b, c, x[ 3], 10, 0x8F0CCC92); // 54
124 II (c, d, a, b, x[10], 15, 0xFFEFF47D); // 55
125 II (b, c, d, a, x[ 1], 21, 0x85845DD1); // 56
126 II (a, b, c, d, x[ 8], 6, 0x6FA87E4F); // 57
127 II (d, a, b, c, x[15], 10, 0xFE2CE6E0); // 58
128 II (c, d, a, b, x[ 6], 15, 0xA3014314); // 59
129 II (b, c, d, a, x[13], 21, 0x4E0811A1); // 60
130 II (a, b, c, d, x[ 4], 6, 0xF7537E82); // 61
131 II (d, a, b, c, x[11], 10, 0xBD3AF235); // 62
132 II (c, d, a, b, x[ 2], 15, 0x2AD7D2BB); // 63
133 II (b, c, d, a, x[ 9], 21, 0xEB86D391); // 64
134
135 // add the processed values to the context
136 state[0] += a; state[1] += b; state[2] += c; state[3] += d;
137 }
138
139
140 /* Update the context for the next 'len' bytes of 'buffer'.
141 'len' does not need to be a multiple of 64.
142 */
md5_update(const uint8_t * const buffer,const unsigned long len)143 void MD5SUM::md5_update( const uint8_t * const buffer, const unsigned long len )
144 {
145 unsigned index = count & 0x3F; // data length in bytes mod 64
146 count += len; // update data length
147 const unsigned rest = 64 - index;
148 unsigned long i;
149
150 if( len >= rest ) // process as many bytes as possible
151 {
152 std::memcpy( ibuf + index, buffer, rest );
153 md5_process_block( ibuf );
154 for( i = rest; i + 63 < len; i += 64 )
155 md5_process_block( buffer + i );
156 index = 0;
157 }
158 else i = 0;
159
160 std::memcpy( ibuf + index, buffer + i, len - i ); // save remaining input
161 }
162
163
164 // finish computation and return the digest
md5_finish(uint8_t digest[16])165 void MD5SUM::md5_finish( uint8_t digest[16] )
166 {
167 uint8_t padding[64] = {
168 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
169 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
171 };
172 uint8_t bits[8];
173 uint64_t c = count << 3; // save data length in bits
174 for( int i = 0; i <= 7; ++i ) { bits[i] = (uint8_t)c; c >>= 8; }
175
176 const unsigned index = count & 0x3F; // data length in bytes mod 64
177 const unsigned len = (index < 56) ? (56 - index) : (120 - index);
178 md5_update( padding, len ); // pad to 56 mod 64
179 md5_update( bits, 8 ); // append data length in bits
180
181 for( int i = 0, j = 0; i < 4; i++, j += 4 ) // store state in digest
182 {
183 digest[j ] = (uint8_t)state[i];
184 digest[j+1] = (uint8_t)(state[i] >> 8);
185 digest[j+2] = (uint8_t)(state[i] >> 16);
186 digest[j+3] = (uint8_t)(state[i] >> 24);
187 }
188 }
189
190
compute_md5(const uint8_t * const buffer,const unsigned long len,uint8_t digest[16])191 void compute_md5( const uint8_t * const buffer, const unsigned long len,
192 uint8_t digest[16] )
193 {
194 MD5SUM md5sum;
195 if( len > 0 ) md5sum.md5_update( buffer, len );
196 md5sum.md5_finish( digest );
197 }
198
199
check_md5(const uint8_t * const buffer,const unsigned long len,const uint8_t digest[16])200 bool check_md5( const uint8_t * const buffer, const unsigned long len,
201 const uint8_t digest[16] )
202 {
203 uint8_t new_digest[16];
204 compute_md5( buffer, len, new_digest );
205 return ( std::memcmp( digest, new_digest, 16 ) == 0 );
206 }
207