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