/home/dko/projects/mobilec/trunk/src/security/xyssl-0.7/library/sha2.c

Go to the documentation of this file.
00001 /* SVN FILE INFO
00002  * $Revision: 174 $ : Last Committed Revision
00003  * $Date: 2008-06-24 10:50:29 -0700 (Tue, 24 Jun 2008) $ : Last Committed Date */
00004 /*
00005  *  FIPS-180-2 compliant SHA-256 implementation
00006  *
00007  *  Copyright (C) 2006-2007  Christophe Devine
00008  *
00009  *  This library is free software; you can redistribute it and/or
00010  *  modify it under the terms of the GNU Lesser General Public
00011  *  License, version 2.1 as published by the Free Software Foundation.
00012  *
00013  *  This library is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Lesser General Public
00019  *  License along with this library; if not, write to the Free Software
00020  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00021  *  MA  02110-1301  USA
00022  */
00023 /*
00024  *  The SHA-256 Secure Hash Standard was published by NIST in 2002.
00025  *
00026  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
00027  */
00028 
00029 #ifndef _CRT_SECURE_NO_DEPRECATE
00030 #define _CRT_SECURE_NO_DEPRECATE 1
00031 #endif
00032 
00033 #include <string.h>
00034 #include <stdio.h>
00035 
00036 #include "xyssl/sha2.h"
00037 
00038 /*
00039  * 32-bit integer manipulation macros (big endian)
00040  */
00041 #ifndef GET_UINT32_BE
00042 #define GET_UINT32_BE(n,b,i)                            \
00043 {                                                       \
00044     (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
00045         | ( (unsigned long) (b)[(i) + 1] << 16 )        \
00046         | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
00047         | ( (unsigned long) (b)[(i) + 3]       );       \
00048 }
00049 #endif
00050 
00051 #ifndef PUT_UINT32_BE
00052 #define PUT_UINT32_BE(n,b,i)                            \
00053 {                                                       \
00054     (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
00055     (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
00056     (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
00057     (b)[(i) + 3] = (unsigned char) ( (n)       );       \
00058 }
00059 #endif
00060 
00061 /*
00062  * SHA-256 context setup
00063  */
00064 void sha2_starts( sha2_context *ctx, int is224 )
00065 {
00066     ctx->total[0] = 0;
00067     ctx->total[1] = 0;
00068 
00069     if( is224 == 0 )
00070     {
00071         /* SHA-256 */
00072         ctx->state[0] = 0x6A09E667;
00073         ctx->state[1] = 0xBB67AE85;
00074         ctx->state[2] = 0x3C6EF372;
00075         ctx->state[3] = 0xA54FF53A;
00076         ctx->state[4] = 0x510E527F;
00077         ctx->state[5] = 0x9B05688C;
00078         ctx->state[6] = 0x1F83D9AB;
00079         ctx->state[7] = 0x5BE0CD19;
00080     }
00081     else
00082     {
00083         /* SHA-224 */
00084         ctx->state[0] = 0xC1059ED8;
00085         ctx->state[1] = 0x367CD507;
00086         ctx->state[2] = 0x3070DD17;
00087         ctx->state[3] = 0xF70E5939;
00088         ctx->state[4] = 0xFFC00B31;
00089         ctx->state[5] = 0x68581511;
00090         ctx->state[6] = 0x64F98FA7;
00091         ctx->state[7] = 0xBEFA4FA4;
00092     }
00093 
00094     ctx->is224 = is224;
00095 }
00096 
00097 static void sha2_process( sha2_context *ctx, unsigned char data[64] )
00098 {
00099     unsigned long temp1, temp2, W[64];
00100     unsigned long A, B, C, D, E, F, G, H;
00101 
00102     GET_UINT32_BE( W[ 0], data,  0 );
00103     GET_UINT32_BE( W[ 1], data,  4 );
00104     GET_UINT32_BE( W[ 2], data,  8 );
00105     GET_UINT32_BE( W[ 3], data, 12 );
00106     GET_UINT32_BE( W[ 4], data, 16 );
00107     GET_UINT32_BE( W[ 5], data, 20 );
00108     GET_UINT32_BE( W[ 6], data, 24 );
00109     GET_UINT32_BE( W[ 7], data, 28 );
00110     GET_UINT32_BE( W[ 8], data, 32 );
00111     GET_UINT32_BE( W[ 9], data, 36 );
00112     GET_UINT32_BE( W[10], data, 40 );
00113     GET_UINT32_BE( W[11], data, 44 );
00114     GET_UINT32_BE( W[12], data, 48 );
00115     GET_UINT32_BE( W[13], data, 52 );
00116     GET_UINT32_BE( W[14], data, 56 );
00117     GET_UINT32_BE( W[15], data, 60 );
00118 
00119 #define  SHR(x,n) ((x & 0xFFFFFFFF) >> n)
00120 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
00121 
00122 #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))
00123 #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))
00124 
00125 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
00126 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
00127 
00128 #define F0(x,y,z) ((x & y) | (z & (x | y)))
00129 #define F1(x,y,z) (z ^ (x & (y ^ z)))
00130 
00131 #define R(t)                                    \
00132 (                                               \
00133     W[t] = S1(W[t -  2]) + W[t -  7] +          \
00134            S0(W[t - 15]) + W[t - 16]            \
00135 )
00136 
00137 #define P(a,b,c,d,e,f,g,h,x,K)                  \
00138 {                                               \
00139     temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
00140     temp2 = S2(a) + F0(a,b,c);                  \
00141     d += temp1; h = temp1 + temp2;              \
00142 }
00143 
00144     A = ctx->state[0];
00145     B = ctx->state[1];
00146     C = ctx->state[2];
00147     D = ctx->state[3];
00148     E = ctx->state[4];
00149     F = ctx->state[5];
00150     G = ctx->state[6];
00151     H = ctx->state[7];
00152 
00153     P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
00154     P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
00155     P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
00156     P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
00157     P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
00158     P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
00159     P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
00160     P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
00161     P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
00162     P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
00163     P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
00164     P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
00165     P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
00166     P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
00167     P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
00168     P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
00169     P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
00170     P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
00171     P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
00172     P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
00173     P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
00174     P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
00175     P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
00176     P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
00177     P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
00178     P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
00179     P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
00180     P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
00181     P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
00182     P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
00183     P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
00184     P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
00185     P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
00186     P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
00187     P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
00188     P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
00189     P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
00190     P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
00191     P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
00192     P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
00193     P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
00194     P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
00195     P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
00196     P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
00197     P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
00198     P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
00199     P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
00200     P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
00201     P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
00202     P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
00203     P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
00204     P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
00205     P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
00206     P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
00207     P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
00208     P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
00209     P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
00210     P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
00211     P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
00212     P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
00213     P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
00214     P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
00215     P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
00216     P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
00217 
00218     ctx->state[0] += A;
00219     ctx->state[1] += B;
00220     ctx->state[2] += C;
00221     ctx->state[3] += D;
00222     ctx->state[4] += E;
00223     ctx->state[5] += F;
00224     ctx->state[6] += G;
00225     ctx->state[7] += H;
00226 }
00227 
00228 /*
00229  * SHA-256 process buffer
00230  */
00231 void sha2_update( sha2_context *ctx, unsigned char *input, int ilen )
00232 {
00233     int fill;
00234     unsigned long left;
00235 
00236     if( ilen <= 0 )
00237         return;
00238 
00239     left = ctx->total[0] & 0x3F;
00240     fill = 64 - left;
00241 
00242     ctx->total[0] += ilen;
00243     ctx->total[0] &= 0xFFFFFFFF;
00244 
00245     if( ctx->total[0] < (unsigned long) ilen )
00246         ctx->total[1]++;
00247 
00248     if( left && ilen >= fill )
00249     {
00250         memcpy( (void *) (ctx->buffer + left),
00251                 (void *) input, fill );
00252         sha2_process( ctx, ctx->buffer );
00253         input += fill;
00254         ilen  -= fill;
00255         left = 0;
00256     }
00257 
00258     while( ilen >= 64 )
00259     {
00260         sha2_process( ctx, input );
00261         input += 64;
00262         ilen  -= 64;
00263     }
00264 
00265     if( ilen > 0 )
00266     {
00267         memcpy( (void *) (ctx->buffer + left),
00268                 (void *) input, ilen );
00269     }
00270 }
00271 
00272 static const unsigned char sha2_padding[64] =
00273 {
00274  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00275     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00276     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00277     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00278 };
00279 
00280 /*
00281  * SHA-256 final digest
00282  */
00283 void sha2_finish( sha2_context *ctx, unsigned char *output )
00284 {
00285     unsigned long last, padn;
00286     unsigned long high, low;
00287     unsigned char msglen[8];
00288 
00289     high = ( ctx->total[0] >> 29 )
00290          | ( ctx->total[1] <<  3 );
00291     low  = ( ctx->total[0] <<  3 );
00292 
00293     PUT_UINT32_BE( high, msglen, 0 );
00294     PUT_UINT32_BE( low,  msglen, 4 );
00295 
00296     last = ctx->total[0] & 0x3F;
00297     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00298 
00299     sha2_update( ctx, (unsigned char *) sha2_padding, padn );
00300     sha2_update( ctx, msglen, 8 );
00301 
00302     PUT_UINT32_BE( ctx->state[0], output,  0 );
00303     PUT_UINT32_BE( ctx->state[1], output,  4 );
00304     PUT_UINT32_BE( ctx->state[2], output,  8 );
00305     PUT_UINT32_BE( ctx->state[3], output, 12 );
00306     PUT_UINT32_BE( ctx->state[4], output, 16 );
00307     PUT_UINT32_BE( ctx->state[5], output, 20 );
00308     PUT_UINT32_BE( ctx->state[6], output, 24 );
00309 
00310     if( ctx->is224 == 0 )
00311         PUT_UINT32_BE( ctx->state[7], output, 28 );
00312 }
00313 
00314 /*
00315  * Output = SHA-256( input buffer )
00316  */
00317 void sha2( unsigned char *input,  int ilen,
00318            unsigned char *output, int is224 )
00319 {
00320     sha2_context ctx;
00321 
00322     sha2_starts( &ctx, is224 );
00323     sha2_update( &ctx, input, ilen );
00324     sha2_finish( &ctx, output );
00325 
00326     memset( &ctx, 0, sizeof( sha2_context ) );
00327 }
00328 
00329 /*
00330  * Output = SHA-256( file contents )
00331  */
00332 int sha2_file( char *path, unsigned char *output, int is224 )
00333 {
00334     FILE *f;
00335     size_t n;
00336     sha2_context ctx;
00337     unsigned char buf[1024];
00338 
00339     if( ( f = fopen( path, "rb" ) ) == NULL )
00340         return( 1 );
00341 
00342     sha2_starts( &ctx, is224 );
00343 
00344     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00345         sha2_update( &ctx, buf, (int) n );
00346 
00347     sha2_finish( &ctx, output );
00348 
00349     memset( &ctx, 0, sizeof( sha2_context ) );
00350 
00351     if( ferror( f ) != 0 )
00352     {
00353         fclose( f );
00354         return( 2 );
00355     }
00356 
00357     fclose( f );
00358     return( 0 );
00359 }
00360 
00361 /*
00362  * SHA-256 HMAC context setup
00363  */
00364 void sha2_hmac_starts( sha2_context *ctx,  int is224,
00365                        unsigned char *key, int keylen )
00366 {
00367     int i;
00368 
00369     memset( ctx->ipad, 0x36, 64 );
00370     memset( ctx->opad, 0x5C, 64 );
00371 
00372     for( i = 0; i < keylen; i++ )
00373     {
00374         if( i >= 64 ) break;
00375 
00376         ctx->ipad[i] ^= key[i];
00377         ctx->opad[i] ^= key[i];
00378     }
00379 
00380     sha2_starts( ctx, is224 );
00381     sha2_update( ctx, ctx->ipad, 64 );
00382 }
00383 
00384 /*
00385  * SHA-256 HMAC process buffer
00386  */
00387 void sha2_hmac_update( sha2_context *ctx,
00388                        unsigned char *input, int ilen )
00389 {
00390     sha2_update( ctx, input, ilen );
00391 }
00392 
00393 /*
00394  * SHA-256 HMAC final digest
00395  */
00396 void sha2_hmac_finish( sha2_context *ctx, unsigned char *output )
00397 {
00398     int is224, hlen;
00399     unsigned char tmpbuf[32];
00400 
00401     is224 = ctx->is224;
00402     hlen = ( is224 == 0 ) ? 32 : 28;
00403 
00404     sha2_finish( ctx, tmpbuf );
00405     sha2_starts( ctx, is224 );
00406     sha2_update( ctx, ctx->opad, 64 );
00407     sha2_update( ctx, tmpbuf, hlen );
00408     sha2_finish( ctx, output );
00409 
00410     memset( tmpbuf, 0, sizeof( tmpbuf ) );
00411 }
00412 
00413 /*
00414  * Output = HMAC-SHA-256( hmac key, input buffer )
00415  */
00416 void sha2_hmac( unsigned char *key,  int keylen,
00417                 unsigned char *input,  int ilen,
00418                 unsigned char *output, int is224 )
00419 {
00420     sha2_context ctx;
00421 
00422     sha2_hmac_starts( &ctx, is224, key, keylen );
00423     sha2_hmac_update( &ctx, input, ilen );
00424     sha2_hmac_finish( &ctx, output );
00425 
00426     memset( &ctx, 0, sizeof( sha2_context ) );
00427 }
00428 
00429 static const char _sha2_src[] = "_sha2_src";
00430 
00431 #if defined(SELF_TEST)
00432 /*
00433  * FIPS-180-2 test vectors
00434  */
00435 static const char sha2_test_str[3][57] = 
00436 {
00437     { "abc" },
00438     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
00439     { "" }
00440 };
00441 
00442 static const unsigned char sha2_test_sum[6][32] =
00443 {
00444     /*
00445      * SHA-224 test vectors
00446      */
00447     { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
00448       0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
00449       0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
00450       0xE3, 0x6C, 0x9D, 0xA7 },
00451     { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
00452       0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
00453       0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
00454       0x52, 0x52, 0x25, 0x25 },
00455     { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
00456       0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
00457       0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
00458       0x4E, 0xE7, 0xAD, 0x67 },
00459 
00460     /*
00461      * SHA-256 test vectors
00462      */
00463     { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
00464       0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
00465       0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
00466       0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
00467     { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
00468       0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
00469       0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
00470       0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
00471     { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
00472       0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
00473       0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
00474       0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
00475 };
00476 
00477 /*
00478  * Checkup routine
00479  */
00480 int sha2_self_test( int verbose )
00481 {
00482     int i, j, k;
00483     unsigned char buf[1000];
00484     unsigned char sha2sum[32];
00485     sha2_context ctx;
00486 
00487     memset( buf, 'a', 1000 );
00488 
00489     for( i = 0; i < 6; i++ )
00490     {
00491         j = i % 3;
00492         k = i < 3;
00493 
00494         if( verbose != 0 )
00495             printf( "  SHA-%d test #%d: ", 256 - k * 32, j + 1 );
00496 
00497         sha2_starts( &ctx, k );
00498 
00499         if( j < 2 )
00500             sha2_update( &ctx,
00501                          (unsigned char *) sha2_test_str[j],
00502                          strlen( sha2_test_str[j] ) );
00503         else
00504         {
00505             for( j = 0; j < 1000; j++ )
00506                 sha2_update( &ctx, buf, 1000 );
00507         }
00508 
00509         sha2_finish( &ctx, sha2sum );
00510 
00511         if( memcmp( sha2sum, sha2_test_sum[i], 32 - k * 4 ) != 0 )
00512         {
00513             if( verbose != 0 )
00514                 printf( "failed\n" );
00515 
00516             return( 1 );
00517         }
00518 
00519         if( verbose != 0 )
00520             printf( "passed\n" );
00521     }
00522 
00523     if( verbose != 0 )
00524         printf( "\n" );
00525 
00526     return( 0 );
00527 }
00528 #else
00529 int sha2_self_test( int verbose )
00530 {
00531     return( 0 );
00532 }
00533 #endif

Generated on Tue Jul 1 15:29:59 2008 for Mobile-C by  doxygen 1.5.4