xref: /optee_os/core/lib/libtomcrypt/src/hashes/md5.c (revision bc420748bfc44a9e09000a3966fc59e9e0219df4)
1 /*
2  * Copyright (c) 2001-2007, Tom St Denis
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
29  *
30  * LibTomCrypt is a library that provides various cryptographic
31  * algorithms in a highly modular and flexible manner.
32  *
33  * The library is free for all purposes without any express
34  * guarantee it works.
35  *
36  * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
37  */
38 #include "tomcrypt.h"
39 
40 
41 /**
42   @file md5.c
43   LTC_MD5 hash function by Tom St Denis
44 */
45 
46 #ifdef LTC_MD5
47 
48 const struct ltc_hash_descriptor md5_desc =
49 {
50     "md5",
51     3,
52     16,
53     64,
54 
55     /* OID */
56    { 1, 2, 840, 113549, 2, 5,  },
57    6,
58 
59     &md5_init,
60     &md5_process,
61     &md5_done,
62     &md5_test,
63     NULL
64 };
65 
66 #define F(x,y,z)  (z ^ (x & (y ^ z)))
67 #define G(x,y,z)  (y ^ (z & (y ^ x)))
68 #define H(x,y,z)  (x^y^z)
69 #define I(x,y,z)  (y^(x|(~z)))
70 
71 #ifdef LTC_SMALL_CODE
72 
73 #define FF(a,b,c,d,M,s,t) \
74     a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
75 
76 #define GG(a,b,c,d,M,s,t) \
77     a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
78 
79 #define HH(a,b,c,d,M,s,t) \
80     a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
81 
82 #define II(a,b,c,d,M,s,t) \
83     a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
84 
85 static const unsigned char Worder[64] = {
86    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
87    1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
88    5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
89    0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
90 };
91 
92 static const unsigned char Rorder[64] = {
93    7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
94    5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
95    4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
96    6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
97 };
98 
99 static const ulong32 Korder[64] = {
100 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
101 0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
102 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
103 0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
104 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
105 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
106 0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
107 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
108 };
109 
110 #else
111 
112 #define FF(a,b,c,d,M,s,t) \
113     a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
114 
115 #define GG(a,b,c,d,M,s,t) \
116     a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
117 
118 #define HH(a,b,c,d,M,s,t) \
119     a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
120 
121 #define II(a,b,c,d,M,s,t) \
122     a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
123 
124 
125 #endif
126 
127 #ifdef LTC_CLEAN_STACK
128 static int _md5_compress(hash_state *md, unsigned char *buf)
129 #else
130 static int  md5_compress(hash_state *md, unsigned char *buf)
131 #endif
132 {
133     ulong32 i, W[16], a, b, c, d;
134 #ifdef LTC_SMALL_CODE
135     ulong32 t;
136 #endif
137 
138     /* copy the state into 512-bits into W[0..15] */
139     for (i = 0; i < 16; i++) {
140         LOAD32L(W[i], buf + (4*i));
141     }
142 
143     /* copy state */
144     a = md->md5.state[0];
145     b = md->md5.state[1];
146     c = md->md5.state[2];
147     d = md->md5.state[3];
148 
149 #ifdef LTC_SMALL_CODE
150     for (i = 0; i < 16; ++i) {
151         FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
152         t = d; d = c; c = b; b = a; a = t;
153     }
154 
155     for (; i < 32; ++i) {
156         GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
157         t = d; d = c; c = b; b = a; a = t;
158     }
159 
160     for (; i < 48; ++i) {
161         HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
162         t = d; d = c; c = b; b = a; a = t;
163     }
164 
165     for (; i < 64; ++i) {
166         II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
167         t = d; d = c; c = b; b = a; a = t;
168     }
169 
170 #else
171     FF(a,b,c,d,W[0],7,0xd76aa478UL)
172     FF(d,a,b,c,W[1],12,0xe8c7b756UL)
173     FF(c,d,a,b,W[2],17,0x242070dbUL)
174     FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
175     FF(a,b,c,d,W[4],7,0xf57c0fafUL)
176     FF(d,a,b,c,W[5],12,0x4787c62aUL)
177     FF(c,d,a,b,W[6],17,0xa8304613UL)
178     FF(b,c,d,a,W[7],22,0xfd469501UL)
179     FF(a,b,c,d,W[8],7,0x698098d8UL)
180     FF(d,a,b,c,W[9],12,0x8b44f7afUL)
181     FF(c,d,a,b,W[10],17,0xffff5bb1UL)
182     FF(b,c,d,a,W[11],22,0x895cd7beUL)
183     FF(a,b,c,d,W[12],7,0x6b901122UL)
184     FF(d,a,b,c,W[13],12,0xfd987193UL)
185     FF(c,d,a,b,W[14],17,0xa679438eUL)
186     FF(b,c,d,a,W[15],22,0x49b40821UL)
187     GG(a,b,c,d,W[1],5,0xf61e2562UL)
188     GG(d,a,b,c,W[6],9,0xc040b340UL)
189     GG(c,d,a,b,W[11],14,0x265e5a51UL)
190     GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
191     GG(a,b,c,d,W[5],5,0xd62f105dUL)
192     GG(d,a,b,c,W[10],9,0x02441453UL)
193     GG(c,d,a,b,W[15],14,0xd8a1e681UL)
194     GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
195     GG(a,b,c,d,W[9],5,0x21e1cde6UL)
196     GG(d,a,b,c,W[14],9,0xc33707d6UL)
197     GG(c,d,a,b,W[3],14,0xf4d50d87UL)
198     GG(b,c,d,a,W[8],20,0x455a14edUL)
199     GG(a,b,c,d,W[13],5,0xa9e3e905UL)
200     GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
201     GG(c,d,a,b,W[7],14,0x676f02d9UL)
202     GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
203     HH(a,b,c,d,W[5],4,0xfffa3942UL)
204     HH(d,a,b,c,W[8],11,0x8771f681UL)
205     HH(c,d,a,b,W[11],16,0x6d9d6122UL)
206     HH(b,c,d,a,W[14],23,0xfde5380cUL)
207     HH(a,b,c,d,W[1],4,0xa4beea44UL)
208     HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
209     HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
210     HH(b,c,d,a,W[10],23,0xbebfbc70UL)
211     HH(a,b,c,d,W[13],4,0x289b7ec6UL)
212     HH(d,a,b,c,W[0],11,0xeaa127faUL)
213     HH(c,d,a,b,W[3],16,0xd4ef3085UL)
214     HH(b,c,d,a,W[6],23,0x04881d05UL)
215     HH(a,b,c,d,W[9],4,0xd9d4d039UL)
216     HH(d,a,b,c,W[12],11,0xe6db99e5UL)
217     HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
218     HH(b,c,d,a,W[2],23,0xc4ac5665UL)
219     II(a,b,c,d,W[0],6,0xf4292244UL)
220     II(d,a,b,c,W[7],10,0x432aff97UL)
221     II(c,d,a,b,W[14],15,0xab9423a7UL)
222     II(b,c,d,a,W[5],21,0xfc93a039UL)
223     II(a,b,c,d,W[12],6,0x655b59c3UL)
224     II(d,a,b,c,W[3],10,0x8f0ccc92UL)
225     II(c,d,a,b,W[10],15,0xffeff47dUL)
226     II(b,c,d,a,W[1],21,0x85845dd1UL)
227     II(a,b,c,d,W[8],6,0x6fa87e4fUL)
228     II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
229     II(c,d,a,b,W[6],15,0xa3014314UL)
230     II(b,c,d,a,W[13],21,0x4e0811a1UL)
231     II(a,b,c,d,W[4],6,0xf7537e82UL)
232     II(d,a,b,c,W[11],10,0xbd3af235UL)
233     II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
234     II(b,c,d,a,W[9],21,0xeb86d391UL)
235 #endif
236 
237     md->md5.state[0] = md->md5.state[0] + a;
238     md->md5.state[1] = md->md5.state[1] + b;
239     md->md5.state[2] = md->md5.state[2] + c;
240     md->md5.state[3] = md->md5.state[3] + d;
241 
242     return CRYPT_OK;
243 }
244 
245 #ifdef LTC_CLEAN_STACK
246 static int md5_compress(hash_state *md, unsigned char *buf)
247 {
248    int err;
249    err = _md5_compress(md, buf);
250    burn_stack(sizeof(ulong32) * 21);
251    return err;
252 }
253 #endif
254 
255 /**
256    Initialize the hash state
257    @param md   The hash state you wish to initialize
258    @return CRYPT_OK if successful
259 */
260 int md5_init(hash_state * md)
261 {
262    LTC_ARGCHK(md != NULL);
263    md->md5.state[0] = 0x67452301UL;
264    md->md5.state[1] = 0xefcdab89UL;
265    md->md5.state[2] = 0x98badcfeUL;
266    md->md5.state[3] = 0x10325476UL;
267    md->md5.curlen = 0;
268    md->md5.length = 0;
269    return CRYPT_OK;
270 }
271 
272 /**
273    Process a block of memory though the hash
274    @param md     The hash state
275    @param in     The data to hash
276    @param inlen  The length of the data (octets)
277    @return CRYPT_OK if successful
278 */
279 HASH_PROCESS(md5_process, md5_compress, md5, 64)
280 
281 /**
282    Terminate the hash to get the digest
283    @param md  The hash state
284    @param out [out] The destination of the hash (16 bytes)
285    @return CRYPT_OK if successful
286 */
287 int md5_done(hash_state * md, unsigned char *out)
288 {
289     int i;
290 
291     LTC_ARGCHK(md  != NULL);
292     LTC_ARGCHK(out != NULL);
293 
294     if (md->md5.curlen >= sizeof(md->md5.buf)) {
295        return CRYPT_INVALID_ARG;
296     }
297 
298 
299     /* increase the length of the message */
300     md->md5.length += md->md5.curlen * 8;
301 
302     /* append the '1' bit */
303     md->md5.buf[md->md5.curlen++] = (unsigned char)0x80;
304 
305     /* if the length is currently above 56 bytes we append zeros
306      * then compress.  Then we can fall back to padding zeros and length
307      * encoding like normal.
308      */
309     if (md->md5.curlen > 56) {
310         while (md->md5.curlen < 64) {
311             md->md5.buf[md->md5.curlen++] = (unsigned char)0;
312         }
313         md5_compress(md, md->md5.buf);
314         md->md5.curlen = 0;
315     }
316 
317     /* pad upto 56 bytes of zeroes */
318     while (md->md5.curlen < 56) {
319         md->md5.buf[md->md5.curlen++] = (unsigned char)0;
320     }
321 
322     /* store length */
323     STORE64L(md->md5.length, md->md5.buf+56);
324     md5_compress(md, md->md5.buf);
325 
326     /* copy output */
327     for (i = 0; i < 4; i++) {
328         STORE32L(md->md5.state[i], out+(4*i));
329     }
330 #ifdef LTC_CLEAN_STACK
331     zeromem(md, sizeof(hash_state));
332 #endif
333     return CRYPT_OK;
334 }
335 
336 /**
337   Self-test the hash
338   @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
339 */
340 int  md5_test(void)
341 {
342  #ifndef LTC_TEST
343     return CRYPT_NOP;
344  #else
345   static const struct {
346       const char *msg;
347       unsigned char hash[16];
348   } tests[] = {
349     { "",
350       { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
351         0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
352     { "a",
353       {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
354        0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
355     { "abc",
356       { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
357         0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
358     { "message digest",
359       { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
360         0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
361     { "abcdefghijklmnopqrstuvwxyz",
362       { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
363         0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
364     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
365       { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
366         0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
367     { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
368       { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
369         0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } },
370     { NULL, { 0 } }
371   };
372 
373   int i;
374   unsigned char tmp[16];
375   hash_state md;
376 
377   for (i = 0; tests[i].msg != NULL; i++) {
378       md5_init(&md);
379       md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
380       md5_done(&md, tmp);
381       if (XMEMCMP(tmp, tests[i].hash, 16) != 0) {
382          return CRYPT_FAIL_TESTVECTOR;
383       }
384   }
385   return CRYPT_OK;
386  #endif
387 }
388 
389 #endif
390 
391 
392 
393 /* $Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */
394 /* $Revision: 1.10 $ */
395 /* $Date: 2007/05/12 14:25:28 $ */
396