LCOV - code coverage report
Current view: top level - common/utils - sha.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 113 130 86.9 %
Date: 2024-04-25 21:43:30 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             : #define SHA1AddLength(context, length)                     \
      53             :     (addTemp = (context)->Length_Low,                      \
      54             :      (context)->Corrupted =                                \
      55             :         (((context)->Length_Low += (length)) < addTemp) && \
      56             :         (++(context)->Length_High == 0) ? shaInputTooLong  \
      57             :                                         : (context)->Corrupted )
      58             : 
      59             : /* Local Function Prototypes */
      60             : static void SHA1ProcessMessageBlock(SHA1Context *context);
      61             : static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte);
      62             : static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte);
      63             : 
      64             : /*
      65             :  *  SHA1Reset
      66             :  *
      67             :  *  Description:
      68             :  *      This function will initialize the SHA1Context in preparation
      69             :  *      for computing a new SHA1 message digest.
      70             :  *
      71             :  *  Parameters:
      72             :  *      context: [in/out]
      73             :  *          The context to reset.
      74             :  *
      75             :  *  Returns:
      76             :  *      sha Error Code.
      77             :  *
      78             :  */
      79           2 : int SHA1Reset(SHA1Context *context)
      80             : {
      81           2 :   if (!context) return shaNull;
      82             : 
      83           2 :   context->Length_High = context->Length_Low = 0;
      84           2 :   context->Message_Block_Index = 0;
      85             : 
      86             :   /* Initial Hash Values: FIPS 180-3 section 5.3.1 */
      87           2 :   context->Intermediate_Hash[0]   = 0x67452301;
      88           2 :   context->Intermediate_Hash[1]   = 0xEFCDAB89;
      89           2 :   context->Intermediate_Hash[2]   = 0x98BADCFE;
      90           2 :   context->Intermediate_Hash[3]   = 0x10325476;
      91           2 :   context->Intermediate_Hash[4]   = 0xC3D2E1F0;
      92             : 
      93           2 :   context->Computed   = 0;
      94           2 :   context->Corrupted  = shaSuccess;
      95             : 
      96           2 :   return shaSuccess;
      97             : }
      98             : 
      99             : /*
     100             :  *  SHA1Input
     101             :  *
     102             :  *  Description:
     103             :  *      This function accepts an array of octets as the next portion
     104             :  *      of the message.
     105             :  *
     106             :  *  Parameters:
     107             :  *      context: [in/out]
     108             :  *          The SHA context to update.
     109             :  *      message_array[ ]: [in]
     110             :  *          An array of octets representing the next portion of
     111             :  *          the message.
     112             :  *      length: [in]
     113             :  *          The length of the message in message_array.
     114             :  *
     115             :  *  Returns:
     116             :  *      sha Error Code.
     117             :  *
     118             :  */
     119           3 : int SHA1Input(SHA1Context *context,
     120             :     const uint8_t *message_array, unsigned length)
     121             : {
     122           3 :   if (!context) return shaNull;
     123           3 :   if (!length) return shaSuccess;
     124           3 :   if (!message_array) return shaNull;
     125           3 :   if (context->Computed) return context->Corrupted = shaStateError;
     126           3 :   if (context->Corrupted) return context->Corrupted;
     127             : 
     128         146 :   while (length--) {
     129         143 :     context->Message_Block[context->Message_Block_Index++] =
     130         143 :       *message_array;
     131             : 
     132         143 :     uint32_t addTemp;
     133         143 :     if ((SHA1AddLength(context, 8) == shaSuccess) &&
     134             :       (context->Message_Block_Index == SHA1_Message_Block_Size))
     135           2 :       SHA1ProcessMessageBlock(context);
     136             : 
     137         143 :     message_array++;
     138             :   }
     139             : 
     140           3 :   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           0 :   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           0 :   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 :   uint32_t addTemp;
     186           0 :   SHA1AddLength(context, length);
     187           0 :   SHA1Finalize(context,
     188           0 :     (uint8_t) ((message_bits & masks[length]) | markbit[length]));
     189             : 
     190           0 :   return context->Corrupted;
     191             : }
     192             : 
     193             : /*
     194             :  * SHA1Result
     195             :  *
     196             :  * Description:
     197             :  *   This function will return the 160-bit message digest
     198             :  *   into the Message_Digest array provided by the caller.
     199             :  *   NOTE:
     200             :  *    The first octet of hash is stored in the element with index 0,
     201             :  *      the last octet of hash in the element with index 19.
     202             :  *
     203             :  * Parameters:
     204             :  *   context: [in/out]
     205             :  *     The context to use to calculate the SHA-1 hash.
     206             :  *   Message_Digest[ ]: [out]
     207             :  *     Where the digest is returned.
     208             :  *
     209             :  * Returns:
     210             :  *   sha Error Code.
     211             :  *
     212             :  */
     213           2 : int SHA1Result(SHA1Context *context,
     214             :     uint8_t Message_Digest[SHA1HashSize])
     215             : {
     216           2 :   int i;
     217             : 
     218           2 :   if (!context) return shaNull;
     219           2 :   if (!Message_Digest) return shaNull;
     220           2 :   if (context->Corrupted) return context->Corrupted;
     221             : 
     222           2 :   if (!context->Computed)
     223           2 :     SHA1Finalize(context, 0x80);
     224             : 
     225          42 :   for (i = 0; i < SHA1HashSize; ++i)
     226          40 :     Message_Digest[i] = (uint8_t) (context->Intermediate_Hash[i>>2]
     227          40 :                                    >> (8 * ( 3 - ( i & 0x03 ) )));
     228             : 
     229             :   return shaSuccess;
     230             : }
     231             : 
     232             : /*
     233             :  * SHA1ProcessMessageBlock
     234             :  *
     235             :  * Description:
     236             :  *   This helper function will process the next 512 bits of the
     237             :  *   message stored in the Message_Block array.
     238             :  *
     239             :  * Parameters:
     240             :  *   context: [in/out]
     241             :  *     The SHA context to update.
     242             :  *
     243             :  * Returns:
     244             :  *   Nothing.
     245             :  *
     246             :  * Comments:
     247             :  *   Many of the variable names in this code, especially the
     248             :  *   single character names, were used because those were the
     249             :  *   names used in the Secure Hash Standard.
     250             :  */
     251           4 : static void SHA1ProcessMessageBlock(SHA1Context *context)
     252             : {
     253             :   /* Constants defined in FIPS 180-3, section 4.2.1 */
     254           4 :   const uint32_t K[4] = {
     255             :       0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
     256             :   };
     257           4 :   int        t;               /* Loop counter */
     258           4 :   uint32_t   temp;            /* Temporary word value */
     259           4 :   uint32_t   W[80];           /* Word sequence */
     260           4 :   uint32_t   A, B, C, D, E;   /* Word buffers */
     261             : 
     262             :   /*
     263             :    * Initialize the first 16 words in the array W
     264             :    */
     265          68 :   for (t = 0; t < 16; t++) {
     266          64 :     W[t]  = ((uint32_t)context->Message_Block[t * 4]) << 24;
     267          64 :     W[t] |= ((uint32_t)context->Message_Block[t * 4 + 1]) << 16;
     268          64 :     W[t] |= ((uint32_t)context->Message_Block[t * 4 + 2]) << 8;
     269          64 :     W[t] |= ((uint32_t)context->Message_Block[t * 4 + 3]);
     270             :   }
     271             : 
     272         260 :   for (t = 16; t < 80; t++)
     273         256 :     W[t] = SHA1_ROTL(1, W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
     274             : 
     275           4 :   A = context->Intermediate_Hash[0];
     276           4 :   B = context->Intermediate_Hash[1];
     277           4 :   C = context->Intermediate_Hash[2];
     278           4 :   D = context->Intermediate_Hash[3];
     279           4 :   E = context->Intermediate_Hash[4];
     280             : 
     281          84 :   for (t = 0; t < 20; t++) {
     282          80 :     temp = SHA1_ROTL(5,A) + SHA_Ch(B, C, D) + E + W[t] + K[0];
     283          80 :     E = D;
     284          80 :     D = C;
     285          80 :     C = SHA1_ROTL(30,B);
     286          80 :     B = A;
     287          80 :     A = temp;
     288             :   }
     289             : 
     290          84 :   for (t = 20; t < 40; t++) {
     291          80 :     temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[1];
     292          80 :     E = D;
     293          80 :     D = C;
     294          80 :     C = SHA1_ROTL(30,B);
     295          80 :     B = A;
     296          80 :     A = temp;
     297             :   }
     298             : 
     299          84 :   for (t = 40; t < 60; t++) {
     300          80 :     temp = SHA1_ROTL(5,A) + SHA_Maj(B, C, D) + E + W[t] + K[2];
     301          80 :     E = D;
     302          80 :     D = C;
     303          80 :     C = SHA1_ROTL(30,B);
     304          80 :     B = A;
     305          80 :     A = temp;
     306             :   }
     307             : 
     308          84 :   for (t = 60; t < 80; t++) {
     309          80 :     temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[3];
     310          80 :     E = D;
     311          80 :     D = C;
     312          80 :     C = SHA1_ROTL(30,B);
     313          80 :     B = A;
     314          80 :     A = temp;
     315             :   }
     316             : 
     317           4 :   context->Intermediate_Hash[0] += A;
     318           4 :   context->Intermediate_Hash[1] += B;
     319           4 :   context->Intermediate_Hash[2] += C;
     320           4 :   context->Intermediate_Hash[3] += D;
     321           4 :   context->Intermediate_Hash[4] += E;
     322           4 :   context->Message_Block_Index = 0;
     323           4 : }
     324             : 
     325             : /*
     326             :  * SHA1Finalize
     327             :  *
     328             :  * Description:
     329             :  *   This helper function finishes off the digest calculations.
     330             :  *
     331             :  * Parameters:
     332             :  *   context: [in/out]
     333             :  *     The SHA context to update.
     334             :  *   Pad_Byte: [in]
     335             :  *     The last byte to add to the message block before the 0-padding
     336             :  *     and length.  This will contain the last bits of the message
     337             :  *     followed by another single bit.  If the message was an
     338             :  *     exact multiple of 8-bits long, Pad_Byte will be 0x80.
     339             :  *
     340             :  * Returns:
     341             :  *   sha Error Code.
     342             :  *
     343             :  */
     344           2 : static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte)
     345             : {
     346           2 :   int i;
     347           2 :   SHA1PadMessage(context, Pad_Byte);
     348             :   /* message may be sensitive, clear it out */
     349         132 :   for (i = 0; i < SHA1_Message_Block_Size; ++i)
     350         128 :     context->Message_Block[i] = 0;
     351           2 :   context->Length_High = 0;     /* and clear length */
     352           2 :   context->Length_Low = 0;
     353           2 :   context->Computed = 1;
     354           2 : }
     355             : 
     356             : /*
     357             :  * SHA1PadMessage
     358             :  *
     359             :  * Description:
     360             :  *   According to the standard, the message must be padded to the next
     361             :  *   even multiple of 512 bits.  The first padding bit must be a '1'.
     362             :  *   The last 64 bits represent the length of the original message.
     363             :  *   All bits in between should be 0.  This helper function will pad
     364             :  *   the message according to those rules by filling the Message_Block
     365             :  *   array accordingly.  When it returns, it can be assumed that the
     366             :  *   message digest has been computed.
     367             :  *
     368             :  * Parameters:
     369             :  *   context: [in/out]
     370             :  *     The context to pad.
     371             :  *   Pad_Byte: [in]
     372             :  *     The last byte to add to the message block before the 0-padding
     373             :  *     and length.  This will contain the last bits of the message
     374             :  *     followed by another single bit.  If the message was an
     375             :  *     exact multiple of 8-bits long, Pad_Byte will be 0x80.
     376             :  *
     377             :  * Returns:
     378             :  *   Nothing.
     379             :  */
     380           2 : static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte)
     381             : {
     382             :   /*
     383             :    * Check to see if the current message block is too small to hold
     384             :    * the initial padding bits and length.  If so, we will pad the
     385             :    * block, process it, and then continue padding into a second
     386             :    * block.
     387             :    */
     388           2 :   if (context->Message_Block_Index >= (SHA1_Message_Block_Size - 8)) {
     389           0 :     context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
     390           0 :     while (context->Message_Block_Index < SHA1_Message_Block_Size)
     391           0 :       context->Message_Block[context->Message_Block_Index++] = 0;
     392             : 
     393           0 :     SHA1ProcessMessageBlock(context);
     394             :   } else
     395           2 :     context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
     396             : 
     397          97 :   while (context->Message_Block_Index < (SHA1_Message_Block_Size - 8))
     398          95 :     context->Message_Block[context->Message_Block_Index++] = 0;
     399             : 
     400             :   /*
     401             :    * Store the message length as the last 8 octets
     402             :    */
     403           2 :   context->Message_Block[56] = (uint8_t) (context->Length_High >> 24);
     404           2 :   context->Message_Block[57] = (uint8_t) (context->Length_High >> 16);
     405           2 :   context->Message_Block[58] = (uint8_t) (context->Length_High >> 8);
     406           2 :   context->Message_Block[59] = (uint8_t) (context->Length_High);
     407           2 :   context->Message_Block[60] = (uint8_t) (context->Length_Low >> 24);
     408           2 :   context->Message_Block[61] = (uint8_t) (context->Length_Low >> 16);
     409           2 :   context->Message_Block[62] = (uint8_t) (context->Length_Low >> 8);
     410           2 :   context->Message_Block[63] = (uint8_t) (context->Length_Low);
     411             : 
     412           2 :   SHA1ProcessMessageBlock(context);
     413           2 : }

Generated by: LCOV version 1.14