• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 
5   This software is provided 'as-is', without any express or implied
6   warranty.  In no event will the authors be held liable for any damages
7   arising from the use of this software.
8 
9   Permission is granted to anyone to use this software for any purpose,
10   including commercial applications, and to alter it and redistribute it
11   freely, subject to the following restrictions:
12 
13   1. The origin of this software must not be misrepresented; you must not
14      claim that you wrote the original software. If you use this software
15      in a product, an acknowledgment in the product documentation would be
16      appreciated but is not required.
17   2. Altered source versions must be plainly marked as such, and must not be
18      misrepresented as being the original software.
19   3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 /*
23  ***********************************************************************
24  ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
25  ** Created: 2/17/90 RLR                                              **
26  ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
27  ***********************************************************************
28  */
29 
30 /*
31  ***********************************************************************
32  ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
33  **                                                                   **
34  ** License to copy and use this software is granted provided that    **
35  ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
36  ** Digest Algorithm" in all material mentioning or referencing this  **
37  ** software or this function.                                        **
38  **                                                                   **
39  ** License is also granted to make and use derivative works          **
40  ** provided that such works are identified as "derived from the RSA  **
41  ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
42  ** material mentioning or referencing the derived work.              **
43  **                                                                   **
44  ** RSA Data Security, Inc. makes no representations concerning       **
45  ** either the merchantability of this software or the suitability    **
46  ** of this software for any particular purpose.  It is provided "as  **
47  ** is" without express or implied warranty of any kind.              **
48  **                                                                   **
49  ** These notices must be retained in any copies of any part of this  **
50  ** documentation and/or software.                                    **
51  ***********************************************************************
52  */
53 
54 #include "SDL_config.h"
55 
56 #include "SDL_test.h"
57 
58 /* Forward declaration of static helper function */
59 static void SDLTest_Md5Transform(MD5UINT4 * buf, MD5UINT4 * in);
60 
61 static unsigned char MD5PADDING[64] = {
62   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
70 };
71 
72 /* F, G, H and I are basic MD5 functions */
73 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
74 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
75 #define H(x, y, z) ((x) ^ (y) ^ (z))
76 #define I(x, y, z) ((y) ^ ((x) | (~z)))
77 
78 /* ROTATE_LEFT rotates x left n bits */
79 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
80 
81 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
82 
83 /* Rotation is separate from addition to prevent recomputation */
84 #define FF(a, b, c, d, x, s, ac) \
85   {(a) += F ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \
86    (a) = ROTATE_LEFT ((a), (s)); \
87    (a) += (b); \
88   }
89 #define GG(a, b, c, d, x, s, ac) \
90   {(a) += G ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \
91    (a) = ROTATE_LEFT ((a), (s)); \
92    (a) += (b); \
93   }
94 #define HH(a, b, c, d, x, s, ac) \
95   {(a) += H ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \
96    (a) = ROTATE_LEFT ((a), (s)); \
97    (a) += (b); \
98   }
99 #define II(a, b, c, d, x, s, ac) \
100   {(a) += I ((b), (c), (d)) + (x) + (MD5UINT4)(ac); \
101    (a) = ROTATE_LEFT ((a), (s)); \
102    (a) += (b); \
103   }
104 
105 /*
106   The routine MD5Init initializes the message-digest context
107   mdContext. All fields are set to zero.
108 */
109 
SDLTest_Md5Init(SDLTest_Md5Context * mdContext)110 void SDLTest_Md5Init(SDLTest_Md5Context * mdContext)
111 {
112   if (mdContext==NULL) return;
113 
114   mdContext->i[0] = mdContext->i[1] = (MD5UINT4) 0;
115 
116   /*
117    * Load magic initialization constants.
118    */
119   mdContext->buf[0] = (MD5UINT4) 0x67452301;
120   mdContext->buf[1] = (MD5UINT4) 0xefcdab89;
121   mdContext->buf[2] = (MD5UINT4) 0x98badcfe;
122   mdContext->buf[3] = (MD5UINT4) 0x10325476;
123 }
124 
125 /*
126  The routine MD5Update updates the message-digest context to
127  account for the presence of each of the characters inBuf[0..inLen-1]
128  in the message whose digest is being computed.
129 */
130 
SDLTest_Md5Update(SDLTest_Md5Context * mdContext,unsigned char * inBuf,unsigned int inLen)131 void SDLTest_Md5Update(SDLTest_Md5Context * mdContext, unsigned char *inBuf,
132           unsigned int inLen)
133 {
134   MD5UINT4  in[16];
135   int       mdi;
136   unsigned int i, ii;
137 
138   if (mdContext == NULL) return;
139   if (inBuf == NULL || inLen < 1) return;
140 
141   /*
142    * compute number of bytes mod 64
143    */
144   mdi = (int) ((mdContext->i[0] >> 3) & 0x3F);
145 
146   /*
147    * update number of bits
148    */
149   if ((mdContext->i[0] + ((MD5UINT4) inLen << 3)) < mdContext->i[0])
150     mdContext->i[1]++;
151   mdContext->i[0] += ((MD5UINT4) inLen << 3);
152   mdContext->i[1] += ((MD5UINT4) inLen >> 29);
153 
154   while (inLen--) {
155     /*
156      * add new character to buffer, increment mdi
157      */
158     mdContext->in[mdi++] = *inBuf++;
159 
160     /*
161      * transform if necessary
162      */
163     if (mdi == 0x40) {
164       for (i = 0, ii = 0; i < 16; i++, ii += 4)
165     in[i] = (((MD5UINT4) mdContext->in[ii + 3]) << 24) |
166       (((MD5UINT4) mdContext->in[ii + 2]) << 16) |
167       (((MD5UINT4) mdContext->in[ii + 1]) << 8) |
168       ((MD5UINT4) mdContext->in[ii]);
169       SDLTest_Md5Transform(mdContext->buf, in);
170       mdi = 0;
171     }
172   }
173 }
174 
175 /*
176  The routine MD5Final terminates the message-digest computation and
177  ends with the desired message digest in mdContext->digest[0...15].
178 */
179 
SDLTest_Md5Final(SDLTest_Md5Context * mdContext)180 void SDLTest_Md5Final(SDLTest_Md5Context * mdContext)
181 {
182   MD5UINT4  in[16];
183   int       mdi;
184   unsigned int i, ii;
185   unsigned int padLen;
186 
187   if (mdContext == NULL) return;
188 
189   /*
190    * save number of bits
191    */
192   in[14] = mdContext->i[0];
193   in[15] = mdContext->i[1];
194 
195   /*
196    * compute number of bytes mod 64
197    */
198   mdi = (int) ((mdContext->i[0] >> 3) & 0x3F);
199 
200   /*
201    * pad out to 56 mod 64
202    */
203   padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
204   SDLTest_Md5Update(mdContext, MD5PADDING, padLen);
205 
206   /*
207    * append length in bits and transform
208    */
209   for (i = 0, ii = 0; i < 14; i++, ii += 4)
210     in[i] = (((MD5UINT4) mdContext->in[ii + 3]) << 24) |
211       (((MD5UINT4) mdContext->in[ii + 2]) << 16) |
212       (((MD5UINT4) mdContext->in[ii + 1]) << 8) |
213       ((MD5UINT4) mdContext->in[ii]);
214   SDLTest_Md5Transform(mdContext->buf, in);
215 
216   /*
217    * store buffer in digest
218    */
219   for (i = 0, ii = 0; i < 4; i++, ii += 4) {
220     mdContext->digest[ii] = (unsigned char) (mdContext->buf[i] & 0xFF);
221     mdContext->digest[ii + 1] =
222       (unsigned char) ((mdContext->buf[i] >> 8) & 0xFF);
223     mdContext->digest[ii + 2] =
224       (unsigned char) ((mdContext->buf[i] >> 16) & 0xFF);
225     mdContext->digest[ii + 3] =
226       (unsigned char) ((mdContext->buf[i] >> 24) & 0xFF);
227   }
228 }
229 
230 /* Basic MD5 step. Transforms buf based on in.
231  */
SDLTest_Md5Transform(MD5UINT4 * buf,MD5UINT4 * in)232 static void SDLTest_Md5Transform(MD5UINT4 * buf, MD5UINT4 * in)
233 {
234   MD5UINT4  a = buf[0], b = buf[1], c = buf[2], d = buf[3];
235 
236   /*
237    * Round 1
238    */
239 #define S11 7
240 #define S12 12
241 #define S13 17
242 #define S14 22
243   FF(a, b, c, d, in[0], S11, 3614090360u);  /* 1 */
244   FF(d, a, b, c, in[1], S12, 3905402710u);  /* 2 */
245   FF(c, d, a, b, in[2], S13, 606105819u);   /* 3 */
246   FF(b, c, d, a, in[3], S14, 3250441966u);  /* 4 */
247   FF(a, b, c, d, in[4], S11, 4118548399u);  /* 5 */
248   FF(d, a, b, c, in[5], S12, 1200080426u);  /* 6 */
249   FF(c, d, a, b, in[6], S13, 2821735955u);  /* 7 */
250   FF(b, c, d, a, in[7], S14, 4249261313u);  /* 8 */
251   FF(a, b, c, d, in[8], S11, 1770035416u);  /* 9 */
252   FF(d, a, b, c, in[9], S12, 2336552879u);  /* 10 */
253   FF(c, d, a, b, in[10], S13, 4294925233u); /* 11 */
254   FF(b, c, d, a, in[11], S14, 2304563134u); /* 12 */
255   FF(a, b, c, d, in[12], S11, 1804603682u); /* 13 */
256   FF(d, a, b, c, in[13], S12, 4254626195u); /* 14 */
257   FF(c, d, a, b, in[14], S13, 2792965006u); /* 15 */
258   FF(b, c, d, a, in[15], S14, 1236535329u); /* 16 */
259 
260   /*
261    * Round 2
262    */
263 #define S21 5
264 #define S22 9
265 #define S23 14
266 #define S24 20
267   GG(a, b, c, d, in[1], S21, 4129170786u);  /* 17 */
268   GG(d, a, b, c, in[6], S22, 3225465664u);  /* 18 */
269   GG(c, d, a, b, in[11], S23, 643717713u);  /* 19 */
270   GG(b, c, d, a, in[0], S24, 3921069994u);  /* 20 */
271   GG(a, b, c, d, in[5], S21, 3593408605u);  /* 21 */
272   GG(d, a, b, c, in[10], S22, 38016083u);   /* 22 */
273   GG(c, d, a, b, in[15], S23, 3634488961u); /* 23 */
274   GG(b, c, d, a, in[4], S24, 3889429448u);  /* 24 */
275   GG(a, b, c, d, in[9], S21, 568446438u);   /* 25 */
276   GG(d, a, b, c, in[14], S22, 3275163606u); /* 26 */
277   GG(c, d, a, b, in[3], S23, 4107603335u);  /* 27 */
278   GG(b, c, d, a, in[8], S24, 1163531501u);  /* 28 */
279   GG(a, b, c, d, in[13], S21, 2850285829u); /* 29 */
280   GG(d, a, b, c, in[2], S22, 4243563512u);  /* 30 */
281   GG(c, d, a, b, in[7], S23, 1735328473u);  /* 31 */
282   GG(b, c, d, a, in[12], S24, 2368359562u); /* 32 */
283 
284   /*
285    * Round 3
286    */
287 #define S31 4
288 #define S32 11
289 #define S33 16
290 #define S34 23
291   HH(a, b, c, d, in[5], S31, 4294588738u);  /* 33 */
292   HH(d, a, b, c, in[8], S32, 2272392833u);  /* 34 */
293   HH(c, d, a, b, in[11], S33, 1839030562u); /* 35 */
294   HH(b, c, d, a, in[14], S34, 4259657740u); /* 36 */
295   HH(a, b, c, d, in[1], S31, 2763975236u);  /* 37 */
296   HH(d, a, b, c, in[4], S32, 1272893353u);  /* 38 */
297   HH(c, d, a, b, in[7], S33, 4139469664u);  /* 39 */
298   HH(b, c, d, a, in[10], S34, 3200236656u); /* 40 */
299   HH(a, b, c, d, in[13], S31, 681279174u);  /* 41 */
300   HH(d, a, b, c, in[0], S32, 3936430074u);  /* 42 */
301   HH(c, d, a, b, in[3], S33, 3572445317u);  /* 43 */
302   HH(b, c, d, a, in[6], S34, 76029189u);    /* 44 */
303   HH(a, b, c, d, in[9], S31, 3654602809u);  /* 45 */
304   HH(d, a, b, c, in[12], S32, 3873151461u); /* 46 */
305   HH(c, d, a, b, in[15], S33, 530742520u);  /* 47 */
306   HH(b, c, d, a, in[2], S34, 3299628645u);  /* 48 */
307 
308   /*
309    * Round 4
310    */
311 #define S41 6
312 #define S42 10
313 #define S43 15
314 #define S44 21
315   II(a, b, c, d, in[0], S41, 4096336452u);  /* 49 */
316   II(d, a, b, c, in[7], S42, 1126891415u);  /* 50 */
317   II(c, d, a, b, in[14], S43, 2878612391u); /* 51 */
318   II(b, c, d, a, in[5], S44, 4237533241u);  /* 52 */
319   II(a, b, c, d, in[12], S41, 1700485571u); /* 53 */
320   II(d, a, b, c, in[3], S42, 2399980690u);  /* 54 */
321   II(c, d, a, b, in[10], S43, 4293915773u); /* 55 */
322   II(b, c, d, a, in[1], S44, 2240044497u);  /* 56 */
323   II(a, b, c, d, in[8], S41, 1873313359u);  /* 57 */
324   II(d, a, b, c, in[15], S42, 4264355552u); /* 58 */
325   II(c, d, a, b, in[6], S43, 2734768916u);  /* 59 */
326   II(b, c, d, a, in[13], S44, 1309151649u); /* 60 */
327   II(a, b, c, d, in[4], S41, 4149444226u);  /* 61 */
328   II(d, a, b, c, in[11], S42, 3174756917u); /* 62 */
329   II(c, d, a, b, in[2], S43, 718787259u);   /* 63 */
330   II(b, c, d, a, in[9], S44, 3951481745u);  /* 64 */
331 
332   buf[0] += a;
333   buf[1] += b;
334   buf[2] += c;
335   buf[3] += d;
336 }
337