Guest User

Untitled

a guest
Apr 19th, 2018
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.50 KB | None | 0 0
  1. /*
  2.  *  sha1.c
  3.  *
  4.  *  Copyright (C) 1998, 2009
  5.  *  Paul E. Jones <paulej@packetizer.com>
  6.  *  All Rights Reserved
  7.  *
  8.  *****************************************************************************
  9.  *  $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $
  10.  *****************************************************************************
  11.  *
  12.  *  Description:
  13.  *      This file implements the Secure Hashing Standard as defined
  14.  *      in FIPS PUB 180-1 published April 17, 1995.
  15.  *
  16.  *      The Secure Hashing Standard, which uses the Secure Hashing
  17.  *      Algorithm (SHA), produces a 160-bit message digest for a
  18.  *      given data stream.  In theory, it is highly improbable that
  19.  *      two messages will produce the same message digest.  Therefore,
  20.  *      this algorithm can serve as a means of providing a "fingerprint"
  21.  *      for a message.
  22.  *
  23.  *  Portability Issues:
  24.  *      SHA-1 is defined in terms of 32-bit "words".  This code was
  25.  *      written with the expectation that the processor has at least
  26.  *      a 32-bit machine word size.  If the machine word size is larger,
  27.  *      the code should still function properly.  One caveat to that
  28.  *      is that the input functions taking characters and character
  29.  *      arrays assume that only 8 bits of information are stored in each
  30.  *      character.
  31.  *
  32.  *  Caveats:
  33.  *      SHA-1 is designed to work with messages less than 2^64 bits
  34.  *      long. Although SHA-1 allows a message digest to be generated for
  35.  *      messages of any number of bits less than 2^64, this
  36.  *      implementation only works with messages with a length that is a
  37.  *      multiple of the size of an 8-bit character.
  38.  *
  39.  */
  40.  
  41. #include "sha1.h"
  42.  
  43. /*
  44.  *  Define the circular shift macro
  45.  */
  46. #define SHA1CircularShift(bits,word) \
  47.                 ((((word) << (bits)) & 0xFFFFFFFF) | \
  48.                 ((word) >> (32-(bits))))
  49.  
  50. /* Function prototypes */
  51. void SHA1ProcessMessageBlock(SHA1Context *);
  52. void SHA1PadMessage(SHA1Context *);
  53.  
  54. /*  
  55.  *  SHA1Reset
  56.  *
  57.  *  Description:
  58.  *      This function will initialize the SHA1Context in preparation
  59.  *      for computing a new message digest.
  60.  *
  61.  *  Parameters:
  62.  *      context: [in/out]
  63.  *          The context to reset.
  64.  *
  65.  *  Returns:
  66.  *      Nothing.
  67.  *
  68.  *  Comments:
  69.  *
  70.  */
  71. void SHA1Reset(SHA1Context *context)
  72. {
  73.     context->Length_Low             = 0;
  74.     context->Length_High            = 0;
  75.     context->Message_Block_Index    = 0;
  76.  
  77.     context->Message_Digest[0]      = 0x67452301;
  78.     context->Message_Digest[1]      = 0xEFCDAB89;
  79.     context->Message_Digest[2]      = 0x98BADCFE;
  80.     context->Message_Digest[3]      = 0x10325476;
  81.     context->Message_Digest[4]      = 0xC3D2E1F0;
  82.  
  83.     context->Computed   = 0;
  84.     context->Corrupted  = 0;
  85. }
  86.  
  87. /*  
  88.  *  SHA1Result
  89.  *
  90.  *  Description:
  91.  *      This function will return the 160-bit message digest into the
  92.  *      Message_Digest array within the SHA1Context provided
  93.  *
  94.  *  Parameters:
  95.  *      context: [in/out]
  96.  *          The context to use to calculate the SHA-1 hash.
  97.  *
  98.  *  Returns:
  99.  *      1 if successful, 0 if it failed.
  100.  *
  101.  *  Comments:
  102.  *
  103.  */
  104. int SHA1Result(SHA1Context *context)
  105. {
  106.  
  107.     if (context->Corrupted)
  108.     {
  109.         return 0;
  110.     }
  111.  
  112.     if (!context->Computed)
  113.     {
  114.         SHA1PadMessage(context);
  115.         context->Computed = 1;
  116.     }
  117.  
  118.     return 1;
  119. }
  120.  
  121. /*  
  122.  *  SHA1Input
  123.  *
  124.  *  Description:
  125.  *      This function accepts an array of octets as the next portion of
  126.  *      the message.
  127.  *
  128.  *  Parameters:
  129.  *      context: [in/out]
  130.  *          The SHA-1 context to update
  131.  *      message_array: [in]
  132.  *          An array of characters representing the next portion of the
  133.  *          message.
  134.  *      length: [in]
  135.  *          The length of the message in message_array
  136.  *
  137.  *  Returns:
  138.  *      Nothing.
  139.  *
  140.  *  Comments:
  141.  *
  142.  */
  143. void SHA1Input(     SHA1Context         *context,
  144.                     const unsigned char *message_array,
  145.                     unsigned            length)
  146. {
  147.     if (!length)
  148.     {
  149.         return;
  150.     }
  151.  
  152.     if (context->Computed || context->Corrupted)
  153.     {
  154.         context->Corrupted = 1;
  155.         return;
  156.     }
  157.  
  158.     while(length-- && !context->Corrupted)
  159.     {
  160.         context->Message_Block[context->Message_Block_Index++] =
  161.                                                 (*message_array & 0xFF);
  162.  
  163.         context->Length_Low += 8;
  164.         /* Force it to 32 bits */
  165.         context->Length_Low &= 0xFFFFFFFF;
  166.         if (context->Length_Low == 0)
  167.         {
  168.             context->Length_High++;
  169.             /* Force it to 32 bits */
  170.             context->Length_High &= 0xFFFFFFFF;
  171.             if (context->Length_High == 0)
  172.             {
  173.                 /* Message is too long */
  174.                 context->Corrupted = 1;
  175.             }
  176.         }
  177.  
  178.         if (context->Message_Block_Index == 64)
  179.         {
  180.             SHA1ProcessMessageBlock(context);
  181.         }
  182.  
  183.         message_array++;
  184.     }
  185. }
  186.  
  187. /*  
  188.  *  SHA1ProcessMessageBlock
  189.  *
  190.  *  Description:
  191.  *      This function will process the next 512 bits of the message
  192.  *      stored in the Message_Block array.
  193.  *
  194.  *  Parameters:
  195.  *      None.
  196.  *
  197.  *  Returns:
  198.  *      Nothing.
  199.  *
  200.  *  Comments:
  201.  *      Many of the variable names in the SHAContext, especially the
  202.  *      single character names, were used because those were the names
  203.  *      used in the publication.
  204.  *        
  205.  *
  206.  */
  207. void SHA1ProcessMessageBlock(SHA1Context *context)
  208. {
  209.     const unsigned K[] =            /* Constants defined in SHA-1   */      
  210.     {
  211.         0x5A827999,
  212.         0x6ED9EBA1,
  213.         0x8F1BBCDC,
  214.         0xCA62C1D6
  215.     };
  216.     int         t;                  /* Loop counter                 */
  217.     unsigned    temp;               /* Temporary word value         */
  218.     unsigned    W[80];              /* Word sequence                */
  219.     unsigned    A, B, C, D, E;      /* Word buffers                 */
  220.  
  221.     /*
  222.      *  Initialize the first 16 words in the array W
  223.      */
  224.     for(t = 0; t < 16; t++)
  225.     {
  226.         W[t] = ((unsigned) context->Message_Block[t * 4]) << 24;
  227.         W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
  228.         W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
  229.         W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
  230.     }
  231.  
  232.     for(t = 16; t < 80; t++)
  233.     {
  234.        W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
  235.     }
  236.  
  237.     A = context->Message_Digest[0];
  238.     B = context->Message_Digest[1];
  239.     C = context->Message_Digest[2];
  240.     D = context->Message_Digest[3];
  241.     E = context->Message_Digest[4];
  242.  
  243.     for(t = 0; t < 20; t++)
  244.     {
  245.         temp =  SHA1CircularShift(5,A) +
  246.                 ((B & C) | ((~B) & D)) + E + W[t] + K[0];
  247.         temp &= 0xFFFFFFFF;
  248.         E = D;
  249.         D = C;
  250.         C = SHA1CircularShift(30,B);
  251.         B = A;
  252.         A = temp;
  253.     }
  254.  
  255.     for(t = 20; t < 40; t++)
  256.     {
  257.         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
  258.         temp &= 0xFFFFFFFF;
  259.         E = D;
  260.         D = C;
  261.         C = SHA1CircularShift(30,B);
  262.         B = A;
  263.         A = temp;
  264.     }
  265.  
  266.     for(t = 40; t < 60; t++)
  267.     {
  268.         temp = SHA1CircularShift(5,A) +
  269.                ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
  270.         temp &= 0xFFFFFFFF;
  271.         E = D;
  272.         D = C;
  273.         C = SHA1CircularShift(30,B);
  274.         B = A;
  275.         A = temp;
  276.     }
  277.  
  278.     for(t = 60; t < 80; t++)
  279.     {
  280.         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
  281.         temp &= 0xFFFFFFFF;
  282.         E = D;
  283.         D = C;
  284.         C = SHA1CircularShift(30,B);
  285.         B = A;
  286.         A = temp;
  287.     }
  288.  
  289.     context->Message_Digest[0] =
  290.                         (context->Message_Digest[0] + A) & 0xFFFFFFFF;
  291.     context->Message_Digest[1] =
  292.                         (context->Message_Digest[1] + B) & 0xFFFFFFFF;
  293.     context->Message_Digest[2] =
  294.                         (context->Message_Digest[2] + C) & 0xFFFFFFFF;
  295.     context->Message_Digest[3] =
  296.                         (context->Message_Digest[3] + D) & 0xFFFFFFFF;
  297.     context->Message_Digest[4] =
  298.                         (context->Message_Digest[4] + E) & 0xFFFFFFFF;
  299.  
  300.     context->Message_Block_Index = 0;
  301. }
  302.  
  303. /*  
  304.  *  SHA1PadMessage
  305.  *
  306.  *  Description:
  307.  *      According to the standard, the message must be padded to an even
  308.  *      512 bits.  The first padding bit must be a '1'.  The last 64
  309.  *      bits represent the length of the original message.  All bits in
  310.  *      between should be 0.  This function will pad the message
  311.  *      according to those rules by filling the Message_Block array
  312.  *      accordingly.  It will also call SHA1ProcessMessageBlock()
  313.  *      appropriately.  When it returns, it can be assumed that the
  314.  *      message digest has been computed.
  315.  *
  316.  *  Parameters:
  317.  *      context: [in/out]
  318.  *          The context to pad
  319.  *
  320.  *  Returns:
  321.  *      Nothing.
  322.  *
  323.  *  Comments:
  324.  *
  325.  */
  326. void SHA1PadMessage(SHA1Context *context)
  327. {
  328.     /*
  329.      *  Check to see if the current message block is too small to hold
  330.      *  the initial padding bits and length.  If so, we will pad the
  331.      *  block, process it, and then continue padding into a second
  332.      *  block.
  333.      */
  334.     if (context->Message_Block_Index > 55)
  335.     {
  336.         context->Message_Block[context->Message_Block_Index++] = 0x80;
  337.         while(context->Message_Block_Index < 64)
  338.         {
  339.             context->Message_Block[context->Message_Block_Index++] = 0;
  340.         }
  341.  
  342.         SHA1ProcessMessageBlock(context);
  343.  
  344.         while(context->Message_Block_Index < 56)
  345.         {
  346.             context->Message_Block[context->Message_Block_Index++] = 0;
  347.         }
  348.     }
  349.     else
  350.     {
  351.         context->Message_Block[context->Message_Block_Index++] = 0x80;
  352.         while(context->Message_Block_Index < 56)
  353.         {
  354.             context->Message_Block[context->Message_Block_Index++] = 0;
  355.         }
  356.     }
  357.  
  358.     /*
  359.      *  Store the message length as the last 8 octets
  360.      */
  361.     context->Message_Block[56] = (context->Length_High >> 24) & 0xFF;
  362.     context->Message_Block[57] = (context->Length_High >> 16) & 0xFF;
  363.     context->Message_Block[58] = (context->Length_High >> 8) & 0xFF;
  364.     context->Message_Block[59] = (context->Length_High) & 0xFF;
  365.     context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF;
  366.     context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF;
  367.     context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF;
  368.     context->Message_Block[63] = (context->Length_Low) & 0xFF;
  369.  
  370.     SHA1ProcessMessageBlock(context);
  371. }
Add Comment
Please, Sign In to add comment