~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Mark Atwood
  • Date: 2011-12-20 02:32:53 UTC
  • mfrom: (2469.1.1 drizzle-build)
  • Revision ID: me@mark.atwood.name-20111220023253-bvu0kr14kwsdvz7g
mergeĀ lp:~brianaker/drizzle/deprecate-pbms

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