~ubuntu-branches/ubuntu/wily/psqlodbc/wily-proposed

« back to all changes in this revision

Viewing changes to md5.c

  • Committer: Package Import Robot
  • Author(s): Christoph Berg
  • Date: 2014-05-29 23:17:25 UTC
  • mfrom: (16.1.8 sid)
  • Revision ID: package-import@ubuntu.com-20140529231725-nhpolx85545e4rk8
Tags: 1:09.03.0300-1
* New upstream release.
* Patch bogus expected output of test catalogfunctions.
* Set team as maintainer.
* Bump to dh 9.
* Use /usr/share/cdbs/1/rules/autoreconf.mk. Closes: #744650.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *      md5.c
3
 
 *
4
 
 *      Implements      the  MD5 Message-Digest Algorithm as specified in
5
 
 *      RFC  1321.      This  implementation  is a simple one, in that it
6
 
 *      needs  every  input  byte  to  be  buffered  before doing any
7
 
 *      calculations.  I  do  not  expect  this  file  to be used for
8
 
 *      general  purpose  MD5'ing  of large amounts of data, only for
9
 
 *      generating hashed passwords from limited input.
10
 
 *
11
 
 *      Sverre H. Huseby <sverrehu@online.no>
12
 
 *
13
 
 *      Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
14
 
 *      Portions Copyright (c) 1994, Regents of the University of California
15
 
 */
16
 
 
17
 
 
18
 
/*
19
 
 *      NOTE:
20
 
 *
21
 
 *      This file was copied from backend/libpq once.
22
 
 */
23
 
 
24
 
#include "md5.h"
25
 
 
26
 
 
27
 
 
28
 
/*
29
 
 *      PRIVATE FUNCTIONS
30
 
 */
31
 
 
32
 
 
33
 
/*
34
 
 *      The returned array is allocated using malloc.  the caller should free it
35
 
 *      when it is no longer needed.
36
 
 */
37
 
static uint8 *
38
 
createPaddedCopyWithLength(uint8 *b, uint32 *l)
39
 
{
40
 
        uint8      *ret;
41
 
        uint32          q;
42
 
        uint32          len,
43
 
                                newLen448;
44
 
        uint32          len_high,
45
 
                                len_low;                /* 64-bit value split into 32-bit sections */
46
 
 
47
 
        len = ((b == NULL) ? 0 : *l);
48
 
        newLen448 = len + 64 - (len % 64) - 8;
49
 
        if (newLen448 <= len)
50
 
                newLen448 += 64;
51
 
 
52
 
        *l = newLen448 + 8;
53
 
        if ((ret = (uint8 *) malloc(sizeof(uint8) * *l)) == NULL)
54
 
                return NULL;
55
 
 
56
 
        if (b != NULL)
57
 
                memcpy(ret, b, sizeof(uint8) * len);
58
 
 
59
 
        /* pad */
60
 
        ret[len] = 0x80;
61
 
        for (q = len + 1; q < newLen448; q++)
62
 
                ret[q] = 0x00;
63
 
 
64
 
        /* append length as a 64 bit bitcount */
65
 
        len_low = len;
66
 
        /* split into two 32-bit values */
67
 
        /* we only look at the bottom 32-bits */
68
 
        len_high = len >> 29;
69
 
        len_low <<= 3;
70
 
        q = newLen448;
71
 
        ret[q++] = (len_low & 0xff);
72
 
        len_low >>= 8;
73
 
        ret[q++] = (len_low & 0xff);
74
 
        len_low >>= 8;
75
 
        ret[q++] = (len_low & 0xff);
76
 
        len_low >>= 8;
77
 
        ret[q++] = (len_low & 0xff);
78
 
        ret[q++] = (len_high & 0xff);
79
 
        len_high >>= 8;
80
 
        ret[q++] = (len_high & 0xff);
81
 
        len_high >>= 8;
82
 
        ret[q++] = (len_high & 0xff);
83
 
        len_high >>= 8;
84
 
        ret[q] = (len_high & 0xff);
85
 
 
86
 
        return ret;
87
 
}
88
 
 
89
 
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
90
 
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
91
 
#define H(x, y, z) ((x) ^ (y) ^ (z))
92
 
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
93
 
#define ROT_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
94
 
 
95
 
static void
96
 
doTheRounds(uint32 X[16], uint32 state[4])
97
 
