1d1b6afe6SNiels Sascha Reedijk/*
2d1b6afe6SNiels Sascha Reedijk * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
3d1b6afe6SNiels Sascha Reedijk * MD5 Message-Digest Algorithm (RFC 1321).
4d1b6afe6SNiels Sascha Reedijk *
5d1b6afe6SNiels Sascha Reedijk * Homepage:
6d1b6afe6SNiels Sascha Reedijk * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
7d1b6afe6SNiels Sascha Reedijk *
8d1b6afe6SNiels Sascha Reedijk * Author:
9d1b6afe6SNiels Sascha Reedijk * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
10d1b6afe6SNiels Sascha Reedijk *
11d1b6afe6SNiels Sascha Reedijk * This software was written by Alexander Peslyak in 2001.  No copyright is
12d1b6afe6SNiels Sascha Reedijk * claimed, and the software is hereby placed in the public domain.
13d1b6afe6SNiels Sascha Reedijk * In case this attempt to disclaim copyright and place the software in the
14d1b6afe6SNiels Sascha Reedijk * public domain is deemed null and void, then the software is
15d1b6afe6SNiels Sascha Reedijk * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
16d1b6afe6SNiels Sascha Reedijk * general public under the following terms:
17d1b6afe6SNiels Sascha Reedijk *
18d1b6afe6SNiels Sascha Reedijk * Redistribution and use in source and binary forms, with or without
19d1b6afe6SNiels Sascha Reedijk * modification, are permitted.
20d1b6afe6SNiels Sascha Reedijk *
21d1b6afe6SNiels Sascha Reedijk * There's ABSOLUTELY NO WARRANTY, express or implied.
22d1b6afe6SNiels Sascha Reedijk *
23d1b6afe6SNiels Sascha Reedijk * (This is a heavily cut-down "BSD license".)
24d1b6afe6SNiels Sascha Reedijk *
25d1b6afe6SNiels Sascha Reedijk * This differs from Colin Plumb's older public domain implementation in that
26d1b6afe6SNiels Sascha Reedijk * no exactly 32-bit integer data type is required (any 32-bit or wider
27d1b6afe6SNiels Sascha Reedijk * unsigned integer data type will do), there's no compile-time endianness
28d1b6afe6SNiels Sascha Reedijk * configuration, and the function prototypes match OpenSSL's.  No code from
29d1b6afe6SNiels Sascha Reedijk * Colin Plumb's implementation has been reused; this comment merely compares
30d1b6afe6SNiels Sascha Reedijk * the properties of the two independent implementations.
31d1b6afe6SNiels Sascha Reedijk *
32d1b6afe6SNiels Sascha Reedijk * The primary goals of this implementation are portability and ease of use.
33d1b6afe6SNiels Sascha Reedijk * It is meant to be fast, but not as fast as possible.  Some known
34d1b6afe6SNiels Sascha Reedijk * optimizations are not included to reduce source code size and avoid
35d1b6afe6SNiels Sascha Reedijk * compile-time configuration.
36d1b6afe6SNiels Sascha Reedijk */
37d1b6afe6SNiels Sascha Reedijk
3804b5e12fSAlexander von Gluck IV
3904b5e12fSAlexander von Gluck IV#include "md5.h"
40d1b6afe6SNiels Sascha Reedijk
41d1b6afe6SNiels Sascha Reedijk#include <string.h>
42d1b6afe6SNiels Sascha Reedijk
43d1b6afe6SNiels Sascha Reedijk
44d1b6afe6SNiels Sascha Reedijk/*
45d1b6afe6SNiels Sascha Reedijk * The basic MD5 functions.
46d1b6afe6SNiels Sascha Reedijk *
47d1b6afe6SNiels Sascha Reedijk * F and G are optimized compared to their RFC 1321 definitions for
48d1b6afe6SNiels Sascha Reedijk * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
49d1b6afe6SNiels Sascha Reedijk * implementation.
50d1b6afe6SNiels Sascha Reedijk */
51d1b6afe6SNiels Sascha Reedijk#define F(x, y, z)			((z) ^ ((x) & ((y) ^ (z))))
52d1b6afe6SNiels Sascha Reedijk#define G(x, y, z)			((y) ^ ((z) & ((x) ^ (y))))
53d1b6afe6SNiels Sascha Reedijk#define H(x, y, z)			((x) ^ (y) ^ (z))
54d1b6afe6SNiels Sascha Reedijk#define I(x, y, z)			((y) ^ ((x) | ~(z)))
55d1b6afe6SNiels Sascha Reedijk
56d1b6afe6SNiels Sascha Reedijk/*
57d1b6afe6SNiels Sascha Reedijk * The MD5 transformation for all four rounds.
58d1b6afe6SNiels Sascha Reedijk */
59d1b6afe6SNiels Sascha Reedijk#define STEP(f, a, b, c, d, x, t, s) \
60d1b6afe6SNiels Sascha Reedijk	(a) += f((b), (c), (d)) + (x) + (t); \
61d1b6afe6SNiels Sascha Reedijk	(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
62d1b6afe6SNiels Sascha Reedijk	(a) += (b);
63d1b6afe6SNiels Sascha Reedijk
64d1b6afe6SNiels Sascha Reedijk/*
65d1b6afe6SNiels Sascha Reedijk * SET reads 4 input bytes in little-endian byte order and stores them
66d1b6afe6SNiels Sascha Reedijk * in a properly aligned word in host byte order.
67d1b6afe6SNiels Sascha Reedijk *
68d1b6afe6SNiels Sascha Reedijk * The check for little-endian architectures that tolerate unaligned
69d1b6afe6SNiels Sascha Reedijk * memory accesses is just an optimization.  Nothing will break if it
70d1b6afe6SNiels Sascha Reedijk * doesn't work.
71d1b6afe6SNiels Sascha Reedijk */
72d1b6afe6SNiels Sascha Reedijk#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
73d1b6afe6SNiels Sascha Reedijk#define SET(n) \
74d1b6afe6SNiels Sascha Reedijk	(*(MD5_u32plus *)&ptr[(n) * 4])
75d1b6afe6SNiels Sascha Reedijk#define GET(n) \
76d1b6afe6SNiels Sascha Reedijk	SET(n)
77d1b6afe6SNiels Sascha Reedijk#else
78d1b6afe6SNiels Sascha Reedijk#define SET(n) \
79d1b6afe6SNiels Sascha Reedijk	(ctx->block[(n)] = \
80d1b6afe6SNiels Sascha Reedijk	(MD5_u32plus)ptr[(n) * 4] | \
81d1b6afe6SNiels Sascha Reedijk	((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
82d1b6afe6SNiels Sascha Reedijk	((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
83d1b6afe6SNiels Sascha Reedijk	((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
84d1b6afe6SNiels Sascha Reedijk#define GET(n) \
85d1b6afe6SNiels Sascha Reedijk	(ctx->block[(n)])
86d1b6afe6SNiels Sascha Reedijk#endif
87d1b6afe6SNiels Sascha Reedijk
88d1b6afe6SNiels Sascha Reedijk/*
89d1b6afe6SNiels Sascha Reedijk * This processes one or more 64-byte data blocks, but does NOT update
90d1b6afe6SNiels Sascha Reedijk * the bit counters.  There are no alignment requirements.
91d1b6afe6SNiels Sascha Reedijk */
92d1b6afe6SNiels Sascha Reedijkstatic void *body(MD5_CTX *ctx, void *data, unsigned long size)
93d1b6afe6SNiels Sascha Reedijk{
94d1b6afe6SNiels Sascha Reedijk	unsigned char *ptr;
95d1b6afe6SNiels Sascha Reedijk	MD5_u32plus a, b, c, d;
96d1b6afe6SNiels Sascha Reedijk	MD5_u32plus saved_a, saved_b, saved_c, saved_d;
97d1b6afe6SNiels Sascha Reedijk
98d1b6afe6SNiels Sascha Reedijk	ptr = data;
99d1b6afe6SNiels Sascha Reedijk
100d1b6afe6SNiels Sascha Reedijk	a = ctx->a;
101d1b6afe6SNiels Sascha Reedijk	b = ctx->b;
102d1b6afe6SNiels Sascha Reedijk	c = ctx->c;
103d1b6afe6SNiels Sascha Reedijk	d = ctx->d;
104d1b6afe6SNiels Sascha Reedijk
105d1b6afe6SNiels Sascha Reedijk	do {
106d1b6afe6SNiels Sascha Reedijk		saved_a = a;
107d1b6afe6SNiels Sascha Reedijk		saved_b = b;
108d1b6afe6SNiels Sascha Reedijk		saved_c = c;
109d1b6afe6SNiels Sascha Reedijk		saved_d = d;
110d1b6afe6SNiels Sascha Reedijk
111d1b6afe6SNiels Sascha Reedijk/* Round 1 */
112d1b6afe6SNiels Sascha Reedijk		STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
113d1b6afe6SNiels Sascha Reedijk		STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
114d1b6afe6SNiels Sascha Reedijk		STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
115d1b6afe6SNiels Sascha Reedijk		STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
116d1b6afe6SNiels Sascha Reedijk		STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
117d1b6afe6SNiels Sascha Reedijk		STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
118d1b6afe6SNiels Sascha Reedijk		STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
119d1b6afe6SNiels Sascha Reedijk		STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
120d1b6afe6SNiels Sascha Reedijk		STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
121d1b6afe6SNiels Sascha Reedijk		STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
122d1b6afe6SNiels Sascha Reedijk		STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
123d1b6afe6SNiels Sascha Reedijk		STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
124d1b6afe6SNiels Sascha Reedijk		STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
125d1b6afe6SNiels Sascha Reedijk		STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
126d1b6afe6SNiels Sascha Reedijk		STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
127d1b6afe6SNiels Sascha Reedijk		STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
128d1b6afe6SNiels Sascha Reedijk
129d1b6afe6SNiels Sascha Reedijk/* Round 2 */
130d1b6afe6SNiels Sascha Reedijk		STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
131d1b6afe6SNiels Sascha Reedijk		STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
132d1b6afe6SNiels Sascha Reedijk		STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
133d1b6afe6SNiels Sascha Reedijk		STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
134d1b6afe6SNiels Sascha Reedijk		STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
135d1b6afe6SNiels Sascha Reedijk		STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
136d1b6afe6SNiels Sascha Reedijk		STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
137d1b6afe6SNiels Sascha Reedijk		STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
138d1b6afe6SNiels Sascha Reedijk		STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
139d1b6afe6SNiels Sascha Reedijk		STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
140d1b6afe6SNiels Sascha Reedijk		STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
141d1b6afe6SNiels Sascha Reedijk		STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
142d1b6afe6SNiels Sascha Reedijk		STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
143d1b6afe6SNiels Sascha Reedijk		STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
144d1b6afe6SNiels Sascha Reedijk		STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
145d1b6afe6SNiels Sascha Reedijk		STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
146d1b6afe6SNiels Sascha Reedijk
147d1b6afe6SNiels Sascha Reedijk/* Round 3 */
148d1b6afe6SNiels Sascha Reedijk		STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
149d1b6afe6SNiels Sascha Reedijk		STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
150d1b6afe6SNiels Sascha Reedijk		STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
151d1b6afe6SNiels Sascha Reedijk		STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
152d1b6afe6SNiels Sascha Reedijk		STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
153d1b6afe6SNiels Sascha Reedijk		STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
154d1b6afe6SNiels Sascha Reedijk		STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
155d1b6afe6SNiels Sascha Reedijk		STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
156d1b6afe6SNiels Sascha Reedijk		STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
157d1b6afe6SNiels Sascha Reedijk		STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
158d1b6afe6SNiels Sascha Reedijk		STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
159d1b6afe6SNiels Sascha Reedijk		STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
160d1b6afe6SNiels Sascha Reedijk		STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
161d1b6afe6SNiels Sascha Reedijk		STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
162d1b6afe6SNiels Sascha Reedijk		STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
163d1b6afe6SNiels Sascha Reedijk		STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
164d1b6afe6SNiels Sascha Reedijk
165d1b6afe6SNiels Sascha Reedijk/* Round 4 */
166d1b6afe6SNiels Sascha Reedijk		STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
167d1b6afe6SNiels Sascha Reedijk		STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
168d1b6afe6SNiels Sascha Reedijk		STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
169d1b6afe6SNiels Sascha Reedijk		STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
170d1b6afe6SNiels Sascha Reedijk		STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
171d1b6afe6SNiels Sascha Reedijk		STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
172d1b6afe6SNiels Sascha Reedijk		STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
173d1b6afe6SNiels Sascha Reedijk		STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
174d1b6afe6SNiels Sascha Reedijk		STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
175d1b6afe6SNiels Sascha Reedijk		STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
176d1b6afe6SNiels Sascha Reedijk		STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
177d1b6afe6SNiels Sascha Reedijk		STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
178d1b6afe6SNiels Sascha Reedijk		STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
179d1b6afe6SNiels Sascha Reedijk		STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
180d1b6afe6SNiels Sascha Reedijk		STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
181d1b6afe6SNiels Sascha Reedijk		STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
182d1b6afe6SNiels Sascha Reedijk
183d1b6afe6SNiels Sascha Reedijk		a += saved_a;
184d1b6afe6SNiels Sascha Reedijk		b += saved_b;
185d1b6afe6SNiels Sascha Reedijk		c += saved_c;
186d1b6afe6SNiels Sascha Reedijk		d += saved_d;
187d1b6afe6SNiels Sascha Reedijk
188d1b6afe6SNiels Sascha Reedijk		ptr += 64;
189d1b6afe6SNiels Sascha Reedijk	} while (size -= 64);
190d1b6afe6SNiels Sascha Reedijk
191d1b6afe6SNiels Sascha Reedijk	ctx->a = a;
192d1b6afe6SNiels Sascha Reedijk	ctx->b = b;
193d1b6afe6SNiels Sascha Reedijk	ctx->c = c;
194d1b6afe6SNiels Sascha Reedijk	ctx->d = d;
195d1b6afe6SNiels Sascha Reedijk
196d1b6afe6SNiels Sascha Reedijk	return ptr;
197d1b6afe6SNiels Sascha Reedijk}
198d1b6afe6SNiels Sascha Reedijk
199d1b6afe6SNiels Sascha Reedijkvoid MD5_Init(MD5_CTX *ctx)
200d1b6afe6SNiels Sascha Reedijk{
201d1b6afe6SNiels Sascha Reedijk	ctx->a = 0x67452301;
202d1b6afe6SNiels Sascha Reedijk	ctx->b = 0xefcdab89;
203d1b6afe6SNiels Sascha Reedijk	ctx->c = 0x98badcfe;
204d1b6afe6SNiels Sascha Reedijk	ctx->d = 0x10325476;
205d1b6afe6SNiels Sascha Reedijk
206d1b6afe6SNiels Sascha Reedijk	ctx->lo = 0;
207d1b6afe6SNiels Sascha Reedijk	ctx->hi = 0;
208d1b6afe6SNiels Sascha Reedijk}
209d1b6afe6SNiels Sascha Reedijk
210d1b6afe6SNiels Sascha Reedijkvoid MD5_Update(MD5_CTX *ctx, void *data, unsigned long size)
211d1b6afe6SNiels Sascha Reedijk{
212d1b6afe6SNiels Sascha Reedijk	MD5_u32plus saved_lo;
213d1b6afe6SNiels Sascha Reedijk	unsigned long used, free;
214d1b6afe6SNiels Sascha Reedijk
215d1b6afe6SNiels Sascha Reedijk	saved_lo = ctx->lo;
216d1b6afe6SNiels Sascha Reedijk	if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
217d1b6afe6SNiels Sascha Reedijk		ctx->hi++;
218d1b6afe6SNiels Sascha Reedijk	ctx->hi += size >> 29;
219d1b6afe6SNiels Sascha Reedijk
220d1b6afe6SNiels Sascha Reedijk	used = saved_lo & 0x3f;
221d1b6afe6SNiels Sascha Reedijk
222d1b6afe6SNiels Sascha Reedijk	if (used) {
223d1b6afe6SNiels Sascha Reedijk		free = 64 - used;
224d1b6afe6SNiels Sascha Reedijk
225d1b6afe6SNiels Sascha Reedijk		if (size < free) {
226d1b6afe6SNiels Sascha Reedijk			memcpy(&ctx->buffer[used], data, size);
227d1b6afe6SNiels Sascha Reedijk			return;
228d1b6afe6SNiels Sascha Reedijk		}
229d1b6afe6SNiels Sascha Reedijk
230d1b6afe6SNiels Sascha Reedijk		memcpy(&ctx->buffer[used], data, free);
231d1b6afe6SNiels Sascha Reedijk		data = (unsigned char *)data + free;
232d1b6afe6SNiels Sascha Reedijk		size -= free;
233d1b6afe6SNiels Sascha Reedijk		body(ctx, ctx->buffer, 64);
234d1b6afe6SNiels Sascha Reedijk	}
235d1b6afe6SNiels Sascha Reedijk
236d1b6afe6SNiels Sascha Reedijk	if (size >= 64) {
237d1b6afe6SNiels Sascha Reedijk		data = body(ctx, data, size & ~(unsigned long)0x3f);
238d1b6afe6SNiels Sascha Reedijk		size &= 0x3f;
239d1b6afe6SNiels Sascha Reedijk	}
240d1b6afe6SNiels Sascha Reedijk
241d1b6afe6SNiels Sascha Reedijk	memcpy(ctx->buffer, data, size);
242d1b6afe6SNiels Sascha Reedijk}
243d1b6afe6SNiels Sascha Reedijk
244d1b6afe6SNiels Sascha Reedijkvoid MD5_Final(unsigned char *result, MD5_CTX *ctx)
245d1b6afe6SNiels Sascha Reedijk{
246d1b6afe6SNiels Sascha Reedijk	unsigned long used, free;
247d1b6afe6SNiels Sascha Reedijk
248d1b6afe6SNiels Sascha Reedijk	used = ctx->lo & 0x3f;
249d1b6afe6SNiels Sascha Reedijk
250d1b6afe6SNiels Sascha Reedijk	ctx->buffer[used++] = 0x80;
251d1b6afe6SNiels Sascha Reedijk
252d1b6afe6SNiels Sascha Reedijk	free = 64 - used;
253d1b6afe6SNiels Sascha Reedijk
254d1b6afe6SNiels Sascha Reedijk	if (free < 8) {
255d1b6afe6SNiels Sascha Reedijk		memset(&ctx->buffer[used], 0, free);
256d1b6afe6SNiels Sascha Reedijk		body(ctx, ctx->buffer, 64);
257d1b6afe6SNiels Sascha Reedijk		used = 0;
258d1b6afe6SNiels Sascha Reedijk		free = 64;
259d1b6afe6SNiels Sascha Reedijk	}
260d1b6afe6SNiels Sascha Reedijk
261d1b6afe6SNiels Sascha Reedijk	memset(&ctx->buffer[used], 0, free - 8);
262d1b6afe6SNiels Sascha Reedijk
263d1b6afe6SNiels Sascha Reedijk	ctx->lo <<= 3;
264d1b6afe6SNiels Sascha Reedijk	ctx->buffer[56] = ctx->lo;
265d1b6afe6SNiels Sascha Reedijk	ctx->buffer[57] = ctx->lo >> 8;
266d1b6afe6SNiels Sascha Reedijk	ctx->buffer[58] = ctx->lo >> 16;
267d1b6afe6SNiels Sascha Reedijk	ctx->buffer[59] = ctx->lo >> 24;
268d1b6afe6SNiels Sascha Reedijk	ctx->buffer[60] = ctx->hi;
269d1b6afe6SNiels Sascha Reedijk	ctx->buffer[61] = ctx->hi >> 8;
270d1b6afe6SNiels Sascha Reedijk	ctx->buffer[62] = ctx->hi >> 16;
271d1b6afe6SNiels Sascha Reedijk	ctx->buffer[63] = ctx->hi >> 24;
272d1b6afe6SNiels Sascha Reedijk
273d1b6afe6SNiels Sascha Reedijk	body(ctx, ctx->buffer, 64);
274d1b6afe6SNiels Sascha Reedijk
275d1b6afe6SNiels Sascha Reedijk	result[0] = ctx->a;
276d1b6afe6SNiels Sascha Reedijk	result[1] = ctx->a >> 8;
277d1b6afe6SNiels Sascha Reedijk	result[2] = ctx->a >> 16;
278d1b6afe6SNiels Sascha Reedijk	result[3] = ctx->a >> 24;
279d1b6afe6SNiels Sascha Reedijk	result[4] = ctx->b;
280d1b6afe6SNiels Sascha Reedijk	result[5] = ctx->b >> 8;
281d1b6afe6SNiels Sascha Reedijk	result[6] = ctx->b >> 16;
282d1b6afe6SNiels Sascha Reedijk	result[7] = ctx->b >> 24;
283d1b6afe6SNiels Sascha Reedijk	result[8] = ctx->c;
284d1b6afe6SNiels Sascha Reedijk	result[9] = ctx->c >> 8;
285d1b6afe6SNiels Sascha Reedijk	result[10] = ctx->c >> 16;
286d1b6afe6SNiels Sascha Reedijk	result[11] = ctx->c >> 24;
287d1b6afe6SNiels Sascha Reedijk	result[12] = ctx->d;
288d1b6afe6SNiels Sascha Reedijk	result[13] = ctx->d >> 8;
289d1b6afe6SNiels Sascha Reedijk	result[14] = ctx->d >> 16;
290d1b6afe6SNiels Sascha Reedijk	result[15] = ctx->d >> 24;
291d1b6afe6SNiels Sascha Reedijk
292d1b6afe6SNiels Sascha Reedijk	memset(ctx, 0, sizeof(*ctx));
293d1b6afe6SNiels Sascha Reedijk}
294