]>
git.ipfire.org Git - people/ms/strongswan.git/blob - programs/pluto/md5.c
2 * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
3 * changes to accomodate it in the kernel by ji.
4 * Minor changes to make 64 bit clean by Peter Onion (i.e. using u_int*_t).
7 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
10 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
13 License to copy and use this software is granted provided that it
14 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
15 Algorithm" in all material mentioning or referencing this software
18 License is also granted to make and use derivative works provided
19 that such works are identified as "derived from the RSA Data
20 Security, Inc. MD5 Message-Digest Algorithm" in all material
21 mentioning or referencing the derived work.
23 RSA Data Security, Inc. makes no representations concerning either
24 the merchantability of this software or the suitability of this
25 software for any particular purpose. It is provided "as is"
26 without express or implied warranty of any kind.
28 These notices must be retained in any copies of any part of this
29 documentation and/or software.
35 * HAVEMEMCOPY is defined if mem* routines are available
37 * HAVEHTON is defined if htons() and htonl() can be used
38 * for big/little endian conversions
44 #include <sys/types.h> /* for u_int*_t */
45 #include <endian.h> /* sets BYTE_ORDER, LITTLE_ENDIAN, and BIG_ENDIAN */
49 #define HAVEMEMCOPY 1 /* use ISO C's memcpy and memset */
51 /* Constants for MD5Transform routine.
71 #define MD5Transform _MD5Transform
73 static void MD5Transform
PROTO_LIST ((UINT4
[4], const unsigned char [64]));
75 #if BYTE_ORDER == LITTLE_ENDIAN
76 #define Encode MD5_memcpy
77 #define Decode MD5_memcpy
79 static void Encode PROTO_LIST
80 ((unsigned char *, UINT4
*, unsigned int));
81 static void Decode PROTO_LIST
82 ((UINT4
*, unsigned char *, unsigned int));
87 #define MD5_memcpy memcpy
88 #define MD5_memset memset
91 #define MD5_memcpy(_a,_b,_c) memcpy((_a), (_b),(_c))
92 #define MD5_memset(_a,_b,_c) memset((_a), '\0',(_c))
94 static void MD5_memcpy
PROTO_LIST ((POINTER
, POINTER
, unsigned int));
95 static void MD5_memset
PROTO_LIST ((POINTER
, int, unsigned int));
98 static unsigned char PADDING
[64] = {
99 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
104 /* F, G, H and I are basic MD5 functions.
106 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
107 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
108 #define H(x, y, z) ((x) ^ (y) ^ (z))
109 #define I(x, y, z) ((y) ^ ((x) | (~z)))
111 /* ROTATE_LEFT rotates x left n bits.
113 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
115 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
116 Rotation is separate from addition to prevent recomputation.
118 #define FF(a, b, c, d, x, s, ac) { \
119 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
120 (a) = ROTATE_LEFT ((a), (s)); \
123 #define GG(a, b, c, d, x, s, ac) { \
124 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
125 (a) = ROTATE_LEFT ((a), (s)); \
128 #define HH(a, b, c, d, x, s, ac) { \
129 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
130 (a) = ROTATE_LEFT ((a), (s)); \
133 #define II(a, b, c, d, x, s, ac) { \
134 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
135 (a) = ROTATE_LEFT ((a), (s)); \
139 /* MD5 initialization. Begins an MD5 operation, writing a new context.
141 void MD5Init (context
)
142 MD5_CTX
*context
; /* context */
144 context
->count
[0] = context
->count
[1] = 0;
145 /* Load magic initialization constants.
147 context
->state
[0] = 0x67452301;
148 context
->state
[1] = 0xefcdab89;
149 context
->state
[2] = 0x98badcfe;
150 context
->state
[3] = 0x10325476;
153 /* MD5 block update operation. Continues an MD5 message-digest
154 operation, processing another message block, and updating the
157 void MD5Update (context
, input
, inputLen
)
158 MD5_CTX
*context
; /* context */
159 const unsigned char *input
; /* input block */
160 UINT4 inputLen
; /* length of input block */
163 unsigned int index
, partLen
;
165 /* Compute number of bytes mod 64 */
166 index
= (unsigned int)((context
->count
[0] >> 3) & 0x3F);
168 /* Update number of bits */
169 if ((context
->count
[0] += (inputLen
<< 3)) < (inputLen
<< 3))
171 context
->count
[1] += (inputLen
>> 29);
173 partLen
= 64 - index
;
175 /* Transform as many times as possible. */
176 if (inputLen
>= partLen
) {
177 MD5_memcpy((POINTER
)&context
->buffer
[index
], (CONSTPOINTER
)input
, partLen
);
178 MD5Transform (context
->state
, context
->buffer
);
180 for (i
= partLen
; i
+ 63 < inputLen
; i
+= 64)
181 MD5Transform (context
->state
, &input
[i
]);
188 /* Buffer remaining input */
189 MD5_memcpy((POINTER
)&context
->buffer
[index
], (CONSTPOINTER
)&input
[i
], inputLen
-i
);
192 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
193 the message digest and zeroizing the context.
195 void MD5Final (digest
, context
)
196 unsigned char digest
[16]; /* message digest */
197 MD5_CTX
*context
; /* context */
199 unsigned char bits
[8];
200 unsigned int index
, padLen
;
202 /* Save number of bits */
203 Encode (bits
, context
->count
, 8);
205 /* Pad out to 56 mod 64.
207 index
= (unsigned int)((context
->count
[0] >> 3) & 0x3f);
208 padLen
= (index
< 56) ? (56 - index
) : (120 - index
);
209 MD5Update (context
, PADDING
, padLen
);
211 /* Append length (before padding) */
212 MD5Update (context
, bits
, 8);
214 if (digest
!= NULL
) /* Bill Simpson's padding */
216 /* store state in digest */
217 Encode (digest
, context
->state
, 16);
219 /* Zeroize sensitive information.
221 MD5_memset ((POINTER
)context
, 0, sizeof (*context
));
225 /* MD5 basic transformation. Transforms state based on block.
227 static void MD5Transform (state
, block
)
229 const unsigned char block
[64];
231 UINT4 a
= state
[0], b
= state
[1], c
= state
[2], d
= state
[3], x
[16];
233 Decode (x
, block
, 64);
236 FF (a
, b
, c
, d
, x
[ 0], S11
, 0xd76aa478); /* 1 */
237 FF (d
, a
, b
, c
, x
[ 1], S12
, 0xe8c7b756); /* 2 */
238 FF (c
, d
, a
, b
, x
[ 2], S13
, 0x242070db); /* 3 */
239 FF (b
, c
, d
, a
, x
[ 3], S14
, 0xc1bdceee); /* 4 */
240 FF (a
, b
, c
, d
, x
[ 4], S11
, 0xf57c0faf); /* 5 */
241 FF (d
, a
, b
, c
, x
[ 5], S12
, 0x4787c62a); /* 6 */
242 FF (c
, d
, a
, b
, x
[ 6], S13
, 0xa8304613); /* 7 */
243 FF (b
, c
, d
, a
, x
[ 7], S14
, 0xfd469501); /* 8 */
244 FF (a
, b
, c
, d
, x
[ 8], S11
, 0x698098d8); /* 9 */
245 FF (d
, a
, b
, c
, x
[ 9], S12
, 0x8b44f7af); /* 10 */
246 FF (c
, d
, a
, b
, x
[10], S13
, 0xffff5bb1); /* 11 */
247 FF (b
, c
, d
, a
, x
[11], S14
, 0x895cd7be); /* 12 */
248 FF (a
, b
, c
, d
, x
[12], S11
, 0x6b901122); /* 13 */
249 FF (d
, a
, b
, c
, x
[13], S12
, 0xfd987193); /* 14 */
250 FF (c
, d
, a
, b
, x
[14], S13
, 0xa679438e); /* 15 */
251 FF (b
, c
, d
, a
, x
[15], S14
, 0x49b40821); /* 16 */
254 GG (a
, b
, c
, d
, x
[ 1], S21
, 0xf61e2562); /* 17 */
255 GG (d
, a
, b
, c
, x
[ 6], S22
, 0xc040b340); /* 18 */
256 GG (c
, d
, a
, b
, x
[11], S23
, 0x265e5a51); /* 19 */
257 GG (b
, c
, d
, a
, x
[ 0], S24
, 0xe9b6c7aa); /* 20 */
258 GG (a
, b
, c
, d
, x
[ 5], S21
, 0xd62f105d); /* 21 */
259 GG (d
, a
, b
, c
, x
[10], S22
, 0x2441453); /* 22 */
260 GG (c
, d
, a
, b
, x
[15], S23
, 0xd8a1e681); /* 23 */
261 GG (b
, c
, d
, a
, x
[ 4], S24
, 0xe7d3fbc8); /* 24 */
262 GG (a
, b
, c
, d
, x
[ 9], S21
, 0x21e1cde6); /* 25 */
263 GG (d
, a
, b
, c
, x
[14], S22
, 0xc33707d6); /* 26 */
264 GG (c
, d
, a
, b
, x
[ 3], S23
, 0xf4d50d87); /* 27 */
265 GG (b
, c
, d
, a
, x
[ 8], S24
, 0x455a14ed); /* 28 */
266 GG (a
, b
, c
, d
, x
[13], S21
, 0xa9e3e905); /* 29 */
267 GG (d
, a
, b
, c
, x
[ 2], S22
, 0xfcefa3f8); /* 30 */
268 GG (c
, d
, a
, b
, x
[ 7], S23
, 0x676f02d9); /* 31 */
269 GG (b
, c
, d
, a
, x
[12], S24
, 0x8d2a4c8a); /* 32 */
272 HH (a
, b
, c
, d
, x
[ 5], S31
, 0xfffa3942); /* 33 */
273 HH (d
, a
, b
, c
, x
[ 8], S32
, 0x8771f681); /* 34 */
274 HH (c
, d
, a
, b
, x
[11], S33
, 0x6d9d6122); /* 35 */
275 HH (b
, c
, d
, a
, x
[14], S34
, 0xfde5380c); /* 36 */
276 HH (a
, b
, c
, d
, x
[ 1], S31
, 0xa4beea44); /* 37 */
277 HH (d
, a
, b
, c
, x
[ 4], S32
, 0x4bdecfa9); /* 38 */
278 HH (c
, d
, a
, b
, x
[ 7], S33
, 0xf6bb4b60); /* 39 */
279 HH (b
, c
, d
, a
, x
[10], S34
, 0xbebfbc70); /* 40 */
280 HH (a
, b
, c
, d
, x
[13], S31
, 0x289b7ec6); /* 41 */
281 HH (d
, a
, b
, c
, x
[ 0], S32
, 0xeaa127fa); /* 42 */
282 HH (c
, d
, a
, b
, x
[ 3], S33
, 0xd4ef3085); /* 43 */
283 HH (b
, c
, d
, a
, x
[ 6], S34
, 0x4881d05); /* 44 */
284 HH (a
, b
, c
, d
, x
[ 9], S31
, 0xd9d4d039); /* 45 */
285 HH (d
, a
, b
, c
, x
[12], S32
, 0xe6db99e5); /* 46 */
286 HH (c
, d
, a
, b
, x
[15], S33
, 0x1fa27cf8); /* 47 */
287 HH (b
, c
, d
, a
, x
[ 2], S34
, 0xc4ac5665); /* 48 */
290 II (a
, b
, c
, d
, x
[ 0], S41
, 0xf4292244); /* 49 */
291 II (d
, a
, b
, c
, x
[ 7], S42
, 0x432aff97); /* 50 */
292 II (c
, d
, a
, b
, x
[14], S43
, 0xab9423a7); /* 51 */
293 II (b
, c
, d
, a
, x
[ 5], S44
, 0xfc93a039); /* 52 */
294 II (a
, b
, c
, d
, x
[12], S41
, 0x655b59c3); /* 53 */
295 II (d
, a
, b
, c
, x
[ 3], S42
, 0x8f0ccc92); /* 54 */
296 II (c
, d
, a
, b
, x
[10], S43
, 0xffeff47d); /* 55 */
297 II (b
, c
, d
, a
, x
[ 1], S44
, 0x85845dd1); /* 56 */
298 II (a
, b
, c
, d
, x
[ 8], S41
, 0x6fa87e4f); /* 57 */
299 II (d
, a
, b
, c
, x
[15], S42
, 0xfe2ce6e0); /* 58 */
300 II (c
, d
, a
, b
, x
[ 6], S43
, 0xa3014314); /* 59 */
301 II (b
, c
, d
, a
, x
[13], S44
, 0x4e0811a1); /* 60 */
302 II (a
, b
, c
, d
, x
[ 4], S41
, 0xf7537e82); /* 61 */
303 II (d
, a
, b
, c
, x
[11], S42
, 0xbd3af235); /* 62 */
304 II (c
, d
, a
, b
, x
[ 2], S43
, 0x2ad7d2bb); /* 63 */
305 II (b
, c
, d
, a
, x
[ 9], S44
, 0xeb86d391); /* 64 */
312 /* Zeroize sensitive information.
314 MD5_memset ((POINTER
)x
, 0, sizeof (x
));
317 #if BYTE_ORDER != LITTLE_ENDIAN
319 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
322 static void Encode (output
, input
, len
)
323 unsigned char *output
;
329 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4) {
330 output
[j
] = (unsigned char)(input
[i
] & 0xff);
331 output
[j
+1] = (unsigned char)((input
[i
] >> 8) & 0xff);
332 output
[j
+2] = (unsigned char)((input
[i
] >> 16) & 0xff);
333 output
[j
+3] = (unsigned char)((input
[i
] >> 24) & 0xff);
337 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
340 static void Decode (output
, input
, len
)
342 unsigned char *input
;
347 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4)
348 output
[i
] = ((UINT4
)input
[j
]) | (((UINT4
)input
[j
+1]) << 8) |
349 (((UINT4
)input
[j
+2]) << 16) | (((UINT4
)input
[j
+3]) << 24);
356 /* Note: Replace "for loop" with standard memcpy if possible.
359 static void MD5_memcpy (output
, input
, len
)
366 for (i
= 0; i
< len
; i
++)
368 output
[i
] = input
[i
];
371 /* Note: Replace "for loop" with standard memset if possible.
373 static void MD5_memset (output
, value
, len
)
380 for (i
= 0; i
< len
; i
++)
381 ((char *)output
)[i
] = (char)value
;