LCOV - code coverage report
Current view: top level - common/utils - sha.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 89 103 86.4 %
Date: 2021-10-13 02:24:04 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /**************************** sha1.c ***************************/
       2             : /***************** See RFC 6234 for details. *******************/
       3             : /* Copyright (c) 2011 IETF Trust and the persons identified as */
       4             : /* authors of the code.  All rights reserved.                  */
       5             : /* See sha.h for terms of use and redistribution.              */
       6             : 
       7             : /*
       8             :  *  Description:
       9             :  *      This file implements the Secure Hash Algorithm SHA-1
      10             :  *      as defined in the U.S. National Institute of Standards
      11             :  *      and Technology Federal Information Processing Standards
      12             :  *      Publication (FIPS PUB) 180-3 published in October 2008
      13             :  *      and formerly defined in its predecessors, FIPS PUB 180-1
      14             :  *      and FIP PUB 180-2.
      15             :  *
      16             :  *      A combined document showing all algorithms is available at
      17             :  *              http://csrc.nist.gov/publications/fips/
      18             :  *                     fips180-3/fips180-3_final.pdf
      19             :  *
      20             :  *      The SHA-1 algorithm produces a 160-bit message digest for a
      21             :  *      given data stream that can serve as a means of providing a
      22             :  *      "fingerprint" for a message.
      23             :  *
      24             :  *  Portability Issues:
      25             :  *      SHA-1 is defined in terms of 32-bit "words".  This code
      26             :  *      uses <stdint.h> (included via "sha.h") to define 32- and
      27             :  *      8-bit unsigned integer types.  If your C compiler does
      28             :  *      not support 32-bit unsigned integers, this code is not
      29             :  *      appropriate.
      30             :  *
      31             :  *  Caveats:
      32             :  *      SHA-1 is designed to work with messages less than 2^64 bits
      33             :  *      long.  This implementation uses SHA1Input() to hash the bits
      34             :  *      that are a multiple of the size of an 8-bit octet, and then
      35             :  *      optionally uses SHA1FinalBits() to hash the final few bits of
      36             :  *      the input.
      37             :  */
      38             : 
      39             : #include "sha.h"
      40             : #include "sha-private.h"
      41             : 
      42             : /*
      43             :  *  Define the SHA1 circular left shift macro
      44             :  */
      45             : #define SHA1_ROTL(bits,word) \
      46             :                 (((word) << (bits)) | ((word) >> (32-(bits))))
      47             : 
      48             : /*
      49             :  * Add "length" to the length.
      50             :  * Set Corrupted when overflow has occurred.
      51             :  */
      52             : static uint32_t addTemp;
      53             : #define SHA1AddLength(context, length)                     \
      54             :     (addTemp = (context)->Length_Low,                      \
      55             :      (context)->Corrupted =                                \
      56             :         (((context)->Length_Low += (length)) < addTemp) && \
      57             :         (++(context)->Length_High == 0) ? shaInputTooLong  \
      58             :                                         : (context)->Corrupted )
      59             : 
      60             : /* Local Function Prototypes */
      61             : static void SHA1ProcessMessageBlock(SHA1Context *context);
      62             : static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte);
      63             : static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte);
      64             : 
      65             : /*
      66             :  *  SHA1Reset
      67             :  *
      68             :  *  Description:
      69             :  *      This function will initialize the SHA1Context in preparation
      70             :  *      for computing a new SHA1 message digest.
      71             :  *
      72             :  *  Parameters:
      73             :  *      context: [in/out]
      74             :  *          The context to reset.
      75             :  *
      76             :  *  Returns:
      77             :  *      sha Error Code.
      78             :  *
      79             :  */
      80        3860 : int SHA1Reset(SHA1Context *context)
      81             : {
      82        3860 :   if (!context) return shaNull;
      83             : 
      84        3860 :   context->Length_High = context->Length_Low = 0;
      85        3860 :   context->Message_Block_Index = 0;
      86             : 
      87             :   /* Initial Hash Values: FIPS 180-3 section 5.3.1 */
      88        3860 :   context->Intermediate_Hash[0]   = 0x67452301;
      89        3860 :   context->Intermediate_Hash[1]   = 0xEFCDAB89;
      90        3860 :   context->Intermediate_Hash[2]   = 0x98BADCFE;
      91        3860 :   context->Intermediate_Hash[3]   = 0x10325476;
      92        3860 :   context->Intermediate_Hash[4]   = 0xC3D2E1F0;
      93             : 
      94        3860 :   context->Computed   = 0;
      95        3860 :   context->Corrupted  = shaSuccess;
      96             : 
      97        3860 :   return shaSuccess;
      98             : }
      99             : 
     100             : /*
     101             :  *  SHA1Input
     102             :  *
     103             :  *  Description:
     104             :  *      This function accepts an array of octets as the next portion
     105             :  *      of the message.
     106             :  *
     107             :  *  Parameters:
     108             :  *      context: [in/out]
     109             :  *          The SHA context to update.
     110             :  *      message_array[ ]: [in]
     111             :  *          An array of octets representing the next portion of
     112             :  *          the message.
     113             :  *      length: [in]
     114             :  *          The length of the message in message_array.
     115             :  *
     116             :  *  Returns:
     117             :  *      sha Error Code.
     118             :  *
     119             :  */
     120        7716 : int SHA1Input(SHA1Context *context,
     121             :     const uint8_t *message_array, unsigned length)
     122             : {
     123        7716 :   if (!context) return shaNull;
     124        7716 :   if (!length) return shaSuccess;
     125        7714 :   if (!message_array) return shaNull;
     126        7714 :   if (context->Computed) return context->Corrupted = shaStateError;
     127        7714 :   if (context->Corrupted) return context->Corrupted;
     128             : 
     129      537871 :   while (length--) {
     130      530157 :     context->Message_Block[context->Message_Block_Index++] =
     131      530157 :       *message_array;
     132             : 
     133      530157 :     if ((SHA1AddLength(context, 8) == shaSuccess) &&
     134             :       (context->Message_Block_Index == SHA1_Message_Block_Size))
     135        7712 :       SHA1ProcessMessageBlock(context);
     136             : 
     137      530157 :     message_array++;
     138             :   }
     139             : 
     140        7714 :   return context->Corrupted;
     141             : }
     142             : 
     143             : /*
     144             :  * SHA1FinalBits
     145             :  *
     146             :  * Description:
     147             :  *   This function will add in any final bits of the message.
     148             :  *
     149             :  * Parameters:
     150             :  *   context: [in/out]
     151             :  *     The SHA context to update.
     152             :  *   message_bits: [in]
     153             :  *     The final bits of the message, in the upper portion of the
     154             :  *     byte.  (Use 0b###00000 instead of 0b00000### to input the
     155             :  *     three bits ###.)
     156             :  *   length: [in]
     157             :  *     The number of bits in message_bits, between 1 and 7.
     158             :  *
     159             :  * Returns:
     160             :  *   sha Error Code.
     161             :  */
     162           0 : int SHA1FinalBits(SHA1Context *context, uint8_t message_bits,
     163             :     unsigned int length)
     164             : {
     165             :   static uint8_t masks[8] = {
     166             :       /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
     167             :       /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
     168             :       /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
     169             :       /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
     170             :   };
     171             : 
     172             :   static uint8_t markbit[8] = {
     173             :       /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
     174             :       /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
     175             :       /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
     176             :       /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
     177             :   };
     178             : 
     179           0 :   if (!context) return shaNull;
     180           0 :   if (!length) return shaSuccess;
     181           0 :   if (context->Corrupted) return context->Corrupted;
     182           0 :   if (context->Computed) return context->Corrupted = shaStateError;
     183           0 :   if (length >= 8) return context->Corrupted = shaBadParam;
     184             : 
     185           0 :   SHA1AddLength(context, length);
     186           0 :   SHA1Finalize(context,
     187           0 :     (uint8_t) ((message_bits & masks[length]) | markbit[length]));
     188             : 
     189           0 :   return context->Corrupted;
     190             : }
     191             : 
     192             : /*
     193             :  * SHA1Result
     194             :  *
     195             :  * Description:
     196             :  *   This function will return the 160-bit message digest
     197             :  *   into the Message_Digest array provided by the caller.
     198             :  *   NOTE:
     199             :  *    The first octet of hash is stored in the element with index 0,
     200             :  *      the last octet of hash in the element with index 19.
     201             :  *
     202             :  * Parameters:
     203             :  *   context: [in/out]
     204             :  *     The context to use to calculate the SHA-1 hash.
     205             :  *   Message_Digest[ ]: [out]
     206             :  *     Where the digest is returned.
     207             :  *
     208             :  * Returns:
     209             :  *   sha Error Code.
     210             :  *
     211             :  */
     212        3860 : int SHA1Result(SHA1Context *context,
     213             :     uint8_t Message_Digest[SHA1HashSize])
     214             : {
     215             :   int i;
     216             : 
     217        3860 :   if (!context) return shaNull;
     218        3860 :   if (!Message_Digest) return shaNull;
     219        3860 :   if (context->Corrupted) return context->Corrupted;
     220             : 
     221        3860 :   if (!context->Computed)
     222        3860 :     SHA1Finalize(context, 0x80);
     223             : 
     224       81060 :   for (i = 0; i < SHA1HashSize; ++i)
     225       77200 :     Message_Digest[i] = (uint8_t) (context->Intermediate_Hash[i>>2]
     226       77200 :                                    >> (8 * ( 3 - ( i & 0x03 ) )));
     227             : 
     228             :   return shaSuccess;
     229             : }
     230             : 
     231             : /*
     232             :  * SHA1ProcessMessageBlock
     233             :  *
     234             :  * Description:
     235             :  *   This helper function will process the next 512 bits of the
     236             :  *   message stored in the Message_Block array.
     237             :  *
     238             :  * Parameters:
     239             :  *   context: [in/out]
     240             :  *     The SHA context to update.
     241             :  *
     242             :  * Returns:
     243             :  *   Nothing.
     244             :  *
     245             :  * Comments:
     246             :  *   Many of the variable names in this code, especially the
     247             :  *   single character names, were used because those were the
     248             :  *   names used in the Secure Hash Standard.
     249             :  */
     250       11572 : static void SHA1ProcessMessageBlock(SHA1Context *context)
     251             : {
     252             :   /* Constants defined in FIPS 180-3, section 4.2.1 */
     253             :   const uint32_t K[4] = {
     254             :       0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
     255             :   };
     256             :   int        t;               /* Loop counter */
     257             :   uint32_t   temp;            /* Temporary word value */
     258             :   uint32_t   W[80];           /* Word sequence */
     259             :   uint32_t   A, B, C, D, E;   /* Word buffers */
     260             : 
     261             :   /*
     262             :    * Initialize the first 16 words in the array W
     263             :    */
     264      196724 :   for (t = 0; t < 16; t++) {
     265      185152 :     W[t]  = ((uint32_t)context->Message_Block[t * 4]) << 24;
     266      185152 :     W[t] |= ((uint32_t)context->Message_Block[t * 4 + 1]) << 16;
     267      185152 :     W[t] |= ((uint32_t)context->Message_Block[t * 4 + 2]) << 8;
     268      185152 :     W[t] |= ((uint32_t)context->Message_Block[t * 4 + 3]);
     269             :   }
     270             : 
     271      752180 :   for (t = 16; t < 80; t++)
     272      740608 :     W[t] = SHA1_ROTL(1, W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
     273             : 
     274       11572 :   A = context->Intermediate_Hash[0];
     275       11572 :   B = context->Intermediate_Hash[1];
     276       11572 :   C = context->Intermediate_Hash[2];
     277       11572 :   D = context->Intermediate_Hash[3];
     278       11572 :   E = context->Intermediate_Hash[4];
     279             : 
     280      243012 :   for (t = 0; t < 20; t++) {
     281      231440 :     temp = SHA1_ROTL(5,A) + SHA_Ch(B, C, D) + E + W[t] + K[0];
     282             :     E = D;
     283             :     D = C;
     284      231440 :     C = SHA1_ROTL(30,B);
     285             :     B = A;
     286             :     A = temp;
     287             :   }
     288             : 
     289      243012 :   for (t = 20; t < 40; t++) {
     290      231440 :     temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[1];
     291             :     E = D;
     292             :     D = C;
     293      231440 :     C = SHA1_ROTL(30,B);
     294             :     B = A;
     295             :     A = temp;
     296             :   }
     297             : 
     298      243012 :   for (t = 40; t < 60; t++) {
     299      231440 :     temp = SHA1_ROTL(5,A) + SHA_Maj(B, C, D) + E + W[t] + K[2];
     300             :     E = D;
     301             :     D = C;
     302      231440 :     C = SHA1_ROTL(30,B);
     303             :     B = A;
     304             :     A = temp;
     305             :   }
     306             : 
     307      243012 :   for (t = 60; t < 80; t++) {
     308      231440 :     temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[3];
     309             :     E = D;
     310             :     D = C;
     311      231440 :     C = SHA1_ROTL(30,B);
     312             :     B = A;
     313             :     A = temp;
     314             :   }
     315             : 
     316       11572 :   context->Intermediate_Hash[0] += A;
     317       11572 :   context->Intermediate_Hash[1] += B;
     318       11572 :   context->Intermediate_Hash[2] += C;
     319       11572 :   context->Intermediate_Hash[3] += D;
     320       11572 :   context->Intermediate_Hash[4] += E;
     321       11572 :   context->Message_Block_Index = 0;
     322       11572 : }
     323             : 
     324             : /*
     325             :  * SHA1Finalize
     326             :  *
     327             :  * Description:
     328             :  *   This helper function finishes off the digest calculations.
     329             :  *
     330             :  * Parameters:
     331             :  *   context: [in/out]
     332             :  *     The SHA context to update.
     333             :  *   Pad_Byte: [in]
     334             :  *     The last byte to add to the message block before the 0-padding
     335             :  *     and length.  This will contain the last bits of the message
     336             :  *     followed by another single bit.  If the message was an
     337             :  *     exact multiple of 8-bits long, Pad_Byte will be 0x80.
     338             :  *
     339             :  * Returns:
     340             :  *   sha Error Code.
     341             :  *
     342             :  */
     343        3860 : static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte)
     344             : {
     345             :   int i;
     346        3860 :   SHA1PadMessage(context, Pad_Byte);
     347             :   /* message may be sensitive, clear it out */
     348      250900 :   for (i = 0; i < SHA1_Message_Block_Size; ++i)
     349      247040 :     context->Message_Block[i] = 0;
     350        3860 :   context->Length_High = 0;     /* and clear length */
     351        3860 :   context->Length_Low = 0;
     352        3860 :   context->Computed = 1;
     353        3860 : }
     354             : 
     355             : /*
     356             :  * SHA1PadMessage
     357             :  *
     358             :  * Description:
     359             :  *   According to the standard, the message must be padded to the next
     360             :  *   even multiple of 512 bits.  The first padding bit must be a '1'.
     361             :  *   The last 64 bits represent the length of the original message.
     362             :  *   All bits in between should be 0.  This helper function will pad
     363             :  *   the message according to those rules by filling the Message_Block
     364             :  *   array accordingly.  When it returns, it can be assumed that the
     365             :  *   message digest has been computed.
     366             :  *
     367             :  * Parameters:
     368             :  *   context: [in/out]
     369             :  *     The context to pad.
     370             :  *   Pad_Byte: [in]
     371             :  *     The last byte to add to the message block before the 0-padding
     372             :  *     and length.  This will contain the last bits of the message
     373             :  *     followed by another single bit.  If the message was an
     374             :  *     exact multiple of 8-bits long, Pad_Byte will be 0x80.
     375             :  *
     376             :  * Returns:
     377             :  *   Nothing.
     378             :  */
     379        3860 : static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte)
     380             : {
     381             :   /*
     382             :    * Check to see if the current message block is too small to hold
     383             :    * the initial padding bits and length.  If so, we will pad the
     384             :    * block, process it, and then continue padding into a second
     385             :    * block.
     386             :    */
     387        3860 :   if (context->Message_Block_Index >= (SHA1_Message_Block_Size - 8)) {
     388           0 :     context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
     389           0 :     while (context->Message_Block_Index < SHA1_Message_Block_Size)
     390           0 :       context->Message_Block[context->Message_Block_Index++] = 0;
     391             : 
     392           0 :     SHA1ProcessMessageBlock(context);
     393             :   } else
     394        3860 :     context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
     395             : 
     396      179571 :   while (context->Message_Block_Index < (SHA1_Message_Block_Size - 8))
     397      175711 :     context->Message_Block[context->Message_Block_Index++] = 0;
     398             : 
     399             :   /*
     400             :    * Store the message length as the last 8 octets
     401             :    */
     402        3860 :   context->Message_Block[56] = (uint8_t) (context->Length_High >> 24);
     403        3860 :   context->Message_Block[57] = (uint8_t) (context->Length_High >> 16);
     404        3860 :   context->Message_Block[58] = (uint8_t) (context->Length_High >> 8);
     405        3860 :   context->Message_Block[59] = (uint8_t) (context->Length_High);
     406        3860 :   context->Message_Block[60] = (uint8_t) (context->Length_Low >> 24);
     407        3860 :   context->Message_Block[61] = (uint8_t) (context->Length_Low >> 16);
     408        3860 :   context->Message_Block[62] = (uint8_t) (context->Length_Low >> 8);
     409        3860 :   context->Message_Block[63] = (uint8_t) (context->Length_Low);
     410             : 
     411        3860 :   SHA1ProcessMessageBlock(context);
     412        3860 : }

Generated by: LCOV version 1.14