~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2010-07-04 20:02:43 UTC
  • mfrom: (1548.2.40 drizzle_pbms)
  • mto: This revision was merged to the branch mainline in revision 1644.
  • Revision ID: mordred@inaugust.com-20100704200243-2vkq9gi6ysauj2tb
Merge PBMS from Barry.

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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
 
 
62
#include "CSDefs.h"
 
63
#include "CSObject.h"
 
64
 
 
65
#include "CSSha1.h"
 
66
 
 
67
#define SHA1CircularShift(bits,word) (((word) << (bits)) | ((word) >> (32-(bits))))
 
68
 
 
69
void CSSha1::sha1_reset()
 
70
{
 
71
        Length = 0;
 
72
        Message_Block_Index = 0;
 
73
 
 
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;
 
79
 
 
80
        Computed = false;
 
81
 
 
82
}
 
83
 
 
84
//------------------------------
 
85
void CSSha1::sha1_digest(Sha1Digest *digest)
 
86
{
 
87
        if (!Computed) {
 
88
                sha1_pad();             
 
89
                memset(Message_Block, 0, 64);
 
90
                Length = 0;
 
91
                Computed = true;
 
92
        }
 
93
 
 
94
        for (int i = 0; i < SHA1_HASH_SIZE; i++)
 
95
                digest->val[i] = (int8_t)((Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) )));
 
96
}
 
97
 
 
98
//------------------------------
 
99
void CSSha1::sha1_input(const void *data, size_t len)
 
100
{
 
101
        uint8_t *message_array = (u_char *) data;
 
102
        
 
103
        if (!len)
 
104
                return;
 
105
 
 
106
        if (Computed)
 
107
                sha1_reset();
 
108
 
 
109
        while (len--) {
 
110
                Message_Block[Message_Block_Index++]= (*message_array & 0xFF);
 
111
                Length += 8;  /* Length is in bits */
 
112
 
 
113
                if (Message_Block_Index == 64)
 
114
                        sha1_process();
 
115
 
 
116
                message_array++;
 
117
        }
 
118
}
 
119
 
 
120
//------------------------------
 
121
void CSSha1::sha1_pad()
 
122
{
 
123
        /*
 
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
 
127
        block.
 
128
        */
 
129
 
 
130
        int i = Message_Block_Index;
 
131
 
 
132
        if (i > 55) {
 
133
                Message_Block[i++] = 0x80;
 
134
                memset(&Message_Block[i], 0, sizeof(Message_Block[0]) * 64-i);
 
135
                Message_Block_Index=64;
 
136
 
 
137
                /* This function sets Message_Block_Index to zero       */
 
138
                sha1_process();
 
139
 
 
140
                memset(Message_Block, 0, sizeof(Message_Block[0]) * 56);
 
141
                Message_Block_Index=56;
 
142
        } else {
 
143
                Message_Block[i++] = 0x80;
 
144
                memset(&Message_Block[i], 0, sizeof(Message_Block[0])*(56-i));
 
145
                Message_Block_Index=56;
 
146
        }
 
147
 
 
148
        /*
 
149
        Store the message length as the last 8 octets
 
150
        */
 
151
 
 
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);
 
160
 
 
161
        sha1_process();
 
162
}
 
163
 
 
164
//------------------------------
 
165
void CSSha1::sha1_process()
 
166
{
 
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                */
 
172
        int idx;
 
173
 
 
174
        /*
 
175
        Initialize the first 16 words in the array W
 
176
        */
 
177
 
 
178
        for (t = 0; t < 16; t++) {
 
179
                idx=t*4;
 
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];
 
184
        }
 
185
 
 
186
 
 
187
        for (t = 16; t < 80; t++) {
 
188
                W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
 
189
        }
 
190
 
 
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];
 
196
 
 
197
        for (t = 0; t < 20; t++) {
 
198
                temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
 
199
                E = D;
 
200
                D = C;
 
201
                C = SHA1CircularShift(30,B);
 
202
                B = A;
 
203
                A = temp;
 
204
        }
 
205
 
 
206
        for (t = 20; t < 40; t++) {
 
207
                temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
 
208
                E = D;
 
209
                D = C;
 
210
                C = SHA1CircularShift(30,B);
 
211
                B = A;
 
212
                A = temp;
 
213
        }
 
214
 
 
215
        for (t = 40; t < 60; t++) {
 
216
                temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]);
 
217
                E = D;
 
218
                D = C;
 
219
                C = SHA1CircularShift(30,B);
 
220
                B = A;
 
221
                A = temp;
 
222
        }
 
223
 
 
224
        for (t = 60; t < 80; t++) {
 
225
                temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
 
226
                E = D;
 
227
                D = C;
 
228
                C = SHA1CircularShift(30,B);
 
229
                B = A;
 
230
                A = temp;
 
231
        }
 
232
 
 
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;
 
238
 
 
239
        Message_Block_Index = 0;
 
240
}
 
241
 
 
242