mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 14:33:32 +03:00 
			
		
		
		
	Ensured that all projects compile Removed compiler warnings Better setting of server_version variable. Fix that make_win_src_distribution creates the privilege tables.
		
			
				
	
	
		
			393 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			393 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
 | 
						|
 | 
						|
 This program is free software; you can redistribute it and/or modify
 | 
						|
 it under the terms of the GNU General Public License as published by
 | 
						|
 the Free Software Foundation; either version 2 of the License, or
 | 
						|
 (at your option) any later version.
 | 
						|
 | 
						|
 This program is distributed in the hope that it will be useful,
 | 
						|
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 GNU General Public License for more details.
 | 
						|
 | 
						|
 You should have received a copy of the GNU General Public License
 | 
						|
 along with this program; if not, write to the Free Software
 | 
						|
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 | 
						|
 | 
						|
/*
 | 
						|
  Original Source from: http://www.faqs.org/rfcs/rfc3174.html
 | 
						|
 | 
						|
 DESCRIPTION
 | 
						|
   This file implements the Secure Hashing Algorithm 1 as
 | 
						|
   defined in FIPS PUB 180-1 published April 17, 1995.
 | 
						|
 | 
						|
   The SHA-1, produces a 160-bit message digest for a given data
 | 
						|
   stream.  It should take about 2**n steps to find a message with the
 | 
						|
   same digest as a given message and 2**(n/2) to find any two
 | 
						|
   messages with the same digest, when n is the digest size in bits.
 | 
						|
   Therefore, this algorithm can serve as a means of providing a
 | 
						|
   "fingerprint" for a message.
 | 
						|
 | 
						|
 PORTABILITY ISSUES
 | 
						|
   SHA-1 is defined in terms of 32-bit "words".  This code uses
 | 
						|
   <stdint.h> (included via "sha1.h" to define 32 and 8 bit unsigned
 | 
						|
   integer types.  If your C compiler does not support 32 bit unsigned
 | 
						|
   integers, this code is not appropriate.
 | 
						|
 | 
						|
 CAVEATS
 | 
						|
   SHA-1 is designed to work with messages less than 2^64 bits long.
 | 
						|
   Although SHA-1 allows a message digest to be generated for messages
 | 
						|
   of any number of bits less than 2^64, this implementation only
 | 
						|
   works with messages with a length that is a multiple of the size of
 | 
						|
   an 8-bit character.
 | 
						|
 | 
						|
  CHANGES
 | 
						|
    2002 by Peter Zaitsev to
 | 
						|
     - fit to new prototypes according to MySQL standard
 | 
						|
     - Some optimizations
 | 
						|
     - All checking is now done in debug only mode
 | 
						|
     - More comments
 | 
						|
*/
 | 
						|
 | 
						|
#include "my_global.h"
 | 
						|
#include "m_string.h"
 | 
						|
#include "sha1.h"
 | 
						|
 | 
						|
/*
 | 
						|
  Define the SHA1 circular left shift macro
 | 
						|
*/
 | 
						|
 | 
						|
#define SHA1CircularShift(bits,word) \
 | 
						|
		(((word) << (bits)) | ((word) >> (32-(bits))))
 | 
						|
 | 
						|
/* Local Function Prototyptes */
 | 
						|
static void SHA1PadMessage(SHA1_CONTEXT*);
 | 
						|
