xref: /openbsd-src/lib/libcrypto/md5/md5.c (revision 82ab76e10ac26541f6a2ebe5efefdab07fb8df8c)
1*82ab76e1Sjsing /* $OpenBSD: md5.c,v 1.25 2025/01/24 13:35:04 jsing Exp $ */
2aeaa0e53Sjsing /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3aeaa0e53Sjsing  * All rights reserved.
4aeaa0e53Sjsing  *
5aeaa0e53Sjsing  * This package is an SSL implementation written
6aeaa0e53Sjsing  * by Eric Young (eay@cryptsoft.com).
7aeaa0e53Sjsing  * The implementation was written so as to conform with Netscapes SSL.
8aeaa0e53Sjsing  *
9aeaa0e53Sjsing  * This library is free for commercial and non-commercial use as long as
10aeaa0e53Sjsing  * the following conditions are aheared to.  The following conditions
11aeaa0e53Sjsing  * apply to all code found in this distribution, be it the RC4, RSA,
12aeaa0e53Sjsing  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13aeaa0e53Sjsing  * included with this distribution is covered by the same copyright terms
14aeaa0e53Sjsing  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15aeaa0e53Sjsing  *
16aeaa0e53Sjsing  * Copyright remains Eric Young's, and as such any Copyright notices in
17aeaa0e53Sjsing  * the code are not to be removed.
18aeaa0e53Sjsing  * If this package is used in a product, Eric Young should be given attribution
19aeaa0e53Sjsing  * as the author of the parts of the library used.
20aeaa0e53Sjsing  * This can be in the form of a textual message at program startup or
21aeaa0e53Sjsing  * in documentation (online or textual) provided with the package.
22aeaa0e53Sjsing  *
23aeaa0e53Sjsing  * Redistribution and use in source and binary forms, with or without
24aeaa0e53Sjsing  * modification, are permitted provided that the following conditions
25aeaa0e53Sjsing  * are met:
26aeaa0e53Sjsing  * 1. Redistributions of source code must retain the copyright
27aeaa0e53Sjsing  *    notice, this list of conditions and the following disclaimer.
28aeaa0e53Sjsing  * 2. Redistributions in binary form must reproduce the above copyright
29aeaa0e53Sjsing  *    notice, this list of conditions and the following disclaimer in the
30aeaa0e53Sjsing  *    documentation and/or other materials provided with the distribution.
31aeaa0e53Sjsing  * 3. All advertising materials mentioning features or use of this software
32aeaa0e53Sjsing  *    must display the following acknowledgement:
33aeaa0e53Sjsing  *    "This product includes cryptographic software written by
34aeaa0e53Sjsing  *     Eric Young (eay@cryptsoft.com)"
35aeaa0e53Sjsing  *    The word 'cryptographic' can be left out if the rouines from the library
36aeaa0e53Sjsing  *    being used are not cryptographic related :-).
37aeaa0e53Sjsing  * 4. If you include any Windows specific code (or a derivative thereof) from
38aeaa0e53Sjsing  *    the apps directory (application code) you must include an acknowledgement:
39aeaa0e53Sjsing  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40aeaa0e53Sjsing  *
41aeaa0e53Sjsing  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42aeaa0e53Sjsing  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43aeaa0e53Sjsing  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44aeaa0e53Sjsing  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45aeaa0e53Sjsing  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46aeaa0e53Sjsing  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47aeaa0e53Sjsing  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48aeaa0e53Sjsing  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49aeaa0e53Sjsing  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50aeaa0e53Sjsing  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51aeaa0e53Sjsing  * SUCH DAMAGE.
52aeaa0e53Sjsing  *
53aeaa0e53Sjsing  * The licence and distribution terms for any publically available version or
54aeaa0e53Sjsing  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55aeaa0e53Sjsing  * copied and put under another distribution licence
56aeaa0e53Sjsing  * [including the GNU Public Licence.]
57aeaa0e53Sjsing  */
58aeaa0e53Sjsing 
59aeaa0e53Sjsing #include <stdio.h>
601b759115Sjsing #include <stdint.h>
61aeaa0e53Sjsing #include <stdlib.h>
62aeaa0e53Sjsing #include <string.h>
63aeaa0e53Sjsing 
64aeaa0e53Sjsing #include <openssl/opensslconf.h>
65aeaa0e53Sjsing 
66aeaa0e53Sjsing #include <openssl/md5.h>
67aeaa0e53Sjsing 
68f4c5b171Sjsing #include "crypto_internal.h"
69f4c5b171Sjsing 
70f4c5b171Sjsing /* Ensure that MD5_LONG and uint32_t are equivalent size. */
71f4c5b171Sjsing CTASSERT(sizeof(MD5_LONG) == sizeof(uint32_t));
72f4c5b171Sjsing 
73aeaa0e53Sjsing #ifdef MD5_ASM
74*82ab76e1Sjsing void md5_block_data_order(MD5_CTX *c, const void *p, size_t num);
75aeaa0e53Sjsing #endif
76aeaa0e53Sjsing 
775d245864Sjsing #ifndef MD5_ASM
78bbd86a02Sjsing static inline uint32_t
79bbd86a02Sjsing md5_F(uint32_t x, uint32_t y, uint32_t z)
80bbd86a02Sjsing {
81bbd86a02Sjsing 	return (x & y) | (~x & z);
82bbd86a02Sjsing }
83bbd86a02Sjsing 
84bbd86a02Sjsing static inline uint32_t
85bbd86a02Sjsing md5_G(uint32_t x, uint32_t y, uint32_t z)
86bbd86a02Sjsing {
87bbd86a02Sjsing 	return (x & z) | (y & ~z);
88bbd86a02Sjsing }
89bbd86a02Sjsing 
90bbd86a02Sjsing static inline uint32_t
91bbd86a02Sjsing md5_H(uint32_t x, uint32_t y, uint32_t z)
92bbd86a02Sjsing {
93bbd86a02Sjsing 	return x ^ y ^ z;
94bbd86a02Sjsing }
95bbd86a02Sjsing 
96bbd86a02Sjsing static inline uint32_t
97bbd86a02Sjsing md5_I(uint32_t x, uint32_t y, uint32_t z)
98bbd86a02Sjsing {
99bbd86a02Sjsing 	return y ^ (x | ~z);
100bbd86a02Sjsing }
101bbd86a02Sjsing 
102bbd86a02Sjsing static inline void
103bbd86a02Sjsing md5_round1(uint32_t *a, uint32_t b, uint32_t c, uint32_t d, uint32_t x,
104bbd86a02Sjsing     uint32_t t, uint32_t s)
105bbd86a02Sjsing {
106bbd86a02Sjsing 	*a = b + crypto_rol_u32(*a + md5_F(b, c, d) + x + t, s);
107bbd86a02Sjsing }
108bbd86a02Sjsing 
109bbd86a02Sjsing static inline void
110bbd86a02Sjsing md5_round2(uint32_t *a, uint32_t b, uint32_t c, uint32_t d, uint32_t x,
111bbd86a02Sjsing     uint32_t t, uint32_t s)
112bbd86a02Sjsing {
113bbd86a02Sjsing 	*a = b + crypto_rol_u32(*a + md5_G(b, c, d) + x + t, s);
114bbd86a02Sjsing }
115bbd86a02Sjsing 
116bbd86a02Sjsing static inline void
117bbd86a02Sjsing md5_round3(uint32_t *a, uint32_t b, uint32_t c, uint32_t d, uint32_t x,
118bbd86a02Sjsing     uint32_t t, uint32_t s)
119bbd86a02Sjsing {
120bbd86a02Sjsing 	*a = b + crypto_rol_u32(*a + md5_H(b, c, d) + x + t, s);
121bbd86a02Sjsing }
122bbd86a02Sjsing 
123bbd86a02Sjsing static inline void
124bbd86a02Sjsing md5_round4(uint32_t *a, uint32_t b, uint32_t c, uint32_t d, uint32_t x,
125bbd86a02Sjsing     uint32_t t, uint32_t s)
126bbd86a02Sjsing {
127bbd86a02Sjsing 	*a = b + crypto_rol_u32(*a + md5_I(b, c, d) + x + t, s);
128bbd86a02Sjsing }
129bbd86a02Sjsing 
1305d245864Sjsing static void
131f4c5b171Sjsing md5_block_data_order(MD5_CTX *c, const void *_in, size_t num)
132aeaa0e53Sjsing {
133f4c5b171Sjsing 	const uint8_t *in = _in;
134bbd86a02Sjsing 	const MD5_LONG *in32;
135f4c5b171Sjsing 	MD5_LONG A, B, C, D;
136d697bab7Sjsing 	MD5_LONG X0, X1, X2, X3, X4, X5, X6, X7,
137aeaa0e53Sjsing 	    X8, X9, X10, X11, X12, X13, X14, X15;
138aeaa0e53Sjsing 
139460f5facSjsing 	while (num-- > 0) {
140aeaa0e53Sjsing 		A = c->A;
141aeaa0e53Sjsing 		B = c->B;
142aeaa0e53Sjsing 		C = c->C;
143aeaa0e53Sjsing 		D = c->D;
144aeaa0e53Sjsing 
145bbd86a02Sjsing 		if ((uintptr_t)in % 4 == 0) {
146bbd86a02Sjsing 			/* Input is 32 bit aligned. */
147bbd86a02Sjsing 			in32 = (const MD5_LONG *)in;
148bbd86a02Sjsing 			X0 = le32toh(in32[0]);
149bbd86a02Sjsing 			X1 = le32toh(in32[1]);
150bbd86a02Sjsing 			X2 = le32toh(in32[2]);
151bbd86a02Sjsing 			X3 = le32toh(in32[3]);
152bbd86a02Sjsing 			X4 = le32toh(in32[4]);
153bbd86a02Sjsing 			X5 = le32toh(in32[5]);
154bbd86a02Sjsing 			X6 = le32toh(in32[6]);
155bbd86a02Sjsing 			X7 = le32toh(in32[7]);
156bbd86a02Sjsing 			X8 = le32toh(in32[8]);
157bbd86a02Sjsing 			X9 = le32toh(in32[9]);
158bbd86a02Sjsing 			X10 = le32toh(in32[10]);
159bbd86a02Sjsing 			X11 = le32toh(in32[11]);
160bbd86a02Sjsing 			X12 = le32toh(in32[12]);
161bbd86a02Sjsing 			X13 = le32toh(in32[13]);
162bbd86a02Sjsing 			X14 = le32toh(in32[14]);
163bbd86a02Sjsing 			X15 = le32toh(in32[15]);
164bbd86a02Sjsing 		} else {
165bbd86a02Sjsing 			/* Input is not 32 bit aligned. */
166f4c5b171Sjsing 			X0 = crypto_load_le32toh(&in[0 * 4]);
167f4c5b171Sjsing 			X1 = crypto_load_le32toh(&in[1 * 4]);
168f4c5b171Sjsing 			X2 = crypto_load_le32toh(&in[2 * 4]);
169f4c5b171Sjsing 			X3 = crypto_load_le32toh(&in[3 * 4]);
170f4c5b171Sjsing 			X4 = crypto_load_le32toh(&in[4 * 4]);
171f4c5b171Sjsing 			X5 = crypto_load_le32toh(&in[5 * 4]);
172f4c5b171Sjsing 			X6 = crypto_load_le32toh(&in[6 * 4]);
173f4c5b171Sjsing 			X7 = crypto_load_le32toh(&in[7 * 4]);
174f4c5b171Sjsing 			X8 = crypto_load_le32toh(&in[8 * 4]);
175f4c5b171Sjsing 			X9 = crypto_load_le32toh(&in[9 * 4]);
176f4c5b171Sjsing 			X10 = crypto_load_le32toh(&in[10 * 4]);
177f4c5b171Sjsing 			X11 = crypto_load_le32toh(&in[11 * 4]);
178f4c5b171Sjsing 			X12 = crypto_load_le32toh(&in[12 * 4]);
179f4c5b171Sjsing 			X13 = crypto_load_le32toh(&in[13 * 4]);
180f4c5b171Sjsing 			X14 = crypto_load_le32toh(&in[14 * 4]);
181f4c5b171Sjsing 			X15 = crypto_load_le32toh(&in[15 * 4]);
182bbd86a02Sjsing 		}
183f4c5b171Sjsing 		in += MD5_CBLOCK;
184f4c5b171Sjsing 
185bbd86a02Sjsing 		md5_round1(&A, B, C, D, X0, 0xd76aa478L, 7);
186bbd86a02Sjsing 		md5_round1(&D, A, B, C, X1, 0xe8c7b756L, 12);
187bbd86a02Sjsing 		md5_round1(&C, D, A, B, X2, 0x242070dbL, 17);
188bbd86a02Sjsing 		md5_round1(&B, C, D, A, X3, 0xc1bdceeeL, 22);
189bbd86a02Sjsing 		md5_round1(&A, B, C, D, X4, 0xf57c0fafL, 7);
190bbd86a02Sjsing 		md5_round1(&D, A, B, C, X5, 0x4787c62aL, 12);
191bbd86a02Sjsing 		md5_round1(&C, D, A, B, X6, 0xa8304613L, 17);
192bbd86a02Sjsing 		md5_round1(&B, C, D, A, X7, 0xfd469501L, 22);
193bbd86a02Sjsing 		md5_round1(&A, B, C, D, X8, 0x698098d8L, 7);
194bbd86a02Sjsing 		md5_round1(&D, A, B, C, X9, 0x8b44f7afL, 12);
195bbd86a02Sjsing 		md5_round1(&C, D, A, B, X10, 0xffff5bb1L, 17);
196bbd86a02Sjsing 		md5_round1(&B, C, D, A, X11, 0x895cd7beL, 22);
197bbd86a02Sjsing 		md5_round1(&A, B, C, D, X12, 0x6b901122L, 7);
198bbd86a02Sjsing 		md5_round1(&D, A, B, C, X13, 0xfd987193L, 12);
199bbd86a02Sjsing 		md5_round1(&C, D, A, B, X14, 0xa679438eL, 17);
200bbd86a02Sjsing 		md5_round1(&B, C, D, A, X15, 0x49b40821L, 22);
201bbd86a02Sjsing 
202bbd86a02Sjsing 		md5_round2(&A, B, C, D, X1, 0xf61e2562L, 5);
203bbd86a02Sjsing 		md5_round2(&D, A, B, C, X6, 0xc040b340L, 9);
204bbd86a02Sjsing 		md5_round2(&C, D, A, B, X11, 0x265e5a51L, 14);
205bbd86a02Sjsing 		md5_round2(&B, C, D, A, X0, 0xe9b6c7aaL, 20);
206bbd86a02Sjsing 		md5_round2(&A, B, C, D, X5, 0xd62f105dL, 5);
207bbd86a02Sjsing 		md5_round2(&D, A, B, C, X10, 0x02441453L, 9);
208bbd86a02Sjsing 		md5_round2(&C, D, A, B, X15, 0xd8a1e681L, 14);
209bbd86a02Sjsing 		md5_round2(&B, C, D, A, X4, 0xe7d3fbc8L, 20);
210bbd86a02Sjsing 		md5_round2(&A, B, C, D, X9, 0x21e1cde6L, 5);
211bbd86a02Sjsing 		md5_round2(&D, A, B, C, X14, 0xc33707d6L, 9);
212bbd86a02Sjsing 		md5_round2(&C, D, A, B, X3, 0xf4d50d87L, 14);
213bbd86a02Sjsing 		md5_round2(&B, C, D, A, X8, 0x455a14edL, 20);
214bbd86a02Sjsing 		md5_round2(&A, B, C, D, X13, 0xa9e3e905L, 5);
215bbd86a02Sjsing 		md5_round2(&D, A, B, C, X2, 0xfcefa3f8L, 9);
216bbd86a02Sjsing 		md5_round2(&C, D, A, B, X7, 0x676f02d9L, 14);
217bbd86a02Sjsing 		md5_round2(&B, C, D, A, X12, 0x8d2a4c8aL, 20);
218bbd86a02Sjsing 
219bbd86a02Sjsing 		md5_round3(&A, B, C, D, X5, 0xfffa3942L, 4);
220bbd86a02Sjsing 		md5_round3(&D, A, B, C, X8, 0x8771f681L, 11);
221bbd86a02Sjsing 		md5_round3(&C, D, A, B, X11, 0x6d9d6122L, 16);
222bbd86a02Sjsing 		md5_round3(&B, C, D, A, X14, 0xfde5380cL, 23);
223bbd86a02Sjsing 		md5_round3(&A, B, C, D, X1, 0xa4beea44L, 4);
224bbd86a02Sjsing 		md5_round3(&D, A, B, C, X4, 0x4bdecfa9L, 11);
225bbd86a02Sjsing 		md5_round3(&C, D, A, B, X7, 0xf6bb4b60L, 16);
226bbd86a02Sjsing 		md5_round3(&B, C, D, A, X10, 0xbebfbc70L, 23);
227bbd86a02Sjsing 		md5_round3(&A, B, C, D, X13, 0x289b7ec6L, 4);
228bbd86a02Sjsing 		md5_round3(&D, A, B, C, X0, 0xeaa127faL, 11);
229bbd86a02Sjsing 		md5_round3(&C, D, A, B, X3, 0xd4ef3085L, 16);
230bbd86a02Sjsing 		md5_round3(&B, C, D, A, X6, 0x04881d05L, 23);
231bbd86a02Sjsing 		md5_round3(&A, B, C, D, X9, 0xd9d4d039L, 4);
232bbd86a02Sjsing 		md5_round3(&D, A, B, C, X12, 0xe6db99e5L, 11);
233bbd86a02Sjsing 		md5_round3(&C, D, A, B, X15, 0x1fa27cf8L, 16);
234bbd86a02Sjsing 		md5_round3(&B, C, D, A, X2, 0xc4ac5665L, 23);
235bbd86a02Sjsing 
236bbd86a02Sjsing 		md5_round4(&A, B, C, D, X0, 0xf4292244L, 6);
237bbd86a02Sjsing 		md5_round4(&D, A, B, C, X7, 0x432aff97L, 10);
238bbd86a02Sjsing 		md5_round4(&C, D, A, B, X14, 0xab9423a7L, 15);
239bbd86a02Sjsing 		md5_round4(&B, C, D, A, X5, 0xfc93a039L, 21);
240bbd86a02Sjsing 		md5_round4(&A, B, C, D, X12, 0x655b59c3L, 6);
241bbd86a02Sjsing 		md5_round4(&D, A, B, C, X3, 0x8f0ccc92L, 10);
242bbd86a02Sjsing 		md5_round4(&C, D, A, B, X10, 0xffeff47dL, 15);
243bbd86a02Sjsing 		md5_round4(&B, C, D, A, X1, 0x85845dd1L, 21);
244bbd86a02Sjsing 		md5_round4(&A, B, C, D, X8, 0x6fa87e4fL, 6);
245bbd86a02Sjsing 		md5_round4(&D, A, B, C, X15, 0xfe2ce6e0L, 10);
246bbd86a02Sjsing 		md5_round4(&C, D, A, B, X6, 0xa3014314L, 15);
247bbd86a02Sjsing 		md5_round4(&B, C, D, A, X13, 0x4e0811a1L, 21);
248bbd86a02Sjsing 		md5_round4(&A, B, C, D, X4, 0xf7537e82L, 6);
249bbd86a02Sjsing 		md5_round4(&D, A, B, C, X11, 0xbd3af235L, 10);
250bbd86a02Sjsing 		md5_round4(&C, D, A, B, X2, 0x2ad7d2bbL, 15);
251bbd86a02Sjsing 		md5_round4(&B, C, D, A, X9, 0xeb86d391L, 21);
252aeaa0e53Sjsing 
253460f5facSjsing 		c->A += A;
254460f5facSjsing 		c->B += B;
255460f5facSjsing 		c->C += C;
256460f5facSjsing 		c->D += D;
257aeaa0e53Sjsing 	}
258aeaa0e53Sjsing }
259aeaa0e53Sjsing #endif
260aeaa0e53Sjsing 
261eff8b94aSjsing int
262eff8b94aSjsing MD5_Init(MD5_CTX *c)
263eff8b94aSjsing {
264eff8b94aSjsing 	memset(c, 0, sizeof(*c));
265647e2446Sjsing 
266647e2446Sjsing 	c->A = 0x67452301UL;
267647e2446Sjsing 	c->B = 0xefcdab89UL;
268647e2446Sjsing 	c->C = 0x98badcfeUL;
269647e2446Sjsing 	c->D = 0x10325476UL;
270647e2446Sjsing 
271eff8b94aSjsing 	return 1;
272eff8b94aSjsing }
273eff8b94aSjsing LCRYPTO_ALIAS(MD5_Init);
274eff8b94aSjsing 
275eff8b94aSjsing int
276eff8b94aSjsing MD5_Update(MD5_CTX *c, const void *data_, size_t len)
277eff8b94aSjsing {
278eff8b94aSjsing 	const unsigned char *data = data_;
279eff8b94aSjsing 	unsigned char *p;
280eff8b94aSjsing 	size_t n;
281eff8b94aSjsing 
282eff8b94aSjsing 	if (len == 0)
283eff8b94aSjsing 		return 1;
284eff8b94aSjsing 
285ecb0d0d4Sjsing 	/* Update message bit counter. */
286ecb0d0d4Sjsing 	crypto_add_u32dw_u64(&c->Nh, &c->Nl, (uint64_t)len << 3);
287eff8b94aSjsing 
288eff8b94aSjsing 	n = c->num;
289eff8b94aSjsing 	if (n != 0) {
290eff8b94aSjsing 		p = (unsigned char *)c->data;
291eff8b94aSjsing 
292eff8b94aSjsing 		if (len >= MD5_CBLOCK || len + n >= MD5_CBLOCK) {
293eff8b94aSjsing 			memcpy(p + n, data, MD5_CBLOCK - n);
294eff8b94aSjsing 			md5_block_data_order(c, p, 1);
295eff8b94aSjsing 			n = MD5_CBLOCK - n;
296eff8b94aSjsing 			data += n;
297eff8b94aSjsing 			len -= n;
298eff8b94aSjsing 			c->num = 0;
299eff8b94aSjsing 			memset(p, 0, MD5_CBLOCK);	/* keep it zeroed */
300eff8b94aSjsing 		} else {
301eff8b94aSjsing 			memcpy(p + n, data, len);
302eff8b94aSjsing 			c->num += (unsigned int)len;
303eff8b94aSjsing 			return 1;
304eff8b94aSjsing 		}
305eff8b94aSjsing 	}
306eff8b94aSjsing 
307eff8b94aSjsing 	n = len/MD5_CBLOCK;
308eff8b94aSjsing 	if (n > 0) {
309eff8b94aSjsing 		md5_block_data_order(c, data, n);
310eff8b94aSjsing 		n *= MD5_CBLOCK;
311eff8b94aSjsing 		data += n;
312eff8b94aSjsing 		len -= n;
313eff8b94aSjsing 	}
314eff8b94aSjsing 
315eff8b94aSjsing 	if (len != 0) {
316eff8b94aSjsing 		p = (unsigned char *)c->data;
317eff8b94aSjsing 		c->num = (unsigned int)len;
318eff8b94aSjsing 		memcpy(p, data, len);
319eff8b94aSjsing 	}
320eff8b94aSjsing 	return 1;
321eff8b94aSjsing }
322eff8b94aSjsing LCRYPTO_ALIAS(MD5_Update);
323eff8b94aSjsing 
324eff8b94aSjsing void
325eff8b94aSjsing MD5_Transform(MD5_CTX *c, const unsigned char *data)
326eff8b94aSjsing {
327eff8b94aSjsing 	md5_block_data_order(c, data, 1);
328eff8b94aSjsing }
329eff8b94aSjsing LCRYPTO_ALIAS(MD5_Transform);
330eff8b94aSjsing 
331eff8b94aSjsing int
332eff8b94aSjsing MD5_Final(unsigned char *md, MD5_CTX *c)
333eff8b94aSjsing {
334eff8b94aSjsing 	unsigned char *p = (unsigned char *)c->data;
335eff8b94aSjsing 	size_t n = c->num;
336eff8b94aSjsing 
337eff8b94aSjsing 	p[n] = 0x80; /* there is always room for one */
338eff8b94aSjsing 	n++;
339eff8b94aSjsing 
340eff8b94aSjsing 	if (n > (MD5_CBLOCK - 8)) {
341eff8b94aSjsing 		memset(p + n, 0, MD5_CBLOCK - n);
342eff8b94aSjsing 		n = 0;
343eff8b94aSjsing 		md5_block_data_order(c, p, 1);
344eff8b94aSjsing 	}
345eff8b94aSjsing 
346f4c5b171Sjsing 	memset(p + n, 0, MD5_CBLOCK - 8 - n);
347f4c5b171Sjsing 	c->data[MD5_LBLOCK - 2] = htole32(c->Nl);
348f4c5b171Sjsing 	c->data[MD5_LBLOCK - 1] = htole32(c->Nh);
349f4c5b171Sjsing 
350eff8b94aSjsing 	md5_block_data_order(c, p, 1);
351eff8b94aSjsing 	c->num = 0;
352eff8b94aSjsing 	memset(p, 0, MD5_CBLOCK);
353eff8b94aSjsing 
354f4c5b171Sjsing 	crypto_store_htole32(&md[0 * 4], c->A);
355f4c5b171Sjsing 	crypto_store_htole32(&md[1 * 4], c->B);
356f4c5b171Sjsing 	crypto_store_htole32(&md[2 * 4], c->C);
357f4c5b171Sjsing 	crypto_store_htole32(&md[3 * 4], c->D);
358eff8b94aSjsing 
359eff8b94aSjsing 	return 1;
360eff8b94aSjsing }
361eff8b94aSjsing LCRYPTO_ALIAS(MD5_Final);
362eff8b94aSjsing 
363aeaa0e53Sjsing unsigned char *
364aeaa0e53Sjsing MD5(const unsigned char *d, size_t n, unsigned char *md)
365aeaa0e53Sjsing {
366aeaa0e53Sjsing 	MD5_CTX c;
367aeaa0e53Sjsing 
368aeaa0e53Sjsing 	if (!MD5_Init(&c))
369aeaa0e53Sjsing 		return NULL;
370aeaa0e53Sjsing 	MD5_Update(&c, d, n);
371aeaa0e53Sjsing 	MD5_Final(md, &c);
372aeaa0e53Sjsing 	explicit_bzero(&c, sizeof(c));
373aeaa0e53Sjsing 	return (md);
374aeaa0e53Sjsing }
375aeaa0e53Sjsing LCRYPTO_ALIAS(MD5);
376