File Coverage

inc/matrixssl-3-9-3-open/crypto/digest/md5.c
Criterion Covered Total %
statement 113 118 95.7
branch 12 16 75.0
condition n/a
subroutine n/a
pod n/a
total 125 134 93.2


line stmt bran cond sub pod time code
1             /**
2             * @file md5.c
3             * @version 950bba4 (HEAD -> master)
4             *
5             * MD5 hash implementation.
6             */
7             /*
8             * Copyright (c) 2013-2017 INSIDE Secure Corporation
9             * Copyright (c) PeerSec Networks, 2002-2011
10             * All Rights Reserved
11             *
12             * The latest version of this code is available at http://www.matrixssl.org
13             *
14             * This software is open source; you can redistribute it and/or modify
15             * it under the terms of the GNU General Public License as published by
16             * the Free Software Foundation; either version 2 of the License, or
17             * (at your option) any later version.
18             *
19             * This General Public License does NOT permit incorporating this software
20             * into proprietary programs. If you are unable to comply with the GPL, a
21             * commercial license for this software may be purchased from INSIDE at
22             * http://www.insidesecure.com/
23             *
24             * This program is distributed in WITHOUT ANY WARRANTY; without even the
25             * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26             * See the GNU General Public License for more details.
27             *
28             * You should have received a copy of the GNU General Public License
29             * along with this program; if not, write to the Free Software
30             * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31             * http://www.gnu.org/copyleft/gpl.html
32             */
33             /******************************************************************************/
34              
35             #include "../cryptoImpl.h"
36              
37             #ifdef USE_MATRIX_MD5
38              
39             static void md5_compress(psMd5_t *md5);
40              
41             /******************************************************************************/
42              
43 12319           int32_t psMd5Init(psMd5_t *md5)
44             {
45             # ifdef CRYPTO_ASSERT
46             psAssert(md5 != NULL);
47             # endif
48 12319           md5->state[0] = 0x67452301UL;
49 12319           md5->state[1] = 0xefcdab89UL;
50 12319           md5->state[2] = 0x98badcfeUL;
51 12319           md5->state[3] = 0x10325476UL;
52 12319           md5->curlen = 0;
53             # ifdef HAVE_NATIVE_INT64
54 12319           md5->length = 0;
55             # else
56             md5->lengthHi = 0;
57             md5->lengthLo = 0;
58             # endif /* HAVE_NATIVE_INT64 */
59 12319           return PS_SUCCESS;
60             }
61              
62             /******************************************************************************/
63              
64 27682           void psMd5Update(psMd5_t *md5, const unsigned char *buf, uint32_t len)
65             {
66             uint32_t n;
67              
68             # ifdef CRYPTO_ASSERT
69             psAssert(md5 != NULL);
70             psAssert(buf != NULL);
71             # endif
72 126289 100         while (len > 0)
73             {
74 98607           n = min(len, (64 - md5->curlen));
75 98607           memcpy(md5->buf + md5->curlen, buf, (size_t) n);
76 98607           md5->curlen += n;
77 98607           buf += n;
78 98607           len -= n;
79              
80             /* is 64 bytes full? */
81 98607 100         if (md5->curlen == 64)
82             {
83 70927           md5_compress(md5);
84             # ifdef HAVE_NATIVE_INT64
85 70927           md5->length += 512;
86             # else
87             n = (md5->lengthLo + 512) & 0xFFFFFFFFL;
88             if (n < md5->lengthLo)
89             {
90             md5->lengthHi++;
91             }
92             md5->lengthLo = n;
93             # endif /* HAVE_NATIVE_INT64 */
94 70927           md5->curlen = 0;
95             }
96             }
97 27682           }
98              
99             /******************************************************************************/
100             /**
101             Finalize and clear/free a hash context.
102             @param[in,out] md5 Hash Context
103             @param[out] hash Pointer to a buffer to receive finalized hash value, or
104             NULL to ignore output and just clear hash context.
105             */
106              
107 6           void psMd5Final(psMd5_t *md5, unsigned char hash[MD5_HASHLEN])
108             {
109             int32 i;
110              
111             # ifndef HAVE_NATIVE_INT64
112             uint32 n;
113             # endif
114              
115             # ifdef CRYPTO_ASSERT
116             psAssert(md5);
117             # endif
118              
119             /* If output parameter is NULL, just clear the context */
120 6 50         if (!hash)
121             {
122 0           goto L_CLEAR;
123             }
124             /* increase the length of the message */
125             # ifdef HAVE_NATIVE_INT64
126 6           md5->length += md5->curlen << 3;
127             # else
128             n = (md5->lengthLo + (md5->curlen << 3)) & 0xFFFFFFFFL;
129             if (n < md5->lengthLo)
130             {
131             md5->lengthHi++;
132             }
133             md5->lengthHi += (md5->curlen >> 29);
134             md5->lengthLo = n;
135             # endif /* HAVE_NATIVE_INT64 */
136              
137             /* append the '1' bit */
138 6           md5->buf[md5->curlen++] = 0x80;
139              
140             /*
141             if the length is currently above 56 bytes we append zeros then compress.
142             Then we can fall back to padding zeros and length encoding like normal.
143             */
144 6 50         if (md5->curlen > 56)
145             {
146 0 0         while (md5->curlen < 64)
147             {
148 0           md5->buf[md5->curlen++] = 0x0;
149             }
150 0           md5_compress(md5);
151 0           md5->curlen = 0;
152             }
153             /* pad up to 56 bytes of zeroes */
154 222 100         while (md5->curlen < 56)
155             {
156 216           md5->buf[md5->curlen++] = 0x0;
157             }
158             /* store length */
159             # ifdef HAVE_NATIVE_INT64
160 6           STORE64L(md5->length, md5->buf + 56);
161             # else
162             STORE32L(md5->lengthLo, md5->buf + 56);
163             STORE32L(md5->lengthHi, md5->buf + 60);
164             # endif /* HAVE_NATIVE_INT64 */
165 6           md5_compress(md5);
166              
167             /* copy output */
168 30 100         for (i = 0; i < 4; i++)
169             {
170 24           STORE32L(md5->state[i], hash + (4 * i));
171             }
172             L_CLEAR:
173 6           memset(md5, 0x0, sizeof(psMd5_t));
174 6           }
175              
176             /******************************************************************************/
177              
178             # define F(x, y, z) (z ^ (x & (y ^ z)))
179             # define G(x, y, z) (y ^ (z & (y ^ x)))
180             # define H(x, y, z) (x ^ y ^ z)
181             # define I(x, y, z) (y ^ (x | (~z)))
182              
183             # ifndef PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE
184              
185             # define FF(a, b, c, d, M, s, t) \
186             a = (a + F(b, c, d) + M + t); a = ROL(a, s) + b;
187              
188             # define GG(a, b, c, d, M, s, t) \
189             a = (a + G(b, c, d) + M + t); a = ROL(a, s) + b;
190              
191             # define HH(a, b, c, d, M, s, t) \
192             a = (a + H(b, c, d) + M + t); a = ROL(a, s) + b;
193              
194             # define II(a, b, c, d, M, s, t) \
195             a = (a + I(b, c, d) + M + t); a = ROL(a, s) + b;
196              
197             static const unsigned char Worder[64] = {
198             0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
199             1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,
200             5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,
201             0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9
202             };
203              
204             static const unsigned char Rorder[64] = {
205             7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
206             5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
207             4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
208             6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
209             };
210              
211             static const uint32 Korder[] = {
212             0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL,
213             0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
214             0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL,
215             0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
216             0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL,
217             0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
218             0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL,
219             0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
220             0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL,
221             0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
222             0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL,
223             0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
224             0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL,
225             0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
226             0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL,
227             0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL,
228             0xe1f27f3aUL, 0xf5710fb0UL, 0xada0e5c4UL, 0x98e4c919UL
229             };
230             # else /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
231              
232             # define FF(a, b, c, d, M, s, t) \
233             a = (a + F(b, c, d) + M + t); a = ROL(a, s) + b;
234              
235             # define GG(a, b, c, d, M, s, t) \
236             a = (a + G(b, c, d) + M + t); a = ROL(a, s) + b;
237              
238             # define HH(a, b, c, d, M, s, t) \
239             a = (a + H(b, c, d) + M + t); a = ROL(a, s) + b;
240              
241             # define II(a, b, c, d, M, s, t) \
242             a = (a + I(b, c, d) + M + t); a = ROL(a, s) + b;
243              
244             # endif /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
245              
246             # ifdef USE_BURN_STACK
247 70933           static void _md5_compress(psMd5_t *md5)
248             # else
249             static void md5_compress(psMd5_t *md5)
250             # endif /* USE_BURN_STACK */
251             {
252             uint32 i, W[16], a, b, c, d;
253              
254             # ifndef PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE
255             uint32 t;
256             # endif
257             # ifdef CRYPTO_ASSERT
258             psAssert(md5 != NULL);
259             # endif
260              
261             /* copy the state into 512-bits into W[0..15] */
262 1205861 100         for (i = 0; i < 16; i++)
263             {
264 1134928           LOAD32L(W[i], md5->buf + (4 * i));
265             }
266              
267             /* copy state */
268 70933           a = md5->state[0];
269 70933           b = md5->state[1];
270 70933           c = md5->state[2];
271 70933           d = md5->state[3];
272              
273             # ifndef PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE
274             for (i = 0; i < 16; ++i)
275             {
276             FF(a, b, c, d, W[Worder[i]], Rorder[i], Korder[i]);
277             t = d; d = c; c = b; b = a; a = t;
278             }
279              
280             for (; i < 32; ++i)
281             {
282             GG(a, b, c, d, W[Worder[i]], Rorder[i], Korder[i]);
283             t = d; d = c; c = b; b = a; a = t;
284             }
285              
286             for (; i < 48; ++i)
287             {
288             HH(a, b, c, d, W[Worder[i]], Rorder[i], Korder[i]);
289             t = d; d = c; c = b; b = a; a = t;
290             }
291              
292             for (; i < 64; ++i)
293             {
294             II(a, b, c, d, W[Worder[i]], Rorder[i], Korder[i]);
295             t = d; d = c; c = b; b = a; a = t;
296             }
297              
298             # else /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
299              
300 70933           FF(a, b, c, d, W[0], 7, 0xd76aa478UL)
301 70933           FF(d, a, b, c, W[1], 12, 0xe8c7b756UL)
302 70933           FF(c, d, a, b, W[2], 17, 0x242070dbUL)
303 70933           FF(b, c, d, a, W[3], 22, 0xc1bdceeeUL)
304 70933           FF(a, b, c, d, W[4], 7, 0xf57c0fafUL)
305 70933           FF(d, a, b, c, W[5], 12, 0x4787c62aUL)
306 70933           FF(c, d, a, b, W[6], 17, 0xa8304613UL)
307 70933           FF(b, c, d, a, W[7], 22, 0xfd469501UL)
308 70933           FF(a, b, c, d, W[8], 7, 0x698098d8UL)
309 70933           FF(d, a, b, c, W[9], 12, 0x8b44f7afUL)
310 70933           FF(c, d, a, b, W[10], 17, 0xffff5bb1UL)
311 70933           FF(b, c, d, a, W[11], 22, 0x895cd7beUL)
312 70933           FF(a, b, c, d, W[12], 7, 0x6b901122UL)
313 70933           FF(d, a, b, c, W[13], 12, 0xfd987193UL)
314 70933           FF(c, d, a, b, W[14], 17, 0xa679438eUL)
315 70933           FF(b, c, d, a, W[15], 22, 0x49b40821UL)
316 70933           GG(a, b, c, d, W[1], 5, 0xf61e2562UL)
317 70933           GG(d, a, b, c, W[6], 9, 0xc040b340UL)
318 70933           GG(c, d, a, b, W[11], 14, 0x265e5a51UL)
319 70933           GG(b, c, d, a, W[0], 20, 0xe9b6c7aaUL)
320 70933           GG(a, b, c, d, W[5], 5, 0xd62f105dUL)
321 70933           GG(d, a, b, c, W[10], 9, 0x02441453UL)
322 70933           GG(c, d, a, b, W[15], 14, 0xd8a1e681UL)
323 70933           GG(b, c, d, a, W[4], 20, 0xe7d3fbc8UL)
324 70933           GG(a, b, c, d, W[9], 5, 0x21e1cde6UL)
325 70933           GG(d, a, b, c, W[14], 9, 0xc33707d6UL)
326 70933           GG(c, d, a, b, W[3], 14, 0xf4d50d87UL)
327 70933           GG(b, c, d, a, W[8], 20, 0x455a14edUL)
328 70933           GG(a, b, c, d, W[13], 5, 0xa9e3e905UL)
329 70933           GG(d, a, b, c, W[2], 9, 0xfcefa3f8UL)
330 70933           GG(c, d, a, b, W[7], 14, 0x676f02d9UL)
331 70933           GG(b, c, d, a, W[12], 20, 0x8d2a4c8aUL)
332 70933           HH(a, b, c, d, W[5], 4, 0xfffa3942UL)
333 70933           HH(d, a, b, c, W[8], 11, 0x8771f681UL)
334 70933           HH(c, d, a, b, W[11], 16, 0x6d9d6122UL)
335 70933           HH(b, c, d, a, W[14], 23, 0xfde5380cUL)
336 70933           HH(a, b, c, d, W[1], 4, 0xa4beea44UL)
337 70933           HH(d, a, b, c, W[4], 11, 0x4bdecfa9UL)
338 70933           HH(c, d, a, b, W[7], 16, 0xf6bb4b60UL)
339 70933           HH(b, c, d, a, W[10], 23, 0xbebfbc70UL)
340 70933           HH(a, b, c, d, W[13], 4, 0x289b7ec6UL)
341 70933           HH(d, a, b, c, W[0], 11, 0xeaa127faUL)
342 70933           HH(c, d, a, b, W[3], 16, 0xd4ef3085UL)
343 70933           HH(b, c, d, a, W[6], 23, 0x04881d05UL)
344 70933           HH(a, b, c, d, W[9], 4, 0xd9d4d039UL)
345 70933           HH(d, a, b, c, W[12], 11, 0xe6db99e5UL)
346 70933           HH(c, d, a, b, W[15], 16, 0x1fa27cf8UL)
347 70933           HH(b, c, d, a, W[2], 23, 0xc4ac5665UL)
348 70933           II(a, b, c, d, W[0], 6, 0xf4292244UL)
349 70933           II(d, a, b, c, W[7], 10, 0x432aff97UL)
350 70933           II(c, d, a, b, W[14], 15, 0xab9423a7UL)
351 70933           II(b, c, d, a, W[5], 21, 0xfc93a039UL)
352 70933           II(a, b, c, d, W[12], 6, 0x655b59c3UL)
353 70933           II(d, a, b, c, W[3], 10, 0x8f0ccc92UL)
354 70933           II(c, d, a, b, W[10], 15, 0xffeff47dUL)
355 70933           II(b, c, d, a, W[1], 21, 0x85845dd1UL)
356 70933           II(a, b, c, d, W[8], 6, 0x6fa87e4fUL)
357 70933           II(d, a, b, c, W[15], 10, 0xfe2ce6e0UL)
358 70933           II(c, d, a, b, W[6], 15, 0xa3014314UL)
359 70933           II(b, c, d, a, W[13], 21, 0x4e0811a1UL)
360 70933           II(a, b, c, d, W[4], 6, 0xf7537e82UL)
361 70933           II(d, a, b, c, W[11], 10, 0xbd3af235UL)
362 70933           II(c, d, a, b, W[2], 15, 0x2ad7d2bbUL)
363 70933           II(b, c, d, a, W[9], 21, 0xeb86d391UL)
364             # endif /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
365              
366 70933           md5->state[0] = md5->state[0] + a;
367 70933           md5->state[1] = md5->state[1] + b;
368 70933           md5->state[2] = md5->state[2] + c;
369 70933           md5->state[3] = md5->state[3] + d;
370 70933           }
371              
372             # ifdef USE_BURN_STACK
373 70933           static void md5_compress(psMd5_t *md5)
374             {
375 70933           _md5_compress(md5);
376 70933           psBurnStack(sizeof(uint32) * 21);
377 70933           }
378             # endif /* USE_BURN_STACK */
379              
380             #endif /* USE_MATRIX_MD5 */
381             /******************************************************************************/
382