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