42 #include "netif/ppp/ppp_opts.h" 43 #if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD4 53 #define GET_ULONG_LE(n,b,i) \ 55 (n) = ( (unsigned long) (b)[(i) ] ) \ 56 | ( (unsigned long) (b)[(i) + 1] << 8 ) \ 57 | ( (unsigned long) (b)[(i) + 2] << 16 ) \ 58 | ( (unsigned long) (b)[(i) + 3] << 24 ); \ 63 #define PUT_ULONG_LE(n,b,i) \ 65 (b)[(i) ] = (unsigned char) ( (n) ); \ 66 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ 67 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ 68 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ 75 void md4_starts( md4_context *ctx )
80 ctx->state[0] = 0x67452301;
81 ctx->state[1] = 0xEFCDAB89;
82 ctx->state[2] = 0x98BADCFE;
83 ctx->state[3] = 0x10325476;
86 static void md4_process( md4_context *ctx,
const unsigned char data[64] )
88 unsigned long X[16], A, B, C, D;
90 GET_ULONG_LE( X[ 0], data, 0 );
91 GET_ULONG_LE( X[ 1], data, 4 );
92 GET_ULONG_LE( X[ 2], data, 8 );
93 GET_ULONG_LE( X[ 3], data, 12 );
94 GET_ULONG_LE( X[ 4], data, 16 );
95 GET_ULONG_LE( X[ 5], data, 20 );
96 GET_ULONG_LE( X[ 6], data, 24 );
97 GET_ULONG_LE( X[ 7], data, 28 );
98 GET_ULONG_LE( X[ 8], data, 32 );
99 GET_ULONG_LE( X[ 9], data, 36 );
100 GET_ULONG_LE( X[10], data, 40 );
101 GET_ULONG_LE( X[11], data, 44 );
102 GET_ULONG_LE( X[12], data, 48 );
103 GET_ULONG_LE( X[13], data, 52 );
104 GET_ULONG_LE( X[14], data, 56 );
105 GET_ULONG_LE( X[15], data, 60 );
107 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 114 #define F(x, y, z) ((x & y) | ((~x) & z)) 115 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } 117 P( A, B, C, D, X[ 0], 3 );
118 P( D, A, B, C, X[ 1], 7 );
119 P( C, D, A, B, X[ 2], 11 );
120 P( B, C, D, A, X[ 3], 19 );
121 P( A, B, C, D, X[ 4], 3 );
122 P( D, A, B, C, X[ 5], 7 );
123 P( C, D, A, B, X[ 6], 11 );
124 P( B, C, D, A, X[ 7], 19 );
125 P( A, B, C, D, X[ 8], 3 );
126 P( D, A, B, C, X[ 9], 7 );
127 P( C, D, A, B, X[10], 11 );
128 P( B, C, D, A, X[11], 19 );
129 P( A, B, C, D, X[12], 3 );
130 P( D, A, B, C, X[13], 7 );
131 P( C, D, A, B, X[14], 11 );
132 P( B, C, D, A, X[15], 19 );
137 #define F(x,y,z) ((x & y) | (x & z) | (y & z)) 138 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } 140 P( A, B, C, D, X[ 0], 3 );
141 P( D, A, B, C, X[ 4], 5 );
142 P( C, D, A, B, X[ 8], 9 );
143 P( B, C, D, A, X[12], 13 );
144 P( A, B, C, D, X[ 1], 3 );
145 P( D, A, B, C, X[ 5], 5 );
146 P( C, D, A, B, X[ 9], 9 );
147 P( B, C, D, A, X[13], 13 );
148 P( A, B, C, D, X[ 2], 3 );
149 P( D, A, B, C, X[ 6], 5 );
150 P( C, D, A, B, X[10], 9 );
151 P( B, C, D, A, X[14], 13 );
152 P( A, B, C, D, X[ 3], 3 );
153 P( D, A, B, C, X[ 7], 5 );
154 P( C, D, A, B, X[11], 9 );
155 P( B, C, D, A, X[15], 13 );
160 #define F(x,y,z) (x ^ y ^ z) 161 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } 163 P( A, B, C, D, X[ 0], 3 );
164 P( D, A, B, C, X[ 8], 9 );
165 P( C, D, A, B, X[ 4], 11 );
166 P( B, C, D, A, X[12], 15 );
167 P( A, B, C, D, X[ 2], 3 );
168 P( D, A, B, C, X[10], 9 );
169 P( C, D, A, B, X[ 6], 11 );
170 P( B, C, D, A, X[14], 15 );
171 P( A, B, C, D, X[ 1], 3 );
172 P( D, A, B, C, X[ 9], 9 );
173 P( C, D, A, B, X[ 5], 11 );
174 P( B, C, D, A, X[13], 15 );
175 P( A, B, C, D, X[ 3], 3 );
176 P( D, A, B, C, X[11], 9 );
177 P( C, D, A, B, X[ 7], 11 );
178 P( B, C, D, A, X[15], 15 );
192 void md4_update( md4_context *ctx,
const unsigned char *input,
int ilen )
200 left = ctx->total[0] & 0x3F;
203 ctx->total[0] += ilen;
204 ctx->total[0] &= 0xFFFFFFFF;
206 if( ctx->total[0] < (
unsigned long) ilen )
209 if( left && ilen >= fill )
211 MEMCPY( (
void *) (ctx->buffer + left),
213 md4_process( ctx, ctx->buffer );
221 md4_process( ctx, input );
228 MEMCPY( (
void *) (ctx->buffer + left),
233 static const unsigned char md4_padding[64] =
235 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
236 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
237 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
238 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
244 void md4_finish( md4_context *ctx,
unsigned char output[16] )
246 unsigned long last, padn;
247 unsigned long high, low;
248 unsigned char msglen[8];
250 high = ( ctx->total[0] >> 29 )
251 | ( ctx->total[1] << 3 );
252 low = ( ctx->total[0] << 3 );
254 PUT_ULONG_LE( low, msglen, 0 );
255 PUT_ULONG_LE( high, msglen, 4 );
257 last = ctx->total[0] & 0x3F;
258 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
260 md4_update( ctx, md4_padding, padn );
261 md4_update( ctx, msglen, 8 );
263 PUT_ULONG_LE( ctx->state[0], output, 0 );
264 PUT_ULONG_LE( ctx->state[1], output, 4 );
265 PUT_ULONG_LE( ctx->state[2], output, 8 );
266 PUT_ULONG_LE( ctx->state[3], output, 12 );
272 void md4(
unsigned char *input,
int ilen,
unsigned char output[16] )
277 md4_update( &ctx, input, ilen );
278 md4_finish( &ctx, output );