{
98
 
        uint32          a,
99
 
                                b,
100
 
                                c,
101
 
                                d;
102
 
 
103
 
        a = state[0];
104
 
        b = state[1];
105
 
        c = state[2];
106
 
        d = state[3];
107
 
 
108
 
        /* round 1 */
109
 
        a = b + ROT_LEFT((a + F(b, c, d) + X[0] + 0xd76aa478), 7);      /* 1 */
110
 
        d = a + ROT_LEFT((d + F(a, b, c) + X[1] + 0xe8c7b756), 12); /* 2 */
111
 
        c = d + ROT_LEFT((c + F(d, a, b) + X[2] + 0x242070db), 17); /* 3 */
112
 
        b = c + ROT_LEFT((b + F(c, d, a) + X[3] + 0xc1bdceee), 22); /* 4 */
113
 
        a = b + ROT_LEFT((a + F(b, c, d) + X[4] + 0xf57c0faf), 7);      /* 5 */
114
 
        d = a + ROT_LEFT((d + F(a, b, c) + X[5] + 0x4787c62a), 12); /* 6 */
115
 
        c = d + ROT_LEFT((c + F(d, a, b) + X[6] + 0xa8304613), 17); /* 7 */
116
 
        b = c + ROT_LEFT((b + F(c, d, a) + X[7] + 0xfd469501), 22); /* 8 */
117
 
        a = b + ROT_LEFT((a + F(b, c, d) + X[8] + 0x698098d8), 7);      /* 9 */
118
 
        d = a + ROT_LEFT((d + F(a, b, c) + X[9] + 0x8b44f7af), 12); /* 10 */
119
 
        c = d + ROT_LEFT((c + F(d, a, b) + X[10] + 0xffff5bb1), 17);            /* 11 */
120
 
        b = c + ROT_LEFT((b + F(c, d, a) + X[11] + 0x895cd7be), 22);            /* 12 */
121
 
        a = b + ROT_LEFT((a + F(b, c, d) + X[12] + 0x6b901122), 7); /* 13 */
122
 
        d = a + ROT_LEFT((d + F(a, b, c) + X[13] + 0xfd987193), 12);            /* 14 */
123
 
        c = d + ROT_LEFT((c + F(d, a, b) + X[14] + 0xa679438e), 17);            /* 15 */
124
 
        b = c + ROT_LEFT((b + F(c, d, a) + X[15] + 0x49b40821), 22);            /* 16 */
125
 
 
126
 
        /* round 2 */
127
 
        a = b + ROT_LEFT((a + G(b, c, d) + X[1] + 0xf61e2562), 5);      /* 17 */
128
 
        d = a + ROT_LEFT((d + G(a, b, c) + X[6] + 0xc040b340), 9);      /* 18 */
129
 
        c = d + ROT_LEFT((c + G(d, a, b) + X[11] + 0x265e5a51), 14);            /* 19 */
130
 
        b = c + ROT_LEFT((b + G(c, d, a) + X[0] + 0xe9b6c7aa), 20); /* 20 */
131
 
        a = b + ROT_LEFT((a + G(b, c, d) + X[5] + 0xd62f105d), 5);      /* 21 */
132
 
        d = a + ROT_LEFT((d + G(a, b, c) + X[10] + 0x02441453), 9); /* 22 */
133
 
        c = d + ROT_LEFT((c + G(d, a, b) + X[15] + 0xd8a1e681), 14);            /* 23 */
134
 
        b = c + ROT_LEFT((b + G(c, d, a) + X[4] + 0xe7d3fbc8), 20); /* 24 */
135
 
        a = b + ROT_LEFT((a + G(b, c, d) + X[9] + 0x21e1cde6), 5);      /* 25 */
136
 
        d = a + ROT_LEFT((d + G(a, b, c) + X[14] + 0xc33707d6), 9); /* 26 */
137
 
        c = d + ROT_LEFT((c + G(d, a, b) + X[3] + 0xf4d50d87), 14); /* 27 */
138
 
        b = c + ROT_LEFT((b + G(c, d, a) + X[8] + 0x455a14ed), 20); /* 28 */
139
 
        a = b + ROT_LEFT((a + G(b, c, d) + X[13] + 0xa9e3e905), 5); /* 29 */
140
 
        d = a + ROT_LEFT((d + G(a, b, c) + X[2] + 0xfcefa3f8), 9);      /* 30 */
141
 
        c = d + ROT_LEFT((c + G(d, a, b) + X[7] + 0x676f02d9), 14); /* 31 */
142
 
        b = c + ROT_LEFT((b + G(c, d, a) + X[12] + 0x8d2a4c8a), 20);            /* 32 */
143
 
 
144
 
        /* round 3 */
145
 
        a = b + ROT_LEFT((a + H(b, c, d) + X[5] + 0xfffa3942), 4);      /* 33 */
146
 
        d = a + ROT_LEFT((d + H(a, b, c) + X[8] + 0x8771f681), 11); /* 34 */
147
 
        c = d + ROT_LEFT((c + H(d, a, b) + X[11] + 0x6d9d6122), 16);            /* 35 */
148
 
        b = c + ROT_LEFT((b + H(c, d, a) + X[14] + 0xfde5380c), 23);            /* 36 */
149
 
        a = b + ROT_LEFT((a + H(b, c, d) + X[1] + 0xa4beea44), 4);      /* 37 */
150
 
        d = a + ROT_LEFT((d + H(a, b, c) + X[4] + 0x4bdecfa9), 11); /* 38 */
151
 
        c = d + ROT_LEFT((c + H(d, a, b) + X[7] + 0xf6bb4b60), 16); /* 39 */
152
 
        b = c + ROT_LEFT((b + H(c, d, a) + X[10] + 0xbebfbc70), 23);            /* 40 */
153
 
        a = b + ROT_LEFT((a + H(b, c, d) + X[13] + 0x289b7ec6), 4); /* 41 */
154
 
        d = a + ROT_LEFT((d + H(a, b, c) + X[0] + 0xeaa127fa), 11); /* 42 */
155
 
        c = d + ROT_LEFT((c + H(d, a, b) + X[3] + 0xd4ef3085), 16); /* 43 */
156
 
        b = c + ROT_LEFT((b + H(c, d, a) + X[6] + 0x04881d05), 23); /* 44 */
157
 
        a = b + ROT_LEFT((a + H(b, c, d) + X[9] + 0xd9d4d039), 4);      /* 45 */
158
 
        d = a + ROT_LEFT((d + H(a, b, c) + X[12] + 0xe6db99e5), 11);            /* 46 */
159
 
        c = d + ROT_LEFT((c + H(d, a, b) + X[15] + 0x1fa27cf8), 16);            /* 47 */
160
 
        b = c + ROT_LEFT((b + H(c, d, a) + X[2] + 0xc4ac5665), 23); /* 48 */
161
 
 
162
 
        /* round 4 */
163
 
        a = b + ROT_LEFT((a + I(b, c, d) + X[0] + 0xf4292244), 6);      /* 49 */
164
 
        d = a + ROT_LEFT((d + I(a, b, c) + X[7] + 0x432aff97), 10); /* 50 */
165
 
        c = d + ROT_LEFT((c + I(d, a, b) + X[14] + 0xab9423a7), 15);            /* 51 */
166
 
        b = c + ROT_LEFT((b + I(c, d, a) + X[5] + 0xfc93a039), 21); /* 52 */
167
 
        a = b + ROT_LEFT((a + I(b, c, d) + X[12] + 0x655b59c3), 6); /* 53 */
168
 
        d = a + ROT_LEFT((d + I(a, b, c) + X[3] + 0x8f0ccc92), 10); /* 54 */
169
 
        c = d + ROT_LEFT((c + I(d, a, b) + X[10] + 0xffeff47d), 15);            /* 55 */
170
 
        b = c + ROT_LEFT((b + I(c, d, a) + X[1] + 0x85845dd1), 21); /* 56 */
171
 
        a = b + ROT_LEFT((a + I(b, c, d) + X[8] + 0x6fa87e4f), 6);      /* 57 */
172
 
        d = a + ROT_LEFT((d + I(a, b, c) + X[15] + 0xfe2ce6e0), 10);            /* 58 */
173
 
        c = d + ROT_LEFT((c + I(d, a, b) + X[6] + 0xa3014314), 15); /* 59 */
174
 
        b = c + ROT_LEFT((b + I(c, d, a) + X[13] + 0x4e0811a1), 21);            /* 60 */
175
 
        a = b + ROT_LEFT((a + I(b, c, d) + X[4] + 0xf7537e82), 6);      /* 61 */
176
 
        d = a + ROT_LEFT((d + I(a, b, c) + X[11] + 0xbd3af235), 10);            /* 62 */
177
 
        c = d + ROT_LEFT((c + I(d, a, b) + X[2] + 0x2ad7d2bb), 15); /* 63 */
178
 
        b = c + ROT_LEFT((b + I(c, d, a) + X[9] + 0xeb86d391), 21); /* 64 */
179
 
 
180
 
        state[0] += a;
181
 
        state[1] += b;
182
 
        state[2] += c;
183
 
        state[3] += d;
184
 
}
185
 
 
186
 
