LCOV - code coverage report
Current view: top level - whrlpool - wp_dgst.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 65 106 61.3 %
Date: 2014-08-02 Functions: 5 5 100.0 %
Branches: 24 56 42.9 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * The Whirlpool hashing function.
       3                 :            :  *
       4                 :            :  * <P>
       5                 :            :  * <b>References</b>
       6                 :            :  *
       7                 :            :  * <P>
       8                 :            :  * The Whirlpool algorithm was developed by
       9                 :            :  * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
      10                 :            :  * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
      11                 :            :  *
      12                 :            :  * See
      13                 :            :  *      P.S.L.M. Barreto, V. Rijmen,
      14                 :            :  *      ``The Whirlpool hashing function,''
      15                 :            :  *      NESSIE submission, 2000 (tweaked version, 2001),
      16                 :            :  *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
      17                 :            :  *
      18                 :            :  * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
      19                 :            :  * Vincent Rijmen. Lookup "reference implementations" on
      20                 :            :  * <http://planeta.terra.com.br/informatica/paulobarreto/>
      21                 :            :  *
      22                 :            :  * =============================================================================
      23                 :            :  *
      24                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
      25                 :            :  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      26                 :            :  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      27                 :            :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
      28                 :            :  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      29                 :            :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      30                 :            :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
      31                 :            :  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      32                 :            :  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
      33                 :            :  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
      34                 :            :  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      35                 :            :  *
      36                 :            :  */
      37                 :            : 
      38                 :            : /*
      39                 :            :  * OpenSSL-specific implementation notes.
      40                 :            :  *
      41                 :            :  * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect
      42                 :            :  * number of *bytes* as input length argument. Bit-oriented routine
      43                 :            :  * as specified by authors is called WHIRLPOOL_BitUpdate[!] and
      44                 :            :  * does not have one-stroke counterpart.
      45                 :            :  *
      46                 :            :  * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially
      47                 :            :  * to serve WHIRLPOOL_Update. This is done for performance.
      48                 :            :  *
      49                 :            :  * Unlike authors' reference implementation, block processing
      50                 :            :  * routine whirlpool_block is designed to operate on multi-block
      51                 :            :  * input. This is done for perfomance.
      52                 :            :  */
      53                 :            : 
      54                 :            : #include "wp_locl.h"
      55                 :            : #include <string.h>
      56                 :            : 
      57                 :          9 : int WHIRLPOOL_Init      (WHIRLPOOL_CTX *c)
      58                 :            :         {
      59                 :            :         memset (c,0,sizeof(*c));
      60                 :          9 :         return(1);
      61                 :            :         }
      62                 :            : 
      63                 :       3481 : int WHIRLPOOL_Update    (WHIRLPOOL_CTX *c,const void *_inp,size_t bytes)
      64                 :            :         {
      65                 :            :         /* Well, largest suitable chunk size actually is
      66                 :            :          * (1<<(sizeof(size_t)*8-3))-64, but below number
      67                 :            :          * is large enough for not to care about excessive
      68                 :            :          * calls to WHIRLPOOL_BitUpdate... */
      69                 :       3481 :         size_t chunk = ((size_t)1)<<(sizeof(size_t)*8-4);
      70                 :       3481 :         const unsigned char *inp = _inp;
      71                 :            : 
      72         [ -  + ]:       3481 :         while (bytes>=chunk)
      73                 :            :                 {
      74                 :          0 :                 WHIRLPOOL_BitUpdate(c,inp,chunk*8);
      75                 :          0 :                 bytes -= chunk;
      76                 :          0 :                 inp   += chunk;
      77                 :            :                 }
      78         [ +  + ]:       3481 :         if (bytes)
      79                 :       3480 :                 WHIRLPOOL_BitUpdate(c,inp,bytes*8);
      80                 :            : 
      81                 :       3481 :         return(1);
      82                 :            :         }
      83                 :            : 
      84                 :       3480 : void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c,const void *_inp,size_t bits)
      85                 :            :         {
      86                 :            :         size_t          n;
      87                 :       3480 :         unsigned int    bitoff = c->bitoff,
      88                 :       3480 :                         bitrem = bitoff%8,
      89                 :       3480 :                         inpgap = (8-(unsigned int)bits%8)&7;
      90                 :       3480 :         const unsigned char *inp=_inp;
      91                 :            : 
      92                 :            :         /* This 256-bit increment procedure relies on the size_t
      93                 :            :          * being natural size of CPU register, so that we don't
      94                 :            :          * have to mask the value in order to detect overflows. */
      95                 :       3480 :         c->bitlen[0] += bits;
      96         [ +  - ]:       3480 :         if (c->bitlen[0] < bits)  /* overflow */
      97                 :            :                 {
      98                 :            :                 n = 1;
      99                 :          0 :                 do  {   c->bitlen[n]++;
     100                 :            :                     } while(c->bitlen[n]==0
     101 [ #  # ][ #  # ]:          0 :                             && ++n<(WHIRLPOOL_COUNTER/sizeof(size_t)));
     102                 :            :                 }
     103                 :            : 
     104                 :            : #ifndef OPENSSL_SMALL_FOOTPRINT
     105                 :            :         reconsider:
     106         [ -  + ]:       3480 :         if (inpgap==0 && bitrem==0)     /* byte-oriented loop */
     107                 :            :                 {
     108         [ +  + ]:      10433 :                 while (bits)
     109                 :            :                         {
     110 [ +  + ][ +  + ]:       6953 :                         if (bitoff==0 && (n=bits/WHIRLPOOL_BBLOCK))
     111                 :            :                                 {
     112                 :       3474 :                                 whirlpool_block(c,inp,n);
     113                 :       3474 :                                 inp  += n*WHIRLPOOL_BBLOCK/8;
     114                 :       3474 :                                 bits %= WHIRLPOOL_BBLOCK;
     115                 :            :                                 }
     116                 :            :                         else
     117                 :            :                                 {
     118                 :       3479 :                                 unsigned int byteoff = bitoff/8;
     119                 :            : 
     120                 :       3479 :                                 bitrem = WHIRLPOOL_BBLOCK - bitoff;/* re-use bitrem */
     121         [ +  + ]:       3479 :                                 if (bits >= bitrem)
     122                 :            :                                         {
     123                 :       1736 :                                         bits -= bitrem;
     124                 :       1736 :                                         bitrem /= 8;
     125                 :       1736 :                                         memcpy(c->data+byteoff,inp,bitrem);
     126                 :       1736 :                                         inp  += bitrem;
     127                 :       1736 :                                         whirlpool_block(c,c->data,1);
     128                 :       1736 :                                         bitoff = 0;
     129                 :            :                                         }
     130                 :            :                                 else
     131                 :            :                                         {
     132                 :       1743 :                                         memcpy(c->data+byteoff,inp,bits/8);
     133                 :       1743 :                                         bitoff += (unsigned int)bits;
     134                 :       1743 :                                         bits = 0;
     135                 :            :                                         }
     136                 :       6953 :                                 c->bitoff = bitoff;
     137                 :            :                                 }
     138                 :            :                         }
     139                 :            :                 }
     140                 :            :         else                            /* bit-oriented loop */
     141                 :            : #endif
     142                 :            :                 {
     143                 :            :                 /*
     144                 :            :                            inp
     145                 :            :                            |
     146                 :            :                            +-------+-------+-------
     147                 :            :                               |||||||||||||||||||||
     148                 :            :                            +-------+-------+-------
     149                 :            :                 +-------+-------+-------+-------+-------
     150                 :            :                 ||||||||||||||                          c->data
     151                 :            :                 +-------+-------+-------+-------+-------
     152                 :            :                         |
     153                 :            :                         c->bitoff/8
     154                 :            :                 */
     155         [ #  # ]:          0 :                 while (bits)
     156                 :            :                         {
     157                 :          0 :                         unsigned int    byteoff = bitoff/8;
     158                 :            :                         unsigned char   b;
     159                 :            : 
     160                 :            : #ifndef OPENSSL_SMALL_FOOTPRINT
     161         [ #  # ]:          0 :                         if (bitrem==inpgap)
     162                 :            :                                 {
     163                 :          0 :                                 c->data[byteoff++] |= inp[0] & (0xff>>inpgap);
     164                 :          0 :                                 inpgap = 8-inpgap;
     165                 :          0 :                                 bitoff += inpgap;  bitrem = 0;  /* bitoff%8 */
     166                 :          0 :                                 bits   -= inpgap;  inpgap = 0;  /* bits%8   */
     167                 :          0 :                                 inp++;
     168         [ #  # ]:          0 :                                 if (bitoff==WHIRLPOOL_BBLOCK)
     169                 :            :                                         {
     170                 :          0 :                                         whirlpool_block(c,c->data,1);
     171                 :          0 :                                         bitoff = 0;
     172                 :            :                                         }
     173                 :          0 :                                 c->bitoff = bitoff;
     174                 :          0 :                                 goto reconsider;
     175                 :            :                                 }
     176                 :            :                         else
     177                 :            : #endif
     178         [ #  # ]:          0 :                         if (bits>=8)
     179                 :            :                                 {
     180                 :          0 :                                 b  = ((inp[0]<<inpgap) | (inp[1]>>(8-inpgap)));
     181                 :          0 :                                 b &= 0xff;
     182         [ #  # ]:          0 :                                 if (bitrem)     c->data[byteoff++] |= b>>bitrem;
     183                 :          0 :                                 else            c->data[byteoff++]  = b;
     184                 :          0 :                                 bitoff += 8;
     185                 :          0 :                                 bits   -= 8;
     186                 :          0 :                                 inp++;
     187         [ #  # ]:          0 :                                 if (bitoff>=WHIRLPOOL_BBLOCK)
     188                 :            :                                         {
     189                 :          0 :                                         whirlpool_block(c,c->data,1);
     190                 :          0 :                                         byteoff  = 0;
     191                 :          0 :                                         bitoff  %= WHIRLPOOL_BBLOCK;
     192                 :            :                                         }
     193         [ #  # ]:          0 :                                 if (bitrem)     c->data[byteoff] = b<<(8-bitrem);
     194                 :            :                                 }
     195                 :            :                         else    /* remaining less than 8 bits */
     196                 :            :                                 {
     197                 :          0 :                                 b = (inp[0]<<inpgap)&0xff;
     198         [ #  # ]:          0 :                                 if (bitrem)     c->data[byteoff++] |= b>>bitrem;
     199                 :          0 :                                 else            c->data[byteoff++]  = b;
     200                 :          0 :                                 bitoff += (unsigned int)bits;
     201         [ #  # ]:          0 :                                 if (bitoff==WHIRLPOOL_BBLOCK)
     202                 :            :                                         {
     203                 :          0 :                                         whirlpool_block(c,c->data,1);
     204                 :          0 :                                         byteoff  = 0;
     205                 :          0 :                                         bitoff  %= WHIRLPOOL_BBLOCK;
     206                 :            :                                         }
     207         [ #  # ]:          0 :                                 if (bitrem)     c->data[byteoff] = b<<(8-bitrem);
     208                 :            :                                 bits = 0;
     209                 :            :                                 }
     210                 :          0 :                         c->bitoff = bitoff;
     211                 :            :                         }
     212                 :            :                 }
     213                 :       3480 :         }
     214                 :            : 
     215                 :          9 : int WHIRLPOOL_Final     (unsigned char *md,WHIRLPOOL_CTX *c)
     216                 :            :         {
     217                 :          9 :         unsigned int    bitoff  = c->bitoff,
     218                 :          9 :                         byteoff = bitoff/8;
     219                 :            :         size_t          i,j,v;
     220                 :            :         unsigned char  *p;
     221                 :            : 
     222                 :          9 :         bitoff %= 8;
     223         [ -  + ]:          9 :         if (bitoff)     c->data[byteoff] |= 0x80>>bitoff;
     224                 :          9 :         else            c->data[byteoff]  = 0x80;
     225                 :          9 :         byteoff++;
     226                 :            : 
     227                 :            :         /* pad with zeros */
     228         [ +  + ]:          9 :         if (byteoff > (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER))
     229                 :            :                 {
     230         [ +  - ]:          2 :                 if (byteoff<WHIRLPOOL_BBLOCK/8)
     231                 :          2 :                         memset(&c->data[byteoff],0,WHIRLPOOL_BBLOCK/8-byteoff);
     232                 :          2 :                 whirlpool_block(c,c->data,1);
     233                 :          2 :                 byteoff = 0;
     234                 :            :                 }
     235         [ +  - ]:          9 :         if (byteoff < (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER))
     236                 :          9 :                 memset(&c->data[byteoff],0,
     237                 :          9 :                         (WHIRLPOOL_BBLOCK/8-WHIRLPOOL_COUNTER)-byteoff);
     238                 :            :         /* smash 256-bit c->bitlen in big-endian order */
     239                 :          9 :         p = &c->data[WHIRLPOOL_BBLOCK/8-1];      /* last byte in c->data */
     240         [ +  + ]:         45 :         for(i=0;i<WHIRLPOOL_COUNTER/sizeof(size_t);i++)
     241         [ +  + ]:        324 :                 for(v=c->bitlen[i],j=0;j<sizeof(size_t);j++,v>>=8)
     242                 :        288 :                         *p-- = (unsigned char)(v&0xff);
     243                 :            : 
     244                 :          9 :         whirlpool_block(c,c->data,1);
     245                 :            : 
     246         [ +  - ]:          9 :         if (md) {
     247                 :          9 :                 memcpy(md,c->H.c,WHIRLPOOL_DIGEST_LENGTH);
     248                 :            :                 memset(c,0,sizeof(*c));
     249                 :          9 :                 return(1);
     250                 :            :                 }
     251                 :            :         return(0);
     252                 :            :         }
     253                 :            : 
     254                 :          8 : unsigned char *WHIRLPOOL(const void *inp, size_t bytes,unsigned char *md)
     255                 :            :         {
     256                 :            :         WHIRLPOOL_CTX ctx;
     257                 :            :         static unsigned char m[WHIRLPOOL_DIGEST_LENGTH];
     258                 :            : 
     259         [ -  + ]:          8 :         if (md == NULL) md=m;
     260                 :          8 :         WHIRLPOOL_Init(&ctx);
     261                 :          8 :         WHIRLPOOL_Update(&ctx,inp,bytes);
     262                 :          8 :         WHIRLPOOL_Final(md,&ctx);
     263                 :          8 :         return(md);
     264                 :            :         }

Generated by: LCOV version 1.9