1
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
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; either version 2 of the License, or
6
(at your option) any later version.
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License
14
along with this program; if not, write to the Free Software
15
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
Original Source from: http://www.faqs.org/rfcs/rfc3174.html
21
This file implements the Secure Hashing Algorithm 1 as
22
defined in FIPS PUB 180-1 published April 17, 1995.
24
The SHA-1, produces a 160-bit message digest for a given data
25
stream. It should take about 2**n steps to find a message with the
26
same digest as a given message and 2**(n/2) to find any two
27
messages with the same digest, when n is the digest size in bits.
28
Therefore, this algorithm can serve as a means of providing a
29
"fingerprint" for a message.
32
SHA-1 is defined in terms of 32-bit "words". This code uses
33
<stdint.h> (included via "sha1.h" to define 32 and 8 bit unsigned
34
integer types. If your C compiler does not support 32 bit unsigned
35
integers, this code is not appropriate.
38
SHA-1 is designed to work with messages less than 2^64 bits long.
39
Although SHA-1 allows a message digest to be generated for messages
40
of any number of bits less than 2^64, this implementation only
41
works with messages with a length that is a multiple of the size of
45
2002 by Peter Zaitsev to
46
- fit to new prototypes according to MySQL standard
48
- All checking is now done in debug only mode
52
#include "my_global.h"
57
Define the SHA1 circular left shift macro
60
#define SHA1CircularShift(bits,word) \
61
(((word) << (bits)) | ((word) >> (32-(bits))))
63
/* Local Function Prototyptes */
64
static void SHA1PadMessage(SHA1_CONTEXT*);
65
static void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
69
Initialize SHA1Context
73
context [in/out] The context to reset.
76
This function will initialize the SHA1Context in preparation
77
for computing a new SHA1 message digest.
81
!= SHA_SUCCESS sha Error Code.
85
const uint32 sha_const_key[5]=
95
int mysql_sha1_reset(SHA1_CONTEXT *context)
103
context->Message_Block_Index = 0;
105
context->Intermediate_Hash[0] = sha_const_key[0];
106
context->Intermediate_Hash[1] = sha_const_key[1];
107
context->Intermediate_Hash[2] = sha_const_key[2];
108
context->Intermediate_Hash[3] = sha_const_key[3];
109
context->Intermediate_Hash[4] = sha_const_key[4];
111
context->Computed = 0;
112
context->Corrupted = 0;
119
Return the 160-bit message digest into the array provided by the caller
123
context [in/out] The context to use to calculate the SHA-1 hash.
124
Message_Digest: [out] Where the digest is returned.
127
NOTE: The first octet of hash is stored in the 0th element,
128
the last octet of hash in the 19th element.
132
!= SHA_SUCCESS sha Error Code.
135
int mysql_sha1_result(SHA1_CONTEXT *context,
136
uint8 Message_Digest[SHA1_HASH_SIZE])
141
if (!context || !Message_Digest)
144
if (context->Corrupted)
145
return context->Corrupted;
148
if (!context->Computed)
150
SHA1PadMessage(context);
151
/* message may be sensitive, clear it out */
152
bzero((char*) context->Message_Block,64);
153
context->Length = 0; /* and clear length */
154
context->Computed = 1;
157
for (i = 0; i < SHA1_HASH_SIZE; i++)
158
Message_Digest[i] = (int8)((context->Intermediate_Hash[i>>2] >> 8
159
* ( 3 - ( i & 0x03 ) )));
165
Accepts an array of octets as the next portion of the message.
169
context [in/out] The SHA context to update
170
message_array An array of characters representing the next portion
172
length The length of the message in message_array
176
!= SHA_SUCCESS sha Error Code.
179
int mysql_sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
186
/* We assume client konows what it is doing in non-debug mode */
187
if (!context || !message_array)
189
if (context->Computed)
190
return (context->Corrupted= SHA_STATE_ERROR);
191
if (context->Corrupted)
192
return context->Corrupted;
197
context->Message_Block[context->Message_Block_Index++]=
198
(*message_array & 0xFF);
199
context->Length += 8; /* Length is in bits */
203
Then we're not debugging we assume we never will get message longer
206
if (context->Length == 0)
207
return (context->Corrupted= 1); /* Message is too long */
210
if (context->Message_Block_Index == 64)
212
SHA1ProcessMessageBlock(context);
221
Process the next 512 bits of the message stored in the Message_Block array.
224
SHA1ProcessMessageBlock()
227
Many of the variable names in this code, especially the single
228
character names, were used because those were the names used in
232
/* Constants defined in SHA-1 */
233
static const uint32 K[]=
242
static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
244
int t; /* Loop counter */
245
uint32 temp; /* Temporary word value */
246
uint32 W[80]; /* Word sequence */
247
uint32 A, B, C, D, E; /* Word buffers */
251
Initialize the first 16 words in the array W
254
for (t = 0; t < 16; t++)
257
W[t] = context->Message_Block[index] << 24;
258
W[t] |= context->Message_Block[index + 1] << 16;
259
W[t] |= context->Message_Block[index + 2] << 8;
260
W[t] |= context->Message_Block[index + 3];
264
for (t = 16; t < 80; t++)
266
W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
269
A = context->Intermediate_Hash[0];
270
B = context->Intermediate_Hash[1];
271
C = context->Intermediate_Hash[2];
272
D = context->Intermediate_Hash[3];
273
E = context->Intermediate_Hash[4];
275
for (t = 0; t < 20; t++)
277
temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
280
C = SHA1CircularShift(30,B);
285
for (t = 20; t < 40; t++)
287
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
290
C = SHA1CircularShift(30,B);
295
for (t = 40; t < 60; t++)
297
temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] +
301
C = SHA1CircularShift(30,B);
306
for (t = 60; t < 80; t++)
308
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
311
C = SHA1CircularShift(30,B);
316
context->Intermediate_Hash[0] += A;
317
context->Intermediate_Hash[1] += B;
318
context->Intermediate_Hash[2] += C;
319
context->Intermediate_Hash[3] += D;
320
context->Intermediate_Hash[4] += E;
322
context->Message_Block_Index = 0;
331
context: [in/out] The context to pad
334
According to the standard, the message must be padded to an even
335
512 bits. The first padding bit must be a '1'. The last 64 bits
336
represent the length of the original message. All bits in between
337
should be 0. This function will pad the message according to
338
those rules by filling the Message_Block array accordingly. It
339
will also call the ProcessMessageBlock function provided
340
appropriately. When it returns, it can be assumed that the message
341
digest has been computed.
345
static void SHA1PadMessage(SHA1_CONTEXT *context)
348
Check to see if the current message block is too small to hold
349
the initial padding bits and length. If so, we will pad the
350
block, process it, and then continue padding into a second
354
int i=context->Message_Block_Index;
358
context->Message_Block[i++] = 0x80;
359
bzero((char*) &context->Message_Block[i],
360
sizeof(context->Message_Block[0])*(64-i));
361
context->Message_Block_Index=64;
363
/* This function sets context->Message_Block_Index to zero */
364
SHA1ProcessMessageBlock(context);
366
bzero((char*) &context->Message_Block[0],
367
sizeof(context->Message_Block[0])*56);
368
context->Message_Block_Index=56;
372
context->Message_Block[i++] = 0x80;
373
bzero((char*) &context->Message_Block[i],
374
sizeof(context->Message_Block[0])*(56-i));
375
context->Message_Block_Index=56;
379
Store the message length as the last 8 octets
382
context->Message_Block[56] = (int8) (context->Length >> 56);
383
context->Message_Block[57] = (int8) (context->Length >> 48);
384
context->Message_Block[58] = (int8) (context->Length >> 40);
385
context->Message_Block[59] = (int8) (context->Length >> 32);
386
context->Message_Block[60] = (int8) (context->Length >> 24);
387
context->Message_Block[61] = (int8) (context->Length >> 16);
388
context->Message_Block[62] = (int8) (context->Length >> 8);
389
context->Message_Block[63] = (int8) (context->Length);
391
SHA1ProcessMessageBlock(context);