static int
187
 
calculateDigestFromBuffer(uint8 *b, uint32 len, uint8 sum[16])
188
 
{
189
 
        register uint32 i,
190
 
                                j,
191
 
                                k,
192
 
                                newI;
193
 
        uint32          l;
194
 
        uint8      *input;
195
 
        register uint32 *wbp;
196
 
        uint32          workBuff[16],
197
 
                                state[4];
198
 
 
199
 
        l = len;
200
 
 
201
 
        state[0] = 0x67452301;
202
 
        state[1] = 0xEFCDAB89;
203
 
        state[2] = 0x98BADCFE;
204
 
        state[3] = 0x10325476;
205
 
 
206
 
        if ((input = createPaddedCopyWithLength(b, &l)) == NULL)
207
 
                return 0;
208
 
 
209
 
        for (i = 0;;)
210
 
        {
211
 
                if ((newI = i + 16 * 4) > l)
212
 
                        break;
213
 
                k = i + 3;
214
 
                for (j = 0; j < 16; j++)
215
 
                {
216
 
                        wbp = (workBuff + j);
217
 
                        *wbp = input[k--];
218
 
                        *wbp <<= 8;
219
 
                        *wbp |= input[k--];
220
 
                        *wbp <<= 8;
221
 
                        *wbp |= input[k--];
222
 
                        *wbp <<= 8;
223
 
                        *wbp |= input[k];
224
 
                        k += 7;
225
 
                }
226
 
                doTheRounds(workBuff, state);
227
 
                i = newI;
228
 
        }
229
 
        free(input);
230
 
 
231
 
        j = 0;
232
 
        for (i = 0; i < 4; i++)
233
 
        {
234
 
                k = state[i];
235
 
                sum[j++] = (k & 0xff);
236
 
                k >>= 8;
237
 
                sum[j++] = (k & 0xff);
238
 
                k >>= 8;
239
 
                sum[j++] = (k & 0xff);
240
 
                k >>= 8;
241
 
                sum[j++] = (k & 0xff);
242
 
        }
243
 
        return 1;
244
 
}
245
 
 
246
 
