~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
212.5.18 by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype.
51
#include <mystrings/m_string.h>
1 by brian
clean slate
52
#include "sha1.h"
53
54
/*
55
  Define the SHA1 circular left shift macro
56
*/
57
58
#define SHA1CircularShift(bits,word) \
59
		(((word) << (bits)) | ((word) >> (32-(bits))))
60
61
/* Local Function Prototyptes */
62
static void SHA1PadMessage(SHA1_CONTEXT*);
63
static void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
64
65
66
/*
67
  Initialize SHA1Context
68
69
  SYNOPSIS
70
    mysql_sha1_reset()
71
    context [in/out]		The context to reset.
72
73
 DESCRIPTION
74
   This function will initialize the SHA1Context in preparation
75
   for computing a new SHA1 message digest.
76
77
 RETURN
78
   SHA_SUCCESS		ok
79
   != SHA_SUCCESS	sha Error Code.
80
*/
81
82
205 by Brian Aker
uint32 -> uin32_t
83
const uint32_t sha_const_key[5]=
1 by brian
clean slate
84
{
85
  0x67452301,
86
  0xEFCDAB89,
87
  0x98BADCFE,
88
  0x10325476,
89
  0xC3D2E1F0
90
};
91
92
93
int mysql_sha1_reset(SHA1_CONTEXT *context)
94
{
95
  context->Length		  = 0;
96
  context->Message_Block_Index	  = 0;
97
98
  context->Intermediate_Hash[0]   = sha_const_key[0];
99
  context->Intermediate_Hash[1]   = sha_const_key[1];
100
  context->Intermediate_Hash[2]   = sha_const_key[2];
101
  context->Intermediate_Hash[3]   = sha_const_key[3];
102
  context->Intermediate_Hash[4]   = sha_const_key[4];
103
104
  context->Computed   = 0;
105
  context->Corrupted  = 0;
106
107
  return SHA_SUCCESS;
108
}
109
110
111
/*
112
   Return the 160-bit message digest into the array provided by the caller
113
114
  SYNOPSIS
115
    mysql_sha1_result()
116
    context [in/out]		The context to use to calculate the SHA-1 hash.
117
    Message_Digest: [out]	Where the digest is returned.
118
119
  DESCRIPTION
120
    NOTE: The first octet of hash is stored in the 0th element,
121
	  the last octet of hash in the 19th element.
122
123
 RETURN
124
   SHA_SUCCESS		ok
125
   != SHA_SUCCESS	sha Error Code.
126
*/
127
128
int mysql_sha1_result(SHA1_CONTEXT *context,
206 by Brian Aker
Removed final uint dead types.
129
                      uint8_t Message_Digest[SHA1_HASH_SIZE])
1 by brian
clean slate
130
{
131
  int i;
132
133
  if (!context->Computed)
134
  {
135
    SHA1PadMessage(context);
136
     /* message may be sensitive, clear it out */
212.6.14 by Mats Kindahl
Removing redundant use of casts in mysys for memcmp(), memcpy(), memset(), and memmove().
137
    memset(context->Message_Block, 0, 64);
1 by brian
clean slate
138
    context->Length   = 0;    /* and clear length  */
139
    context->Computed = 1;
140
  }
141
142
  for (i = 0; i < SHA1_HASH_SIZE; i++)
206 by Brian Aker
Removed final uint dead types.
143
    Message_Digest[i] = (int8_t)((context->Intermediate_Hash[i>>2] >> 8
1 by brian
clean slate
144
			 * ( 3 - ( i & 0x03 ) )));
145
  return SHA_SUCCESS;
146
}
147
148
149
/*
150
  Accepts an array of octets as the next portion of the message.
151
152
  SYNOPSIS
153
   mysql_sha1_input()
154
   context [in/out]	The SHA context to update
155
   message_array	An array of characters representing the next portion
156
			of the message.
157
  length		The length of the message in message_array
158
159
 RETURN
160
   SHA_SUCCESS		ok
161
   != SHA_SUCCESS	sha Error Code.
162
*/
163
206 by Brian Aker
Removed final uint dead types.
164
int mysql_sha1_input(SHA1_CONTEXT *context, const uint8_t *message_array,
1 by brian
clean slate
165
                     unsigned length)