static void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
  Initialize SHA1Context
 | 
						|
 | 
						|
  SYNOPSIS
 | 
						|
    sha1_reset()
 | 
						|
    context [in/out]		The context to reset.
 | 
						|
 | 
						|
 DESCRIPTION
 | 
						|
   This function will initialize the SHA1Context in preparation
 | 
						|
   for computing a new SHA1 message digest.
 | 
						|
 | 
						|
 RETURN
 | 
						|
   SHA_SUCCESS		ok
 | 
						|
   != SHA_SUCCESS	sha Error Code.
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
const uint32 sha_const_key[5]=
 | 
						|
{
 | 
						|
  0x67452301,
 | 
						|
  0xEFCDAB89,
 | 
						|
  0x98BADCFE,
 | 
						|
  0x10325476,
 | 
						|
  0xC3D2E1F0
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
int sha1_reset(SHA1_CONTEXT *context)
 | 
						|
{
 | 
						|
#ifndef DBUG_OFF
 | 
						|
  if (!context)
 | 
						|
    return SHA_NULL;
 | 
						|
#endif
 | 
						|
 | 
						|
  context->Length		  = 0;
 | 
						|
  context->Message_Block_Index	  = 0;
 | 
						|
 | 
						|
  context->Intermediate_Hash[0]   = sha_const_key[0];
 | 
						|
  context->Intermediate_Hash[1]   = sha_const_key[1];
 | 
						|
  context->Intermediate_Hash[2]   = sha_const_key[2];
 | 
						|
  context->Intermediate_Hash[3]   = sha_const_key[3];
 | 
						|
  context->Intermediate_Hash[4]   = sha_const_key[4];
 | 
						|
 | 
						|
  context->Computed   = 0;
 | 
						|
  context->Corrupted  = 0;
 | 
						|
 | 
						|
  return SHA_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
   Return the 160-bit message digest into the array provided by the caller
 | 
						|
 | 
						|
  SYNOPSIS
 | 
						|
    sha1_result()
 | 
						|
    context [in/out]		The context to use to calculate the SHA-1 hash.
 | 
						|
    Message_Digest: [out]	Where the digest is returned.
 | 
						|
 | 
						|
  DESCRIPTION
 | 
						|
    NOTE: The first octet of hash is stored in the 0th element,
 | 
						|
	  the last octet of hash in the 19th element.
 | 
						|
 | 
						|
 RETURN
 | 
						|
   SHA_SUCCESS		ok
 | 
						|
   != SHA_SUCCESS	sha Error Code.
 | 
						|
*/
 | 
						|
 | 
						|
int sha1_result(SHA1_CONTEXT *context,
 | 
						|
		uint8 Message_Digest[SHA1_HASH_SIZE])
 | 
						|
{
 | 
						|
  int i;
 | 
						|
 | 
						|
#ifndef DBUG_OFF
 | 
						|
  if (!context || !Message_Digest)
 | 
						|
    return SHA_NULL;
 | 
						|
 | 
						|
  if (context->Corrupted)
 | 
						|
    return context->Corrupted;
 | 
						|
#endif
 | 
						|
 | 
						|
  if (!context->Computed)
 | 
						|
  {
 | 
						|
    SHA1PadMessage(context);
 | 
						|
     /* message may be sensitive, clear it out */
 | 
						|
    bzero((char*) context->Message_Block,64);
 | 
						|
    context->Length   = 0;    /* and clear length  */
 | 
						|
    context->Computed = 1;
 | 
						|
  }
 | 
						|
 | 
						|
  for (i = 0; i < SHA1_HASH_SIZE; i++)
 | 
						|
    Message_Digest[i] = (int8)((context->Intermediate_Hash[i>>2] >> 8
 | 
						|
			 * ( 3 - ( i & 0x03 ) )));
 | 
						|
  return SHA_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
  Accepts an array of octets as the next portion of the message.
 | 
						|
 | 
						|
  SYNOPSIS
 | 
						|
   sha1_input()
 | 
						|
   context [in/out]	The SHA context to update
 | 
						|
   message_array	An array of characters representing the next portion
 | 
						|
			of the message.
 | 
						|
  length		The length of the message in message_array
 | 
						|
 | 
						|
 RETURN
 | 
						|
   SHA_SUCCESS		ok
 | 
						|
   != SHA_SUCCESS	sha Error Code.
 | 
						|
*/
 | 
						|
 | 
						|
int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
 | 
						|
	       unsigned length)
 | 
						|
{
 | 
						|
  if (!length)
 | 
						|
    return SHA_SUCCESS;
 | 
						|
 | 
						|
#ifndef DBUG_OFF
 | 
						|
  /* We assume client konows what it is doing in non-debug mode */
 | 
						|
  if (!context || !message_array)
 | 
						|
    return SHA_NULL;
 | 
						|
  if (context->Computed)
 | 
						|
    return (context->Corrupted= SHA_STATE_ERROR);
 | 
						|
  if (context->Corrupted)
 | 
						|
    return context->Corrupted;
 | 
						|
#endif
 | 
						|
 | 
						|
  while (length--)
 | 
						|
  {
 | 
						|
    context->Message_Block[context->Message_Block_Index++]=
 | 
						|
      (*message_array & 0xFF);
 | 
						|
    context->Length  += 8;  /* Length is in bits */
 | 
						|
 | 
						|
#ifndef DBUG_OFF
 | 
						|
    /*
 | 
						|
      Then we're not debugging we assume we never will get message longer
 | 
						|
      2^64 bits.
 | 
						|
    */
 | 
						|
    if (context->Length == 0)
 | 
						|
      return (context->Corrupted= 1);	   /* Message is too long */
 | 
						|
#endif
 | 
						|
 | 
						|
    if (context->Message_Block_Index == 64)
 | 
						|
    {
 | 
						|
      SHA1ProcessMessageBlock(context);
 | 
						|
    }
 | 
						|
    message_array++;
 | 
						|
  }
 | 
						|
  return SHA_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
  Process the next 512 bits of the message stored in the Message_Block array.
 | 
						|
 | 
						|
  SYNOPSIS
 | 
						|
    SHA1ProcessMessageBlock()
 | 
						|
 | 
						|
   DESCRIPTION
 | 
						|
     Many of the variable names in this code, especially the single
 | 
						|
     character names, were used because those were the names used in
 | 
						|
     the publication.
 | 
						|
*/
 | 
						|
 | 
						|
/* Constants defined in SHA-1	*/
 | 
						|
static const uint32  K[]=
 | 
						|
{
 | 
						|
  0x5A827999,
 | 
						|
  0x6ED9EBA1,
 | 
						|
  0x8F1BBCDC,
 | 
						|
  0xCA62C1D6
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
 | 
						|
{
 | 
						|
  int		t;		   /* Loop counter		  */
 | 
						|
  uint32	temp;		   /* Temporary word value	  */
 | 
						|
  uint32	W[80];		   /* Word sequence		  */
 | 
						|
  uint32	A, B, C, D, E;	   /* Word buffers		  */
 | 
						|
  int index;
 | 
						|
 | 
						|
  /*
 | 
						|
    Initialize the first 16 words in the array W
 | 
						|
  */
 | 
						|
 | 
						|
  for (t = 0; t < 16; t++)
 | 
						|
  {
 | 
						|
    index=t*4;
 | 
						|
    W[t] = context->Message_Block[index] << 24;
 | 
						|
    W[t] |= context->Message_Block[index + 1] << 16;
 | 
						|
    W[t] |= context->Message_Block[index + 2] << 8;
 | 
						|
    W[t] |= context->Message_Block[index + 3];
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  for (t = 16; t < 80; t++)
 | 
						|
  {
 | 
						|
    W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
 | 
						|
  }
 | 
						|
 | 
						|
  A = context->Intermediate_Hash[0];
 | 
						|
  B = context->Intermediate_Hash[1];
 | 
						|
  C = context->Intermediate_Hash[2];
 | 
						|
  D = context->Intermediate_Hash[3];
 | 
						|
  E = context->Intermediate_Hash[4];
 | 
						|
 | 
						|
  for (t = 0; t < 20; t++)
 | 
						|
  {
 | 
						|
    temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
 | 
						|
    E = D;
 | 
						|
    D = C;
 | 
						|
    C = SHA1CircularShift(30,B);
 | 
						|
    B = A;
 | 
						|
    A = temp;
 | 
						|
  }
 | 
						|
 | 
						|
  for (t = 20; t < 40; t++)
 | 
						|
  {
 | 
						|
    temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
 | 
						|
    E = D;
 | 
						|
    D = C;
 | 
						|
    C = SHA1CircularShift(30,B);
 | 
						|
    B = A;
 | 
						|
    A = temp;
 | 
						|
  }
 | 
						|
 | 
						|
  for (t = 40; t < 60; t++)
 | 
						|
  {
 | 
						|
    temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] +
 | 
						|
	   K[2]);
 | 
						|
    E = D;
 | 
						|
    D = C;
 | 
						|
    C = SHA1CircularShift(30,B);
 | 
						|
    B = A;
 | 
						|
    A = temp;
 | 
						|
  }
 | 
						|
 | 
						|
  for (t = 60; t < 80; t++)
 | 
						|
  {
 | 
						|
    temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
 | 
						|
    E = D;
 | 
						|
    D = C;
 | 
						|
    C = SHA1CircularShift(30,B);
 | 
						|
    B = A;
 | 
						|
    A = temp;
 | 
						|
  }
 | 
						|
 | 
						|
  context->Intermediate_Hash[0] += A;
 | 
						|
  context->Intermediate_Hash[1] += B;
 | 
						|
  context->Intermediate_Hash[2] += C;
 | 
						|
  context->Intermediate_Hash[3] += D;
 | 
						|
  context->Intermediate_Hash[4] += E;
 | 
						|
 | 
						|
  context->Message_Block_Index = 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
  Pad message
 | 
						|
 | 
						|
  SYNOPSIS
 | 
						|
    SHA1PadMessage()
 | 
						|
    context: [in/out]		The context to pad
 | 
						|
 | 
						|
  DESCRIPTION
 | 
						|
    According to the standard, the message must be padded to an even
 | 
						|
    512 bits.  The first padding bit must be a '1'. The last 64 bits
 | 
						|
    represent the length of the original message.  All bits in between
 | 
						|
    should be 0.  This function will pad the message according to
 | 
						|
    those rules by filling the Message_Block array accordingly.  It
 | 
						|
    will also call the ProcessMessageBlock function provided
 | 
						|
    appropriately. When it returns, it can be assumed that the message
 | 
						|
    digest has been computed.
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
static void SHA1PadMessage(SHA1_CONTEXT *context)
 | 
						|
{
 | 
						|
  /*
 | 
						|
    Check to see if the current message block is too small to hold
 | 
						|
    the initial padding bits and length.  If so, we will pad the
 | 
						|
    block, process it, and then continue padding into a second
 | 
						|
    block.
 | 
						|
  */
 | 
						|
 | 
						|
  int i=context->Message_Block_Index;
 | 
						|
 | 
						|
  if (i > 55)
 | 
						|
  {
 | 
						|
    context->Message_Block[i++] = 0x80;
 | 
						|
    bzero((char*) &context->Message_Block[i],
 | 
						|
	  sizeof(context->Message_Block[0])*(64-i));
 | 
						|
    context->Message_Block_Index=64;
 | 
						|
 | 
						|
    /* This function sets context->Message_Block_Index to zero	*/
 | 
						|
    SHA1ProcessMessageBlock(context);
 | 
						|
 | 
						|
    bzero((char*) &context->Message_Block[0],
 | 
						|
	  sizeof(context->Message_Block[0])*56);
 | 
						|
    context->Message_Block_Index=56;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    context->Message_Block[i++] = 0x80;
 | 
						|
    bzero((char*) &context->Message_Block[i],
 | 
						|
	  sizeof(context->Message_Block[0])*(56-i));
 | 
						|
    context->Message_Block_Index=56;
 | 
						|
  }
 | 
						|
 | 
						|
  /*
 | 
						|
    Store the message length as the last 8 octets
 | 
						|
  */
 | 
						|
 | 
						|
  context->Message_Block[56] = (int8) (context->Length >> 56);
 | 
						|
  context->Message_Block[57] = (int8) (context->Length >> 48);
 | 
						|
  context->Message_Block[58] = (int8) (context->Length >> 40);
 | 
						|
  context->Message_Block[59] = (int8) (context->Length >> 32);
 | 
						|
  context->Message_Block[60] = (int8) (context->Length >> 24);
 | 
						|
  context->Message_Block[61] = (int8) (context->Length >> 16);
 | 
						|
  context->Message_Block[62] = (int8) (context->Length >> 8);
 | 
						|
  context->Message_Block[63] = (int8) (context->Length);
 | 
						|
 | 
						|
  SHA1ProcessMessageBlock(context);
 | 
						|
}
 |