Parcourir la source

[crypto] Replace MD5 implementation

Replace MD5 implementation with one which is around 20% smaller.  This
implementation has been verified using the existing MD5 self-tests.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown il y a 13 ans
Parent
révision
fba2310562
2 fichiers modifiés avec 301 ajouts et 190 suppressions
  1. 242
    180
      src/crypto/md5.c
  2. 59
    10
      src/include/ipxe/md5.h

+ 242
- 180
src/crypto/md5.c Voir le fichier

@@ -1,233 +1,295 @@
1
-/* 
2
- * Cryptographic API.
1
+/*
2
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3 3
  *
4
- * MD5 Message Digest Algorithm (RFC1321).
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
5 8
  *
6
- * Derived from cryptoapi implementation, originally based on the
7
- * public domain implementation written by Colin Plumb in 1993.
8
- *
9
- * Reduced object size by around 50% compared to the original Linux
10
- * version for use in Etherboot by Michael Brown.
11
- *
12
- * Copyright (c) Cryptoapi developers.
13
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
14
- * Copyright (c) 2006 Michael Brown <mbrown@fensystems.co.uk>
15
- * 
16
- * This program is free software; you can redistribute it and/or modify it
17
- * under the terms of the GNU General Public License as published by the Free
18
- * Software Foundation; either version 2 of the License, or (at your option) 
19
- * any later version.
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
20 13
  *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 17
  */
22 18
 
23 19
 FILE_LICENCE ( GPL2_OR_LATER );
24 20
 
21
+/** @file
22
+ *
23
+ * MD5 algorithm
24
+ *
25
+ */
26
+
25 27
 #include <stdint.h>
26 28
 #include <string.h>
27 29
 #include <byteswap.h>
30
+#include <assert.h>
28 31
 #include <ipxe/crypto.h>
29 32
 #include <ipxe/md5.h>
30 33
 
