1 /*
2  * Copyright (C) 2016 Jakub Kruszona-Zawadzki, Core Technology Sp. z o.o.
3  *
4  * This file is part of MooseFS.
5  *
6  * MooseFS 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, version 2 (only).
9  *
10  * MooseFS is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with MooseFS; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA
18  * or visit http://www.gnu.org/licenses/gpl-2.0.html
19  */
20 
21 #include <string.h>
22 #include <inttypes.h>
23 #include "md5.h"
24 
25 #define S11 7
26 #define S12 12
27 #define S13 17
28 #define S14 22
29 #define S21 5
30 #define S22 9
31 #define S23 14
32 #define S24 20
33 #define S31 4
34 #define S32 11
35 #define S33 16
36 #define S34 23
37 #define S41 6
38 #define S42 10
39 #define S43 15
40 #define S44 21
41 
42 static const uint8_t padding[64] = {
43 	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
46 };
47 
48 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
49 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
50 #define H(x, y, z) ((x) ^ (y) ^ (z))
51 #define I(x, y, z) ((y) ^ ((x) | (~z)))
52 
53 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
54 
55 #define FF(a, b, c, d, x, s, ac) { \
56  (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
57  (a) = ROTATE_LEFT ((a), (s)); \
58  (a) += (b); \
59   }
60 #define GG(a, b, c, d, x, s, ac) { \
61  (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
62  (a) = ROTATE_LEFT ((a), (s)); \
63  (a) += (b); \
64   }
65 #define HH(a, b, c, d, x, s, ac) { \
66  (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
67  (a) = ROTATE_LEFT ((a), (s)); \
68  (a) += (b); \
69   }
70 #define II(a, b, c, d, x, s, ac) { \
71  (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
72  (a) = ROTATE_LEFT ((a), (s)); \
73  (a) += (b); \
74   }
75 
md5_encode(uint8_t * output,const uint32_t * input,uint32_t len)76 static void md5_encode (uint8_t *output,const uint32_t *input,uint32_t len) {
77 	uint32_t i,j;
78 
79 	for (i=0,j=0 ; i<len ; i++,j+=4) {
80 		output[j] = (uint8_t)(input[i]&0xff);
81 		output[j+1] = (uint8_t)((input[i]>>8)&0xff);
82 		output[j+2] = (uint8_t)((input[i]>>16)&0xff);
83 		output[j+3] = (uint8_t)((input[i]>>24)&0xff);
84 	}
85 }
86 
md5_decode(uint32_t * output,const uint8_t * input,uint32_t len)87 static void md5_decode (uint32_t *output,const uint8_t *input,uint32_t len) {
88 	uint32_t i,j;
89 
90 	for (i=0,j=0 ; i<len ; i++,j+=4) {
91 		output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1])<<8) | (((uint32_t)input[j+2])<<16) | (((uint32_t)input[j+3])<<24);
92 	}
93 }
94 
md5_transform(uint32_t state[4],const uint8_t block[64])95 static void md5_transform (uint32_t state[4],const uint8_t block[64]) {
96 	uint32_t a=state[0], b=state[1], c=state[2], d=state[3], x[16];
97 
98 	md5_decode(x,block,16);
99 
100 	FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
101 	FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
102 	FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
103 	FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
104 	FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
105 	FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
106 	FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
107 	FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
108 	FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
109 	FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
110 	FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
111 	FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
112 	FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
113 	FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
114 	FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
115 	FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
116 
117 	GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
118 	GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
119 	GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
120 	GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
121 	GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
122 	GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
123 	GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
124 	GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
125 	GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
126 	GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
127 	GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
128 	GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
129 	GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
130 	GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
131 	GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
132 	GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
133 
134 	HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
135 	HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
136 	HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
137 	HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
138 	HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
139 	HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
140 	HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
141 	HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
142 	HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
143 	HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
144 	HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
145 	HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
146 	HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
147 	HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
148 	HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
149 	HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
150 
151 	II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
152 	II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
153 	II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
154 	II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
155 	II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
156 	II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
157 	II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
158 	II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
159 	II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
160 	II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
161 	II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
162 	II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
163 	II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
164 	II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
165 	II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
166 	II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
167 
168 	state[0] += a;
169 	state[1] += b;
170 	state[2] += c;
171 	state[3] += d;
172 
173 	memset((char*)x,0,sizeof(x));
174 }
175 
176 
177 
md5_init(md5ctx * ctx)178 void md5_init (md5ctx *ctx) {
179 	ctx->count[0] = ctx->count[1] = 0;
180 	ctx->state[0] = 0x67452301U;
181 	ctx->state[1] = 0xefcdab89U;
182 	ctx->state[2] = 0x98badcfeU;
183 	ctx->state[3] = 0x10325476U;
184 }
185 
md5_update(md5ctx * ctx,const uint8_t * buff,uint32_t leng)186 void md5_update (md5ctx *ctx,const uint8_t *buff,uint32_t leng) {
187 	uint32_t i,indx,partleng;
188 
189 	indx = (uint32_t)((ctx->count[0]>>3)&0x3F);
190 
191 	if ((ctx->count[0]+=((uint32_t)leng<<3)) < ((uint32_t)leng<<3)) {
192 		ctx->count[1]++;
193 	}
194 	ctx->count[1] += ((uint32_t)leng>>29);
195 
196 	partleng = 64-indx;
197 
198 	if (leng>=partleng) {
199 		memcpy((char*)(ctx->buffer+indx),(const char*)buff,partleng);
200 		md5_transform(ctx->state,ctx->buffer);
201 
202 		for (i=partleng ; i+63<leng ; i+=64) {
203 			md5_transform(ctx->state,buff+i);
204 		}
205 		indx = 0;
206 	} else {
207 		i = 0;
208 	}
209 
210 	memcpy((char*)(ctx->buffer+indx),(const char*)(buff+i),leng-i);
211 }
212 
md5_final(uint8_t digest[16],md5ctx * ctx)213 void md5_final (uint8_t digest[16],md5ctx *ctx) {
214 	uint8_t bits[8];
215 	uint32_t indx,padleng;
216 
217 	md5_encode(bits,ctx->count,2);
218 	indx = (uint32_t)((ctx->count[0]>>3)&0x3f);
219 	padleng = (indx<56)?(56-indx):(120-indx);
220 	md5_update (ctx,padding,padleng);
221 	md5_update(ctx,bits,8);
222 	md5_encode(digest,ctx->state,4);
223 	memset((char*)ctx,0,sizeof(md5ctx));
224 }
225