upload tizen1.0 source
[framework/system/sync-agent.git] / framework / src / securityAssistant / IN_SA_MD5.c
1 /*
2 * $Id: md5.c,v 1.3 2004/04/14 21:06:23 mkern Exp $
3 * This code implements the MD5 message-digest algorithm.
4 * The algorithm is due to Ron Rivest.  This code was
5 * written by Colin Plumb in 1993, no copyright is claimed.
6 * This code is in the public domain; do with it what you wish.
7 *
8 * Equivalent code is available from RSA Data Security, Inc.
9 * This code has been tested against that, and is equivalent,
10 * except that you don't need to include two pages of legalese
11 * with every copy.
12 *
13 * To compute the message digest of a chunk of bytes, declare an
14 * MD5Context structure, pass it to MD5Init, call MD5Update as
15 * needed on buffers full of bytes, and then call MD5Final, which
16 * will fill a supplied 16-byte array with the digest.
17 */
18
19
20
21 #include <string.h>
22 #include "securityAssistant/IN_SA_MD5.h"
23
24 static void MD5Transform(unsigned long int buf[4], const unsigned long int in[16]);
25 static void _byte_reverse(unsigned char *buf, unsigned int longs);
26
27 void MD5GetDigest(const char *buffer, int buffer_size, unsigned char *digest)
28 {
29         MD5Context ctx;
30
31         MD5Init(&ctx);
32         MD5Update(&ctx, buffer, buffer_size);
33         MD5Final(&ctx, digest);
34
35 }
36
37 void MD5Init(MD5Context *ctx)
38 {
39         ctx->buf[0] = 0x67452301;
40         ctx->buf[1] = 0xefcdab89;
41         ctx->buf[2] = 0x98badcfe;
42         ctx->buf[3] = 0x10325476;
43
44         ctx->bits[0] = 0;
45         ctx->bits[1] = 0;
46
47         if (IS_BIG_ENDIAN())
48                 ctx->doByteReverse = 1;
49         else
50                 ctx->doByteReverse = 0;
51 }
52
53 void MD5Update(MD5Context *ctx, const char *buf, unsigned long int len)
54 {
55         unsigned int t;
56
57         /* Update bitcount */
58
59         t = ctx->bits[0];
60         if ((ctx->bits[0] = t + ((unsigned int)len << 3)) < t)
61                 ctx->bits[1]++; /* Carry from low to high */
62         ctx->bits[1] += len >> 29;
63
64         t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
65
66         /* Handle any leading odd-sized chunks */
67
68         if (t) {
69                 unsigned char *p = (unsigned char *)ctx->in + t;
70
71                 t = 64 - t;
72                 if (len < t) {
73                         memcpy(p, buf, len);
74                         return;
75                 }
76                 memcpy(p, buf, t);
77                 if (ctx->doByteReverse)
78                         _byte_reverse(ctx->in, 16);
79                 MD5Transform(ctx->buf, (const long unsigned int *)ctx->in);
80                 buf += t;
81                 len -= t;
82         }
83         /* Process data in 64-byte chunks */
84
85         while (len >= 64) {
86                 memcpy(ctx->in, buf, 64);
87                 if (ctx->doByteReverse)
88                         _byte_reverse(ctx->in, 16);
89                 MD5Transform(ctx->buf, (const long unsigned int *)ctx->in);
90                 buf += 64;
91                 len -= 64;
92         }
93
94         /* Handle any remaining bytes of data. */
95
96         memcpy(ctx->in, buf, len);
97 }
98
99 static void MD5Transform(unsigned long int buf[4], const unsigned long int in[16])
100 {
101         register unsigned int a, b, c, d;
102
103         a = buf[0];
104         b = buf[1];
105         c = buf[2];
106         d = buf[3];
107
108         MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
109         MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
110         MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
111         MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
112         MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
113         MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
114         MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
115         MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
116         MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
117         MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
118         MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
119         MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
120         MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
121         MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
122         MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
123         MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
124
125         MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
126         MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
127         MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
128         MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
129         MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
130         MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
131         MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
132         MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
133         MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
134         MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
135         MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
136         MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
137         MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
138         MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
139         MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
140         MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
141
142         MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
143         MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
144         MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
145         MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
146         MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
147         MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
148         MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
149         MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
150         MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
151         MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
152         MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
153         MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
154         MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
155         MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
156         MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
157         MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
158
159         MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
160         MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
161         MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
162         MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
163         MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
164         MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
165         MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
166         MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
167         MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
168         MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
169         MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
170         MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
171         MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
172         MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
173         MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
174         MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
175
176         buf[0] += a;
177         buf[1] += b;
178         buf[2] += c;
179         buf[3] += d;
180 }
181
182 static void _byte_reverse(unsigned char *buf, unsigned int longs)
183 {
184         unsigned int t;
185         do {
186                 t = (unsigned int)((unsigned int)buf[3] << 8 | buf[2]) << 16 | ((unsigned int)buf[1] << 8 | buf[0]);
187                 *(unsigned int *)buf = t;
188                 buf += 4;
189         } while (--longs);
190 }
191
192 void MD5Final(MD5Context *ctx, unsigned char *digest)
193 {
194         unsigned int count;
195         unsigned char *p;
196
197         /* Compute number of bytes mod 64 */
198         count = (ctx->bits[0] >> 3) & 0x3F;
199
200         /* Set the first char of padding to 0x80.  This is safe since there is
201            always at least one byte free */
202         p = ctx->in + count;
203         *p++ = 0x80;
204
205         /* Bytes of padding needed to make 64 bytes */
206         count = 64 - 1 - count;
207
208         /* Pad out to 56 mod 64 */
209         if (count < 8) {
210                 /* Two lots of padding:  Pad the first block to 64 bytes */
211                 memset(p, 0, count);
212                 if (ctx->doByteReverse)
213                         _byte_reverse(ctx->in, 16);
214                 MD5Transform(ctx->buf, (const long unsigned int *)ctx->in);
215
216                 /* Now fill the next block with 56 bytes */
217                 memset(ctx->in, 0, 56);
218         } else {
219                 /* Pad block to 56 bytes */
220                 memset(p, 0, count - 8);
221         }
222         if (ctx->doByteReverse)
223                 _byte_reverse(ctx->in, 14);
224
225         /* Append length in bits and transform */
226         ((unsigned int *)ctx->in)[14] = ctx->bits[0];
227         ((unsigned int *)ctx->in)[15] = ctx->bits[1];
228
229         MD5Transform(ctx->buf, (const long unsigned int *)ctx->in);
230         if (ctx->doByteReverse)
231                 _byte_reverse((unsigned char *)ctx->buf, 4);
232         memcpy(digest, ctx->buf, 16);
233 }