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