1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
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.
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.
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
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.
24
Original Source from: http://www.faqs.org/rfcs/rfc3174.html
25
and MySQL mysys/sha1.c build 5.1.24.
28
This file implements the Secure Hashing Algorithm 1 as
29
defined in FIPS PUB 180-1 published April 17, 1995.
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.
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.
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
52
2002 by Peter Zaitsev to
53
- fit to new prototypes according to MySQL standard
55
- All checking is now done in debug only mode
67
#define SHA1CircularShift(bits,word) (((word) << (bits)) | ((word) >> (32-(bits))))
69
void CSSha1::sha1_reset()
72
Message_Block_Index = 0;
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;
84
//------------------------------
85
void CSSha1::sha1_digest(Sha1Digest *digest)
89
memset(Message_Block, 0, 64);
94
for (int i = 0; i < SHA1_HASH_SIZE; i++)
95
digest->val[i] = (int8_t)((Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) )));
98
//------------------------------
99
void CSSha1::sha1_input(const void *data, size_t len)
101
uint8_t *message_array = (u_char *) data;
110
Message_Block[Message_Block_Index++]= (*message_array & 0xFF);
111
Length += 8; /* Length is in bits */
113
if (Message_Block_Index == 64)
120
//------------------------------
121
void CSSha1::sha1_pad()
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
130
int i = Message_Block_Index;
133
Message_Block[i++] = 0x80;
134
memset(&Message_Block[i], 0, sizeof(Message_Block[0]) * 64-i);
135
Message_Block_Index=64;
137
/* This function sets Message_Block_Index to zero */
140
memset(Message_Block, 0, sizeof(Message_Block[0]) * 56);
141
Message_Block_Index=56;
143
Message_Block[i++] = 0x80;
144
memset(&Message_Block[i], 0, sizeof(Message_Block[0])*(56-i));
145
Message_Block_Index=56;
149
Store the message length as the last 8 octets
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);
164
//------------------------------
165
void CSSha1::sha1_process()
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 */
175
Initialize the first 16 words in the array W
178
for (t = 0; t < 16; t++) {
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];
187
for (t = 16; t < 80; t++) {
188
W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
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];
197
for (t = 0; t < 20; t++) {
198
temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
201
C = SHA1CircularShift(30,B);
206
for (t = 20; t < 40; t++) {
207
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
210
C = SHA1CircularShift(30,B);
215
for (t = 40; t < 60; t++) {
216
temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]);
219
C = SHA1CircularShift(30,B);
224
for (t = 60; t < 80; t++) {
225
temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
228
C = SHA1CircularShift(30,B);
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;
239
Message_Block_Index = 0;