~drizzle-trunk/drizzle/development

1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
1
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
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
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
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>
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
61
#include <stdint.h>
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
62
63
#include "CSDefs.h"
64
#include "CSObject.h"
65
66
#include "CSSha1.h"
67
68
#define SHA1CircularShift(bits,word) (((word) << (bits)) | ((word) >> (32-(bits))))
69
70
void CSSha1::sha1_reset()
71
{
72
	Length = 0;
73
	Message_Block_Index = 0;
74
75
	Intermediate_Hash[0] = 0x67452301;
76
	Intermediate_Hash[1] = 0xEFCDAB89;
77
	Intermediate_Hash[2] = 0x98BADCFE;
78
	Intermediate_Hash[3] = 0x10325476;
79
	Intermediate_Hash[4] = 0xC3D2E1F0;
80
81
	Computed = false;
82
83
}
84
85
//------------------------------
86
void CSSha1::sha1_digest(Sha1Digest *digest)
87
{
88
	if (!Computed) {
89
		sha1_pad();		
90
		memset(Message_Block, 0, 64);
91
		Length = 0;
92
		Computed = true;
93
	}
94
95
	for (int i = 0; i < SHA1_HASH_SIZE; i++)
96
		digest->val[i] = (int8_t)((Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) )));
97
}
98
99
//------------------------------
100
void CSSha1::sha1_input(const void *data, size_t len)
101
{
102
	uint8_t *message_array = (u_char *) data;
103
	
104
	if (!len)
105
		return;
106
107
	if (Computed)
108
		sha1_reset();
109
110
	while (len--) {
111
		Message_Block[Message_Block_Index++]= (*message_array & 0xFF);
112
		Length += 8;  /* Length is in bits */
113
114
		if (Message_Block_Index == 64)
115
			sha1_process();
116
117
		message_array++;
118
	}
119
}
120
121
//------------------------------
122
void CSSha1::sha1_pad()
123
{
124
	/*
125
	Check to see if the current message block is too small to hold
126
	the initial padding bits and length.  If so, we will pad the
127
	block, process it, and then continue padding into a second
128
	block.
129
	*/
130
131
	int i = Message_Block_Index;
132
133
	if (i > 55) {
134
		Message_Block[i++] = 0x80;
135
		memset(&Message_Block[i], 0, sizeof(Message_Block[0]) * 64-i);
136
		Message_Block_Index=64;
137
138
		/* This function sets Message_Block_Index to zero	*/
139
		sha1_process();
140
141
		memset(Message_Block, 0, sizeof(Message_Block[0]) * 56);
142
		Message_Block_Index=56;
143
	} else {
144
		Message_Block[i++] = 0x80;
145
		memset(&Message_Block[i], 0, sizeof(Message_Block[0])*(56-i));
146
		Message_Block_Index=56;
147
	}
148
149
	/*
150
	Store the message length as the last 8 octets
151
	*/
152
153
	Message_Block[56] = (int8_t) (Length >> 56);
154
	Message_Block[57] = (int8_t) (Length >> 48);
155
	Message_Block[58] = (int8_t) (Length >> 40);
156
	Message_Block[59] = (int8_t) (Length >> 32);
157
	Message_Block[60] = (int8_t) (Length >> 24);
158
	Message_Block[61] = (int8_t) (Length >> 16);
159
	Message_Block[62] = (int8_t) (Length >> 8);
160
	Message_Block[63] = (int8_t) (Length);
161
162
	sha1_process();
163
}
164
165
//------------------------------
166
void CSSha1::sha1_process()
167
{
168
    const uint32_t K[] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };
169
	int		t;		   /* Loop counter		  */
170
	uint32_t	temp;		   /* Temporary word value	  */
171
	uint32_t	W[80];		   /* Word sequence		  */
172
	uint32_t	A, B, C, D, E;	   /* Word buffers		  */
173
	int idx;
174
175
	/*
176
	Initialize the first 16 words in the array W
177
	*/
178
179
	for (t = 0; t < 16; t++) {
180
		idx=t*4;
181
		W[t] = Message_Block[idx] << 24;
182
		W[t] |= Message_Block[idx + 1] << 16;
183
		W[t] |= Message_Block[idx + 2] << 8;
184
		W[t] |= Message_Block[idx + 3];
185
	}
186
187
188
	for (t = 16; t < 80; t++) {
189
		W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
190
	}
191
192
	A = Intermediate_Hash[0];
193
	B = Intermediate_Hash[1];
194
	C = Intermediate_Hash[2];
195
	D = Intermediate_Hash[3];
196
	E = Intermediate_Hash[4];
197
198
	for (t = 0; t < 20; t++) {
199
		temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
200
		E = D;
201
		D = C;
202
		C = SHA1CircularShift(30,B);
203
		B = A;
204
		A = temp;
205
	}
206
207
	for (t = 20; t < 40; t++) {
208
		temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
209
		E = D;
210
		D = C;
211
		C = SHA1CircularShift(30,B);
212
		B = A;
213
		A = temp;
214
	}
215
216
	for (t = 40; t < 60; t++) {
217
		temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]);
218
		E = D;
219
		D = C;
220
		C = SHA1CircularShift(30,B);
221
		B = A;
222
		A = temp;
223
	}
224
225
	for (t = 60; t < 80; t++) {
226
		temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
227
		E = D;
228
		D = C;
229
		C = SHA1CircularShift(30,B);
230
		B = A;
231
		A = temp;
232
	}
233
234
	Intermediate_Hash[0] += A;
235
	Intermediate_Hash[1] += B;
236
	Intermediate_Hash[2] += C;
237
	Intermediate_Hash[3] += D;
238
	Intermediate_Hash[4] += E;
239
240
	Message_Block_Index = 0;
241
}
242
243