static void
247
 
bytesToHex(uint8 b[16], char *s)
248
 
{
249
 
        static const char *hex = "0123456789abcdef";
250
 
        int                     q,
251
 
                                w;
252
 
 
253
 
        for (q = 0, w = 0; q < 16; q++)
254
 
        {
255
 
                s[w++] = hex[(b[q] >> 4) & 0x0F];
256
 
                s[w++] = hex[b[q] & 0x0F];
257
 
        }
258
 
        s[w] = '\0';
259
 
}
260
 
 
261
 
/*
262
 
 *      PUBLIC FUNCTIONS
263
 
 */
264
 
 
265
 
/*
266
 
 *      md5_hash
267
 
 *
268
 
 *      Calculates the MD5 sum of the bytes in a buffer.
269
 
 *
270
 
 *      SYNOPSIS          #include "crypt.h"
271
 
 *                                int md5_hash(const void *buff, size_t len, char *hexsum)
272
 
 *
273
 
 *      INPUT             buff    the buffer containing the bytes that you want
274
 
 *                                                the MD5 sum of.
275
 
 *                                len     number of bytes in the buffer.
276
 
 *
277
 
 *      OUTPUT            hexsum  the MD5 sum as a '\0'-terminated string of
278
 
 *                                                hexadecimal digits.  an MD5 sum is 16 bytes long.
279
 
 *                                                each byte is represented by two heaxadecimal
280
 
 *                                                characters.  you thus need to provide an array
281
 
 *                                                of 33 characters, including the trailing '\0'.
282
 
 *
283
 
 *      RETURNS           false on failure (out of memory for internal buffers) or
284
 
 *                                true on success.
285
 
 *
286
 
 *      STANDARDS         MD5 is described in RFC 1321.
287
 
 *
288
 
 *      AUTHOR            Sverre H. Huseby <sverrehu@online.no>
289
 
 *
290
 
 */
291
 
bool
292
 
md5_hash(const void *buff, size_t len, char *hexsum)
293
 
{
294
 
        uint8           sum[16];
295
 
 
296
 
        if (!calculateDigestFromBuffer((uint8 *) buff, (uint32) len, sum))
297
 
                return false;
298
 
 
299
 
        bytesToHex(sum, hexsum);
300
 
        return true;
301
 
}
302
 
 
303
 
 
304
 
 
305
 
/*
306
 
 * Computes MD5 checksum of "passwd" (a null-terminated string) followed
307
 
 * by "salt" (which need not be null-terminated).
308
 
 *
309
 
 * Output format is "md5" followed by a 32-hex-digit MD5 checksum.
310
 
 * Hence, the output buffer "buf" must be at least 36 bytes long.
311
 
 *
312
 
 * Returns TRUE if okay, FALSE on error (out of memory).
313
 
 */
314
 
bool
315
 
EncryptMD5(const char *passwd, const char *salt, size_t salt_len,
316
 
                   char *buf)
317
 
{
318
 
        size_t          passwd_len = strlen(passwd);
319
 
        char       *crypt_buf = malloc(passwd_len + salt_len + 1);
320
 
        bool            ret;
321
 
 
322
 
        if (!crypt_buf)
323
 
                return false;
324
 
 
325
 
        /*
326
 
         * Place salt at the end because it may be known by users trying to
327
 
         * crack the MD5 output.
328
 
         */
329
 
        memcpy(crypt_buf, passwd, passwd_len);
330
 
        memcpy(crypt_buf + passwd_len, salt, salt_len);
331
 
 
332
 
        strcpy(buf, "md5");
333
 
        ret = md5_hash(crypt_buf, passwd_len + salt_len, buf + 3);
334
 
 
335
 
        free(crypt_buf);
336
 
 
337
 
        return ret;
338
 
}
 
