~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSSha1.cc

  • Committer: Olaf van der Spek
  • Date: 2011-02-12 18:24:24 UTC
  • mto: (2167.1.2 build) (2172.1.4 build)
  • mto: This revision was merged to the branch mainline in revision 2168.
  • Revision ID: olafvdspek@gmail.com-20110212182424-kgnm9osi7qo97at2
casts

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
 
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
 
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
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>
 
61
#include <stdint.h>
 
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