xref: /optee_os/core/lib/libtomcrypt/src/hashes/md5.c (revision 8411e6ad673d20c4742ed30c785e3f5cdea54dfa)
1*8411e6adSJerome Forissier /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2*8411e6adSJerome Forissier /* SPDX-License-Identifier: Unlicense */
35a913ee7SJerome Forissier #include "tomcrypt_private.h"
4b0104773SPascal Brand 
5b0104773SPascal Brand 
6b0104773SPascal Brand /**
7b0104773SPascal Brand   @file md5.c
8b0104773SPascal Brand   LTC_MD5 hash function by Tom St Denis
9b0104773SPascal Brand */
10b0104773SPascal Brand 
11b0104773SPascal Brand #ifdef LTC_MD5
12b0104773SPascal Brand 
13b0104773SPascal Brand const struct ltc_hash_descriptor md5_desc =
14b0104773SPascal Brand {
15b0104773SPascal Brand     "md5",
16b0104773SPascal Brand     3,
17b0104773SPascal Brand     16,
18b0104773SPascal Brand     64,
19b0104773SPascal Brand 
20b0104773SPascal Brand     /* OID */
21b0104773SPascal Brand    { 1, 2, 840, 113549, 2, 5,  },
22b0104773SPascal Brand    6,
23b0104773SPascal Brand 
24b0104773SPascal Brand     &md5_init,
25b0104773SPascal Brand     &md5_process,
26b0104773SPascal Brand     &md5_done,
27b0104773SPascal Brand     &md5_test,
28b0104773SPascal Brand     NULL
29b0104773SPascal Brand };
30b0104773SPascal Brand 
31b0104773SPascal Brand #define F(x,y,z)  (z ^ (x & (y ^ z)))
32b0104773SPascal Brand #define G(x,y,z)  (y ^ (z & (y ^ x)))
33b0104773SPascal Brand #define H(x,y,z)  (x^y^z)
34b0104773SPascal Brand #define I(x,y,z)  (y^(x|(~z)))
35b0104773SPascal Brand 
36b0104773SPascal Brand #ifdef LTC_SMALL_CODE
37b0104773SPascal Brand 
38b0104773SPascal Brand #define FF(a,b,c,d,M,s,t) \
39b0104773SPascal Brand     a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
40b0104773SPascal Brand 
41b0104773SPascal Brand #define GG(a,b,c,d,M,s,t) \
42b0104773SPascal Brand     a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
43b0104773SPascal Brand 
44b0104773SPascal Brand #define HH(a,b,c,d,M,s,t) \
45b0104773SPascal Brand     a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
46b0104773SPascal Brand 
47b0104773SPascal Brand #define II(a,b,c,d,M,s,t) \
48b0104773SPascal Brand     a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
49b0104773SPascal Brand 
50b0104773SPascal Brand static const unsigned char Worder[64] = {
51b0104773SPascal Brand    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
52b0104773SPascal Brand    1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
53b0104773SPascal Brand    5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
54b0104773SPascal Brand    0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
55b0104773SPascal Brand };
56b0104773SPascal Brand 
57b0104773SPascal Brand static const unsigned char Rorder[64] = {
58b0104773SPascal Brand    7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
59b0104773SPascal Brand    5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
60b0104773SPascal Brand    4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
61b0104773SPascal Brand    6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
62b0104773SPascal Brand };
63b0104773SPascal Brand 
64b0104773SPascal Brand static const ulong32 Korder[64] = {
65b0104773SPascal Brand 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
66b0104773SPascal Brand 0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
67b0104773SPascal Brand 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
68b0104773SPascal Brand 0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
69b0104773SPascal Brand 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
70b0104773SPascal Brand 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
71b0104773SPascal Brand 0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
72b0104773SPascal Brand 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
73b0104773SPascal Brand };
74b0104773SPascal Brand 
75b0104773SPascal Brand #else
76b0104773SPascal Brand 
77b0104773SPascal Brand #define FF(a,b,c,d,M,s,t) \
78b0104773SPascal Brand     a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
79b0104773SPascal Brand 
80b0104773SPascal Brand #define GG(a,b,c,d,M,s,t) \
81b0104773SPascal Brand     a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
82b0104773SPascal Brand 
83b0104773SPascal Brand #define HH(a,b,c,d,M,s,t) \
84b0104773SPascal Brand     a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
85b0104773SPascal Brand 
86b0104773SPascal Brand #define II(a,b,c,d,M,s,t) \
87b0104773SPascal Brand     a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
88b0104773SPascal Brand 
89b0104773SPascal Brand 
90b0104773SPascal Brand #endif
91b0104773SPascal Brand 
92b0104773SPascal Brand #ifdef LTC_CLEAN_STACK
ss_md5_compress(hash_state * md,const unsigned char * buf)93*8411e6adSJerome Forissier static int ss_md5_compress(hash_state *md, const unsigned char *buf)
94b0104773SPascal Brand #else
95*8411e6adSJerome Forissier static int  s_md5_compress(hash_state *md, const unsigned char *buf)
96b0104773SPascal Brand #endif
97b0104773SPascal Brand {
98b0104773SPascal Brand     ulong32 i, W[16], a, b, c, d;
99b0104773SPascal Brand #ifdef LTC_SMALL_CODE
100b0104773SPascal Brand     ulong32 t;
101b0104773SPascal Brand #endif
102b0104773SPascal Brand 
103b0104773SPascal Brand     /* copy the state into 512-bits into W[0..15] */
104b0104773SPascal Brand     for (i = 0; i < 16; i++) {
105b0104773SPascal Brand         LOAD32L(W[i], buf + (4*i));
106b0104773SPascal Brand     }
107b0104773SPascal Brand 
108b0104773SPascal Brand     /* copy state */
109b0104773SPascal Brand     a = md->md5.state[0];
110b0104773SPascal Brand     b = md->md5.state[1];
111b0104773SPascal Brand     c = md->md5.state[2];
112b0104773SPascal Brand     d = md->md5.state[3];
113b0104773SPascal Brand 
114b0104773SPascal Brand #ifdef LTC_SMALL_CODE
115b0104773SPascal Brand     for (i = 0; i < 16; ++i) {
116b0104773SPascal Brand         FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
117b0104773SPascal Brand         t = d; d = c; c = b; b = a; a = t;
118b0104773SPascal Brand     }
119b0104773SPascal Brand 
120b0104773SPascal Brand     for (; i < 32; ++i) {
121b0104773SPascal Brand         GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
122b0104773SPascal Brand         t = d; d = c; c = b; b = a; a = t;
123b0104773SPascal Brand     }
124b0104773SPascal Brand 
125b0104773SPascal Brand     for (; i < 48; ++i) {
126b0104773SPascal Brand         HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
127b0104773SPascal Brand         t = d; d = c; c = b; b = a; a = t;
128b0104773SPascal Brand     }
129b0104773SPascal Brand 
130b0104773SPascal Brand     for (; i < 64; ++i) {
131b0104773SPascal Brand         II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
132b0104773SPascal Brand         t = d; d = c; c = b; b = a; a = t;
133b0104773SPascal Brand     }
134b0104773SPascal Brand 
135b0104773SPascal Brand #else
136b0104773SPascal Brand     FF(a,b,c,d,W[0],7,0xd76aa478UL)
137b0104773SPascal Brand     FF(d,a,b,c,W[1],12,0xe8c7b756UL)
138b0104773SPascal Brand     FF(c,d,a,b,W[2],17,0x242070dbUL)
139b0104773SPascal Brand     FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
140b0104773SPascal Brand     FF(a,b,c,d,W[4],7,0xf57c0fafUL)
141b0104773SPascal Brand     FF(d,a,b,c,W[5],12,0x4787c62aUL)
142b0104773SPascal Brand     FF(c,d,a,b,W[6],17,0xa8304613UL)
143b0104773SPascal Brand     FF(b,c,d,a,W[7],22,0xfd469501UL)
144b0104773SPascal Brand     FF(a,b,c,d,W[8],7,0x698098d8UL)
145b0104773SPascal Brand     FF(d,a,b,c,W[9],12,0x8b44f7afUL)
146b0104773SPascal Brand     FF(c,d,a,b,W[10],17,0xffff5bb1UL)
147b0104773SPascal Brand     FF(b,c,d,a,W[11],22,0x895cd7beUL)
148b0104773SPascal Brand     FF(a,b,c,d,W[12],7,0x6b901122UL)
149b0104773SPascal Brand     FF(d,a,b,c,W[13],12,0xfd987193UL)
150b0104773SPascal Brand     FF(c,d,a,b,W[14],17,0xa679438eUL)
151b0104773SPascal Brand     FF(b,c,d,a,W[15],22,0x49b40821UL)
152b0104773SPascal Brand     GG(a,b,c,d,W[1],5,0xf61e2562UL)
153b0104773SPascal Brand     GG(d,a,b,c,W[6],9,0xc040b340UL)
154b0104773SPascal Brand     GG(c,d,a,b,W[11],14,0x265e5a51UL)
155b0104773SPascal Brand     GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
156b0104773SPascal Brand     GG(a,b,c,d,W[5],5,0xd62f105dUL)
157b0104773SPascal Brand     GG(d,a,b,c,W[10],9,0x02441453UL)
158b0104773SPascal Brand     GG(c,d,a,b,W[15],14,0xd8a1e681UL)
159b0104773SPascal Brand     GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
160b0104773SPascal Brand     GG(a,b,c,d,W[9],5,0x21e1cde6UL)
161b0104773SPascal Brand     GG(d,a,b,c,W[14],9,0xc33707d6UL)
162b0104773SPascal Brand     GG(c,d,a,b,W[3],14,0xf4d50d87UL)
163b0104773SPascal Brand     GG(b,c,d,a,W[8],20,0x455a14edUL)
164b0104773SPascal Brand     GG(a,b,c,d,W[13],5,0xa9e3e905UL)
165b0104773SPascal Brand     GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
166b0104773SPascal Brand     GG(c,d,a,b,W[7],14,0x676f02d9UL)
167b0104773SPascal Brand     GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
168b0104773SPascal Brand     HH(a,b,c,d,W[5],4,0xfffa3942UL)
169b0104773SPascal Brand     HH(d,a,b,c,W[8],11,0x8771f681UL)
170b0104773SPascal Brand     HH(c,d,a,b,W[11],16,0x6d9d6122UL)
171b0104773SPascal Brand     HH(b,c,d,a,W[14],23,0xfde5380cUL)
172b0104773SPascal Brand     HH(a,b,c,d,W[1],4,0xa4beea44UL)
173b0104773SPascal Brand     HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
174b0104773SPascal Brand     HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
175b0104773SPascal Brand     HH(b,c,d,a,W[10],23,0xbebfbc70UL)
176b0104773SPascal Brand     HH(a,b,c,d,W[13],4,0x289b7ec6UL)
177b0104773SPascal Brand     HH(d,a,b,c,W[0],11,0xeaa127faUL)
178b0104773SPascal Brand     HH(c,d,a,b,W[3],16,0xd4ef3085UL)
179b0104773SPascal Brand     HH(b,c,d,a,W[6],23,0x04881d05UL)
180b0104773SPascal Brand     HH(a,b,c,d,W[9],4,0xd9d4d039UL)
181b0104773SPascal Brand     HH(d,a,b,c,W[12],11,0xe6db99e5UL)
182b0104773SPascal Brand     HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
183b0104773SPascal Brand     HH(b,c,d,a,W[2],23,0xc4ac5665UL)
184b0104773SPascal Brand     II(a,b,c,d,W[0],6,0xf4292244UL)
185b0104773SPascal Brand     II(d,a,b,c,W[7],10,0x432aff97UL)
186b0104773SPascal Brand     II(c,d,a,b,W[14],15,0xab9423a7UL)
187b0104773SPascal Brand     II(b,c,d,a,W[5],21,0xfc93a039UL)
188b0104773SPascal Brand     II(a,b,c,d,W[12],6,0x655b59c3UL)
189b0104773SPascal Brand     II(d,a,b,c,W[3],10,0x8f0ccc92UL)
190b0104773SPascal Brand     II(c,d,a,b,W[10],15,0xffeff47dUL)
191b0104773SPascal Brand     II(b,c,d,a,W[1],21,0x85845dd1UL)
192b0104773SPascal Brand     II(a,b,c,d,W[8],6,0x6fa87e4fUL)
193b0104773SPascal Brand     II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
194b0104773SPascal Brand     II(c,d,a,b,W[6],15,0xa3014314UL)
195b0104773SPascal Brand     II(b,c,d,a,W[13],21,0x4e0811a1UL)
196b0104773SPascal Brand     II(a,b,c,d,W[4],6,0xf7537e82UL)
197b0104773SPascal Brand     II(d,a,b,c,W[11],10,0xbd3af235UL)
198b0104773SPascal Brand     II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
199b0104773SPascal Brand     II(b,c,d,a,W[9],21,0xeb86d391UL)
200b0104773SPascal Brand #endif
201b0104773SPascal Brand 
202b0104773SPascal Brand     md->md5.state[0] = md->md5.state[0] + a;
203b0104773SPascal Brand     md->md5.state[1] = md->md5.state[1] + b;
204b0104773SPascal Brand     md->md5.state[2] = md->md5.state[2] + c;
205b0104773SPascal Brand     md->md5.state[3] = md->md5.state[3] + d;
206b0104773SPascal Brand 
207b0104773SPascal Brand     return CRYPT_OK;
208b0104773SPascal Brand }
209b0104773SPascal Brand 
210b0104773SPascal Brand #ifdef LTC_CLEAN_STACK
s_md5_compress(hash_state * md,const unsigned char * buf)211*8411e6adSJerome Forissier static int s_md5_compress(hash_state *md, const unsigned char *buf)
212b0104773SPascal Brand {
213b0104773SPascal Brand    int err;
214*8411e6adSJerome Forissier    err = ss_md5_compress(md, buf);
215b0104773SPascal Brand    burn_stack(sizeof(ulong32) * 21);
216b0104773SPascal Brand    return err;
217b0104773SPascal Brand }
218b0104773SPascal Brand #endif
219b0104773SPascal Brand 
220b0104773SPascal Brand /**
221b0104773SPascal Brand    Initialize the hash state
222b0104773SPascal Brand    @param md   The hash state you wish to initialize
223b0104773SPascal Brand    @return CRYPT_OK if successful
224b0104773SPascal Brand */
md5_init(hash_state * md)225b0104773SPascal Brand int md5_init(hash_state * md)
226b0104773SPascal Brand {
227b0104773SPascal Brand    LTC_ARGCHK(md != NULL);
228b0104773SPascal Brand    md->md5.state[0] = 0x67452301UL;
229b0104773SPascal Brand    md->md5.state[1] = 0xefcdab89UL;
230b0104773SPascal Brand    md->md5.state[2] = 0x98badcfeUL;
231b0104773SPascal Brand    md->md5.state[3] = 0x10325476UL;
232b0104773SPascal Brand    md->md5.curlen = 0;
233b0104773SPascal Brand    md->md5.length = 0;
234b0104773SPascal Brand    return CRYPT_OK;
235b0104773SPascal Brand }
236b0104773SPascal Brand 
237b0104773SPascal Brand /**
238b0104773SPascal Brand    Process a block of memory though the hash
239b0104773SPascal Brand    @param md     The hash state
240b0104773SPascal Brand    @param in     The data to hash
241b0104773SPascal Brand    @param inlen  The length of the data (octets)
242b0104773SPascal Brand    @return CRYPT_OK if successful
243b0104773SPascal Brand */
244*8411e6adSJerome Forissier HASH_PROCESS(md5_process, s_md5_compress, md5, 64)
245b0104773SPascal Brand 
246b0104773SPascal Brand /**
247b0104773SPascal Brand    Terminate the hash to get the digest
248b0104773SPascal Brand    @param md  The hash state
249b0104773SPascal Brand    @param out [out] The destination of the hash (16 bytes)
250b0104773SPascal Brand    @return CRYPT_OK if successful
251b0104773SPascal Brand */
md5_done(hash_state * md,unsigned char * out)252b0104773SPascal Brand int md5_done(hash_state * md, unsigned char *out)
253b0104773SPascal Brand {
254b0104773SPascal Brand     int i;
255b0104773SPascal Brand 
256b0104773SPascal Brand     LTC_ARGCHK(md  != NULL);
257b0104773SPascal Brand     LTC_ARGCHK(out != NULL);
258b0104773SPascal Brand 
259b0104773SPascal Brand     if (md->md5.curlen >= sizeof(md->md5.buf)) {
260b0104773SPascal Brand        return CRYPT_INVALID_ARG;
261b0104773SPascal Brand     }
262b0104773SPascal Brand 
263b0104773SPascal Brand 
264b0104773SPascal Brand     /* increase the length of the message */
265b0104773SPascal Brand     md->md5.length += md->md5.curlen * 8;
266b0104773SPascal Brand 
267b0104773SPascal Brand     /* append the '1' bit */
268b0104773SPascal Brand     md->md5.buf[md->md5.curlen++] = (unsigned char)0x80;
269b0104773SPascal Brand 
270b0104773SPascal Brand     /* if the length is currently above 56 bytes we append zeros
271b0104773SPascal Brand      * then compress.  Then we can fall back to padding zeros and length
272b0104773SPascal Brand      * encoding like normal.
273b0104773SPascal Brand      */
274b0104773SPascal Brand     if (md->md5.curlen > 56) {
275b0104773SPascal Brand         while (md->md5.curlen < 64) {
276b0104773SPascal Brand             md->md5.buf[md->md5.curlen++] = (unsigned char)0;
277b0104773SPascal Brand         }
278*8411e6adSJerome Forissier         s_md5_compress(md, md->md5.buf);
279b0104773SPascal Brand         md->md5.curlen = 0;
280b0104773SPascal Brand     }
281b0104773SPascal Brand 
282b0104773SPascal Brand     /* pad upto 56 bytes of zeroes */
283b0104773SPascal Brand     while (md->md5.curlen < 56) {
284b0104773SPascal Brand         md->md5.buf[md->md5.curlen++] = (unsigned char)0;
285b0104773SPascal Brand     }
286b0104773SPascal Brand 
287b0104773SPascal Brand     /* store length */
288b0104773SPascal Brand     STORE64L(md->md5.length, md->md5.buf+56);
289*8411e6adSJerome Forissier     s_md5_compress(md, md->md5.buf);
290b0104773SPascal Brand 
291b0104773SPascal Brand     /* copy output */
292b0104773SPascal Brand     for (i = 0; i < 4; i++) {
293b0104773SPascal Brand         STORE32L(md->md5.state[i], out+(4*i));
294b0104773SPascal Brand     }
295b0104773SPascal Brand #ifdef LTC_CLEAN_STACK
296b0104773SPascal Brand     zeromem(md, sizeof(hash_state));
297b0104773SPascal Brand #endif
298b0104773SPascal Brand     return CRYPT_OK;
299b0104773SPascal Brand }
300b0104773SPascal Brand 
301b0104773SPascal Brand /**
302b0104773SPascal Brand   Self-test the hash
303b0104773SPascal Brand   @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
304b0104773SPascal Brand */
md5_test(void)305b0104773SPascal Brand int  md5_test(void)
306b0104773SPascal Brand {
307b0104773SPascal Brand  #ifndef LTC_TEST
308b0104773SPascal Brand     return CRYPT_NOP;
309b0104773SPascal Brand  #else
310b0104773SPascal Brand   static const struct {
311b0104773SPascal Brand       const char *msg;
312b0104773SPascal Brand       unsigned char hash[16];
313b0104773SPascal Brand   } tests[] = {
314b0104773SPascal Brand     { "",
315b0104773SPascal Brand       { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
316b0104773SPascal Brand         0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
317b0104773SPascal Brand     { "a",
318b0104773SPascal Brand       {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
319b0104773SPascal Brand        0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
320b0104773SPascal Brand     { "abc",
321b0104773SPascal Brand       { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
322b0104773SPascal Brand         0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
323b0104773SPascal Brand     { "message digest",
324b0104773SPascal Brand       { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
325b0104773SPascal Brand         0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
326b0104773SPascal Brand     { "abcdefghijklmnopqrstuvwxyz",
327b0104773SPascal Brand       { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
328b0104773SPascal Brand         0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
329b0104773SPascal Brand     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
330b0104773SPascal Brand       { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
331b0104773SPascal Brand         0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
332b0104773SPascal Brand     { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
333b0104773SPascal Brand       { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
334b0104773SPascal Brand         0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } },
335b0104773SPascal Brand     { NULL, { 0 } }
336b0104773SPascal Brand   };
337b0104773SPascal Brand 
338b0104773SPascal Brand   int i;
339b0104773SPascal Brand   unsigned char tmp[16];
340b0104773SPascal Brand   hash_state md;
341b0104773SPascal Brand 
342b0104773SPascal Brand   for (i = 0; tests[i].msg != NULL; i++) {
343b0104773SPascal Brand       md5_init(&md);
344*8411e6adSJerome Forissier       md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)XSTRLEN(tests[i].msg));
345b0104773SPascal Brand       md5_done(&md, tmp);
3465a913ee7SJerome Forissier       if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "MD5", i)) {
347b0104773SPascal Brand          return CRYPT_FAIL_TESTVECTOR;
348b0104773SPascal Brand       }
349b0104773SPascal Brand   }
350b0104773SPascal Brand   return CRYPT_OK;
351b0104773SPascal Brand  #endif
352b0104773SPascal Brand }
353b0104773SPascal Brand 
354b0104773SPascal Brand #endif
355b0104773SPascal Brand 
356b0104773SPascal Brand 
357