1
/*
 
2
 *      md5.c
 
3
 *
 
4
 *      Implements      the  MD5 Message-Digest Algorithm as specified in
 
5
 *      RFC  1321.      This  implementation  is a simple one, in that it
 
6
 *      needs  every  input  byte  to  be  buffered  before doing any
 
7
 *      calculations.  I  do  not  expect  this  file  to be used for
 
8
 *      general  purpose  MD5'ing  of large amounts of data, only for
 
9
 *      generating hashed passwords from limited input.
 
10
 *
 
11
 *      Sverre H. Huseby <sverrehu@online.no>
 
12
 *
 
13
 *      Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
 
14
 *      Portions Copyright (c) 1994, Regents of the University of California
 
15
 */
 
16
 
 
17
 
 
18
/*
 
19
 *      NOTE:
 
20
 *
 
21
 *      This file was copied from backend/libpq once.
 
22
 */
 
23
 
 
24
#include "md5.h"
 
25
 
 
26
 
 
27
 
 
28
/*
 
29
 *      PRIVATE FUNCTIONS
 
30
 */
 
31
 
 
32
 
 
33
/*
 
34
 *      The returned array is allocated using malloc.  the caller should free it
 
35
 *      when it is no longer needed.
 
36
 */
 
37
static uint8 *
 
38
createPaddedCopyWithLength(uint8 *b, uint32 *l)
 
39
{
 
40
        uint8      *ret;
 
41
        uint32          q;
 
42
        uint32          len,
 
43
                                newLen448;
 
44
        uint32          len_high,
 
45
                                len_low;                /* 64-bit value split into 32-bit sections */
 
46
 
 
47
        len = ((b == NULL) ? 0 : *l);
 
48
        newLen448 = len + 64 - (len % 64) - 8;
 
49
        if (newLen448 <= len)
 
50
                newLen448 += 64;
 
51
 
 
52
        *l = newLen448 + 8;
 
53
        if ((ret = (uint8 *) malloc(sizeof(uint8) * *l)) == NULL)
 
54
                return NULL;
 
55
 
 
56
        if (b != NULL)
 
57
                memcpy(ret, b, sizeof(uint8) * len);
 
58
 
 
59
        /* pad */
 
60
        ret[len] = 0x80;
 
61
        for (q = len + 1; q < newLen448; q++)
 
62
                ret[q] = 0x00;
 
63
 
 
64
        /* append length as a 64 bit bitcount */
 
65
        len_low = len;
 
66
        /* split into two 32-bit values */
 
67
        /* we only look at the bottom 32-bits */
 
68
        len_high = len >> 29;
 
69
        len_low <<= 3;
 
70
        q = newLen448;
 
71
        ret[q++] = (len_low & 0xff);
 
72
        len_low >>= 8;
 
73
        ret[q++] = (len_low & 0xff);
 
74
        len_low >>= 8;
 
75
        ret[q++] = (len_low & 0xff);
 
76
        len_low >>= 8;
 
77
        ret[q++] = (len_low & 0xff);
 
78
        ret[q++] = (len_high & 0xff);
 
79
        len_high >>= 8;
 
80
        ret[q++] = (len_high & 0xff);
 
81
        len_high >>= 8;
 
82
        ret[q++] = (len_high & 0xff);
 
83
        len_high >>= 8;
 
84
        ret[q] = (len_high & 0xff);
 
85
 
 
86
        return ret;
 
87
}
 
88
 
 
89
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
 
90
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
 
91
#define H(x, y, z) ((x) ^ (y) ^ (z))
 
92
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
 
93
#define ROT_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
 
94
 
 
95
static void
 
96
doTheRounds(uint32 X[16], uint32 state[4])
 
