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 126292 100         while (len > 0)
73             {
74 98610           n = min(len, (64 - md5->curlen));
75 98610           memcpy(md5->buf + md5->curlen, buf, (size_t) n);
76 98610           md5->curlen += n;
77 98610           buf += n;
78 98610           len -= n;
79              
80             /* is 64 bytes full? */
81 98610 100         if (md5->curlen == 64)
82             {
83 70930           md5_compress(md5);
84             # ifdef HAVE_NATIVE_INT64
85 70930           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 70930           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 70936           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 1205912 100         for (i = 0; i < 16; i++)
263             {
264 1134976           LOAD32L(W[i], md5->buf + (4 * i));
265             }
266              
267             /* copy state */
268 70936           a = md5->state[0];
269 70936           b = md5->state[1];
270 70936           c = md5->state[2];
271 70936           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 70936           FF(a, b, c, d, W[0], 7, 0xd76aa478UL)
301 70936           FF(d, a, b, c, W[1], 12, 0xe8c7b756UL)
302 70936           FF(c, d, a, b, W[2], 17, 0x242070dbUL)
303 70936           FF(b, c, d, a, W[3], 22, 0xc1bdceeeUL)
304 70936           FF(a, b, c, d, W[4], 7, 0xf57c0fafUL)
305 70936           FF(d, a, b, c, W[5], 12, 0x4787c62aUL)
306 70936           FF(c, d, a, b, W[6], 17, 0xa8304613UL)
307 70936           FF(b, c, d, a, W[7], 22, 0xfd469501UL)
308 70936           FF(a, b, c, d, W[8], 7, 0x698098d8UL)
309 70936           FF(d, a, b, c, W[9], 12, 0x8b44f7afUL)
310 70936           FF(c, d, a, b, W[10], 17, 0xffff5bb1UL)
311 70936           FF(b, c, d, a, W[11], 22, 0x895cd7beUL)
312 70936           FF(a, b, c, d, W[12], 7, 0x6b901122UL)
313 70936           FF(d, a, b, c, W[13], 12, 0xfd987193UL)
314 70936           FF(c, d, a, b, W[14], 17, 0xa679438eUL)
315 70936           FF(b, c, d, a, W[15], 22, 0x49b40821UL)
316 70936           GG(a, b, c, d, W[1], 5, 0xf61e2562UL)
317 70936           GG(d, a, b, c, W[6], 9, 0xc040b340UL)
318 70936           GG(c, d, a, b, W[11], 14, 0x265e5a51UL)
319 70936           GG(b, c, d, a, W[0], 20, 0xe9b6c7aaUL)
320 70936           GG(a, b, c, d, W[5], 5, 0xd62f105dUL)
321 70936           GG(d, a, b, c, W[10], 9, 0x02441453UL)
322 70936           GG(c, d, a, b, W[15], 14, 0xd8a1e681UL)
323 70936           GG(b, c, d, a, W[4], 20, 0xe7d3fbc8UL)
324 70936           GG(a, b, c, d, W[9], 5, 0x21e1cde6UL)
325 70936           GG(d, a, b, c, W[14], 9, 0xc33707d6UL)
326 70936           GG(c, d, a, b, W[3], 14, 0xf4d50d87UL)
327 70936           GG(b, c, d, a, W[8], 20, 0x455a14edUL)
328 70936           GG(a, b, c, d, W[13], 5, 0xa9e3e905UL)
329 70936           GG(d, a, b, c, W[2], 9, 0xfcefa3f8UL)
330 70936           GG(c, d, a, b, W[7], 14, 0x676f02d9UL)
331 70936           GG(b, c, d, a, W[12], 20, 0x8d2a4c8aUL)
332 70936           HH(a, b, c, d, W[5], 4, 0xfffa3942UL)
333 70936           HH(d, a, b, c, W[8], 11, 0x8771f681UL)
334 70936           HH(c, d, a, b, W[11], 16, 0x6d9d6122UL)
335 70936           HH(b, c, d, a, W[14], 23, 0xfde5380cUL)
336 70936           HH(a, b, c, d, W[1], 4, 0xa4beea44UL)
337 70936           HH(d, a, b, c, W[4], 11, 0x4bdecfa9UL)
338 70936           HH(c, d, a, b, W[7], 16, 0xf6bb4b60UL)
339 70936           HH(b, c, d, a, W[10], 23, 0xbebfbc70UL)
340 70936           HH(a, b, c, d, W[13], 4, 0x289b7ec6UL)
341 70936           HH(d, a, b, c, W[0], 11, 0xeaa127faUL)
342 70936           HH(c, d, a, b, W[3], 16, 0xd4ef3085UL)
343 70936           HH(b, c, d, a, W[6], 23, 0x04881d05UL)
344 70936           HH(a, b, c, d, W[9], 4, 0xd9d4d039UL)
345 70936           HH(d, a, b, c, W[12], 11, 0xe6db99e5UL)
346 70936           HH(c, d, a, b, W[15], 16, 0x1fa27cf8UL)
347 70936           HH(b, c, d, a, W[2], 23, 0xc4ac5665UL)
348 70936           II(a, b, c, d, W[0], 6, 0xf4292244UL)
349 70936           II(d, a, b, c, W[7], 10, 0x432aff97UL)
350 70936           II(c, d, a, b, W[14], 15, 0xab9423a7UL)
351 70936           II(b, c, d, a, W[5], 21, 0xfc93a039UL)
352 70936           II(a, b, c, d, W[12], 6, 0x655b59c3UL)
353 70936           II(d, a, b, c, W[3], 10, 0x8f0ccc92UL)
354 70936           II(c, d, a, b, W[10], 15, 0xffeff47dUL)
355 70936           II(b, c, d, a, W[1], 21, 0x85845dd1UL)
356 70936           II(a, b, c, d, W[8], 6, 0x6fa87e4fUL)
357 70936           II(d, a, b, c, W[15], 10, 0xfe2ce6e0UL)
358 70936           II(c, d, a, b, W[6], 15, 0xa3014314UL)
359 70936           II(b, c, d, a, W[13], 21, 0x4e0811a1UL)
360 70936           II(a, b, c, d, W[4], 6, 0xf7537e82UL)
361 70936           II(d, a, b, c, W[11], 10, 0xbd3af235UL)
362 70936           II(c, d, a, b, W[2], 15, 0x2ad7d2bbUL)
363 70936           II(b, c, d, a, W[9], 21, 0xeb86d391UL)
364             # endif /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
365              
366 70936           md5->state[0] = md5->state[0] + a;
367 70936           md5->state[1] = md5->state[1] + b;
368 70936           md5->state[2] = md5->state[2] + c;
369 70936           md5->state[3] = md5->state[3] + d;
370 70936           }
371              
372             # ifdef USE_BURN_STACK
373 70936           static void md5_compress(psMd5_t *md5)
374             {
375 70936           _md5_compress(md5);
376 70936           psBurnStack(sizeof(uint32) * 21);
377 70936           }
378             # endif /* USE_BURN_STACK */
379              
380             #endif /* USE_MATRIX_MD5 */
381             /******************************************************************************/
382