sha1.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:10k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.  This program is free software; you can redistribute it and/or modify
  3.  it under the terms of the GNU General Public License as published by
  4.  the Free Software Foundation; either version 2 of the License, or
  5.  (at your option) any later version.
  6.  This program is distributed in the hope that it will be useful,
  7.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.  GNU General Public License for more details.
  10.  You should have received a copy of the GNU General Public License
  11.  along with this program; if not, write to the Free Software
  12.  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /*
  14.   Original Source from: http://www.faqs.org/rfcs/rfc3174.html
  15.  DESCRIPTION
  16.    This file implements the Secure Hashing Algorithm 1 as
  17.    defined in FIPS PUB 180-1 published April 17, 1995.
  18.    The SHA-1, produces a 160-bit message digest for a given data
  19.    stream.  It should take about 2**n steps to find a message with the
  20.    same digest as a given message and 2**(n/2) to find any two
  21.    messages with the same digest, when n is the digest size in bits.
  22.    Therefore, this algorithm can serve as a means of providing a
  23.    "fingerprint" for a message.
  24.  PORTABILITY ISSUES
  25.    SHA-1 is defined in terms of 32-bit "words".  This code uses
  26.    <stdint.h> (included via "sha1.h" to define 32 and 8 bit unsigned
  27.    integer types.  If your C compiler does not support 32 bit unsigned
  28.    integers, this code is not appropriate.
  29.  CAVEATS
  30.    SHA-1 is designed to work with messages less than 2^64 bits long.
  31.    Although SHA-1 allows a message digest to be generated for messages
  32.    of any number of bits less than 2^64, this implementation only
  33.    works with messages with a length that is a multiple of the size of
  34.    an 8-bit character.
  35.   CHANGES
  36.     2002 by Peter Zaitsev to
  37.      - fit to new prototypes according to MySQL standard
  38.      - Some optimizations
  39.      - All checking is now done in debug only mode
  40.      - More comments
  41. */
  42. #include "my_global.h"
  43. #include "m_string.h"
  44. #include "sha1.h"
  45. /*
  46.   Define the SHA1 circular left shift macro
  47. */
  48. #define SHA1CircularShift(bits,word) 
  49. (((word) << (bits)) | ((word) >> (32-(bits))))
  50. /* Local Function Prototyptes */
  51. static void SHA1PadMessage(SHA1_CONTEXT*);
  52. static void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
  53. /*
  54.   Initialize SHA1Context
  55.   SYNOPSIS
  56.     sha1_reset()
  57.     context [in/out] The context to reset.
  58.  DESCRIPTION
  59.    This function will initialize the SHA1Context in preparation
  60.    for computing a new SHA1 message digest.
  61.  RETURN
  62.    SHA_SUCCESS ok
  63.    != SHA_SUCCESS sha Error Code.
  64. */
  65. const uint32 sha_const_key[5]=
  66. {
  67.   0x67452301,
  68.   0xEFCDAB89,
  69.   0x98BADCFE,
  70.   0x10325476,
  71.   0xC3D2E1F0
  72. };
  73. int sha1_reset(SHA1_CONTEXT *context)
  74. {
  75. #ifndef DBUG_OFF
  76.   if (!context)
  77.     return SHA_NULL;
  78. #endif
  79.   context->Length   = 0;
  80.   context->Message_Block_Index   = 0;
  81.   context->Intermediate_Hash[0]   = sha_const_key[0];
  82.   context->Intermediate_Hash[1]   = sha_const_key[1];
  83.   context->Intermediate_Hash[2]   = sha_const_key[2];
  84.   context->Intermediate_Hash[3]   = sha_const_key[3];
  85.   context->Intermediate_Hash[4]   = sha_const_key[4];
  86.   context->Computed   = 0;
  87.   context->Corrupted  = 0;
  88.   return SHA_SUCCESS;
  89. }
  90. /*
  91.    Return the 160-bit message digest into the array provided by the caller
  92.   SYNOPSIS
  93.     sha1_result()
  94.     context [in/out] The context to use to calculate the SHA-1 hash.
  95.     Message_Digest: [out] Where the digest is returned.
  96.   DESCRIPTION
  97.     NOTE: The first octet of hash is stored in the 0th element,
  98.   the last octet of hash in the 19th element.
  99.  RETURN
  100.    SHA_SUCCESS ok
  101.    != SHA_SUCCESS sha Error Code.
  102. */
  103. int sha1_result(SHA1_CONTEXT *context,
  104. uint8 Message_Digest[SHA1_HASH_SIZE])
  105. {
  106.   int i;
  107. #ifndef DBUG_OFF
  108.   if (!context || !Message_Digest)
  109.     return SHA_NULL;
  110.   if (context->Corrupted)
  111.     return context->Corrupted;
  112. #endif
  113.   if (!context->Computed)
  114.   {
  115.     SHA1PadMessage(context);
  116.      /* message may be sensitive, clear it out */
  117.     bzero((char*) context->Message_Block,64);
  118.     context->Length   = 0;    /* and clear length  */
  119.     context->Computed = 1;
  120.   }
  121.   for (i = 0; i < SHA1_HASH_SIZE; i++)
  122.     Message_Digest[i] = (int8)((context->Intermediate_Hash[i>>2] >> 8
  123.  * ( 3 - ( i & 0x03 ) )));
  124.   return SHA_SUCCESS;
  125. }
  126. /*
  127.   Accepts an array of octets as the next portion of the message.
  128.   SYNOPSIS
  129.    sha1_input()
  130.    context [in/out] The SHA context to update
  131.    message_array An array of characters representing the next portion
  132. of the message.
  133.   length The length of the message in message_array
  134.  RETURN
  135.    SHA_SUCCESS ok
  136.    != SHA_SUCCESS sha Error Code.
  137. */
  138. int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
  139.        unsigned length)
  140. {
  141.   if (!length)
  142.     return SHA_SUCCESS;
  143. #ifndef DBUG_OFF
  144.   /* We assume client konows what it is doing in non-debug mode */
  145.   if (!context || !message_array)
  146.     return SHA_NULL;
  147.   if (context->Computed)
  148.     return (context->Corrupted= SHA_STATE_ERROR);
  149.   if (context->Corrupted)
  150.     return context->Corrupted;
  151. #endif
  152.   while (length--)
  153.   {
  154.     context->Message_Block[context->Message_Block_Index++]=
  155.       (*message_array & 0xFF);
  156.     context->Length  += 8;  /* Length is in bits */
  157. #ifndef DBUG_OFF
  158.     /*
  159.       Then we're not debugging we assume we never will get message longer
  160.       2^64 bits.
  161.     */
  162.     if (context->Length == 0)
  163.       return (context->Corrupted= 1);    /* Message is too long */
  164. #endif
  165.     if (context->Message_Block_Index == 64)
  166.     {
  167.       SHA1ProcessMessageBlock(context);
  168.     }
  169.     message_array++;
  170.   }
  171.   return SHA_SUCCESS;
  172. }
  173. /*
  174.   Process the next 512 bits of the message stored in the Message_Block array.
  175.   SYNOPSIS
  176.     SHA1ProcessMessageBlock()
  177.    DESCRIPTION
  178.      Many of the variable names in this code, especially the single
  179.      character names, were used because those were the names used in
  180.      the publication.
  181. */
  182. /* Constants defined in SHA-1 */
  183. static const uint32  K[]=
  184. {
  185.   0x5A827999,
  186.   0x6ED9EBA1,
  187.   0x8F1BBCDC,
  188.   0xCA62C1D6
  189. };
  190. static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
  191. {
  192.   int t;    /* Loop counter   */
  193.   uint32 temp;    /* Temporary word value   */
  194.   uint32 W[80];    /* Word sequence   */
  195.   uint32 A, B, C, D, E;    /* Word buffers   */
  196.   int index;
  197.   /*
  198.     Initialize the first 16 words in the array W
  199.   */
  200.   for (t = 0; t < 16; t++)
  201.   {
  202.     index=t*4;
  203.     W[t] = context->Message_Block[index] << 24;
  204.     W[t] |= context->Message_Block[index + 1] << 16;
  205.     W[t] |= context->Message_Block[index + 2] << 8;
  206.     W[t] |= context->Message_Block[index + 3];
  207.   }
  208.   for (t = 16; t < 80; t++)
  209.   {
  210.     W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
  211.   }
  212.   A = context->Intermediate_Hash[0];
  213.   B = context->Intermediate_Hash[1];
  214.   C = context->Intermediate_Hash[2];
  215.   D = context->Intermediate_Hash[3];
  216.   E = context->Intermediate_Hash[4];
  217.   for (t = 0; t < 20; t++)
  218.   {
  219.     temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
  220.     E = D;
  221.     D = C;
  222.     C = SHA1CircularShift(30,B);
  223.     B = A;
  224.     A = temp;
  225.   }
  226.   for (t = 20; t < 40; t++)
  227.   {
  228.     temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
  229.     E = D;
  230.     D = C;
  231.     C = SHA1CircularShift(30,B);
  232.     B = A;
  233.     A = temp;
  234.   }
  235.   for (t = 40; t < 60; t++)
  236.   {
  237.     temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] +
  238.    K[2]);
  239.     E = D;
  240.     D = C;
  241.     C = SHA1CircularShift(30,B);
  242.     B = A;
  243.     A = temp;
  244.   }
  245.   for (t = 60; t < 80; t++)
  246.   {
  247.     temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
  248.     E = D;
  249.     D = C;
  250.     C = SHA1CircularShift(30,B);
  251.     B = A;
  252.     A = temp;
  253.   }
  254.   context->Intermediate_Hash[0] += A;
  255.   context->Intermediate_Hash[1] += B;
  256.   context->Intermediate_Hash[2] += C;
  257.   context->Intermediate_Hash[3] += D;
  258.   context->Intermediate_Hash[4] += E;
  259.   context->Message_Block_Index = 0;
  260. }
  261. /*
  262.   Pad message
  263.   SYNOPSIS
  264.     SHA1PadMessage()
  265.     context: [in/out] The context to pad
  266.   DESCRIPTION
  267.     According to the standard, the message must be padded to an even
  268.     512 bits.  The first padding bit must be a '1'. The last 64 bits
  269.     represent the length of the original message.  All bits in between
  270.     should be 0.  This function will pad the message according to
  271.     those rules by filling the Message_Block array accordingly.  It
  272.     will also call the ProcessMessageBlock function provided
  273.     appropriately. When it returns, it can be assumed that the message
  274.     digest has been computed.
  275. */
  276. static void SHA1PadMessage(SHA1_CONTEXT *context)
  277. {
  278.   /*
  279.     Check to see if the current message block is too small to hold
  280.     the initial padding bits and length.  If so, we will pad the
  281.     block, process it, and then continue padding into a second
  282.     block.
  283.   */
  284.   int i=context->Message_Block_Index;
  285.   if (i > 55)
  286.   {
  287.     context->Message_Block[i++] = 0x80;
  288.     bzero((char*) &context->Message_Block[i],
  289.   sizeof(context->Message_Block[0])*(64-i));
  290.     context->Message_Block_Index=64;
  291.     /* This function sets context->Message_Block_Index to zero */
  292.     SHA1ProcessMessageBlock(context);
  293.     bzero((char*) &context->Message_Block[0],
  294.   sizeof(context->Message_Block[0])*56);
  295.     context->Message_Block_Index=56;
  296.   }
  297.   else
  298.   {
  299.     context->Message_Block[i++] = 0x80;
  300.     bzero((char*) &context->Message_Block[i],
  301.   sizeof(context->Message_Block[0])*(56-i));
  302.     context->Message_Block_Index=56;
  303.   }
  304.   /*
  305.     Store the message length as the last 8 octets
  306.   */
  307.   context->Message_Block[56] = (int8) (context->Length >> 56);
  308.   context->Message_Block[57] = (int8) (context->Length >> 48);
  309.   context->Message_Block[58] = (int8) (context->Length >> 40);
  310.   context->Message_Block[59] = (int8) (context->Length >> 32);
  311.   context->Message_Block[60] = (int8) (context->Length >> 24);
  312.   context->Message_Block[61] = (int8) (context->Length >> 16);
  313.   context->Message_Block[62] = (int8) (context->Length >> 8);
  314.   context->Message_Block[63] = (int8) (context->Length);
  315.   SHA1ProcessMessageBlock(context);
  316. }