STM32F7 Ethernet interface for nucleo STM32F767

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_md5.c Source File

lwip_md5.c

00001 /*
00002  *  RFC 1321 compliant MD5 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 MD5 algorithm was designed by Ron Rivest in 1991.
00037  *
00038  *  http://www.ietf.org/rfc/rfc1321.txt
00039  */
00040 
00041 #include "netif/ppp/ppp_opts.h"
00042 #if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD5
00043 
00044 #include "netif/ppp/polarssl/md5.h"
00045 
00046 #include <string.h>
00047 
00048 /*
00049  * 32-bit integer manipulation macros (little endian)
00050  */
00051 #ifndef GET_ULONG_LE
00052 #define GET_ULONG_LE(n,b,i)                             \
00053 {                                                       \
00054     (n) = ( (unsigned long) (b)[(i)    ]       )        \
00055         | ( (unsigned long) (b)[(i) + 1] <<  8 )        \
00056         | ( (unsigned long) (b)[(i) + 2] << 16 )        \
00057         | ( (unsigned long) (b)[(i) + 3] << 24 );       \
00058 }
00059 #endif
00060 
00061 #ifndef PUT_ULONG_LE
00062 #define PUT_ULONG_LE(n,b,i)                             \
00063 {                                                       \
00064     (b)[(i)    ] = (unsigned char) ( (n)       );       \
00065     (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
00066     (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
00067     (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
00068 }
00069 #endif
00070 
00071 /*
00072  * MD5 context setup
00073  */
00074 void md5_starts( md5_context *ctx )
00075 {
00076     ctx->total [0] = 0;
00077     ctx->total [1] = 0;
00078 
00079     ctx->state [0] = 0x67452301;
00080     ctx->state [1] = 0xEFCDAB89;
00081     ctx->state [2] = 0x98BADCFE;
00082     ctx->state [3] = 0x10325476;
00083 }
00084 
00085 static void md5_process( md5_context *ctx, const unsigned char data[64] )
00086 {
00087     unsigned long X[16], A, B, C, D;
00088 
00089     GET_ULONG_LE( X[ 0], data,  0 );
00090     GET_ULONG_LE( X[ 1], data,  4 );
00091     GET_ULONG_LE( X[ 2], data,  8 );
00092     GET_ULONG_LE( X[ 3], data, 12 );
00093     GET_ULONG_LE( X[ 4], data, 16 );
00094     GET_ULONG_LE( X[ 5], data, 20 );
00095     GET_ULONG_LE( X[ 6], data, 24 );
00096     GET_ULONG_LE( X[ 7], data, 28 );
00097     GET_ULONG_LE( X[ 8], data, 32 );
00098     GET_ULONG_LE( X[ 9], data, 36 );
00099     GET_ULONG_LE( X[10], data, 40 );
00100     GET_ULONG_LE( X[11], data, 44 );
00101     GET_ULONG_LE( X[12], data, 48 );
00102     GET_ULONG_LE( X[13], data, 52 );
00103     GET_ULONG_LE( X[14], data, 56 );
00104     GET_ULONG_LE( X[15], data, 60 );
00105 
00106 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00107 
00108 #define P(a,b,c,d,k,s,t)                                \
00109 {                                                       \
00110     a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
00111 }
00112 
00113     A = ctx->state [0];
00114     B = ctx->state [1];
00115     C = ctx->state [2];
00116     D = ctx->state [3];
00117 
00118 #define F(x,y,z) (z ^ (x & (y ^ z)))
00119 
00120     P( A, B, C, D,  0,  7, 0xD76AA478 );
00121     P( D, A, B, C,  1, 12, 0xE8C7B756 );
00122     P( C, D, A, B,  2, 17, 0x242070DB );
00123     P( B, C, D, A,  3, 22, 0xC1BDCEEE );
00124     P( A, B, C, D,  4,  7, 0xF57C0FAF );
00125     P( D, A, B, C,  5, 12, 0x4787C62A );
00126     P( C, D, A, B,  6, 17, 0xA8304613 );
00127     P( B, C, D, A,  7, 22, 0xFD469501 );
00128     P( A, B, C, D,  8,  7, 0x698098D8 );
00129     P( D, A, B, C,  9, 12, 0x8B44F7AF );
00130     P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
00131     P( B, C, D, A, 11, 22, 0x895CD7BE );
00132     P( A, B, C, D, 12,  7, 0x6B901122 );
00133     P( D, A, B, C, 13, 12, 0xFD987193 );
00134     P( C, D, A, B, 14, 17, 0xA679438E );
00135     P( B, C, D, A, 15, 22, 0x49B40821 );
00136 
00137 #undef F
00138 
00139 #define F(x,y,z) (y ^ (z & (x ^ y)))
00140 
00141     P( A, B, C, D,  1,  5, 0xF61E2562 );
00142     P( D, A, B, C,  6,  9, 0xC040B340 );
00143     P( C, D, A, B, 11, 14, 0x265E5A51 );
00144     P( B, C, D, A,  0, 20, 0xE9B6C7AA );
00145     P( A, B, C, D,  5,  5, 0xD62F105D );
00146     P( D, A, B, C, 10,  9, 0x02441453 );
00147     P( C, D, A, B, 15, 14, 0xD8A1E681 );
00148     P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
00149     P( A, B, C, D,  9,  5, 0x21E1CDE6 );
00150     P( D, A, B, C, 14,  9, 0xC33707D6 );
00151     P( C, D, A, B,  3, 14, 0xF4D50D87 );
00152     P( B, C, D, A,  8, 20, 0x455A14ED );
00153     P( A, B, C, D, 13,  5, 0xA9E3E905 );
00154     P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
00155     P( C, D, A, B,  7, 14, 0x676F02D9 );
00156     P( B, C, D, A, 12, 20, 0x8D2A4C8A );
00157 
00158 #undef F
00159     
00160 #define F(x,y,z) (x ^ y ^ z)
00161 
00162     P( A, B, C, D,  5,  4, 0xFFFA3942 );
00163     P( D, A, B, C,  8, 11, 0x8771F681 );
00164     P( C, D, A, B, 11, 16, 0x6D9D6122 );
00165     P( B, C, D, A, 14, 23, 0xFDE5380C );
00166     P( A, B, C, D,  1,  4, 0xA4BEEA44 );
00167     P( D, A, B, C,  4, 11, 0x4BDECFA9 );
00168     P( C, D, A, B,  7, 16, 0xF6BB4B60 );
00169     P( B, C, D, A, 10, 23, 0xBEBFBC70 );
00170     P( A, B, C, D, 13,  4, 0x289B7EC6 );
00171     P( D, A, B, C,  0, 11, 0xEAA127FA );
00172     P( C, D, A, B,  3, 16, 0xD4EF3085 );
00173     P( B, C, D, A,  6, 23, 0x04881D05 );
00174     P( A, B, C, D,  9,  4, 0xD9D4D039 );
00175     P( D, A, B, C, 12, 11, 0xE6DB99E5 );
00176     P( C, D, A, B, 15, 16, 0x1FA27CF8 );
00177     P( B, C, D, A,  2, 23, 0xC4AC5665 );
00178 
00179 #undef F
00180 
00181 #define F(x,y,z) (y ^ (x | ~z))
00182 
00183     P( A, B, C, D,  0,  6, 0xF4292244 );
00184     P( D, A, B, C,  7, 10, 0x432AFF97 );
00185     P( C, D, A, B, 14, 15, 0xAB9423A7 );
00186     P( B, C, D, A,  5, 21, 0xFC93A039 );
00187     P( A, B, C, D, 12,  6, 0x655B59C3 );
00188     P( D, A, B, C,  3, 10, 0x8F0CCC92 );
00189     P( C, D, A, B, 10, 15, 0xFFEFF47D );
00190     P( B, C, D, A,  1, 21, 0x85845DD1 );
00191     P( A, B, C, D,  8,  6, 0x6FA87E4F );
00192     P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
00193     P( C, D, A, B,  6, 15, 0xA3014314 );
00194     P( B, C, D, A, 13, 21, 0x4E0811A1 );
00195     P( A, B, C, D,  4,  6, 0xF7537E82 );
00196     P( D, A, B, C, 11, 10, 0xBD3AF235 );
00197     P( C, D, A, B,  2, 15, 0x2AD7D2BB );
00198     P( B, C, D, A,  9, 21, 0xEB86D391 );
00199 
00200 #undef F
00201 
00202     ctx->state [0] += A;
00203     ctx->state [1] += B;
00204     ctx->state [2] += C;
00205     ctx->state [3] += D;
00206 }
00207 
00208 /*
00209  * MD5 process buffer
00210  */
00211 void md5_update( md5_context *ctx, const unsigned char *input, int ilen )
00212 {
00213     int fill;
00214     unsigned long left;
00215 
00216     if( ilen <= 0 )
00217         return;
00218 
00219     left = ctx->total [0] & 0x3F;
00220     fill = 64 - left;
00221 
00222     ctx->total [0] += ilen;
00223     ctx->total [0] &= 0xFFFFFFFF;
00224 
00225     if( ctx->total [0] < (unsigned long) ilen )
00226         ctx->total [1]++;
00227 
00228     if( left && ilen >= fill )
00229     {
00230         MEMCPY( (void *) (ctx->buffer  + left),
00231                 input, fill );
00232         md5_process( ctx, ctx->buffer  );
00233         input += fill;
00234         ilen  -= fill;
00235         left = 0;
00236     }
00237 
00238     while( ilen >= 64 )
00239     {
00240         md5_process( ctx, input );
00241         input += 64;
00242         ilen  -= 64;
00243     }
00244 
00245     if( ilen > 0 )
00246     {
00247         MEMCPY( (void *) (ctx->buffer  + left),
00248                 input, ilen );
00249     }
00250 }
00251 
00252 static const unsigned char md5_padding[64] =
00253 {
00254  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00255     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00256     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00257     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00258 };
00259 
00260 /*
00261  * MD5 final digest
00262  */
00263 void md5_finish( md5_context *ctx, unsigned char output[16] )
00264 {
00265     unsigned long last, padn;
00266     unsigned long high, low;
00267     unsigned char msglen[8];
00268 
00269     high = ( ctx->total [0] >> 29 )
00270          | ( ctx->total [1] <<  3 );
00271     low  = ( ctx->total [0] <<  3 );
00272 
00273     PUT_ULONG_LE( low,  msglen, 0 );
00274     PUT_ULONG_LE( high, msglen, 4 );
00275 
00276     last = ctx->total [0] & 0x3F;
00277     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00278 
00279     md5_update( ctx, md5_padding, padn );
00280     md5_update( ctx, msglen, 8 );
00281 
00282     PUT_ULONG_LE( ctx->state [0], output,  0 );
00283     PUT_ULONG_LE( ctx->state [1], output,  4 );
00284     PUT_ULONG_LE( ctx->state [2], output,  8 );
00285     PUT_ULONG_LE( ctx->state [3], output, 12 );
00286 }
00287 
00288 /*
00289  * output = MD5( input buffer )
00290  */
00291 void md5( unsigned char *input, int ilen, unsigned char output[16] )
00292 {
00293     md5_context ctx;
00294 
00295     md5_starts( &ctx );
00296     md5_update( &ctx, input, ilen );
00297     md5_finish( &ctx, output );
00298 }
00299 
00300 #endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD5 */