STM32F7 Ethernet interface for nucleo STM32F767

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_md4.c Source File

lwip_md4.c

00001 /*
00002  *  RFC 1186/1320 compliant MD4 implementation
00003  *
00004  *  Based on XySSL: Copyright (C) 2006-2008  Christophe Devine
00005  *
00006  *  Copyright (C) 2009  Paul Bakker <polarssl_maintainer at polarssl dot org>
00007  *
00008  *  All rights reserved.
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *  
00014  *    * Redistributions of source code must retain the above copyright
00015  *      notice, this list of conditions and the following disclaimer.
00016  *    * Redistributions in binary form must reproduce the above copyright
00017  *      notice, this list of conditions and the following disclaimer in the
00018  *      documentation and/or other materials provided with the distribution.
00019  *    * Neither the names of PolarSSL or XySSL nor the names of its contributors
00020  *      may be used to endorse or promote products derived from this software
00021  *      without specific prior written permission.
00022  *  
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00029  *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00030  *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00031  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00032  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00033  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 /*
00036  *  The MD4 algorithm was designed by Ron Rivest in 1990.
00037  *
00038  *  http://www.ietf.org/rfc/rfc1186.txt
00039  *  http://www.ietf.org/rfc/rfc1320.txt
00040  */
00041 
00042 #include "netif/ppp/ppp_opts.h"
00043 #if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD4
00044 
00045 #include "netif/ppp/polarssl/md4.h"
00046 
00047 #include <string.h>
00048 
00049 /*
00050  * 32-bit integer manipulation macros (little endian)
00051  */
00052 #ifndef GET_ULONG_LE
00053 #define GET_ULONG_LE(n,b,i)                             \
00054 {                                                       \
00055     (n) = ( (unsigned long) (b)[(i)    ]       )        \
00056         | ( (unsigned long) (b)[(i) + 1] <<  8 )        \
00057         | ( (unsigned long) (b)[(i) + 2] << 16 )        \
00058         | ( (unsigned long) (b)[(i) + 3] << 24 );       \
00059 }
00060 #endif
00061 
00062 #ifndef PUT_ULONG_LE
00063 #define PUT_ULONG_LE(n,b,i)                             \
00064 {                                                       \
00065     (b)[(i)    ] = (unsigned char) ( (n)       );       \
00066     (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
00067     (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
00068     (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
00069 }
00070 #endif
00071 
00072 /*
00073  * MD4 context setup
00074  */
00075 void md4_starts( md4_context *ctx )
00076 {
00077     ctx->total [0] = 0;
00078     ctx->total [1] = 0;
00079 
00080     ctx->state [0] = 0x67452301;
00081     ctx->state [1] = 0xEFCDAB89;
00082     ctx->state [2] = 0x98BADCFE;
00083     ctx->state [3] = 0x10325476;
00084 }
00085 
00086 static void md4_process( md4_context *ctx, const unsigned char data[64] )
00087 {
00088     unsigned long X[16], A, B, C, D;
00089 
00090     GET_ULONG_LE( X[ 0], data,  0 );
00091     GET_ULONG_LE( X[ 1], data,  4 );
00092     GET_ULONG_LE( X[ 2], data,  8 );
00093     GET_ULONG_LE( X[ 3], data, 12 );
00094     GET_ULONG_LE( X[ 4], data, 16 );
00095     GET_ULONG_LE( X[ 5], data, 20 );
00096     GET_ULONG_LE( X[ 6], data, 24 );
00097     GET_ULONG_LE( X[ 7], data, 28 );
00098     GET_ULONG_LE( X[ 8], data, 32 );
00099     GET_ULONG_LE( X[ 9], data, 36 );
00100     GET_ULONG_LE( X[10], data, 40 );
00101     GET_ULONG_LE( X[11], data, 44 );
00102     GET_ULONG_LE( X[12], data, 48 );
00103     GET_ULONG_LE( X[13], data, 52 );
00104     GET_ULONG_LE( X[14], data, 56 );
00105     GET_ULONG_LE( X[15], data, 60 );
00106 
00107 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00108 
00109     A = ctx->state [0];
00110     B = ctx->state [1];
00111     C = ctx->state [2];
00112     D = ctx->state [3];
00113 
00114 #define F(x, y, z) ((x & y) | ((~x) & z))
00115 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
00116 
00117     P( A, B, C, D, X[ 0],  3 );
00118     P( D, A, B, C, X[ 1],  7 );
00119     P( C, D, A, B, X[ 2], 11 );
00120     P( B, C, D, A, X[ 3], 19 );
00121     P( A, B, C, D, X[ 4],  3 );
00122     P( D, A, B, C, X[ 5],  7 );
00123     P( C, D, A, B, X[ 6], 11 );
00124     P( B, C, D, A, X[ 7], 19 );
00125     P( A, B, C, D, X[ 8],  3 );
00126     P( D, A, B, C, X[ 9],  7 );
00127     P( C, D, A, B, X[10], 11 );
00128     P( B, C, D, A, X[11], 19 );
00129     P( A, B, C, D, X[12],  3 );
00130     P( D, A, B, C, X[13],  7 );
00131     P( C, D, A, B, X[14], 11 );
00132     P( B, C, D, A, X[15], 19 );
00133 
00134 #undef P
00135 #undef F
00136 
00137 #define F(x,y,z) ((x & y) | (x & z) | (y & z))
00138 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
00139 
00140     P( A, B, C, D, X[ 0],  3 );
00141     P( D, A, B, C, X[ 4],  5 );
00142     P( C, D, A, B, X[ 8],  9 );
00143     P( B, C, D, A, X[12], 13 );
00144     P( A, B, C, D, X[ 1],  3 );
00145     P( D, A, B, C, X[ 5],  5 );
00146     P( C, D, A, B, X[ 9],  9 );
00147     P( B, C, D, A, X[13], 13 );
00148     P( A, B, C, D, X[ 2],  3 );
00149     P( D, A, B, C, X[ 6],  5 );
00150     P( C, D, A, B, X[10],  9 );
00151     P( B, C, D, A, X[14], 13 );
00152     P( A, B, C, D, X[ 3],  3 );
00153     P( D, A, B, C, X[ 7],  5 );
00154     P( C, D, A, B, X[11],  9 );
00155     P( B, C, D, A, X[15], 13 );
00156 
00157 #undef P
00158 #undef F
00159 
00160 #define F(x,y,z) (x ^ y ^ z)
00161 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
00162 
00163     P( A, B, C, D, X[ 0],  3 );
00164     P( D, A, B, C, X[ 8],  9 );
00165     P( C, D, A, B, X[ 4], 11 );
00166     P( B, C, D, A, X[12], 15 );
00167     P( A, B, C, D, X[ 2],  3 );
00168     P( D, A, B, C, X[10],  9 );
00169     P( C, D, A, B, X[ 6], 11 );
00170     P( B, C, D, A, X[14], 15 );
00171     P( A, B, C, D, X[ 1],  3 );
00172     P( D, A, B, C, X[ 9],  9 );
00173     P( C, D, A, B, X[ 5], 11 );
00174     P( B, C, D, A, X[13], 15 );
00175     P( A, B, C, D, X[ 3],  3 );
00176     P( D, A, B, C, X[11],  9 );
00177     P( C, D, A, B, X[ 7], 11 );
00178     P( B, C, D, A, X[15], 15 );
00179 
00180 #undef F
00181 #undef P
00182 
00183     ctx->state [0] += A;
00184     ctx->state [1] += B;
00185     ctx->state [2] += C;
00186     ctx->state [3] += D;
00187 }
00188 
00189 /*
00190  * MD4 process buffer
00191  */
00192 void md4_update( md4_context *ctx, const unsigned char *input, int ilen )
00193 {
00194     int fill;
00195     unsigned long left;
00196 
00197     if( ilen <= 0 )
00198         return;
00199 
00200     left = ctx->total [0] & 0x3F;
00201     fill = 64 - left;
00202 
00203     ctx->total [0] += ilen;
00204     ctx->total [0] &= 0xFFFFFFFF;
00205 
00206     if( ctx->total [0] < (unsigned long) ilen )
00207         ctx->total [1]++;
00208 
00209     if( left && ilen >= fill )
00210     {
00211         MEMCPY( (void *) (ctx->buffer  + left),
00212                 input, fill );
00213         md4_process( ctx, ctx->buffer  );
00214         input += fill;
00215         ilen  -= fill;
00216         left = 0;
00217     }
00218 
00219     while( ilen >= 64 )
00220     {
00221         md4_process( ctx, input );
00222         input += 64;
00223         ilen  -= 64;
00224     }
00225 
00226     if( ilen > 0 )
00227     {
00228         MEMCPY( (void *) (ctx->buffer  + left),
00229                 input, ilen );
00230     }
00231 }
00232 
00233 static const unsigned char md4_padding[64] =
00234 {
00235  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00236     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00237     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00238     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00239 };
00240 
00241 /*
00242  * MD4 final digest
00243  */
00244 void md4_finish( md4_context *ctx, unsigned char output[16] )
00245 {
00246     unsigned long last, padn;
00247     unsigned long high, low;
00248     unsigned char msglen[8];
00249 
00250     high = ( ctx->total [0] >> 29 )
00251          | ( ctx->total [1] <<  3 );
00252     low  = ( ctx->total [0] <<  3 );
00253 
00254     PUT_ULONG_LE( low,  msglen, 0 );
00255     PUT_ULONG_LE( high, msglen, 4 );
00256 
00257     last = ctx->total [0] & 0x3F;
00258     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00259 
00260     md4_update( ctx, md4_padding, padn );
00261     md4_update( ctx, msglen, 8 );
00262 
00263     PUT_ULONG_LE( ctx->state [0], output,  0 );
00264     PUT_ULONG_LE( ctx->state [1], output,  4 );
00265     PUT_ULONG_LE( ctx->state [2], output,  8 );
00266     PUT_ULONG_LE( ctx->state [3], output, 12 );
00267 }
00268 
00269 /*
00270  * output = MD4( input buffer )
00271  */
00272 void md4( unsigned char *input, int ilen, unsigned char output[16] )
00273 {
00274     md4_context ctx;
00275 
00276     md4_starts( &ctx );
00277     md4_update( &ctx, input, ilen );
00278     md4_finish( &ctx, output );
00279 }
00280 
00281 #endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD4 */