97
{
 
98
        uint32          a,
 
99
                                b,
 
100
                                c,
 
101
                                d;
 
102
 
 
103
        a = state[0];
 
104
        b = state[1];
 
105
        c = state[2];
 
106
        d = state[3];
 
107
 
 
108
        /* round 1 */
 
109
        a = b + ROT_LEFT((a + F(b, c, d) + X[0] + 0xd76aa478), 7);      /* 1 */
 
110
        d = a + ROT_LEFT((d + F(a, b, c) + X[1] + 0xe8c7b756), 12); /* 2 */
 
111
        c = d + ROT_LEFT((c + F(d, a, b) + X[2] + 0x242070db), 17); /* 3 */
 
112
        b = c + ROT_LEFT((b + F(c, d, a) + X[3] + 0xc1bdceee), 22); /* 4 */
 
113
        a = b + ROT_LEFT((a + F(b, c, d) + X[4] + 0xf57c0faf), 7);      /* 5 */
 
114
        d = a + ROT_LEFT((d + F(a, b, c) + X[5] + 0x4787c62a), 12); /* 6 */
 
115
        c = d + ROT_LEFT((c + F(d, a, b) + X[6] + 0xa8304613), 17); /* 7 */
 
116
        b = c + ROT_LEFT((b + F(c, d, a) + X[7] + 0xfd469501), 22); /* 8 */
 
117
        a = b + ROT_LEFT((a + F(b, c, d) + X[8] + 0x698098d8), 7);      /* 9 */
 
118
        d = a + ROT_LEFT((d + F(a, b, c) + X[9] + 0x8b44f7af), 12); /* 10 */
 
119
        c = d + ROT_LEFT((c + F(d, a, b) + X[10] + 0xffff5bb1), 17);            /* 11 */
 
120
        b = c + ROT_LEFT((b + F(c, d, a) + X[11] + 0x895cd7be), 22);            /* 12 */
 
121
        a = b + ROT_LEFT((a + F(b, c, d) + X[12] + 0x6b901122), 7); /* 13 */
 
122
        d = a + ROT_LEFT((d + F(a, b, c) + X[13] + 0xfd987193), 12);            /* 14 */
 
123
        c = d + ROT_LEFT((c + F(d, a, b) + X[14] + 0xa679438e), 17);            /* 15 */
 
124
        b = c + ROT_LEFT((b + F(c, d, a) + X[15] + 0x49b40821), 22);            /* 16 */
 
125
 
 
126
        /* round 2 */
 
127
        a = b + ROT_LEFT((a + G(b, c, d) + X[1] + 0xf61e2562), 5);      /* 17 */
 
128
        d = a + ROT_LEFT((d + G(a, b, c) + X[6] + 0xc040b340), 9);      /* 18 */
 
129
        c = d + ROT_LEFT((c + G(d, a, b) + X[11] + 0x265e5a51), 14);            /* 19 */
 
130
        b = c + ROT_LEFT((b + G(c, d, a) + X[0] + 0xe9b6c7aa), 20); /* 20 */
 
131
        a = b + ROT_LEFT((a + G(b, c, d) + X[5] + 0xd62f105d), 5);      /* 21 */
 
132
        d = a + ROT_LEFT((d + G(a, b, c) + X[10] + 0x02441453), 9); /* 22 */
 
133
        c = d + ROT_LEFT((c + G(d, a, b) + X[15] + 0xd8a1e681), 14);            /* 23 */
 
134
        b = c + ROT_LEFT((b + G(c, d, a) + X[4] + 0xe7d3fbc8), 20); /* 24 */
 
135
        a = b + ROT_LEFT((a + G(b, c, d) + X[9] + 0x21e1cde6), 5);      /* 25 */
 
136
        d = a + ROT_LEFT((d + G(a, b, c) + X[14] + 0xc33707d6), 9); /* 26 */
 
137
        c = d + ROT_LEFT((c + G(d, a, b) + X[3] + 0xf4d50d87), 14); /* 27 */
 
138
        b = c + ROT_LEFT((b + G(c, d, a) + X[8] + 0x455a14ed), 20); /* 28 */
 
139
        a = b + ROT_LEFT((a + G(b, c, d) + X[13] + 0xa9e3e905), 5); /* 29 */
 
140
        d = a + ROT_LEFT((d + G(a, b, c) + X[2] + 0xfcefa3f8), 9);      /* 30 */
 
141
        c = d + ROT_LEFT((c + G(d, a, b) + X[7] + 0x676f02d9), 14); /* 31 */
 
142
        b = c + ROT_LEFT((b + G(c, d, a) + X[12] + 0x8d2a4c8a), 20);            /* 32 */
 
143
 
 
144
        /* round 3 */
 
145
        a = b + ROT_LEFT((a + H(b, c, d) + X[5] + 0xfffa3942), 4);      /* 33 */
 
146
        d = a + ROT_LEFT((d + H(a, b, c) + X[8] + 0x8771f681), 11); /* 34 */
 
147
        c = d + ROT_LEFT((c + H(d, a, b) + X[11] + 0x6d9d6122), 16);            /* 35 */
 
148
        b = c + ROT_LEFT((b + H(c, d, a) + X[14] + 0xfde5380c), 23);            /* 36 */
 
149
        a = b + ROT_LEFT((a + H(b, c, d) + X[1] + 0xa4beea44), 4);      /* 37 */
 
150
        d = a + ROT_LEFT((d + H(a, b, c) + X[4] + 0x4bdecfa9), 11); /* 38 */
 
151
        c = d + ROT_LEFT((c + H(d, a, b) + X[7] + 0xf6bb4b60), 16); /* 39 */
 
152
        b = c + ROT_LEFT((b + H(c, d, a) + X[10] + 0xbebfbc70), 23);            /* 40 */
 
153
        a = b + ROT_LEFT((a + H(b, c, d) + X[13] + 0x289b7ec6), 4); /* 41 */
 
154
        d = a + ROT_LEFT((d + H(a, b, c) + X[0] + 0xeaa127fa), 11); /* 42 */
 
155
        c = d + ROT_LEFT((c + H(d, a, b) + X[3] + 0xd4ef3085), 16); /* 43 */
 
156
        b = c + ROT_LEFT((b + H(c, d, a) + X[6] + 0x04881d05), 23); /* 44 */
 
157
        a = b + ROT_LEFT((a + H(b, c, d) + X[9] + 0xd9d4d039), 4);      /* 45 */
 
158
        d = a + ROT_LEFT((d + H(a, b, c) + X[12] + 0xe6db99e5), 11);            /* 46 */
 
159
        c = d + ROT_LEFT((c + H(d, a, b) + X[15] + 0x1fa27cf8), 16);            /* 47 */
 
160
        b = c + ROT_LEFT((b + H(c, d, a) + X[2] + 0xc4ac5665), 23); /* 48 */
 
161
 
 
162
        /* round 4 */
 
163
        a = b + ROT_LEFT((a + I(b, c, d) + X[0] + 0xf4292244), 6);      /* 49 */
 
164
        d = a + ROT_LEFT((d + I(a, b, c) + X[7] + 0x432aff97), 10); /* 50 */
 
165
        c = d + ROT_LEFT((c + I(d, a, b) + X[14] + 0xab9423a7), 15);            /* 51 */
 
166
        b = c + ROT_LEFT((b + I(c, d, a) + X[5] + 0xfc93a039), 21); /* 52 */
 
167
        a = b + ROT_LEFT((a + I(b, c, d) + X[12] + 0x655b59c3), 6); /* 53 */
 
168
        d = a + ROT_LEFT((d + I(a, b, c) + X[3] + 0x8f0ccc92), 10); /* 54 */
 
169
        c = d + ROT_LEFT((c + I(d, a, b) + X[10] + 0xffeff47d), 15);            /* 55 */
 
170
        b = c + ROT_LEFT((b + I(c, d, a) + X[1] + 0x85845dd1), 21); /* 56 */
 
171
        a = b + ROT_LEFT((a + I(b, c, d) + X[8] + 0x6fa87e4f), 6);      /* 57 */
 
172
        d = a + ROT_LEFT((d + I(a, b, c) + X[15] + 0xfe2ce6e0), 10);            /* 58 */
 
173
        c = d + ROT_LEFT((c + I(d, a, b) + X[6] + 0xa3014314), 15); /* 59 */
 
174
        b = c + ROT_LEFT((b + I(c, d, a) + X[13] + 0x4e0811a1), 21);            /* 60 */
 
175
        a = b + ROT_LEFT((a + I(b, c, d) + X[4] + 0xf7537e82), 6);      /* 61 */
 
176
        d = a + ROT_LEFT((d + I(a, b, c) + X[11] + 0xbd3af235), 10);            /* 62 */
 
177
        c = d + ROT_LEFT((c + I(d, a, b) + X[2] + 0x2ad7d2bb), 15); /* 63 */
 
178
        b = c + ROT_LEFT((b + I(c, d, a) + X[9] + 0xeb86d391), 21); /* 64 */
 
179
 
 
180
        state[0] += a;
 
181
        state[1] += b;
 
182
        state[2] += c;
 
183
        state[3] += d;
 
184
}
 
