~drizzle-trunk/drizzle/development

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