166
{
167
  if (!length)
168
    return SHA_SUCCESS;
169
170
  while (length--)
171
  {
172
    context->Message_Block[context->Message_Block_Index++]=
173
      (*message_array & 0xFF);
174
    context->Length  += 8;  /* Length is in bits */
175
176
    if (context->Message_Block_Index == 64)
177
    {
178
      SHA1ProcessMessageBlock(context);
179
    }
180
    message_array++;
181
  }
182
  return SHA_SUCCESS;
183
}
184
185
186
/*
187
  Process the next 512 bits of the message stored in the Message_Block array.
188
189
  SYNOPSIS
190
    SHA1ProcessMessageBlock()
191
192
   DESCRIPTION
193
     Many of the variable names in this code, especially the single
194
     character names, were used because those were the names used in
195
     the publication.
196
*/
197
198
/* Constants defined in SHA-1	*/
205 by Brian Aker
uint32 -> uin32_t
199
static const uint32_t  K[]=
1 by brian
clean slate
200
{
201
  0x5A827999,
202
  0x6ED9EBA1,
203
  0x8F1BBCDC,
204
  0xCA62C1D6
205
};
206
207
208
static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
209
{
210
  int		t;		   /* Loop counter		  */
205 by Brian Aker
uint32 -> uin32_t
211
  uint32_t	temp;		   /* Temporary word value	  */
212
  uint32_t	W[80];		   /* Word sequence		  */
213
  uint32_t	A, B, C, D, E;	   /* Word buffers		  */
1 by brian
clean slate
214
  int idx;
215
216
  /*
217
    Initialize the first 16 words in the array W
218
  */
219
220
  for (t = 0; t < 16; t++)
221
  {
222
    idx=t*4;
223
    W[t] = context->Message_Block[idx] << 24;
224
    W[t] |= context->Message_Block[idx + 1] << 16;
225
    W[t] |= context->Message_Block[idx + 2] << 8;
226
    W[t] |= context->Message_Block[idx + 3];
227
  }
228
229
230
  for (t = 16; t < 80; t++)
231
  {
232
    W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
233
  }
234
235
  A = context->Intermediate_Hash[0];
236
  B = context->Intermediate_Hash[1];
237
  C = context->Intermediate_Hash[2];
238
  D = context->Intermediate_Hash[3];
239
  E = context->Intermediate_Hash[4];
240
241
  for (t = 0; t < 20; t++)
242
  {
243
    temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
244
    E = D;
245
    D = C;
246
    C = SHA1CircularShift(30,B);
247
    B = A;
248
    A = temp;
249
  }
250
251
  for (t = 20; t < 40; t++)
252
  {
253
    temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
254
    E = D;
255
    D = C;
256
    C = SHA1CircularShift(30,B);
257
    B = A;
258
    A = temp;
259
  }
260
261
  for (t = 40; t < 60; t++)
262
  {
263
    temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] +
264
	   K[2]);
265
    E = D;
266
    D = C;
267
    C = SHA1CircularShift(30,B);
268
    B = A;
269
    A = temp;
270
  }
271
272
  for (t = 60; t < 80; t++)
273
  {
274
    temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
275
    E = D;
276
    D = C;
277
    C = SHA1CircularShift(30,B);
278
    B = A;
279
    A = temp;
280
  }
281
282
  context->Intermediate_Hash[0] += A;
283
  context->Intermediate_Hash[1] += B;
284
  context->Intermediate_Hash[2] += C;
285
  context->Intermediate_Hash[3] += D;
286
  context->Intermediate_Hash[4] += E;
287
288
  context->Message_Block_Index = 0;
289
}
290
291
292
/*
293
  Pad message
294
295
  SYNOPSIS
296
    SHA1PadMessage()
297
    context: [in/out]		The context to pad
298
299
  DESCRIPTION
300
    According to the standard, the message must be padded to an even
301
    512 bits.  The first padding bit must be a '1'. The last 64 bits
302
    represent the length of the original message.  All bits in between
303
    should be 0.  This function will pad the message according to
304
    those rules by filling the Message_Block array accordingly.  It
305
    will also call the ProcessMessageBlock function provided
306
    appropriately. When it returns, it can be assumed that the message
307
    digest has been computed.
308
309
*/
310
311
static void SHA1PadMessage(SHA1_CONTEXT *context)
312
{
313
  /*
314
    Check to see if the current message block is too small to hold
315
    the initial padding bits and length.  If so, we will pad the
316
    block, process it, and then continue padding into a second
317
    block.
318
  */
319
320
  int i=context->Message_Block_Index;
321
322
  if (i > 55)
323
  {
324
    context->Message_Block[i++] = 0x80;
212.6.14 by Mats Kindahl
Removing redundant use of casts in mysys for memcmp(), memcpy(), memset(), and memmove().
325
    memset(&context->Message_Block[i], 0,
326
           sizeof(context->Message_Block[0])*(64-i));
1 by brian
clean slate
327
    context->Message_Block_Index=64;
328
329
    /* This function sets context->Message_Block_Index to zero	*/
330
    SHA1ProcessMessageBlock(context);
331
212.6.14 by Mats Kindahl
Removing redundant use of casts in mysys for memcmp(), memcpy(), memset(), and memmove().
332
    memset(&context->Message_Block[0], 0,
333
           sizeof(context->Message_Block[0])*56);
1 by brian
clean slate
334
    context->Message_Block_Index=56;
335
  }
336
  else
337
  {
338
    context->Message_Block[i++] = 0x80;
212.6.14 by Mats Kindahl
Removing redundant use of casts in mysys for memcmp(), memcpy(), memset(), and memmove().
339
    memset(&context->Message_Block[i], 0,
340
           sizeof(context->Message_Block[0])*(56-i));
1 by brian
clean slate
341
    context->Message_Block_Index=56;
342
  }
343
344
  /*
345
    Store the message length as the last 8 octets
346
  */
347
206 by Brian Aker
Removed final uint dead types.
348
  context->Message_Block[56] = (int8_t) (context->Length >> 56);
349
  context->Message_Block[57] = (int8_t) (context->Length >> 48);
350
  context->Message_Block[58] = (int8_t) (context->Length >> 40);
351
  context->Message_Block[59] = (int8_t) (context->Length >> 32);
352
  context->Message_Block[60] = (int8_t) (context->Length >> 24);
353
  context->Message_Block[61] = (int8_t) (context->Length >> 16);
354
  context->Message_Block[62] = (int8_t) (context->Length >> 8);
355
  context->Message_Block[63] = (int8_t) (context->Length);
1 by brian
clean slate
356
357
  SHA1ProcessMessageBlock(context);
358
}