185
 
 
186
static int
 
187
calculateDigestFromBuffer(uint8 *b, uint32 len, uint8 sum[16])
 
188
{
 
189
        register uint32 i,
 
190
                                j,
 
191
                                k,
 
192
                                newI;
 
193
        uint32          l;
 
194
        uint8      *input;
 
195
        register uint32 *wbp;
 
196
        uint32          workBuff[16],
 
197
                                state[4];
 
198
 
 
199
        l = len;
 
200
 
 
201
        state[0] = 0x67452301;
 
202
        state[1] = 0xEFCDAB89;
 
203
        state[2] = 0x98BADCFE;
 
204
        state[3] = 0x10325476;
 
205
 
 
206
        if ((input = createPaddedCopyWithLength(b, &l)) == NULL)
 
207
                return 0;
 
208
 
 
209
        for (i = 0;;)
 
210
        {
 
211
                if ((newI = i + 16 * 4) > l)
 
212
                        break;
 
213
                k = i + 3;
 
214
                for (j = 0; j < 16; j++)
 
215
                {
 
216
                        wbp = (workBuff + j);
 
217
                        *wbp = input[k--];
 
218
                        *wbp <<= 8;
 
219
                        *wbp |= input[k--];
 
220
                        *wbp <<= 8;
 
221
                        *wbp |= input[k--];
 
222
                        *wbp <<= 8;
 
223
                        *wbp |= input[k];
 
224
                        k += 7;
 
225
                }
 
226
                doTheRounds(workBuff, state);
 
227
                i = newI;
 
228
        }
 
229
        free(input);
 
230
 
 
231
        j = 0;
 
232
        for (i = 0; i < 4; i++)
 
233
        {
 
234
                k = state[i];
 
235
                sum[j++] = (k & 0xff);
 
236
                k >>= 8;
 
237
                sum[j++] = (k & 0xff);
 
238
                k >>= 8;
 
239
                sum[j++] = (k & 0xff);
 
240
                k >>= 8;
 
241
                sum[j++] = (k & 0xff);
 
242
        }
 
243
        return 1;
 
244
}
 
