1 /*
2 ** OSSP uuid - Universally Unique Identifier
3 ** Copyright (c) 2004-2008 Ralf S. Engelschall <rse@engelschall.com>
4 ** Copyright (c) 2004-2008 The OSSP Project <http://www.ossp.org/>
5 **
6 ** This file is part of OSSP uuid, a library for the generation
7 ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
8 **
9 ** Permission to use, copy, modify, and distribute this software for
10 ** any purpose with or without fee is hereby granted, provided that
11 ** the above copyright notice and this permission notice appear in all
12 ** copies.
13 **
14 ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
15 ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
18 ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24 ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 ** SUCH DAMAGE.
26 **
27 ** uuid_md5.c: MD5 API implementation
28 */
29
30 /* own headers (part 1/2) */
31 #include "uuid_ac.h"
32
33 /* system headers */
34 #include <stdlib.h>
35 #include <string.h>
36
37 /* own headers (part 2/2) */
38 #include "uuid_md5.h"
39
40 /*
41 * This is a RFC 1321 compliant Message Digest 5 (MD5) algorithm
42 * implementation. It is directly derived from the RSA code published in
43 * RFC 1321 with just the following functionality preserving changes:
44 * - converted function definitions from K&R to ANSI C
45 * - included contents of the "global.h" and "md5.h" headers
46 * - moved the SXX defines into the MD5Transform function
47 * - replaced MD5_memcpy() with memcpy(3) and MD5_memset() with memset(3)
48 * - renamed "index" variables to "idx" to avoid namespace conflicts
49 * - reformatted C style to conform with OSSP C style
50 * - added own OSSP style frontend API
51 */
52
53 /*
54 ** ==== BEGIN RFC 1321 CODE ====
55 */
56
57 /*
58 * RSA Data Security, Inc., MD5 message-digest algorithm
59 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991.
60 * All rights reserved.
61 *
62 * License to copy and use this software is granted provided that it
63 * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
64 * Algorithm" in all material mentioning or referencing this software
65 * or this function.
66 *
67 * License is also granted to make and use derivative works provided
68 * that such works are identified as "derived from the RSA Data
69 * Security, Inc. MD5 Message-Digest Algorithm" in all material
70 * mentioning or referencing the derived work.
71 *
72 * RSA Data Security, Inc. makes no representations concerning either
73 * the merchantability of this software or the suitability of this
74 * software for any particular purpose. It is provided "as is"
75 * without express or implied warranty of any kind.
76 *
77 * These notices must be retained in any copies of any part of this
78 * documentation and/or software.
79 */
80
81 /* POINTER defines a generic pointer type */
82 typedef unsigned char *POINTER;
83
84 /* UINT4 defines a four byte word */
85 #if SIZEOF_UNSIGNED_SHORT == 4
86 typedef unsigned short int UINT4;
87 #elif SIZEOF_UNSIGNED_INT == 4
88 typedef unsigned int UINT4;
89 #elif SIZEOF_UNSIGNED_LONG == 4
90 typedef unsigned long int UINT4;
91 #elif SIZEOF_UNSIGNED_LONG_LONG == 4
92 typedef unsigned long long int UINT4;
93 #else
94 #error ERROR: unable to determine UINT4 type (four byte word)
95 #endif
96
97 /* MD5 context. */
98 typedef struct {
99 UINT4 state[4]; /* state (ABCD) */
100 UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
101 unsigned char buffer[64]; /* input buffer */
102 } MD5_CTX;
103
104 /* prototypes for internal functions */
105 static void MD5Init (MD5_CTX *_ctx);
106 static void MD5Update (MD5_CTX *_ctx, unsigned char *, unsigned int);
107 static void MD5Final (unsigned char [], MD5_CTX *);
108 static void MD5Transform (UINT4 [], unsigned char []);
109 static void Encode (unsigned char *, UINT4 *, unsigned int);
110 static void Decode (UINT4 *, unsigned char *, unsigned int);
111
112 /* finalization padding */
113 static unsigned char PADDING[64] = {
114 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
117 };
118
119 /* F, G, H and I are basic MD5 functions. */
120 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
121 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
122 #define H(x, y, z) ((x) ^ (y) ^ (z))
123 #define I(x, y, z) ((y) ^ ((x) | (~z)))
124
125 /* ROTATE_LEFT rotates x left n bits. */
126 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
127
128 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
129 Rotation is separate from addition to prevent recomputation. */
130 #define FF(a, b, c, d, x, s, ac) { \
131 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
132 (a) = ROTATE_LEFT ((a), (s)); \
133 (a) += (b); \
134 }
135 #define GG(a, b, c, d, x, s, ac) { \
136 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
137 (a) = ROTATE_LEFT ((a), (s)); \
138 (a) += (b); \
139 }
140 #define HH(a, b, c, d, x, s, ac) { \
141 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
142 (a) = ROTATE_LEFT ((a), (s)); \
143 (a) += (b); \
144 }
145 #define II(a, b, c, d, x, s, ac) { \
146 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
147 (a) = ROTATE_LEFT ((a), (s)); \
148 (a) += (b); \
149 }
150
151 /* MD5 initialization. Begins an MD5 operation, writing a new context. */
MD5Init(MD5_CTX * context)152 static void MD5Init(
153 MD5_CTX *context)
154 {
155 context->count[0] = context->count[1] = 0;
156
157 /* Load magic initialization constants. */
158 context->state[0] = 0x67452301;
159 context->state[1] = 0xefcdab89;
160 context->state[2] = 0x98badcfe;
161 context->state[3] = 0x10325476;
162 return;
163 }
164
165 /* MD5 block update operation. Continues an MD5 message-digest
166 operation, processing another message block, and updating the
167 context. */
MD5Update(MD5_CTX * context,unsigned char * input,unsigned int inputLen)168 static void MD5Update(
169 MD5_CTX *context, /* context */
170 unsigned char *input, /* input block */
171 unsigned int inputLen) /* length of input block */
172 {
173 unsigned int i, idx, partLen;
174
175 /* Compute number of bytes mod 64 */
176 idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
177
178 /* Update number of bits */
179 if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
180 context->count[1]++;
181 context->count[1] += ((UINT4)inputLen >> 29);
182
183 partLen = (unsigned int)64 - idx;
184
185 /* Transform as many times as possible. */
186 if (inputLen >= partLen) {
187 memcpy((POINTER)&context->buffer[idx], (POINTER)input, (size_t)partLen);
188 MD5Transform(context->state, context->buffer);
189 for (i = partLen; i + 63 < inputLen; i += 64)
190 MD5Transform(context->state, &input[i]);
191 idx = 0;
192 }
193 else
194 i = 0;
195
196 /* Buffer remaining input */
197 memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i], (size_t)(inputLen - i));
198 }
199
200 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
201 the message digest and zeroizing the context. */
MD5Final(unsigned char digest[],MD5_CTX * context)202 static void MD5Final(
203 unsigned char digest[], /* message digest */
204 MD5_CTX *context) /* context */
205 {
206 unsigned char bits[8];
207 unsigned int idx, padLen;
208
209 /* Save number of bits */
210 Encode(bits, context->count, 8);
211
212 /* Pad out to 56 mod 64. */
213 idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
214 padLen = (idx < 56) ? ((unsigned int)56 - idx) : ((unsigned int)120 - idx);
215 MD5Update(context, PADDING, padLen);
216
217 /* Append length (before padding) */
218 MD5Update(context, bits, 8);
219
220 /* Store state in digest */
221 Encode(digest, context->state, 16);
222
223 /* Zeroize sensitive information. */
224 memset((POINTER)context, 0, sizeof(*context));
225 }
226
227 /* MD5 basic transformation. Transforms state based on block. */
MD5Transform(UINT4 state[],unsigned char block[])228 static void MD5Transform(
229 UINT4 state[],
230 unsigned char block[])
231 {
232 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
233
234 Decode(x, block, 64);
235
236 /* Round 1 */
237 #define S11 7
238 #define S12 12
239 #define S13 17
240 #define S14 22
241 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
242 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
243 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
244 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
245 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
246 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
247 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
248 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
249 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
250 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
251 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
252 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
253 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
254 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
255 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
256 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
257
258 /* Round 2 */
259 #define S21 5
260 #define S22 9
261 #define S23 14
262 #define S24 20
263 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
264 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
265 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
266 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
267 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
268 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
269 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
270 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
271 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
272 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
273 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
274 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
275 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
276 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
277 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
278 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
279
280 /* Round 3 */
281 #define S31 4
282 #define S32 11
283 #define S33 16
284 #define S34 23
285 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
286 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
287 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
288 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
289 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
290 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
291 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
292 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
293 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
294 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
295 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
296 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
297 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
298 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
299 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
300 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
301
302 /* Round 4 */
303 #define S41 6
304 #define S42 10
305 #define S43 15
306 #define S44 21
307 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
308 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
309 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
310 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
311 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
312 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
313 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
314 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
315 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
316 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
317 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
318 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
319 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
320 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
321 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
322 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
323
324 state[0] += a;
325 state[1] += b;
326 state[2] += c;
327 state[3] += d;
328
329 /* Zeroize sensitive information. */
330 memset((POINTER)x, 0, sizeof(x));
331 }
332
333 /* Encodes input (UINT4) into output (unsigned char).
334 Assumes len is a multiple of 4. */
Encode(unsigned char * output,UINT4 * input,unsigned int len)335 static void Encode(
336 unsigned char *output,
337 UINT4 *input,
338 unsigned int len)
339 {
340 unsigned int i, j;
341
342 for (i = 0, j = 0; j < len; i++, j += 4) {
343 output[j] = (unsigned char)( input[i] & 0xff);
344 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
345 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
346 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
347 }
348 return;
349 }
350
351 /* Decodes input (unsigned char) into output (UINT4).
352 Assumes len is a multiple of 4. */
Decode(UINT4 * output,unsigned char * input,unsigned int len)353 static void Decode(
354 UINT4 *output,
355 unsigned char *input,
356 unsigned int len)
357 {
358 unsigned int i, j;
359
360 for (i = 0, j = 0; j < len; i++, j += 4)
361 output[i] = ( (UINT4)input[j])
362 | (((UINT4)input[j+1]) << 8 )
363 | (((UINT4)input[j+2]) << 16)
364 | (((UINT4)input[j+3]) << 24);
365 return;
366 }
367
368 /*
369 ** ==== END RFC 1321 CODE ====
370 */
371
372 struct md5_st {
373 MD5_CTX ctx;
374 };
375
md5_create(md5_t ** md5)376 md5_rc_t md5_create(md5_t **md5)
377 {
378 if (md5 == NULL)
379 return MD5_RC_ARG;
380 if ((*md5 = (md5_t *)malloc(sizeof(md5_t))) == NULL)
381 return MD5_RC_MEM;
382 MD5Init(&((*md5)->ctx));
383 return MD5_RC_OK;
384 }
385
md5_init(md5_t * md5)386 md5_rc_t md5_init(md5_t *md5)
387 {
388 if (md5 == NULL)
389 return MD5_RC_ARG;
390 MD5Init(&(md5->ctx));
391 return MD5_RC_OK;
392 }
393
md5_update(md5_t * md5,const void * data_ptr,size_t data_len)394 md5_rc_t md5_update(md5_t *md5, const void *data_ptr, size_t data_len)
395 {
396 if (md5 == NULL)
397 return MD5_RC_ARG;
398 MD5Update(&(md5->ctx), (unsigned char *)data_ptr, (unsigned int)data_len);
399 return MD5_RC_OK;
400 }
401
md5_store(md5_t * md5,void ** data_ptr,size_t * data_len)402 md5_rc_t md5_store(md5_t *md5, void **data_ptr, size_t *data_len)
403 {
404 MD5_CTX ctx;
405
406 if (md5 == NULL || data_ptr == NULL)
407 return MD5_RC_ARG;
408 if (*data_ptr == NULL) {
409 if ((*data_ptr = malloc(MD5_LEN_BIN)) == NULL)
410 return MD5_RC_MEM;
411 if (data_len != NULL)
412 *data_len = MD5_LEN_BIN;
413 }
414 else {
415 if (data_len != NULL) {
416 if (*data_len < MD5_LEN_BIN)
417 return MD5_RC_MEM;
418 *data_len = MD5_LEN_BIN;
419 }
420 }
421 memcpy((void *)(&ctx), (void *)(&(md5->ctx)), sizeof(MD5_CTX));
422 MD5Final((unsigned char *)(*data_ptr), &(ctx));
423 return MD5_RC_OK;
424 }
425
md5_format(md5_t * md5,char ** data_ptr,size_t * data_len)426 md5_rc_t md5_format(md5_t *md5, char **data_ptr, size_t *data_len)
427 {
428 static const char hex[] = "0123456789abcdef";
429 unsigned char buf[MD5_LEN_BIN];
430 unsigned char *bufptr;
431 size_t buflen;
432 md5_rc_t rc;
433 int i;
434
435 if (md5 == NULL || data_ptr == NULL)
436 return MD5_RC_ARG;
437 if (*data_ptr == NULL) {
438 if ((*data_ptr = (char *)malloc(MD5_LEN_STR+1)) == NULL)
439 return MD5_RC_MEM;
440 if (data_len != NULL)
441 *data_len = MD5_LEN_STR+1;
442 }
443 else {
444 if (data_len != NULL) {
445 if (*data_len < MD5_LEN_STR+1)
446 return MD5_RC_MEM;
447 *data_len = MD5_LEN_STR+1;
448 }
449 }
450
451 bufptr = buf;
452 buflen = sizeof(buf);
453 if ((rc = md5_store(md5, (void **)((void *)&bufptr), &buflen)) != MD5_RC_OK)
454 return rc;
455
456 for (i = 0; i < (int)buflen; i++) {
457 (*data_ptr)[(i*2)+0] = hex[(int)(bufptr[i] >> 4)];
458 (*data_ptr)[(i*2)+1] = hex[(int)(bufptr[i] & 0x0f)];
459 }
460 (*data_ptr)[(i*2)] = '\0';
461 return MD5_RC_OK;
462 }
463
md5_destroy(md5_t * md5)464 md5_rc_t md5_destroy(md5_t *md5)
465 {
466 if (md5 == NULL)
467 return MD5_RC_ARG;
468 free(md5);
469 return MD5_RC_OK;
470 }
471
472