LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/whrlpool - wp_dgst.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 98 0.0 %
Date: 2015-10-10 Functions: 0 5 0.0 %

          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 <openssl/crypto.h>
      56             : #include <string.h>
      57             : 
      58           0 : fips_md_init(WHIRLPOOL)
      59             : {
      60             :     memset(c, 0, sizeof(*c));
      61           0 :     return (1);
      62             : }
      63             : 
      64           0 : int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *_inp, size_t bytes)
      65             : {
      66             :     /*
      67             :      * Well, largest suitable chunk size actually is
      68             :      * (1<<(sizeof(size_t)*8-3))-64, but below number is large enough for not
      69             :      * to care about excessive calls to WHIRLPOOL_BitUpdate...
      70             :      */
      71             :     size_t chunk = ((size_t)1) << (sizeof(size_t) * 8 - 4);
      72             :     const unsigned char *inp = _inp;
      73             : 
      74           0 :     while (bytes >= chunk) {
      75           0 :         WHIRLPOOL_BitUpdate(c, inp, chunk * 8);
      76           0 :         bytes -= chunk;
      77           0 :         inp += chunk;
      78             :     }
      79           0 :     if (bytes)
      80           0 :         WHIRLPOOL_BitUpdate(c, inp, bytes * 8);
      81             : 
      82           0 :     return (1);
      83             : }
      84             : 
      85           0 : void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits)
      86             : {
      87             :     size_t n;
      88           0 :     unsigned int bitoff = c->bitoff,
      89           0 :         bitrem = bitoff % 8, inpgap = (8 - (unsigned int)bits % 8) & 7;
      90             :     const unsigned char *inp = _inp;
      91             : 
      92             :     /*
      93             :      * This 256-bit increment procedure relies on the size_t being natural
      94             :      * size of CPU register, so that we don't have to mask the value in order
      95             :      * to detect overflows.
      96             :      */
      97           0 :     c->bitlen[0] += bits;
      98           0 :     if (c->bitlen[0] < bits) {  /* overflow */
      99             :         n = 1;
     100             :         do {
     101           0 :             c->bitlen[n]++;
     102             :         } while (c->bitlen[n] == 0
     103           0 :                  && ++n < (WHIRLPOOL_COUNTER / sizeof(size_t)));
     104             :     }
     105             : #ifndef OPENSSL_SMALL_FOOTPRINT
     106             :  reconsider:
     107           0 :     if (inpgap == 0 && bitrem == 0) { /* byte-oriented loop */
     108           0 :         while (bits) {
     109           0 :             if (bitoff == 0 && (n = bits / WHIRLPOOL_BBLOCK)) {
     110           0 :                 whirlpool_block(c, inp, n);
     111           0 :                 inp += n * WHIRLPOOL_BBLOCK / 8;
     112           0 :                 bits %= WHIRLPOOL_BBLOCK;
     113             :             } else {
     114           0 :                 unsigned int byteoff = bitoff / 8;
     115             : 
     116           0 :                 bitrem = WHIRLPOOL_BBLOCK - bitoff; /* re-use bitrem */
     117           0 :                 if (bits >= bitrem) {
     118           0 :                     bits -= bitrem;
     119           0 :                     bitrem /= 8;
     120           0 :                     memcpy(c->data + byteoff, inp, bitrem);
     121           0 :                     inp += bitrem;
     122           0 :                     whirlpool_block(c, c->data, 1);
     123             :                     bitoff = 0;
     124             :                 } else {
     125           0 :                     memcpy(c->data + byteoff, inp, bits / 8);
     126           0 :                     bitoff += (unsigned int)bits;
     127             :                     bits = 0;
     128             :                 }
     129           0 :                 c->bitoff = bitoff;
     130             :             }
     131             :         }
     132             :     } else                      /* bit-oriented loop */
     133             : #endif
     134             :     {
     135             :         /*-
     136             :                    inp
     137             :                    |
     138             :                    +-------+-------+-------
     139             :                       |||||||||||||||||||||
     140             :                    +-------+-------+-------
     141             :         +-------+-------+-------+-------+-------
     142             :         ||||||||||||||                          c->data
     143             :         +-------+-------+-------+-------+-------
     144             :                 |
     145             :                 c->bitoff/8
     146             :         */
     147           0 :         while (bits) {
     148           0 :             unsigned int byteoff = bitoff / 8;
     149             :             unsigned char b;
     150             : 
     151             : #ifndef OPENSSL_SMALL_FOOTPRINT
     152           0 :             if (bitrem == inpgap) {
     153           0 :                 c->data[byteoff++] |= inp[0] & (0xff >> inpgap);
     154           0 :                 inpgap = 8 - inpgap;
     155           0 :                 bitoff += inpgap;
     156             :                 bitrem = 0;     /* bitoff%8 */
     157           0 :                 bits -= inpgap;
     158             :                 inpgap = 0;     /* bits%8 */
     159           0 :                 inp++;
     160           0 :                 if (bitoff == WHIRLPOOL_BBLOCK) {
     161           0 :                     whirlpool_block(c, c->data, 1);
     162             :                     bitoff = 0;
     163             :                 }
     164           0 :                 c->bitoff = bitoff;
     165           0 :                 goto reconsider;
     166             :             } else
     167             : #endif
     168           0 :             if (bits >= 8) {
     169           0 :                 b = ((inp[0] << inpgap) | (inp[1] >> (8 - inpgap)));
     170             :                 b &= 0xff;
     171           0 :                 if (bitrem)
     172           0 :                     c->data[byteoff++] |= b >> bitrem;
     173             :                 else
     174           0 :                     c->data[byteoff++] = b;
     175           0 :                 bitoff += 8;
     176           0 :                 bits -= 8;
     177           0 :                 inp++;
     178           0 :                 if (bitoff >= WHIRLPOOL_BBLOCK) {
     179           0 :                     whirlpool_block(c, c->data, 1);
     180             :                     byteoff = 0;
     181           0 :                     bitoff %= WHIRLPOOL_BBLOCK;
     182             :                 }
     183           0 :                 if (bitrem)
     184           0 :                     c->data[byteoff] = b << (8 - bitrem);
     185             :             } else {            /* remaining less than 8 bits */
     186             : 
     187           0 :                 b = (inp[0] << inpgap) & 0xff;
     188           0 :                 if (bitrem)
     189           0 :                     c->data[byteoff++] |= b >> bitrem;
     190             :                 else
     191           0 :                     c->data[byteoff++] = b;
     192           0 :                 bitoff += (unsigned int)bits;
     193           0 :                 if (bitoff == WHIRLPOOL_BBLOCK) {
     194           0 :                     whirlpool_block(c, c->data, 1);
     195             :                     byteoff = 0;
     196           0 :                     bitoff %= WHIRLPOOL_BBLOCK;
     197             :                 }
     198           0 :                 if (bitrem)
     199           0 :                     c->data[byteoff] = b << (8 - bitrem);
     200             :                 bits = 0;
     201             :             }
     202           0 :             c->bitoff = bitoff;
     203             :         }
     204             :     }
     205           0 : }
     206             : 
     207           0 : int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c)
     208             : {
     209           0 :     unsigned int bitoff = c->bitoff, byteoff = bitoff / 8;
     210             :     size_t i, j, v;
     211             :     unsigned char *p;
     212             : 
     213           0 :     bitoff %= 8;
     214           0 :     if (bitoff)
     215           0 :         c->data[byteoff] |= 0x80 >> bitoff;
     216             :     else
     217           0 :         c->data[byteoff] = 0x80;
     218           0 :     byteoff++;
     219             : 
     220             :     /* pad with zeros */
     221           0 :     if (byteoff > (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER)) {
     222           0 :         if (byteoff < WHIRLPOOL_BBLOCK / 8)
     223           0 :             memset(&c->data[byteoff], 0, WHIRLPOOL_BBLOCK / 8 - byteoff);
     224           0 :         whirlpool_block(c, c->data, 1);
     225             :         byteoff = 0;
     226             :     }
     227           0 :     if (byteoff < (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER))
     228           0 :         memset(&c->data[byteoff], 0,
     229           0 :                (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER) - byteoff);
     230             :     /* smash 256-bit c->bitlen in big-endian order */
     231           0 :     p = &c->data[WHIRLPOOL_BBLOCK / 8 - 1]; /* last byte in c->data */
     232           0 :     for (i = 0; i < WHIRLPOOL_COUNTER / sizeof(size_t); i++)
     233           0 :         for (v = c->bitlen[i], j = 0; j < sizeof(size_t); j++, v >>= 8)
     234           0 :             *p-- = (unsigned char)(v & 0xff);
     235             : 
     236           0 :     whirlpool_block(c, c->data, 1);
     237             : 
     238           0 :     if (md) {
     239           0 :         memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH);
     240             :         memset(c, 0, sizeof(*c));
     241           0 :         return (1);
     242             :     }
     243             :     return (0);
     244             : }
     245             : 
     246           0 : unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md)
     247             : {
     248             :     WHIRLPOOL_CTX ctx;
     249             :     static unsigned char m[WHIRLPOOL_DIGEST_LENGTH];
     250             : 
     251           0 :     if (md == NULL)
     252             :         md = m;
     253             :     WHIRLPOOL_Init(&ctx);
     254           0 :     WHIRLPOOL_Update(&ctx, inp, bytes);
     255           0 :     WHIRLPOOL_Final(md, &ctx);
     256           0 :     return (md);
     257             : }

Generated by: LCOV version 1.10