31
-struct md5_step {
32
-	u32 ( * f ) ( u32 b, u32 c, u32 d );
33
-	u8 coefficient;
34
-	u8 constant;
34
+/**
35
+ * Rotate dword left
36
+ *
37
+ * @v dword		Dword
38
+ * @v rotate		Amount of rotation
39
+ */
40
+static inline __attribute__ (( always_inline )) uint32_t
41
+rol32 ( uint32_t dword, unsigned int rotate ) {
42
+	return ( ( dword << rotate ) | ( dword >> ( 32 - rotate ) ) );
43
+}
44
+
45
+/** MD5 variables */
46
+struct md5_variables {
47
+	/* This layout matches that of struct md5_digest_data,
48
+	 * allowing for efficient endianness-conversion,
49
+	 */
50
+	uint32_t a;
51
+	uint32_t b;
52
+	uint32_t c;
53
+	uint32_t d;
54
+	uint32_t w[16];
55
+} __attribute__ (( packed ));
56
+
57
+/** MD5 constants */
58
+static const uint32_t k[64] = {
59
+	0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a,
60
+	0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
61
+	0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340,
62
+	0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
63
+	0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
64
+	0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
65
+	0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa,
66
+	0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
67
+	0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92,
68
+	0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
69
+	0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
70
+};
71
+
72
+/** MD5 shift amounts */
73
+static const uint8_t r[64] = {
74
+	7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
75
+	5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,
76
+	4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
77
+	6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
35 78
 };
36 79
 
37
-static u32 f1(u32 b, u32 c, u32 d)
38
-{
39
-	return ( d ^ ( b & ( c ^ d ) ) );
80
+/**
81
+ * f(b,c,d) for steps 0 to 15
82
+ *
83
+ * @v v		MD5 variables
84
+ * @ret f	f(b,c,d)
85
+ */
86
+static uint32_t md5_f_0_15 ( struct md5_variables *v ) {
87
+	return ( v->d ^ ( v->b & ( v->c ^ v->d ) ) );
40 88
 }
41 89
 
42
-static u32 f2(u32 b, u32 c, u32 d)
43
-{
44
-	return ( c ^ ( d & ( b ^ c ) ) );
90
+/**
91
+ * f(b,c,d) for steps 16 to 31
92
+ *
93
+ * @v v		MD5 variables
94
+ * @ret f	f(b,c,d)
95
+ */
96
+static uint32_t md5_f_16_31 ( struct md5_variables *v ) {
97
+	return ( v->c ^ ( v->d & ( v->b ^ v->c ) ) );
45 98
 }
46 99
 
47
-static u32 f3(u32 b, u32 c, u32 d)
48
-{
49
-	return ( b ^ c ^ d );
100
+/**
101
+ * f(b,c,d) for steps 32 to 47
102
+ *
103
+ * @v v		MD5 variables
104
+ * @ret f	f(b,c,d)
105
+ */
106
+static uint32_t md5_f_32_47 ( struct md5_variables *v ) {
107
+	return ( v->b ^ v->c ^ v->d );
50 108
 }
51 109
 
52
-static u32 f4(u32 b, u32 c, u32 d)
53
-{
54
-	return ( c ^ ( b | ~d ) );
110
+/**
111
+ * f(b,c,d) for steps 48 to 63
112
+ *
113
+ * @v v		MD5 variables
114
+ * @ret f	f(b,c,d)
115
+ */
116
+static uint32_t md5_f_48_63 ( struct md5_variables *v ) {
117
+	return ( v->c ^ ( v->b | (~v->d) ) );
55 118
 }
56 119
 
57
-static struct md5_step md5_steps[4] = {
58
-	{
59
-		.f = f1,
60
-		.coefficient = 1,
61
-		.constant = 0,
62
-	},
63
-	{
64
-		.f = f2,
65
-		.coefficient = 5,
66
-		.constant = 1,
67
-	},
68
-	{
69
-		.f = f3,
70
-		.coefficient = 3,
71
-		.constant = 5,
72
-	},
73
-	{
74
-		.f = f4,
75
-		.coefficient = 7,
76
-		.constant = 0,
77
-	}
120
+/** An MD5 step function */
121
+struct md5_step {
122
+	/**
123
+	 * Calculate f(b,c,d)
124
+	 *
125
+	 * @v v		MD5 variables
126
+	 * @ret f	f(b,c,d)
127
+	 */
128
+	uint32_t ( * f ) ( struct md5_variables *v );
129
+	/** Coefficient of i in g=ni+m */
130
+	uint8_t coefficient;
131
+	/** Constant term in g=ni+m */
132
+	uint8_t constant;
78 133
 };
79 134
 
80
-static const u8 r[64] = {
81
-	7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
82
-	5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
83
-	4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
84
-	6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
135
+/** MD5 steps */
136
+static struct md5_step md5_steps[4] = {
137
+	/** 0 to 15 */
138
+	{ .f = md5_f_0_15,	.coefficient = 1,	.constant = 0 },
139
+	/** 16 to 31 */
140
+	{ .f = md5_f_16_31,	.coefficient = 5,	.constant = 1 },
141
+	/** 32 to 47 */
142
+	{ .f = md5_f_32_47,	.coefficient = 3,	.constant = 5 },
143
+	/** 48 to 63 */
144
+	{ .f = md5_f_48_63,	.coefficient = 7,	.constant = 0 },
85 145
 };
86 146
 
87
-static const u32 k[64] = {
88
-	0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL,
89
-	0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
90
-	0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL,
91
-	0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
92
-	0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL,
93
-	0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
94
-	0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL,
95
-	0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
96
-	0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL,
97
-	0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
98
-	0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL,
99
-	0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
100
-	0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL,
101
-	0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
102
-	0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL,
103
-	0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL,
104
-};
147
+/**
148
+ * Initialise MD5 algorithm
149
+ *
150
+ * @v ctx		MD5 context
151
+ */
152
+static void md5_init ( void *ctx ) {
153
+	struct md5_context *context = ctx;
154
+
155
+	context->ddd.dd.digest.h[0] = cpu_to_le32 ( 0x67452301 );
156
+	context->ddd.dd.digest.h[1] = cpu_to_le32 ( 0xefcdab89 );
157
+	context->ddd.dd.digest.h[2] = cpu_to_le32 ( 0x98badcfe );
158
+	context->ddd.dd.digest.h[3] = cpu_to_le32 ( 0x10325476 );
159
+	context->len = 0;
160
+}
105 161
 
106
-static void md5_transform(u32 *hash, const u32 *in)
107
-{
108
-	u32 a, b, c, d, f, g, temp;
109
-	int i;
162
+/**
163
+ * Calculate MD5 digest of accumulated data
164
+ *
165
+ * @v context		MD5 context
166
+ */
167
+static void md5_digest ( struct md5_context *context ) {
168
+        union {
169
+		union md5_digest_data_dwords ddd;
170
+		struct md5_variables v;
171
+	} u;
172
+	uint32_t *a = &u.v.a;
173
+	uint32_t *b = &u.v.b;
174
+	uint32_t *c = &u.v.c;
175
+	uint32_t *d = &u.v.d;
176
+	uint32_t *w = u.v.w;
177
+	uint32_t f;
178
+	uint32_t g;
179
+	uint32_t temp;
110 180
 	struct md5_step *step;
181
+	unsigned int i;
111 182
 
112
-	a = hash[0];
113
-	b = hash[1];
114
-	c = hash[2];
115
-	d = hash[3];
183
+	/* Sanity checks */
184
+	assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 );
185
+	linker_assert ( &u.ddd.dd.digest.h[0] == a, md5_bad_layout );
186
+	linker_assert ( &u.ddd.dd.digest.h[1] == b, md5_bad_layout );
187
+	linker_assert ( &u.ddd.dd.digest.h[2] == c, md5_bad_layout );
188
+	linker_assert ( &u.ddd.dd.digest.h[3] == d, md5_bad_layout );
189
+	linker_assert ( &u.ddd.dd.data.dword[0] == w, md5_bad_layout );
116 190
 
117
-	for ( i = 0 ; i < 64 ; i++ ) {
118
-		step = &md5_steps[i >> 4];
119
-		f = step->f ( b, c, d );
120
-		g = ( ( i * step->coefficient + step->constant ) & 0xf );
121
-		temp = d;
122
-		d = c;
123
-		c = b;
124
-		a += ( f + k[i] + in[g] );
125
-		a = ( ( a << r[i] ) | ( a >> ( 32-r[i] ) ) );
126
-		b += a;
127
-		a = temp;
128
-	}
129
-
130
-	hash[0] += a;
131
-	hash[1] += b;
132
-	hash[2] += c;
133
-	hash[3] += d;
134
-}
191
+	DBGC ( context, "MD5 digesting:\n" );
192
+	DBGC_HDA ( context, 0, &context->ddd.dd.digest,
193
+		   sizeof ( context->ddd.dd.digest ) );
194
+	DBGC_HDA ( context, context->len, &context->ddd.dd.data,
195
+		   sizeof ( context->ddd.dd.data ) );
135 196
 
136
-/* XXX: this stuff can be optimized */
137
-static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
138
-{
139
-	while (words--) {
140
-		le32_to_cpus(buf);
141
-		buf++;
197
+	/* Convert h[0..3] to host-endian, and initialise a, b, c, d,
198
+	 * and w[0..15]
199
+	 */
200
+	for ( i = 0 ; i < ( sizeof ( u.ddd.dword ) /
201
+			    sizeof ( u.ddd.dword[0] ) ) ; i++ ) {
202
+		le32_to_cpus ( &context->ddd.dword[i] );
203
+		u.ddd.dword[i] = context->ddd.dword[i];
142 204
 	}
143
-}
144 205
 
145
-static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
146
-{
147
-	while (words--) {
148
-		cpu_to_le32s(buf);
149
-		buf++;
206
+	/* Main loop */
207
+	for ( i = 0 ; i < 64 ; i++ ) {
208
+		step = &md5_steps[ i / 16 ];
209
+		f = step->f ( &u.v );
210
+		g = ( ( ( step->coefficient * i ) + step->constant ) % 16 );
211
+		temp = *d;
212
+		*d = *c;
213
+		*c = *b;
214
+		*b = ( *b + rol32 ( ( *a + f + k[i] + w[g] ), r[i] ) );
215
+		*a = temp;
216
+		DBGC2 ( context, "%2d : %08x %08x %08x %08x\n",
217
+			i, *a, *b, *c, *d );
150 218
 	}
151
-}
152 219
 
153
-static inline void md5_transform_helper(struct md5_ctx *ctx)
154
-{
155
-	le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
156
-	md5_transform(ctx->hash, ctx->block);
157
-}
158
-
159
-static void md5_init(void *context)
160
-{
161
-	struct md5_ctx *mctx = context;
220
+	/* Add chunk to hash and convert back to big-endian */
221
+	for ( i = 0 ; i < 4 ; i++ ) {
222
+		context->ddd.dd.digest.h[i] =
223
+			cpu_to_le32 ( context->ddd.dd.digest.h[i] +
224
+				      u.ddd.dd.digest.h[i] );
225
+	}
162 226
 
163
-	mctx->hash[0] = 0x67452301;
164
-	mctx->hash[1] = 0xefcdab89;
165
-	mctx->hash[2] = 0x98badcfe;
166
-	mctx->hash[3] = 0x10325476;
167
-	mctx->byte_count = 0;
227
+	DBGC ( context, "MD5 digested:\n" );
228
+	DBGC_HDA ( context, 0, &context->ddd.dd.digest,
229
+		   sizeof ( context->ddd.dd.digest ) );
168 230
 }
169 231
 
170
-static void md5_update(void *context, const void *data, size_t len)
171
-{
172
-	struct md5_ctx *mctx = context;
173
-	const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
174
-
175
-	mctx->byte_count += len;
232
+/**
233
+ * Accumulate data with MD5 algorithm
234
+ *
235
+ * @v ctx		MD5 context
236
+ * @v data		Data
237
+ * @v len		Length of data
238
+ */
239
+static void md5_update ( void *ctx, const void *data, size_t len ) {
240
+	struct md5_context *context = ctx;
241
+	const uint8_t *byte = data;
242
+	size_t offset;
176 243
 
177
-	if (avail > len) {
178
-		memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
179
-		       data, len);
180
-		return;
244
+	/* Accumulate data a byte at a time, performing the digest
245
+	 * whenever we fill the data buffer
246
+	 */
247
+	while ( len-- ) {
248
+		offset = ( context->len % sizeof ( context->ddd.dd.data ) );
249
+		context->ddd.dd.data.byte[offset] = *(byte++);
250
+		context->len++;
251
+		if ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 )
252
+			md5_digest ( context );
181 253
 	}
254
+}
182 255
 
183
-	memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
184
-	       data, avail);
185
-
186
-	md5_transform_helper(mctx);
187
-	data += avail;
188
-	len -= avail;
256
+/**
257
+ * Generate MD5 digest
258
+ *
259
+ * @v ctx		MD5 context
260
+ * @v out		Output buffer
261
+ */
262
+static void md5_final ( void *ctx, void *out ) {
263
+	struct md5_context *context = ctx;
264
+	uint64_t len_bits;
265
+	uint8_t pad;
189 266
 
190
-	while (len >= sizeof(mctx->block)) {
191
-		memcpy(mctx->block, data, sizeof(mctx->block));
192
-		md5_transform_helper(mctx);
193
-		data += sizeof(mctx->block);
194
-		len -= sizeof(mctx->block);
195
-	}
267
+	/* Record length before pre-processing */
268
+	len_bits = cpu_to_le64 ( ( ( uint64_t ) context->len ) * 8 );
196 269
 
197
-	memcpy(mctx->block, data, len);
198
-}
270
+	/* Pad with a single "1" bit followed by as many "0" bits as required */
271
+	pad = 0x80;
272
+	do {
273
+		md5_update ( ctx, &pad, sizeof ( pad ) );
274
+		pad = 0x00;
275
+	} while ( ( context->len % sizeof ( context->ddd.dd.data ) ) !=
276
+		  offsetof ( typeof ( context->ddd.dd.data ), final.len ) );
199 277
 
200
-static void md5_final(void *context, void *out)
201
-{
202
-	struct md5_ctx *mctx = context;
203
-	const unsigned int offset = mctx->byte_count & 0x3f;
204
-	char *p = (char *)mctx->block + offset;
205
-	int padding = 56 - (offset + 1);
206
-
207
-	*p++ = 0x80;
208
-	if (padding < 0) {
209
-		memset(p, 0x00, padding + sizeof (u64));
210
-		md5_transform_helper(mctx);
211
-		p = (char *)mctx->block;
212
-		padding = 56;
213
-	}
278
+	/* Append length (in bits) */
279
+	md5_update ( ctx, &len_bits, sizeof ( len_bits ) );
280
+	assert ( ( context->len % sizeof ( context->ddd.dd.data ) ) == 0 );
214 281
 
215
-	memset(p, 0, padding);
216
-	mctx->block[14] = mctx->byte_count << 3;
217
-	mctx->block[15] = mctx->byte_count >> 29;
218
-	le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
219
-	                  sizeof(u64)) / sizeof(u32));
220
-	md5_transform(mctx->hash, mctx->block);
221
-	cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
222
-	memcpy(out, mctx->hash, sizeof(mctx->hash));
223
-	memset(mctx, 0, sizeof(*mctx));
282
+	/* Copy out final digest */
283
+	memcpy ( out, &context->ddd.dd.digest,
284
+		 sizeof ( context->ddd.dd.digest ) );
224 285
 }
225 286
 
287
+/** MD5 algorithm */
226 288
 struct digest_algorithm md5_algorithm = {
227 289
 	.name		= "md5",
228
-	.ctxsize	= MD5_CTX_SIZE,
229
-	.blocksize	= ( MD5_BLOCK_WORDS * 4 ),
230
-	.digestsize	= MD5_DIGEST_SIZE,
290
+	.ctxsize	= sizeof ( struct md5_context ),
291
+	.blocksize	= sizeof ( union md5_block ),
292
+	.digestsize	= sizeof ( struct md5_digest ),
231 293
 	.init		= md5_init,
232 294
 	.update		= md5_update,
233 295
 	.final		= md5_final,

+ 59
- 10
src/include/ipxe/md5.h Voir le fichier

@@ -1,23 +1,72 @@
1 1
 #ifndef _IPXE_MD5_H
2 2
 #define _IPXE_MD5_H
3 3
 
4
-FILE_LICENCE ( GPL2_OR_LATER );
4
+/** @file
5
+ *
6
+ * MD5 algorithm
7
+ *
8
+ */
5 9
 
6
-struct digest_algorithm;
10
+FILE_LICENCE ( GPL2_OR_LATER );
7 11
 
8 12
 #include <stdint.h>
13
+#include <ipxe/crypto.h>
14
+
15
+/** An MD5 digest */
16
+struct md5_digest {
17
+	/** Hash output */
18
+	uint32_t h[4];
19
+};
9 20
 
10
-#define MD5_DIGEST_SIZE		16
11
-#define MD5_BLOCK_WORDS		16
12
-#define MD5_HASH_WORDS		4
21
+/** An MD5 data block */
22
+union md5_block {
23
+	/** Raw bytes */
24
+	uint8_t byte[64];
25
+	/** Raw dwords */
26
+	uint32_t dword[16];
27
+	/** Final block structure */
28
+	struct {
29
+		/** Padding */
30
+		uint8_t pad[56];
31
+		/** Length in bits */
32
+		uint64_t len;
33
+	} final;
34
+};
35
+
36
+/** MD5 digest and data block
37
+ *
38
+ * The order of fields within this structure is designed to minimise
39
+ * code size.
40
+ */
41
+struct md5_digest_data {
42
+	/** Digest of data already processed */
43
+	struct md5_digest digest;
44
+	/** Accumulated data */
45
+	union md5_block data;
46
+} __attribute__ (( packed ));
13 47
 
14
-struct md5_ctx {
15
-	u32 hash[MD5_HASH_WORDS];
16
-	u32 block[MD5_BLOCK_WORDS];
17
-	u64 byte_count;
48
+/** MD5 digest and data block */
49
+union md5_digest_data_dwords {
50
+	/** Digest and data block */
51
+	struct md5_digest_data dd;
52
+	/** Raw dwords */
53
+	uint32_t dword[ sizeof ( struct md5_digest_data ) /
54
+			sizeof ( uint32_t ) ];
18 55
 };
19 56
 
20
-#define MD5_CTX_SIZE sizeof ( struct md5_ctx )
57
+/** An MD5 context */
58
+struct md5_context {
59
+	/** Amount of accumulated data */
60
+	size_t len;
61
+	/** Digest and accumulated data */
62
+	union md5_digest_data_dwords ddd;
63
+} __attribute__ (( packed ));
64
+
65
+/** MD5 context size */
66
+#define MD5_CTX_SIZE sizeof ( struct md5_context )
67
+
68
+/** MD5 digest size */
69
+#define MD5_DIGEST_SIZE sizeof ( struct md5_digest )
21 70
 
22 71
 extern struct digest_algorithm md5_algorithm;
23 72
 

Chargement…
Annuler
Enregistrer