LCOV - code coverage report
Current view: top level - third_party/openssl/crypto - md32_common.h (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 42 48 87.5 %
Date: 2015-10-10 Functions: 4 18 22.2 %

          Line data    Source code
       1             : /* crypto/md32_common.h */
       2             : /* ====================================================================
       3             :  * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
       4             :  *
       5             :  * Redistribution and use in source and binary forms, with or without
       6             :  * modification, are permitted provided that the following conditions
       7             :  * are met:
       8             :  *
       9             :  * 1. Redistributions of source code must retain the above copyright
      10             :  *    notice, this list of conditions and the following disclaimer.
      11             :  *
      12             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in
      14             :  *    the documentation and/or other materials provided with the
      15             :  *    distribution.
      16             :  *
      17             :  * 3. All advertising materials mentioning features or use of this
      18             :  *    software must display the following acknowledgment:
      19             :  *    "This product includes software developed by the OpenSSL Project
      20             :  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
      21             :  *
      22             :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      23             :  *    endorse or promote products derived from this software without
      24             :  *    prior written permission. For written permission, please contact
      25             :  *    licensing@OpenSSL.org.
      26             :  *
      27             :  * 5. Products derived from this software may not be called "OpenSSL"
      28             :  *    nor may "OpenSSL" appear in their names without prior written
      29             :  *    permission of the OpenSSL Project.
      30             :  *
      31             :  * 6. Redistributions of any form whatsoever must retain the following
      32             :  *    acknowledgment:
      33             :  *    "This product includes software developed by the OpenSSL Project
      34             :  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
      35             :  *
      36             :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      37             :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      38             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      39             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      40             :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      41             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      42             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      43             :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      44             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      45             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      46             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      47             :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      48             :  * ====================================================================
      49             :  *
      50             :  */
      51             : 
      52             : /*-
      53             :  * This is a generic 32 bit "collector" for message digest algorithms.
      54             :  * Whenever needed it collects input character stream into chunks of
      55             :  * 32 bit values and invokes a block function that performs actual hash
      56             :  * calculations.
      57             :  *
      58             :  * Porting guide.
      59             :  *
      60             :  * Obligatory macros:
      61             :  *
      62             :  * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
      63             :  *      this macro defines byte order of input stream.
      64             :  * HASH_CBLOCK
      65             :  *      size of a unit chunk HASH_BLOCK operates on.
      66             :  * HASH_LONG
      67             :  *      has to be at lest 32 bit wide, if it's wider, then
      68             :  *      HASH_LONG_LOG2 *has to* be defined along
      69             :  * HASH_CTX
      70             :  *      context structure that at least contains following
      71             :  *      members:
      72             :  *              typedef struct {
      73             :  *                      ...
      74             :  *                      HASH_LONG       Nl,Nh;
      75             :  *                      either {
      76             :  *                      HASH_LONG       data[HASH_LBLOCK];
      77             :  *                      unsigned char   data[HASH_CBLOCK];
      78             :  *                      };
      79             :  *                      unsigned int    num;
      80             :  *                      ...
      81             :  *                      } HASH_CTX;
      82             :  *      data[] vector is expected to be zeroed upon first call to
      83             :  *      HASH_UPDATE.
      84             :  * HASH_UPDATE
      85             :  *      name of "Update" function, implemented here.
      86             :  * HASH_TRANSFORM
      87             :  *      name of "Transform" function, implemented here.
      88             :  * HASH_FINAL
      89             :  *      name of "Final" function, implemented here.
      90             :  * HASH_BLOCK_DATA_ORDER
      91             :  *      name of "block" function capable of treating *unaligned* input
      92             :  *      message in original (data) byte order, implemented externally.
      93             :  * HASH_MAKE_STRING
      94             :  *      macro convering context variables to an ASCII hash string.
      95             :  *
      96             :  * MD5 example:
      97             :  *
      98             :  *      #define DATA_ORDER_IS_LITTLE_ENDIAN
      99             :  *
     100             :  *      #define HASH_LONG               MD5_LONG
     101             :  *      #define HASH_LONG_LOG2          MD5_LONG_LOG2
     102             :  *      #define HASH_CTX                MD5_CTX
     103             :  *      #define HASH_CBLOCK             MD5_CBLOCK
     104             :  *      #define HASH_UPDATE             MD5_Update
     105             :  *      #define HASH_TRANSFORM          MD5_Transform
     106             :  *      #define HASH_FINAL              MD5_Final
     107             :  *      #define HASH_BLOCK_DATA_ORDER   md5_block_data_order
     108             :  *
     109             :  *                                      <appro@fy.chalmers.se>
     110             :  */
     111             : 
     112             : #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
     113             : # error "DATA_ORDER must be defined!"
     114             : #endif
     115             : 
     116             : #ifndef HASH_CBLOCK
     117             : # error "HASH_CBLOCK must be defined!"
     118             : #endif
     119             : #ifndef HASH_LONG
     120             : # error "HASH_LONG must be defined!"
     121             : #endif
     122             : #ifndef HASH_CTX
     123             : # error "HASH_CTX must be defined!"
     124             : #endif
     125             : 
     126             : #ifndef HASH_UPDATE
     127             : # error "HASH_UPDATE must be defined!"
     128             : #endif
     129             : #ifndef HASH_TRANSFORM
     130             : # error "HASH_TRANSFORM must be defined!"
     131             : #endif
     132             : #ifndef HASH_FINAL
     133             : # error "HASH_FINAL must be defined!"
     134             : #endif
     135             : 
     136             : #ifndef HASH_BLOCK_DATA_ORDER
     137             : # error "HASH_BLOCK_DATA_ORDER must be defined!"
     138             : #endif
     139             : 
     140             : /*
     141             :  * Engage compiler specific rotate intrinsic function if available.
     142             :  */
     143             : #undef ROTATE
     144             : #ifndef PEDANTIC
     145             : # if defined(_MSC_VER)
     146             : #  define ROTATE(a,n)   _lrotl(a,n)
     147             : # elif defined(__ICC)
     148             : #  define ROTATE(a,n)   _rotl(a,n)
     149             : # elif defined(__MWERKS__)
     150             : #  if defined(__POWERPC__)
     151             : #   define ROTATE(a,n)  __rlwinm(a,n,0,31)
     152             : #  elif defined(__MC68K__)
     153             :     /* Motorola specific tweak. <appro@fy.chalmers.se> */
     154             : #   define ROTATE(a,n)  ( n<24 ? __rol(a,n) : __ror(a,32-n) )
     155             : #  else
     156             : #   define ROTATE(a,n)  __rol(a,n)
     157             : #  endif
     158             : # elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
     159             :   /*
     160             :    * Some GNU C inline assembler templates. Note that these are
     161             :    * rotates by *constant* number of bits! But that's exactly
     162             :    * what we need here...
     163             :    *                                    <appro@fy.chalmers.se>
     164             :    */
     165             : #  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
     166             : #   define ROTATE(a,n)  ({ register unsigned int ret;   \
     167             :                                 asm (                   \
     168             :                                 "roll %1,%0"            \
     169             :                                 : "=r"(ret)             \
     170             :                                 : "I"(n), "0"((unsigned int)(a))        \
     171             :                                 : "cc");                \
     172             :                            ret;                         \
     173             :                         })
     174             : #  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
     175             :         defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
     176             : #   define ROTATE(a,n)  ({ register unsigned int ret;   \
     177             :                                 asm (                   \
     178             :                                 "rlwinm %0,%1,%2,0,31"  \
     179             :                                 : "=r"(ret)             \
     180             :                                 : "r"(a), "I"(n));      \
     181             :                            ret;                         \
     182             :                         })
     183             : #  elif defined(__s390x__)
     184             : #   define ROTATE(a,n) ({ register unsigned int ret;    \
     185             :                                 asm ("rll %0,%1,%2"     \
     186             :                                 : "=r"(ret)             \
     187             :                                 : "r"(a), "I"(n));      \
     188             :                           ret;                          \
     189             :                         })
     190             : #  endif
     191             : # endif
     192             : #endif                          /* PEDANTIC */
     193             : 
     194             : #ifndef ROTATE
     195             : # define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
     196             : #endif
     197             : 
     198             : #if defined(DATA_ORDER_IS_BIG_ENDIAN)
     199             : 
     200             : # ifndef PEDANTIC
     201             : #  if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
     202             : #   if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
     203             :       (defined(__x86_64) || defined(__x86_64__))
     204             : #    if !defined(B_ENDIAN)
     205             :     /*
     206             :      * This gives ~30-40% performance improvement in SHA-256 compiled
     207             :      * with gcc [on P4]. Well, first macro to be frank. We can pull
     208             :      * this trick on x86* platforms only, because these CPUs can fetch
     209             :      * unaligned data without raising an exception.
     210             :      */
     211             : #     define HOST_c2l(c,l)        ({ unsigned int r=*((const unsigned int *)(c)); \
     212             :                                    asm ("bswapl %0":"=r"(r):"0"(r));    \
     213             :                                    (c)+=4; (l)=r;                       })
     214             : #     define HOST_l2c(l,c)        ({ unsigned int r=(l);                  \
     215             :                                    asm ("bswapl %0":"=r"(r):"0"(r));    \
     216             :                                    *((unsigned int *)(c))=r; (c)+=4; r; })
     217             : #    endif
     218             : #   elif defined(__aarch64__)
     219             : #    if defined(__BYTE_ORDER__)
     220             : #     if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
     221             : #      define HOST_c2l(c,l)      ({ unsigned int r;              \
     222             :                                    asm ("rev    %w0,%w1"        \
     223             :                                         :"=r"(r)                \
     224             :                                         :"r"(*((const unsigned int *)(c))));\
     225             :                                    (c)+=4; (l)=r;               })
     226             : #      define HOST_l2c(l,c)      ({ unsigned int r;              \
     227             :                                    asm ("rev    %w0,%w1"        \
     228             :                                         :"=r"(r)                \
     229             :                                         :"r"((unsigned int)(l)));\
     230             :                                    *((unsigned int *)(c))=r; (c)+=4; r; })
     231             : #     elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
     232             : #      define HOST_c2l(c,l)      ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
     233             : #      define HOST_l2c(l,c)      (*((unsigned int *)(c))=(l), (c)+=4, (l))
     234             : #     endif
     235             : #    endif
     236             : #   endif
     237             : #  endif
     238             : #  if defined(__s390__) || defined(__s390x__)
     239             : #   define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
     240             : #   define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
     241             : #  endif
     242             : # endif
     243             : 
     244             : # ifndef HOST_c2l
     245             : #  define HOST_c2l(c,l)   (l =(((unsigned long)(*((c)++)))<<24),          \
     246             :                          l|=(((unsigned long)(*((c)++)))<<16),          \
     247             :                          l|=(((unsigned long)(*((c)++)))<< 8),          \
     248             :                          l|=(((unsigned long)(*((c)++)))    )           )
     249             : # endif
     250             : # ifndef HOST_l2c
     251             : #  define HOST_l2c(l,c)   (*((c)++)=(unsigned char)(((l)>>24)&0xff),      \
     252             :                          *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
     253             :                          *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
     254             :                          *((c)++)=(unsigned char)(((l)    )&0xff),      \
     255             :                          l)
     256             : # endif
     257             : 
     258             : #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
     259             : 
     260             : # ifndef PEDANTIC
     261             : #  if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
     262             : #   if defined(__s390x__)
     263             : #    define HOST_c2l(c,l)        ({ asm ("lrv    %0,%1"                  \
     264             :                                    :"=d"(l) :"m"(*(const unsigned int *)(c)));\
     265             :                                    (c)+=4; (l);                         })
     266             : #    define HOST_l2c(l,c)        ({ asm ("strv   %1,%0"                  \
     267             :                                    :"=m"(*(unsigned int *)(c)) :"d"(l));\
     268             :                                    (c)+=4; (l);                         })
     269             : #   endif
     270             : #  endif
     271             : #  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
     272             : #   ifndef B_ENDIAN
     273             :     /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
     274             : #    define HOST_c2l(c,l)        ((l)=*((const unsigned int *)(c)), (c)+=4, l)
     275             : #    define HOST_l2c(l,c)        (*((unsigned int *)(c))=(l), (c)+=4, l)
     276             : #   endif
     277             : #  endif
     278             : # endif
     279             : 
     280             : # ifndef HOST_c2l
     281             : #  define HOST_c2l(c,l)   (l =(((unsigned long)(*((c)++)))    ),          \
     282             :                          l|=(((unsigned long)(*((c)++)))<< 8),          \
     283             :                          l|=(((unsigned long)(*((c)++)))<<16),          \
     284             :                          l|=(((unsigned long)(*((c)++)))<<24)           )
     285             : # endif
     286             : # ifndef HOST_l2c
     287             : #  define HOST_l2c(l,c)   (*((c)++)=(unsigned char)(((l)    )&0xff),      \
     288             :                          *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
     289             :                          *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
     290             :                          *((c)++)=(unsigned char)(((l)>>24)&0xff),      \
     291             :                          l)
     292             : # endif
     293             : 
     294             : #endif
     295             : 
     296             : /*
     297             :  * Time for some action:-)
     298             :  */
     299             : 
     300      209818 : int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
     301             : {
     302             :     const unsigned char *data = data_;
     303             :     unsigned char *p;
     304             :     HASH_LONG l;
     305             :     size_t n;
     306             : 
     307      209818 :     if (len == 0)
     308             :         return 1;
     309             : 
     310      209818 :     l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
     311             :     /*
     312             :      * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai
     313             :      * <weidai@eskimo.com> for pointing it out.
     314             :      */
     315      209818 :     if (l < c->Nl)              /* overflow */
     316           0 :         c->Nh++;
     317      209818 :     c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
     318             :                                        * 16-bit */
     319      209818 :     c->Nl = l;
     320             : 
     321      209818 :     n = c->num;
     322      209818 :     if (n != 0) {
     323      140281 :         p = (unsigned char *)c->data;
     324             : 
     325      140281 :         if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
     326       15783 :             memcpy(p + n, data, HASH_CBLOCK - n);
     327       15783 :             HASH_BLOCK_DATA_ORDER(c, p, 1);
     328             :             n = HASH_CBLOCK - n;
     329       15783 :             data += n;
     330       15783 :             len -= n;
     331       15783 :             c->num = 0;
     332             :             memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
     333             :         } else {
     334      124498 :             memcpy(p + n, data, len);
     335      124498 :             c->num += (unsigned int)len;
     336      124498 :             return 1;
     337             :         }
     338             :     }
     339             : 
     340       85320 :     n = len / HASH_CBLOCK;
     341       85320 :     if (n > 0) {
     342       13568 :         HASH_BLOCK_DATA_ORDER(c, data, n);
     343       13568 :         n *= HASH_CBLOCK;
     344       13568 :         data += n;
     345       13568 :         len -= n;
     346             :     }
     347             : 
     348       85320 :     if (len != 0) {
     349       77236 :         p = (unsigned char *)c->data;
     350       77236 :         c->num = (unsigned int)len;
     351             :         memcpy(p, data, len);
     352             :     }
     353             :     return 1;
     354             : }
     355             : 
     356           0 : void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
     357             : {
     358           0 :     HASH_BLOCK_DATA_ORDER(c, data, 1);
     359           0 : }
     360             : 
     361       64385 : int HASH_FINAL(unsigned char *md, HASH_CTX *c)
     362             : {
     363       64385 :     unsigned char *p = (unsigned char *)c->data;
     364       64385 :     size_t n = c->num;
     365             : 
     366       64385 :     p[n] = 0x80;                /* there is always room for one */
     367       64385 :     n++;
     368             : 
     369       64385 :     if (n > (HASH_CBLOCK - 8)) {
     370       22443 :         memset(p + n, 0, HASH_CBLOCK - n);
     371             :         n = 0;
     372       22443 :         HASH_BLOCK_DATA_ORDER(c, p, 1);
     373             :     }
     374       64385 :     memset(p + n, 0, HASH_CBLOCK - 8 - n);
     375             : 
     376             :     p += HASH_CBLOCK - 8;
     377             : #if   defined(DATA_ORDER_IS_BIG_ENDIAN)
     378       64385 :     (void)HOST_l2c(c->Nh, p);
     379       64385 :     (void)HOST_l2c(c->Nl, p);
     380             : #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
     381           0 :     (void)HOST_l2c(c->Nl, p);
     382           0 :     (void)HOST_l2c(c->Nh, p);
     383             : #endif
     384             :     p -= HASH_CBLOCK;
     385       64385 :     HASH_BLOCK_DATA_ORDER(c, p, 1);
     386       64385 :     c->num = 0;
     387             :     memset(p, 0, HASH_CBLOCK);
     388             : 
     389             : #ifndef HASH_MAKE_STRING
     390             : # error "HASH_MAKE_STRING must be defined!"
     391             : #else
     392       64385 :     HASH_MAKE_STRING(c, md);
     393             : #endif
     394             : 
     395       40475 :     return 1;
     396             : }
     397             : 
     398             : #ifndef MD32_REG_T
     399             : # if defined(__alpha) || defined(__sparcv9) || defined(__mips)
     400             : #  define MD32_REG_T long
     401             : /*
     402             :  * This comment was originaly written for MD5, which is why it
     403             :  * discusses A-D. But it basically applies to all 32-bit digests,
     404             :  * which is why it was moved to common header file.
     405             :  *
     406             :  * In case you wonder why A-D are declared as long and not
     407             :  * as MD5_LONG. Doing so results in slight performance
     408             :  * boost on LP64 architectures. The catch is we don't
     409             :  * really care if 32 MSBs of a 64-bit register get polluted
     410             :  * with eventual overflows as we *save* only 32 LSBs in
     411             :  * *either* case. Now declaring 'em long excuses the compiler
     412             :  * from keeping 32 MSBs zeroed resulting in 13% performance
     413             :  * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
     414             :  * Well, to be honest it should say that this *prevents*
     415             :  * performance degradation.
     416             :  *                              <appro@fy.chalmers.se>
     417             :  */
     418             : # else
     419             : /*
     420             :  * Above is not absolute and there are LP64 compilers that
     421             :  * generate better code if MD32_REG_T is defined int. The above
     422             :  * pre-processor condition reflects the circumstances under which
     423             :  * the conclusion was made and is subject to further extension.
     424             :  *                              <appro@fy.chalmers.se>
     425             :  */
     426             : #  define MD32_REG_T int
     427             : # endif
     428             : #endif

Generated by: LCOV version 1.10