Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_sha1.c Source File

lwip_sha1.c

00001 /*
00002  *  FIPS-180-1 compliant SHA-1 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 SHA-1 standard was published by NIST in 1993.
00037  *
00038  *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
00039  */
00040 
00041 #include "netif/ppp/ppp_opts.h"
00042 #if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_SHA1
00043 
00044 #include "netif/ppp/polarssl/sha1.h"
00045 
00046 #include <string.h>
00047 
00048 /*
00049  * 32-bit integer manipulation macros (big endian)
00050  */
00051 #ifndef GET_ULONG_BE
00052 #define GET_ULONG_BE(n,b,i)                             \
00053 {                                                       \
00054     (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
00055         | ( (unsigned long) (b)[(i) + 1] << 16 )        \
00056         | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
00057         | ( (unsigned long) (b)[(i) + 3]       );       \
00058 }
00059 #endif
00060 
00061 #ifndef PUT_ULONG_BE
00062 #define PUT_ULONG_BE(n,b,i)                             \
00063 {                                                       \
00064     (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
00065     (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
00066     (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
00067     (b)[(i) + 3] = (unsigned char) ( (n)       );       \
00068 }
00069 #endif
00070 
00071 /*
00072  * SHA-1 context setup
00073  */
00074 void sha1_starts( sha1_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     ctx->state [4] = 0xC3D2E1F0;
00084 }
00085 
00086 static void sha1_process( sha1_context *ctx, const unsigned char data[64] )
00087 {
00088     unsigned long temp, W[16], A, B, C, D, E;
00089 
00090     GET_ULONG_BE( W[ 0], data,  0 );
00091     GET_ULONG_BE( W[ 1], data,  4 );
00092     GET_ULONG_BE( W[ 2], data,  8 );
00093     GET_ULONG_BE( W[ 3], data, 12 );
00094     GET_ULONG_BE( W[ 4], data, 16 );
00095     GET_ULONG_BE( W[ 5], data, 20 );
00096     GET_ULONG_BE( W[ 6], data, 24 );
00097     GET_ULONG_BE( W[ 7], data, 28 );
00098     GET_ULONG_BE( W[ 8], data, 32 );
00099     GET_ULONG_BE( W[ 9], data, 36 );
00100     GET_ULONG_BE( W[10], data, 40 );
00101     GET_ULONG_BE( W[11], data, 44 );
00102     GET_ULONG_BE( W[12], data, 48 );
00103     GET_ULONG_BE( W[13], data, 52 );
00104     GET_ULONG_BE( W[14], data, 56 );
00105     GET_ULONG_BE( W[15], data, 60 );
00106 
00107 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00108 
00109 #define R(t)                                            \
00110 (                                                       \
00111     temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^     \
00112            W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],      \
00113     ( W[t & 0x0F] = S(temp,1) )                         \
00114 )
00115 
00116 #define P(a,b,c,d,e,x)                                  \
00117 {                                                       \
00118     e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
00119 }
00120 
00121     A = ctx->state [0];
00122     B = ctx->state [1];
00123     C = ctx->state [2];
00124     D = ctx->state [3];
00125     E = ctx->state [4];
00126 
00127 #define F(x,y,z) (z ^ (x & (y ^ z)))
00128 #define K 0x5A827999
00129 
00130     P( A, B, C, D, E, W[0]  );
00131     P( E, A, B, C, D, W[1]  );
00132     P( D, E, A, B, C, W[2]  );
00133     P( C, D, E, A, B, W[3]  );
00134     P( B, C, D, E, A, W[4]  );
00135     P( A, B, C, D, E, W[5]  );
00136     P( E, A, B, C, D, W[6]  );
00137     P( D, E, A, B, C, W[7]  );
00138     P( C, D, E, A, B, W[8]  );
00139     P( B, C, D, E, A, W[9]  );
00140     P( A, B, C, D, E, W[10] );
00141     P( E, A, B, C, D, W[11] );
00142     P( D, E, A, B, C, W[12] );
00143     P( C, D, E, A, B, W[13] );
00144     P( B, C, D, E, A, W[14] );
00145     P( A, B, C, D, E, W[15] );
00146     P( E, A, B, C, D, R(16) );
00147     P( D, E, A, B, C, R(17) );
00148     P( C, D, E, A, B, R(18) );
00149     P( B, C, D, E, A, R(19) );
00150 
00151 #undef K
00152 #undef F
00153 
00154 #define F(x,y,z) (x ^ y ^ z)
00155 #define K 0x6ED9EBA1
00156 
00157     P( A, B, C, D, E, R(20) );
00158     P( E, A, B, C, D, R(21) );
00159     P( D, E, A, B, C, R(22) );
00160     P( C, D, E, A, B, R(23) );
00161     P( B, C, D, E, A, R(24) );
00162     P( A, B, C, D, E, R(25) );
00163     P( E, A, B, C, D, R(26) );
00164     P( D, E, A, B, C, R(27) );
00165     P( C, D, E, A, B, R(28) );
00166     P( B, C, D, E, A, R(29) );
00167     P( A, B, C, D, E, R(30) );
00168     P( E, A, B, C, D, R(31) );
00169     P( D, E, A, B, C, R(32) );
00170     P( C, D, E, A, B, R(33) );
00171     P( B, C, D, E, A, R(34) );
00172     P( A, B, C, D, E, R(35) );
00173     P( E, A, B, C, D, R(36) );
00174     P( D, E, A, B, C, R(37) );
00175     P( C, D, E, A, B, R(38) );
00176     P( B, C, D, E, A, R(39) );
00177 
00178 #undef K
00179 #undef F
00180 
00181 #define F(x,y,z) ((x & y) | (z & (x | y)))
00182 #define K 0x8F1BBCDC
00183 
00184     P( A, B, C, D, E, R(40) );
00185     P( E, A, B, C, D, R(41) );
00186     P( D, E, A, B, C, R(42) );
00187     P( C, D, E, A, B, R(43) );
00188     P( B, C, D, E, A, R(44) );
00189     P( A, B, C, D, E, R(45) );
00190     P( E, A, B, C, D, R(46) );
00191     P( D, E, A, B, C, R(47) );
00192     P( C, D, E, A, B, R(48) );
00193     P( B, C, D, E, A, R(49) );
00194     P( A, B, C, D, E, R(50) );
00195     P( E, A, B, C, D, R(51) );
00196     P( D, E, A, B, C, R(52) );
00197     P( C, D, E, A, B, R(53) );
00198     P( B, C, D, E, A, R(54) );
00199     P( A, B, C, D, E, R(55) );
00200     P( E, A, B, C, D, R(56) );
00201     P( D, E, A, B, C, R(57) );
00202     P( C, D, E, A, B, R(58) );
00203     P( B, C, D, E, A, R(59) );
00204 
00205 #undef K
00206 #undef F
00207 
00208 #define F(x,y,z) (x ^ y ^ z)
00209 #define K 0xCA62C1D6
00210 
00211     P( A, B, C, D, E, R(60) );
00212     P( E, A, B, C, D, R(61) );
00213     P( D, E, A, B, C, R(62) );
00214     P( C, D, E, A, B, R(63) );
00215     P( B, C, D, E, A, R(64) );
00216     P( A, B, C, D, E, R(65) );
00217     P( E, A, B, C, D, R(66) );
00218     P( D, E, A, B, C, R(67) );
00219     P( C, D, E, A, B, R(68) );
00220     P( B, C, D, E, A, R(69) );
00221     P( A, B, C, D, E, R(70) );
00222     P( E, A, B, C, D, R(71) );
00223     P( D, E, A, B, C, R(72) );
00224     P( C, D, E, A, B, R(73) );
00225     P( B, C, D, E, A, R(74) );
00226     P( A, B, C, D, E, R(75) );
00227     P( E, A, B, C, D, R(76) );
00228     P( D, E, A, B, C, R(77) );
00229     P( C, D, E, A, B, R(78) );
00230     P( B, C, D, E, A, R(79) );
00231 
00232 #undef K
00233 #undef F
00234 
00235     ctx->state [0] += A;
00236     ctx->state [1] += B;
00237     ctx->state [2] += C;
00238     ctx->state [3] += D;
00239     ctx->state [4] += E;
00240 }
00241 
00242 /*
00243  * SHA-1 process buffer
00244  */
00245 void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen )
00246 {
00247     int fill;
00248     unsigned long left;
00249 
00250     if( ilen <= 0 )
00251         return;
00252 
00253     left = ctx->total [0] & 0x3F;
00254     fill = 64 - left;
00255 
00256     ctx->total [0] += ilen;
00257     ctx->total [0] &= 0xFFFFFFFF;
00258 
00259     if( ctx->total [0] < (unsigned long) ilen )
00260         ctx->total [1]++;
00261 
00262     if( left && ilen >= fill )
00263     {
00264         MEMCPY( (void *) (ctx->buffer  + left),
00265                 input, fill );
00266         sha1_process( ctx, ctx->buffer  );
00267         input += fill;
00268         ilen  -= fill;
00269         left = 0;
00270     }
00271 
00272     while( ilen >= 64 )
00273     {
00274         sha1_process( ctx, input );
00275         input += 64;
00276         ilen  -= 64;
00277     }
00278 
00279     if( ilen > 0 )
00280     {
00281         MEMCPY( (void *) (ctx->buffer  + left),
00282                 input, ilen );
00283     }
00284 }
00285 
00286 static const unsigned char sha1_padding[64] =
00287 {
00288  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00289     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00290     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00291     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00292 };
00293 
00294 /*
00295  * SHA-1 final digest
00296  */
00297 void sha1_finish( sha1_context *ctx, unsigned char output[20] )
00298 {
00299     unsigned long last, padn;
00300     unsigned long high, low;
00301     unsigned char msglen[8];
00302 
00303     high = ( ctx->total [0] >> 29 )
00304          | ( ctx->total [1] <<  3 );
00305     low  = ( ctx->total [0] <<  3 );
00306 
00307     PUT_ULONG_BE( high, msglen, 0 );
00308     PUT_ULONG_BE( low,  msglen, 4 );
00309 
00310     last = ctx->total [0] & 0x3F;
00311     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00312 
00313     sha1_update( ctx, sha1_padding, padn );
00314     sha1_update( ctx, msglen, 8 );
00315 
00316     PUT_ULONG_BE( ctx->state [0], output,  0 );
00317     PUT_ULONG_BE( ctx->state [1], output,  4 );
00318     PUT_ULONG_BE( ctx->state [2], output,  8 );
00319     PUT_ULONG_BE( ctx->state [3], output, 12 );
00320     PUT_ULONG_BE( ctx->state [4], output, 16 );
00321 }
00322 
00323 /*
00324  * output = SHA-1( input buffer )
00325  */
00326 void sha1( unsigned char *input, int ilen, unsigned char output[20] )
00327 {
00328     sha1_context ctx;
00329 
00330     sha1_starts( &ctx );
00331     sha1_update( &ctx, input, ilen );
00332     sha1_finish( &ctx, output );
00333 }
00334 
00335 #endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_SHA1 */