~drizzle-trunk/drizzle/development

1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
2
 *
3
 * PrimeBase S3Daemon
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
 *
19
 *  Modified by Barry Leslie on 10/21/08.
20
 *	I have put a C++ wrapper around the data and functions to create an sha1 class.
21
 *
22
 */
23
/*
24
  Original Source from: http://www.faqs.org/rfcs/rfc3174.html
25
  and MySQL mysys/sha1.c build 5.1.24.
26
27
 DESCRIPTION
28
   This file implements the Secure Hashing Algorithm 1 as
29
   defined in FIPS PUB 180-1 published April 17, 1995.
30
31
   The SHA-1, produces a 160-bit message digest for a given data
32
   stream.  It should take about 2**n steps to find a message with the
33
   same digest as a given message and 2**(n/2) to find any two
34
   messages with the same digest, when n is the digest size in bits.
35
   Therefore, this algorithm can serve as a means of providing a
36
   "fingerprint" for a message.
37
38
 PORTABILITY ISSUES
39
   SHA-1 is defined in terms of 32-bit "words".  This code uses
40
   <stdint.h> (included via "sha1.h" to define 32 and 8 bit unsigned
41
   integer types.  If your C compiler does not support 32 bit unsigned
42
   integers, this code is not appropriate.
43
44
 CAVEATS
45
   SHA-1 is designed to work with messages less than 2^64 bits long.
46
   Although SHA-1 allows a message digest to be generated for messages
47
   of any number of bits less than 2^64, this implementation only
48
   works with messages with a length that is a multiple of the size of
49
   an 8-bit character.
50
51
  CHANGES
52
    2002 by Peter Zaitsev to
53
     - fit to new prototypes according to MySQL standard
54
     - Some optimizations
55
     - All checking is now done in debug only mode
56
     - More comments
57
*/
58
59
#include "CSConfig.h"
60
#include <string.h>
61
62
#include "CSDefs.h"
63
#include "CSObject.h"
64
65
#include "CSSha1.h"
66
67
#define SHA1CircularShift(bits,word) (((word) << (bits)) | ((word) >> (32-(bits))))
68
69
void CSSha1::sha1_reset()
70
{
71
	Length = 0;
72
	Message_Block_Index = 0;
73
74
	Intermediate_Hash[0] = 0x67452301;
75
	Intermediate_Hash[1] = 0xEFCDAB89;
76
	Intermediate_Hash[2] = 0x98BADCFE;
77
	Intermediate_Hash[3] = 0x10325476;
78
	Intermediate_Hash[4] = 0xC3D2E1F0;
79
80
	Computed = false;
81
82
}
83
84
//------------------------------
85
void CSSha1::sha1_digest(Sha1Digest *digest)
86
{
87
	if (!Computed) {
88
		sha1_pad();		
89
		memset(Message_Block, 0, 64);
90
		Length = 0;
91
		Computed = true;
92
	}
93
94
	for (int i = 0; i < SHA1_HASH_SIZE; i++)
95
		digest->val[i] = (int8_t)((Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) )));
96
}
97
98
//------------------------------
99
void CSSha1::sha1_input(const void *data, size_t len)
100
{
101
	uint8_t *message_array = (u_char *) data;
102
	
103
	if (!len)
104
		return;
105
106
	if (Computed)
107
		sha1_reset();
108
109
	while (len--) {
110
		Message_Block[Message_Block_Index++]= (*message_array & 0xFF);
111
		Length += 8;  /* Length is in bits */
112
113
		if (Message_Block_Index == 64)
114
			sha1_process();
115
116
		message_array++;
117
	}
118
}
119
120
//------------------------------
121
void CSSha1::sha1_pad()
122
{
123
	/*
124
	Check to see if the current message block is too small to hold
125
	the initial padding bits and length.  If so, we will pad the
126
	block, process it, and then continue padding into a second
127
	block.
128
	*/
129
130
	int i = Message_Block_Index;
131
132
	if (i > 55) {
133
		Message_Block[i++] = 0x80;
134
		memset(&Message_Block[i], 0, sizeof(Message_Block[0]) * 64-i);
135
		Message_Block_Index=64;
136
137
		/* This function sets Message_Block_Index to zero	*/
138
		sha1_process();
139
140
		memset(Message_Block, 0, sizeof(Message_Block[0]) * 56);
141
		Message_Block_Index=56;
142
	} else {
143
		Message_Block[i++] = 0x80;
144
		memset(&Message_Block[i], 0, sizeof(Message_Block[0])*(56-i));
145
		Message_Block_Index=56;
146
	}
147
148
	/*
149
	Store the message length as the last 8 octets
150
	*/
151
152
	Message_Block[56] = (int8_t) (Length >> 56);
153
	Message_Block[57] = (int8_t) (Length >> 48);
154
	Message_Block[58] = (int8_t) (Length >> 40);
155
	Message_Block[59] = (int8_t) (Length >> 32);
156
	Message_Block[60] = (int8_t) (Length >> 24);
157
	Message_Block[61] = (int8_t) (Length >> 16);
158
	Message_Block[62] = (int8_t) (Length >> 8);
159
	Message_Block[63] = (int8_t) (Length);
160
161
	sha1_process();
162
}
163
164
//------------------------------
165
void CSSha1::sha1_process()
166
{
167
    const uint32_t K[] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };
168
	int		t;		   /* Loop counter		  */
169
	uint32_t	temp;		   /* Temporary word value	  */
170
	uint32_t	W[80];		   /* Word sequence		  */
171
	uint32_t	A, B, C, D, E;	   /* Word buffers		  */
172
	int idx;
173
174
	/*
175
	Initialize the first 16 words in the array W
176
	*/
177
178
	for (t = 0; t < 16; t++) {
179
		idx=t*4;
180
		W[t] = Message_Block[idx] << 24;
181
		W[t] |= Message_Block[idx + 1] << 16;
182
		W[t] |= Message_Block[idx + 2] << 8;
183
		W[t] |= Message_Block[idx + 3];
184
	}
185
186
187
	for (t = 16; t < 80; t++) {
188
		W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
189
	}
190
191
	A = Intermediate_Hash[0];
192
	B = Intermediate_Hash[1];
193
	C = Intermediate_Hash[2];
194
	D = Intermediate_Hash[3];
195
	E = Intermediate_Hash[4];
196
197
	for (t = 0; t < 20; t++) {
198
		temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
199
		E = D;
200
		D = C;
201
		C = SHA1CircularShift(30,B);
202
		B = A;
203
		A = temp;
204
	}
205
206
	for (t = 20; t < 40; t++) {
207
		temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
208
		E = D;
209
		D = C;
210
		C = SHA1CircularShift(30,B);
211
		B = A;
212
		A = temp;
213
	}
214
215
	for (t = 40; t < 60; t++) {
216
		temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]);
217
		E = D;
218
		D = C;
219
		C = SHA1CircularShift(30,B);
220
		B = A;
221
		A = temp;
222
	}
223
224
	for (t = 60; t < 80; t++) {
225
		temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
226
		E = D;
227
		D = C;
228
		C = SHA1CircularShift(30,B);
229
		B = A;
230
		A = temp;
231
	}
232
233
	Intermediate_Hash[0] += A;
234
	Intermediate_Hash[1] += B;
235
	Intermediate_Hash[2] += C;
236
	Intermediate_Hash[3] += D;
237
	Intermediate_Hash[4] += E;
238
239
	Message_Block_Index = 0;
240
}
241
242