supl/locationsuplfw/protocolhandlerapi/src/epos_suplkey.cpp
changeset 0 667063e416a2
child 13 9c303455e256
equal deleted inserted replaced
-1:000000000000 0:667063e416a2
       
     1 /*
       
     2  ---------------------------------------------------------------------------
       
     3  Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.
       
     4  All rights reserved.
       
     5 
       
     6  LICENSE TERMS
       
     7 
       
     8  The free distribution and use of this software in both source and binary
       
     9  form is allowed (with or without changes) provided that:
       
    10 
       
    11    1. distributions of this source code include the above copyright
       
    12       notice, this list of conditions and the following disclaimer;
       
    13 
       
    14    2. distributions in binary form include the above copyright
       
    15       notice, this list of conditions and the following disclaimer
       
    16       in the documentation and/or other associated materials;
       
    17 
       
    18    3. the copyright holder's name is not used to endorse products
       
    19       built using this software without specific written permission.
       
    20 
       
    21  ALTERNATIVELY, provided that this notice is retained in full, this product
       
    22  may be distributed under the terms of the GNU General Public License (GPL),
       
    23  in which case the provisions of the GPL apply INSTEAD OF those given above.
       
    24 
       
    25  DISCLAIMER
       
    26 
       
    27  This software is provided 'as is' with no explicit or implied warranties
       
    28  in respect of its properties, including, but not limited to, correctness
       
    29  and/or fitness for purpose.
       
    30  ---------------------------------------------------------------------------
       
    31 */
       
    32 
       
    33 
       
    34 //#include "stdafx.h"
       
    35 
       
    36 
       
    37 #include <libc/string.h>     /* for memcpy() etc.        */
       
    38 #include <libc/stdlib.h>     /* for _lrotl with VC++     */
       
    39 
       
    40 #if defined(__GNUC__) || defined(__GNU_LIBRARY__)
       
    41 #include <byteswap.h>
       
    42 #include <endian.h>
       
    43 #endif
       
    44 
       
    45 #include "sha1.h"
       
    46 #include "hmac.h"
       
    47 
       
    48 void derive_key(const unsigned char pwd[],  /* the PASSWORD     */
       
    49                unsigned int pwd_len,        /* and its length   */
       
    50                const unsigned char salt[],  /* the SALT and its */
       
    51                unsigned int salt_len,       /* length           */
       
    52                unsigned int iter,   /* the number of iterations */
       
    53                unsigned char key[], /* space for the output key */
       
    54                unsigned int key_len)/* and its required length  */
       
    55 {
       
    56     unsigned int    i, j, k, n_blk;
       
    57     unsigned char uu[OUT_BLOCK_LENGTH], ux[OUT_BLOCK_LENGTH];
       
    58     hmac_ctx c1[1], c2[1], c3[1];
       
    59 
       
    60     /* set HMAC context (c1) for password               */
       
    61     hmac_sha1_begin(c1);
       
    62     hmac_sha1_key(pwd, pwd_len, c1);
       
    63 
       
    64     /* set HMAC context (c2) for password and salt      */
       
    65     memcpy(c2, c1, sizeof(hmac_ctx));
       
    66     hmac_sha1_data(salt, salt_len, c2);
       
    67 
       
    68     /* find the number of SHA blocks in the key         */
       
    69     n_blk = 1 + (key_len - 1) / OUT_BLOCK_LENGTH;
       
    70 
       
    71     for(i = 0; i < n_blk; ++i) /* for each block in key */
       
    72     {
       
    73         /* ux[] holds the running xor value             */
       
    74         memset(ux, 0, OUT_BLOCK_LENGTH);
       
    75 
       
    76         /* set HMAC context (c3) for password and salt  */
       
    77         memcpy(c3, c2, sizeof(hmac_ctx));
       
    78 
       
    79         /* enter additional data for 1st block into uu  */
       
    80         uu[0] = (unsigned char)((i + 1) >> 24);
       
    81         uu[1] = (unsigned char)((i + 1) >> 16);
       
    82         uu[2] = (unsigned char)((i + 1) >> 8);
       
    83         uu[3] = (unsigned char)(i + 1);
       
    84 
       
    85         /* this is the key mixing iteration         */
       
    86         for(j = 0, k = 4; j < iter; ++j)
       
    87         {
       
    88             /* add previous round data to HMAC      */
       
    89             hmac_sha1_data(uu, k, c3);
       
    90 
       
    91             /* obtain HMAC for uu[]                 */
       
    92             hmac_sha1_end(uu, OUT_BLOCK_LENGTH, c3);
       
    93 
       
    94             /* xor into the running xor block       */
       
    95             for(k = 0; k < OUT_BLOCK_LENGTH; ++k)
       
    96                 ux[k] ^= uu[k];
       
    97 
       
    98             /* set HMAC context (c3) for password   */
       
    99             memcpy(c3, c1, sizeof(hmac_ctx));
       
   100         }
       
   101 
       
   102         /* compile key blocks into the key output   */
       
   103         j = 0; k = i * OUT_BLOCK_LENGTH;
       
   104         while(j < OUT_BLOCK_LENGTH && k < key_len)
       
   105             key[k++] = ux[j++];
       
   106     }
       
   107 }
       
   108 
       
   109 /*#ifdef TEST*/
       
   110 
       
   111 #include <stdio.h>
       
   112 
       
   113 #if 0
       
   114 
       
   115 struct
       
   116 {   unsigned int    pwd_len;
       
   117     unsigned int    salt_len;
       
   118     unsigned int    it_count;
       
   119     unsigned char   *pwd;
       
   120     unsigned char   salt[32];
       
   121     unsigned char   key[32];
       
   122 } tests[] =
       
   123 {
       
   124     {   8, 4, 5, (unsigned char*)"password",
       
   125         {   0x12, 0x34, 0x56, 0x78 },
       
   126         {   0x5c, 0x75, 0xce, 0xf0, 0x1a, 0x96, 0x0d, 0xf7,
       
   127             0x4c, 0xb6, 0xb4, 0x9b, 0x9e, 0x38, 0xe6, 0xb5 } /* ... */
       
   128     },
       
   129     {   8, 8, 5, (unsigned char*)"password",
       
   130         {   0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12 },
       
   131         {   0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6,
       
   132             0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49 } /* ... */
       
   133     }
       
   134 };
       
   135 
       
   136 
       
   137 
       
   138 
       
   139 
       
   140 
       
   141 void get_key(unsigned char key[], 
       
   142                unsigned int keylength)
       
   143 {
       
   144 
       
   145 	unsigned int    i, j, n=0,bitykeylen = 256;
       
   146     unsigned char   bitykey[256];
       
   147 
       
   148     for(i = 0; i <1; ++i)
       
   149     {
       
   150         derive_key(tests[i].pwd, tests[i].pwd_len, tests[i].salt,
       
   151                     tests[i].salt_len, tests[i].it_count, bitykey, bitykeylen);
       
   152         for(j = 0; j < bitykeylen && j < 64; j += 4)
       
   153         {
       
   154             if(j % ( keylength / 8 ) == 0 && j!=0 )
       
   155                 break;
       
   156 			key[n++] = bitykey[j];
       
   157 			key[n++]=  bitykey[j+1];
       
   158 			key[n++]=  bitykey[j+2];
       
   159 			key[n++] = bitykey[j+3];
       
   160         }
       
   161     }
       
   162 }
       
   163 
       
   164 #endif
       
   165 /*int _tmain(int argc, _TCHAR* argv[])
       
   166 {
       
   167 	unsigned char key[16];
       
   168 	unsigned int  keylength = 128;
       
   169 	get_key( key , keylength);
       
   170 	return 0;
       
   171 }*/
       
   172 /*.............hmac...................*/
       
   173 /* initialise the HMAC context to zero */
       
   174 void hmac_sha1_begin(hmac_ctx cx[1])
       
   175 {
       
   176     memset(cx, 0, sizeof(hmac_ctx));
       
   177 }
       
   178 
       
   179 /* input the HMAC key (can be called multiple times)    */
       
   180 int hmac_sha1_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1])
       
   181 {
       
   182     if(cx->klen == HMAC_IN_DATA)                /* error if further key input   */
       
   183         return HMAC_BAD_MODE;                   /* is attempted in data mode    */
       
   184 
       
   185     if(cx->klen + key_len > IN_BLOCK_LENGTH)    /* if the key has to be hashed  */
       
   186     {
       
   187         if(cx->klen <= IN_BLOCK_LENGTH)         /* if the hash has not yet been */
       
   188         {                                       /* started, initialise it and   */
       
   189             sha1_begin(cx->ctx);                /* hash stored key characters   */
       
   190             sha1_hash(cx->key, cx->klen, cx->ctx);
       
   191         }
       
   192 
       
   193         sha1_hash(key, key_len, cx->ctx);       /* hash long key data into hash */
       
   194     }
       
   195     else                                        /* otherwise store key data     */
       
   196         memcpy(cx->key + cx->klen, key, key_len);
       
   197 
       
   198     cx->klen += key_len;                        /* update the key length count  */
       
   199     return HMAC_OK;
       
   200 }
       
   201 
       
   202 /* input the HMAC data (can be called multiple times) - */
       
   203 /* note that this call terminates the key input phase   */
       
   204 void hmac_sha1_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1])
       
   205 {   unsigned int i;
       
   206 
       
   207     if(cx->klen != HMAC_IN_DATA)                /* if not yet in data phase */
       
   208     {
       
   209         if(cx->klen > IN_BLOCK_LENGTH)          /* if key is being hashed   */
       
   210         {                                       /* complete the hash and    */
       
   211             sha1_end(cx->key, cx->ctx);         /* store the result as the  */
       
   212             cx->klen = OUT_BLOCK_LENGTH;        /* key and set new length   */
       
   213         }
       
   214 
       
   215         /* pad the key if necessary */
       
   216         memset(cx->key + cx->klen, 0, IN_BLOCK_LENGTH - cx->klen);
       
   217 
       
   218         /* xor ipad into key value  */
       
   219         for(i = 0; i < (IN_BLOCK_LENGTH >> 2); ++i)
       
   220             ((unsigned long*)cx->key)[i] ^= 0x36363636;
       
   221 
       
   222         /* and start hash operation */
       
   223         sha1_begin(cx->ctx);
       
   224         sha1_hash(cx->key, IN_BLOCK_LENGTH, cx->ctx);
       
   225 
       
   226         /* mark as now in data mode */
       
   227         cx->klen = HMAC_IN_DATA;
       
   228     }
       
   229 
       
   230     /* hash the data (if any)       */
       
   231     if(data_len)
       
   232         sha1_hash(data, data_len, cx->ctx);
       
   233 }
       
   234 
       
   235 /* compute and output the MAC value */
       
   236 void hmac_sha1_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1])
       
   237 {   unsigned char dig[OUT_BLOCK_LENGTH];
       
   238     unsigned int i;
       
   239 
       
   240     /* if no data has been entered perform a null data phase        */
       
   241     if(cx->klen != HMAC_IN_DATA)
       
   242         hmac_sha1_data((const unsigned char*)0, 0, cx);
       
   243 
       
   244     sha1_end(dig, cx->ctx);         /* complete the inner hash      */
       
   245 
       
   246     /* set outer key value using opad and removing ipad */
       
   247     for(i = 0; i < (IN_BLOCK_LENGTH >> 2); ++i)
       
   248         ((unsigned long*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c;
       
   249 
       
   250     /* perform the outer hash operation */
       
   251     sha1_begin(cx->ctx);
       
   252     sha1_hash(cx->key, IN_BLOCK_LENGTH, cx->ctx);
       
   253     sha1_hash(dig, OUT_BLOCK_LENGTH, cx->ctx);
       
   254     sha1_end(dig, cx->ctx);
       
   255 
       
   256     /* output the hash value            */
       
   257     for(i = 0; i < mac_len; ++i)
       
   258         mac[i] = dig[i];
       
   259 }
       
   260 
       
   261 /* 'do it all in one go' subroutine     */
       
   262 void hmac_sha1(const unsigned char key[], unsigned int key_len,
       
   263           const unsigned char data[], unsigned int data_len,
       
   264           unsigned char mac[], unsigned int mac_len)
       
   265 {   hmac_ctx    cx[1];
       
   266 
       
   267     hmac_sha1_begin(cx);
       
   268     hmac_sha1_key(key, key_len, cx);
       
   269     hmac_sha1_data(data, data_len, cx);
       
   270     hmac_sha1_end(mac, mac_len, cx);
       
   271 }
       
   272 
       
   273 /****************hmac*******************/
       
   274 
       
   275 /*****************************sha1******************/
       
   276 /*
       
   277     To obtain the highest speed on processors with 32-bit words, this code
       
   278     needs to determine the order in which bytes are packed into such words.
       
   279     The following block of code is an attempt to capture the most obvious
       
   280     ways in which various environemnts specify their endian definitions.
       
   281     It may well fail, in which case the definitions will need to be set by
       
   282     editing at the points marked **** EDIT HERE IF NECESSARY **** below.
       
   283 */
       
   284 #define SHA_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
       
   285 #define SHA_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
       
   286 /*
       
   287 #if !defined(PLATFORM_BYTE_ORDER)
       
   288 #if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
       
   289 #  if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
       
   290 #    if defined(BYTE_ORDER)
       
   291 #      if   (BYTE_ORDER == LITTLE_ENDIAN)
       
   292 #        define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
       
   293 #      elif (BYTE_ORDER == BIG_ENDIAN)
       
   294 #        define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
       
   295 #      endif
       
   296 #    endif
       
   297 #  elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
       
   298 #    define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
       
   299 #  elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
       
   300 #    define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
       
   301 #  endif
       
   302 #elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
       
   303 #  if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
       
   304 #    if defined(_BYTE_ORDER)
       
   305 #      if   (_BYTE_ORDER == _LITTLE_ENDIAN)
       
   306 #        define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
       
   307 #      elif (_BYTE_ORDER == _BIG_ENDIAN)
       
   308 #        define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
       
   309 #      endif
       
   310 #    endif
       
   311 #  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
       
   312 #    define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
       
   313 #  elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
       
   314 #    define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
       
   315 #  endif
       
   316 #elif 0     /#* **** EDIT HERE IF NECESSARY **** */
       
   317 /*#define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
       
   318 /#*#elif 0     /#* **** EDIT HERE IF NECESSARY ****# /
       
   319 #define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
       
   320 #elif (('1234' >> 24) == '1')
       
   321 #  define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
       
   322 #elif (('4321' >> 24) == '1')
       
   323 #  define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
       
   324 #endif
       
   325 #endif
       
   326 */
       
   327 //#define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
       
   328 //#  define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
       
   329 #  define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
       
   330 #if !defined(PLATFORM_BYTE_ORDER)
       
   331 #  error Please set undetermined byte order (lines 87 or 89 of sha1.c).
       
   332 #endif
       
   333 
       
   334 #define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
       
   335 
       
   336 #if (PLATFORM_BYTE_ORDER == SHA_BIG_ENDIAN)
       
   337 #define swap_b32(x) (x)
       
   338 #elif defined(bswap_32)
       
   339 #define swap_b32(x) bswap_32(x)
       
   340 #else
       
   341 #define swap_b32(x) ((rotl32((x), 8) & 0x00ff00ff) | (rotl32((x), 24) & 0xff00ff00))
       
   342 #endif
       
   343 
       
   344 #define SHA1_MASK   (SHA1_BLOCK_SIZE - 1)
       
   345 
       
   346 /* reverse byte order in 32-bit words       */
       
   347 
       
   348 #define ch(x,y,z)       (((x) & (y)) ^ (~(x) & (z)))
       
   349 #define parity(x,y,z)   ((x) ^ (y) ^ (z))
       
   350 #define maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
       
   351 
       
   352 /* A normal version as set out in the FIPS  */
       
   353 
       
   354 #define rnd(f,k)    \
       
   355     t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; \
       
   356     e = d; d = c; c = rotl32(b, 30); b = t
       
   357 
       
   358 void sha1_compile(sha1_ctx ctx[1])
       
   359 {   sha1_32t    w[80], i, a, b, c, d, e, t;
       
   360 
       
   361     /* note that words are compiled from the buffer into 32-bit */
       
   362     /* words in big-endian order so an order reversal is needed */
       
   363     /* here on little endian machines                           */
       
   364     for(i = 0; i < SHA1_BLOCK_SIZE / 4; ++i)
       
   365         w[i] = swap_b32(ctx->wbuf[i]);
       
   366 
       
   367     for(i = SHA1_BLOCK_SIZE / 4; i < 80; ++i)
       
   368         w[i] = rotl32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
       
   369 
       
   370     a = ctx->hash[0];
       
   371     b = ctx->hash[1];
       
   372     c = ctx->hash[2];
       
   373     d = ctx->hash[3];
       
   374     e = ctx->hash[4];
       
   375 
       
   376     for(i = 0; i < 20; ++i)
       
   377     {
       
   378         rnd(ch, 0x5a827999);
       
   379     }
       
   380 
       
   381     for(i = 20; i < 40; ++i)
       
   382     {
       
   383         rnd(parity, 0x6ed9eba1);
       
   384     }
       
   385 
       
   386     for(i = 40; i < 60; ++i)
       
   387     {
       
   388         rnd(maj, 0x8f1bbcdc);
       
   389     }
       
   390 
       
   391     for(i = 60; i < 80; ++i)
       
   392     {
       
   393         rnd(parity, 0xca62c1d6);
       
   394     }
       
   395 
       
   396     ctx->hash[0] += a;
       
   397     ctx->hash[1] += b;
       
   398     ctx->hash[2] += c;
       
   399     ctx->hash[3] += d;
       
   400     ctx->hash[4] += e;
       
   401 }
       
   402 
       
   403 void sha1_begin(sha1_ctx ctx[1])
       
   404 {
       
   405     ctx->count[0] = ctx->count[1] = 0;
       
   406     ctx->hash[0] = 0x67452301;
       
   407     ctx->hash[1] = 0xefcdab89;
       
   408     ctx->hash[2] = 0x98badcfe;
       
   409     ctx->hash[3] = 0x10325476;
       
   410     ctx->hash[4] = 0xc3d2e1f0;
       
   411 }
       
   412 
       
   413 /* SHA1 hash data in an array of bytes into hash buffer and */
       
   414 /* call the hash_compile function as required.              */
       
   415 
       
   416 void sha1_hash(const unsigned char data[], unsigned int len, sha1_ctx ctx[1])
       
   417 {   sha1_32t pos = (sha1_32t)(ctx->count[0] & SHA1_MASK),
       
   418              space = SHA1_BLOCK_SIZE - pos;
       
   419     const unsigned char *sp = data;
       
   420 
       
   421     if((ctx->count[0] += len) < len)
       
   422         ++(ctx->count[1]);
       
   423 
       
   424     while(len >= space)     /* tranfer whole blocks if possible  */
       
   425     {
       
   426         memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
       
   427         sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0;
       
   428         sha1_compile(ctx);
       
   429     }
       
   430 
       
   431     /*lint -e{803} conceivable data overrun */
       
   432     /* there are two cases: the above while loop entered or not */
       
   433     /* entered. If not entered, 'space = SHA1_BLOCK_SIZE - pos' */
       
   434     /* and 'len < space' so that 'len + pos < SHA1_BLOCK_SIZE'. */
       
   435     /* If entered, 'pos = 0', 'space = SHA1_BLOCK_SIZE' and     */
       
   436     /* 'len < space' so that 'pos + len < SHA1_BLOCK_SIZE'. In  */
       
   437     /* both cases, therefore, the memory copy is in the buffer  */
       
   438 
       
   439     memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
       
   440 }
       
   441 
       
   442 /* SHA1 final padding and digest calculation  */
       
   443 
       
   444 #if (PLATFORM_BYTE_ORDER == SHA_LITTLE_ENDIAN)
       
   445 static sha1_32t  mask[4] =
       
   446     {   0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff };
       
   447 static sha1_32t  bits[4] =
       
   448     {   0x00000080, 0x00008000, 0x00800000, 0x80000000 };
       
   449 #else
       
   450 static sha1_32t  mask[4] =
       
   451     {   0x00000000, 0xff000000, 0xffff0000, 0xffffff00 };
       
   452 static sha1_32t  bits[4] =
       
   453     {   0x80000000, 0x00800000, 0x00008000, 0x00000080 };
       
   454 #endif
       
   455 
       
   456 void sha1_end(unsigned char hval[], sha1_ctx ctx[1])
       
   457 {   sha1_32t    i = (sha1_32t)(ctx->count[0] & SHA1_MASK);
       
   458 
       
   459  
       
   460     /* mask out the rest of any partial 32-bit word and then set    */
       
   461     /* the next byte to 0x80. On big-endian machines any bytes in   */
       
   462     /* the buffer will be at the top end of 32 bit words, on little */
       
   463     /* endian machines they will be at the bottom. Hence the AND    */
       
   464     /* and OR masks above are reversed for little endian systems    */
       
   465     /* Note that we can always add the first padding byte at this   */
       
   466     /* point because the buffer always has at least one empty slot  */
       
   467     ctx->wbuf[i >> 2] = (ctx->wbuf[i >> 2] & mask[i & 3]) | bits[i & 3];
       
   468 
       
   469     /* we need 9 or more empty positions, one for the padding byte  */
       
   470     /* (above) and eight for the length count.  If there is not     */
       
   471     /* enough space pad and empty the buffer                        */
       
   472     if(i > SHA1_BLOCK_SIZE - 9)
       
   473     {
       
   474         if(i < 60) ctx->wbuf[15] = 0;
       
   475         sha1_compile(ctx);
       
   476         i = 0;
       
   477     }
       
   478     else    /* compute a word index for the empty buffer positions  */
       
   479         i = (i >> 2) + 1;
       
   480 
       
   481     while(i < 14) /* and zero pad all but last two positions        */
       
   482         ctx->wbuf[i++] = 0;
       
   483 
       
   484     /* assemble the eight byte counter in in big-endian format      */
       
   485     ctx->wbuf[14] = swap_b32((ctx->count[1] << 3) | (ctx->count[0] >> 29));
       
   486     ctx->wbuf[15] = swap_b32(ctx->count[0] << 3);
       
   487 
       
   488     sha1_compile(ctx);
       
   489 
       
   490     /* extract the hash value as bytes in case the hash buffer is   */
       
   491     /* misaligned for 32-bit words                                  */
       
   492     /*lint -e{504} unusual shift operation (unusually formed right argument) */
       
   493     for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
       
   494         hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
       
   495 }
       
   496 
       
   497 void sha1(unsigned char hval[], const unsigned char data[], unsigned int len)
       
   498 {   sha1_ctx    cx[1];
       
   499 
       
   500     sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);
       
   501 }