1 /*
2   Contributed code pasted here to make nDPI self-contained with no
3   external dependencies
4 */
5 
6 #include "ndpi_api.h"
7 #include "ndpi_md5.h"
8 
9 /* **************************************** */
10 
is_big_endian(void)11 static int is_big_endian(void) {
12   static const int n = 1;
13   return ((char *) &n)[0] == 0;
14 }
15 
byte_reverse(unsigned char * buf,unsigned longs)16 static void byte_reverse(unsigned char *buf, unsigned longs) {
17   // Forrest: MD5 expect LITTLE_ENDIAN, swap if BIG_ENDIAN
18   if (is_big_endian()) {
19     do {
20       u_int32_t t;
21 
22       t = (u_int32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
23 	((unsigned) buf[1] << 8 | buf[0]);
24       * (u_int32_t *) buf = t;
25       buf += 4;
26     } while (--longs);
27   }
28 }
29 
30 #define F1(x, y, z) (z ^ (x & (y ^ z)))
31 #define F2(x, y, z) F1(z, x, y)
32 #define F3(x, y, z) (x ^ y ^ z)
33 #define F4(x, y, z) (y ^ (x | ~z))
34 
35 #define MD5STEP(f, w, x, y, z, data, s)	\
36   ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
37 
38 /* **************************************** */
39 
40 // Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
41 // initialization constants.
ndpi_MD5Init(ndpi_MD5_CTX * ctx)42 void ndpi_MD5Init(ndpi_MD5_CTX *ctx) {
43   ctx->buf[0] = 0x67452301;
44   ctx->buf[1] = 0xefcdab89;
45   ctx->buf[2] = 0x98badcfe;
46   ctx->buf[3] = 0x10325476;
47 
48   ctx->bits[0] = 0;
49   ctx->bits[1] = 0;
50 }
51 
52 /* **************************************** */
53 
MD5Transform(u_int32_t buf[4],u_int32_t const in[16])54 static void MD5Transform(u_int32_t buf[4], u_int32_t const in[16]) {
55   u_int32_t a, b, c, d;
56 
57   a = buf[0];
58   b = buf[1];
59   c = buf[2];
60   d = buf[3];
61 
62   MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
63   MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
64   MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
65   MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
66   MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
67   MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
68   MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
69   MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
70   MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
71   MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
72   MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
73   MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
74   MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
75   MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
76   MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
77   MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
78 
79   MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
80   MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
81   MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
82   MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
83   MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
84   MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
85   MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
86   MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
87   MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
88   MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
89   MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
90   MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
91   MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
92   MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
93   MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
94   MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
95 
96   MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
97   MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
98   MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
99   MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
100   MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
101   MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
102   MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
103   MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
104   MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
105   MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
106   MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
107   MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
108   MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
109   MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
110   MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
111   MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
112 
113   MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
114   MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
115   MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
116   MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
117   MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
118   MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
119   MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
120   MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
121   MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
122   MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
123   MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
124   MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
125   MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
126   MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
127   MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
128   MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
129 
130   buf[0] += a;
131   buf[1] += b;
132   buf[2] += c;
133   buf[3] += d;
134 }
135 
136 /* **************************************** */
137 
ndpi_MD5Update(ndpi_MD5_CTX * ctx,unsigned char const * buf,unsigned len)138 void ndpi_MD5Update(ndpi_MD5_CTX *ctx, unsigned char const *buf, unsigned len) {
139   u_int32_t t;
140 
141   t = ctx->bits[0];
142   if ((ctx->bits[0] = t + ((u_int32_t) len << 3)) < t)
143     ctx->bits[1]++;
144   ctx->bits[1] += len >> 29;
145 
146   t = (t >> 3) & 0x3f;
147 
148   if (t) {
149     unsigned char *p = (unsigned char *) ctx->in + t;
150 
151     t = 64 - t;
152     if (len < t) {
153       memcpy(p, buf, len);
154       return;
155     }
156     memcpy(p, buf, t);
157     byte_reverse(ctx->in, 16);
158     MD5Transform(ctx->buf, (u_int32_t *) ctx->in);
159     buf += t;
160     len -= t;
161   }
162 
163   while (len >= 64) {
164     memcpy(ctx->in, buf, 64);
165     byte_reverse(ctx->in, 16);
166     MD5Transform(ctx->buf, (u_int32_t *) ctx->in);
167     buf += 64;
168     len -= 64;
169   }
170 
171   memcpy(ctx->in, buf, len);
172 }
173 
174 /* **************************************** */
175 
ndpi_MD5Final(unsigned char digest[16],ndpi_MD5_CTX * ctx)176 void ndpi_MD5Final(unsigned char digest[16], ndpi_MD5_CTX *ctx) {
177   unsigned count;
178   unsigned char *p;
179   u_int32_t *c = (u_int32_t*)ctx->in;
180 
181   count = (ctx->bits[0] >> 3) & 0x3F;
182 
183   p = ctx->in + count;
184   *p++ = 0x80;
185   count = 64 - 1 - count;
186   if (count < 8) {
187     memset(p, 0, count);
188     byte_reverse(ctx->in, 16);
189     MD5Transform(ctx->buf, (u_int32_t *) ctx->in);
190     memset(ctx->in, 0, 56);
191   } else {
192     memset(p, 0, count - 8);
193   }
194   byte_reverse(ctx->in, 14);
195 
196   c[14] = ctx->bits[0];
197   c[15] = ctx->bits[1];
198 
199   MD5Transform(ctx->buf, (u_int32_t *) ctx->in);
200   byte_reverse((unsigned char *) ctx->buf, 4);
201   memcpy(digest, ctx->buf, 16);
202   memset((char *) ctx, 0, sizeof(*ctx));
203 }
204 
205