245
 
 
246
static void
 
247
bytesToHex(uint8 b[16], char *s)
 
248
{
 
249
        static const char *hex = "0123456789abcdef";
 
250
        int                     q,
 
251
                                w;
 
252
 
 
253
        for (q = 0, w = 0; q < 16; q++)
 
254
        {
 
255
                s[w++] = hex[(b[q] >> 4) & 0x0F];
 
256
                s[w++] = hex[b[q] & 0x0F];
 
257
        }
 
258
        s[w] = '\0';
 
259
}
 
260
 
 
261
/*
 
262
 *      PUBLIC FUNCTIONS
 
263
 */
 
264
 
 
265
/*
 
266
 *      md5_hash
 
267
 *
 
268
 *      Calculates the MD5 sum of the bytes in a buffer.
 
269
 *
 
270
 *      SYNOPSIS          #include "crypt.h"
 
271
 *                                int md5_hash(const void *buff, size_t len, char *hexsum)
 
272
 *
 
273
 *      INPUT             buff    the buffer containing the bytes that you want
 
274
 *                                                the MD5 sum of.
 
275
 *                                len     number of bytes in the buffer.
 
276
 *
 
277
 *      OUTPUT            hexsum  the MD5 sum as a '\0'-terminated string of
 
278
 *                                                hexadecimal digits.  an MD5 sum is 16 bytes long.
 
279
 *                                                each byte is represented by two heaxadecimal
 
280
 *                                                characters.  you thus need to provide an array
 
281
 *                                                of 33 characters, including the trailing '\0'.
 
282
 *
 
283
 *      RETURNS           false on failure (out of memory for internal buffers) or
 
284
 *                                true on success.
 
285
 *
 
286
 *      STANDARDS         MD5 is described in RFC 1321.
 
287
 *
 
288
 *      AUTHOR            Sverre H. Huseby <sverrehu@online.no>
 
289
 *
 
290
 */
 
291
bool
 
292
md5_hash(const void *buff, size_t len, char *hexsum)
 
293
{
 
294
        uint8           sum[16];
 
295
 
 
296
        if (!calculateDigestFromBuffer((uint8 *) buff, (uint32) len, sum))
 
297
                return false;
 
298
 
 
299
        bytesToHex(sum, hexsum);
 
300
        return true;
 
301
}
 
302
 
 
303
 
 
304
 
 
305
/*
 
306
 * Computes MD5 checksum of "passwd" (a null-terminated string) followed
 
307
 * by "salt" (which need not be null-terminated).
 
308
 *
 
309
 * Output format is "md5" followed by a 32-hex-digit MD5 checksum.
 
310
 * Hence, the output buffer "buf" must be at least 36 bytes long.
 
311
 *
 
312
 * Returns TRUE if okay, FALSE on error (out of memory).
 
313
 */
 
314
bool
 
315
EncryptMD5(const char *passwd, const char *salt, size_t salt_len,
 
316
                   char *buf)
 
317
{
 
318
        size_t          passwd_len = strlen(passwd);
 
319
        char       *crypt_buf = malloc(passwd_len + salt_len + 1);
 
320
        bool            ret;
 
321
 
 
322
        if (!crypt_buf)
 
323
                return false;
 
324
 
 
325
        /*
 
326
         * Place salt at the end because it may be known by users trying to
 
327
         * crack the MD5 output.
 
328
         */
 
329
        memcpy(crypt_buf, passwd, passwd_len);
 
330
        memcpy(crypt_buf + passwd_len, salt, salt_len);
 
331
 
 
332
        strcpy(buf, "md5");
 
333
        ret = md5_hash(crypt_buf, passwd_len + salt_len, buf + 3);
 
334
 
 
335
        free(crypt_buf);
 
336
 
 
337
        return ret;
 
338
}