mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / mysys / sha1.c
blobe5b33a9ad130054dce8631899b800cd4e2be46bb
1 /* Copyright (c) 2002, 2004, 2006 MySQL 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; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 Original Source from: http://www.faqs.org/rfcs/rfc3174.html
20 Copyright (C) The Internet Society (2001). All Rights Reserved.
22 This document and translations of it may be copied and furnished to
23 others, and derivative works that comment on or otherwise explain it
24 or assist in its implementation may be prepared, copied, published
25 and distributed, in whole or in part, without restriction of any
26 kind, provided that the above copyright notice and this paragraph are
27 included on all such copies and derivative works. However, this
28 document itself may not be modified in any way, such as by removing
29 the copyright notice or references to the Internet Society or other
30 Internet organizations, except as needed for the purpose of
31 developing Internet standards in which case the procedures for
32 copyrights defined in the Internet Standards process must be
33 followed, or as required to translate it into languages other than
34 English.
36 The limited permissions granted above are perpetual and will not be
37 revoked by the Internet Society or its successors or assigns.
39 This document and the information contained herein is provided on an
40 "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
41 TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
42 BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
43 HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
44 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
46 Acknowledgement
47 Funding for the RFC Editor function is currently provided by the
48 Internet Society.
50 DESCRIPTION
51 This file implements the Secure Hashing Algorithm 1 as
52 defined in FIPS PUB 180-1 published April 17, 1995.
54 The SHA-1, produces a 160-bit message digest for a given data
55 stream. It should take about 2**n steps to find a message with the
56 same digest as a given message and 2**(n/2) to find any two
57 messages with the same digest, when n is the digest size in bits.
58 Therefore, this algorithm can serve as a means of providing a
59 "fingerprint" for a message.
61 PORTABILITY ISSUES
62 SHA-1 is defined in terms of 32-bit "words". This code uses
63 <stdint.h> (included via "sha1.h" to define 32 and 8 bit unsigned
64 integer types. If your C compiler does not support 32 bit unsigned
65 integers, this code is not appropriate.
67 CAVEATS
68 SHA-1 is designed to work with messages less than 2^64 bits long.
69 Although SHA-1 allows a message digest to be generated for messages
70 of any number of bits less than 2^64, this implementation only
71 works with messages with a length that is a multiple of the size of
72 an 8-bit character.
74 CHANGES
75 2002 by Peter Zaitsev to
76 - fit to new prototypes according to MySQL standard
77 - Some optimizations
78 - All checking is now done in debug only mode
79 - More comments
82 #include "my_global.h"
83 #include "m_string.h"
84 #include "sha1.h"
87 Define the SHA1 circular left shift macro
90 #define SHA1CircularShift(bits,word) \
91 (((word) << (bits)) | ((word) >> (32-(bits))))
93 /* Local Function Prototyptes */
94 static void SHA1PadMessage(SHA1_CONTEXT*);
95 static void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
99 Initialize SHA1Context
101 SYNOPSIS
102 mysql_sha1_reset()
103 context [in/out] The context to reset.
105 DESCRIPTION
106 This function will initialize the SHA1Context in preparation
107 for computing a new SHA1 message digest.
109 RETURN
110 SHA_SUCCESS ok
111 != SHA_SUCCESS sha Error Code.
115 const uint32 sha_const_key[5]=
117 0x67452301,
118 0xEFCDAB89,
119 0x98BADCFE,
120 0x10325476,
121 0xC3D2E1F0
125 int mysql_sha1_reset(SHA1_CONTEXT *context)
127 #ifndef DBUG_OFF
128 if (!context)
129 return SHA_NULL;
130 #endif
132 context->Length = 0;
133 context->Message_Block_Index = 0;
135 context->Intermediate_Hash[0] = sha_const_key[0];
136 context->Intermediate_Hash[1] = sha_const_key[1];
137 context->Intermediate_Hash[2] = sha_const_key[2];
138 context->Intermediate_Hash[3] = sha_const_key[3];
139 context->Intermediate_Hash[4] = sha_const_key[4];
141 context->Computed = 0;
142 context->Corrupted = 0;
144 return SHA_SUCCESS;
149 Return the 160-bit message digest into the array provided by the caller
151 SYNOPSIS
152 mysql_sha1_result()
153 context [in/out] The context to use to calculate the SHA-1 hash.
154 Message_Digest: [out] Where the digest is returned.
156 DESCRIPTION
157 NOTE: The first octet of hash is stored in the 0th element,
158 the last octet of hash in the 19th element.
160 RETURN
161 SHA_SUCCESS ok
162 != SHA_SUCCESS sha Error Code.
165 int mysql_sha1_result(SHA1_CONTEXT *context,
166 uint8 Message_Digest[SHA1_HASH_SIZE])
168 int i;
170 #ifndef DBUG_OFF
171 if (!context || !Message_Digest)
172 return SHA_NULL;
174 if (context->Corrupted)
175 return context->Corrupted;
176 #endif
178 if (!context->Computed)
180 SHA1PadMessage(context);
181 /* message may be sensitive, clear it out */
182 bzero((char*) context->Message_Block,64);
183 context->Length = 0; /* and clear length */
184 context->Computed = 1;
187 for (i = 0; i < SHA1_HASH_SIZE; i++)
188 Message_Digest[i] = (int8)((context->Intermediate_Hash[i>>2] >> 8
189 * ( 3 - ( i & 0x03 ) )));
190 return SHA_SUCCESS;
195 Accepts an array of octets as the next portion of the message.
197 SYNOPSIS
198 mysql_sha1_input()
199 context [in/out] The SHA context to update
200 message_array An array of characters representing the next portion
201 of the message.
202 length The length of the message in message_array
204 RETURN
205 SHA_SUCCESS ok
206 != SHA_SUCCESS sha Error Code.
209 int mysql_sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
210 unsigned length)
212 if (!length)
213 return SHA_SUCCESS;
215 #ifndef DBUG_OFF
216 /* We assume client konows what it is doing in non-debug mode */
217 if (!context || !message_array)
218 return SHA_NULL;
219 if (context->Computed)
220 return (context->Corrupted= SHA_STATE_ERROR);
221 if (context->Corrupted)
222 return context->Corrupted;
223 #endif
225 while (length--)
227 context->Message_Block[context->Message_Block_Index++]=
228 (*message_array & 0xFF);
229 context->Length += 8; /* Length is in bits */
231 #ifndef DBUG_OFF
233 Then we're not debugging we assume we never will get message longer
234 2^64 bits.
236 if (context->Length == 0)
237 return (context->Corrupted= 1); /* Message is too long */
238 #endif
240 if (context->Message_Block_Index == 64)
242 SHA1ProcessMessageBlock(context);
244 message_array++;
246 return SHA_SUCCESS;
251 Process the next 512 bits of the message stored in the Message_Block array.
253 SYNOPSIS
254 SHA1ProcessMessageBlock()
256 DESCRIPTION
257 Many of the variable names in this code, especially the single
258 character names, were used because those were the names used in
259 the publication.
262 /* Constants defined in SHA-1 */
263 static const uint32 K[]=
265 0x5A827999,
266 0x6ED9EBA1,
267 0x8F1BBCDC,
268 0xCA62C1D6
272 static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
274 int t; /* Loop counter */
275 uint32 temp; /* Temporary word value */
276 uint32 W[80]; /* Word sequence */
277 uint32 A, B, C, D, E; /* Word buffers */
278 int idx;
281 Initialize the first 16 words in the array W
284 for (t = 0; t < 16; t++)
286 idx=t*4;
287 W[t] = context->Message_Block[idx] << 24;
288 W[t] |= context->Message_Block[idx + 1] << 16;
289 W[t] |= context->Message_Block[idx + 2] << 8;
290 W[t] |= context->Message_Block[idx + 3];
294 for (t = 16; t < 80; t++)
296 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
299 A = context->Intermediate_Hash[0];
300 B = context->Intermediate_Hash[1];
301 C = context->Intermediate_Hash[2];
302 D = context->Intermediate_Hash[3];
303 E = context->Intermediate_Hash[4];
305 for (t = 0; t < 20; t++)
307 temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
308 E = D;
309 D = C;
310 C = SHA1CircularShift(30,B);
311 B = A;
312 A = temp;
315 for (t = 20; t < 40; t++)
317 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
318 E = D;
319 D = C;
320 C = SHA1CircularShift(30,B);
321 B = A;
322 A = temp;
325 for (t = 40; t < 60; t++)
327 temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] +
328 K[2]);
329 E = D;
330 D = C;
331 C = SHA1CircularShift(30,B);
332 B = A;
333 A = temp;
336 for (t = 60; t < 80; t++)
338 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
339 E = D;
340 D = C;
341 C = SHA1CircularShift(30,B);
342 B = A;
343 A = temp;
346 context->Intermediate_Hash[0] += A;
347 context->Intermediate_Hash[1] += B;
348 context->Intermediate_Hash[2] += C;
349 context->Intermediate_Hash[3] += D;
350 context->Intermediate_Hash[4] += E;
352 context->Message_Block_Index = 0;
357 Pad message
359 SYNOPSIS
360 SHA1PadMessage()
361 context: [in/out] The context to pad
363 DESCRIPTION
364 According to the standard, the message must be padded to an even
365 512 bits. The first padding bit must be a '1'. The last 64 bits
366 represent the length of the original message. All bits in between
367 should be 0. This function will pad the message according to
368 those rules by filling the Message_Block array accordingly. It
369 will also call the ProcessMessageBlock function provided
370 appropriately. When it returns, it can be assumed that the message
371 digest has been computed.
375 static void SHA1PadMessage(SHA1_CONTEXT *context)
378 Check to see if the current message block is too small to hold
379 the initial padding bits and length. If so, we will pad the
380 block, process it, and then continue padding into a second
381 block.
384 int i=context->Message_Block_Index;
386 if (i > 55)
388 context->Message_Block[i++] = 0x80;
389 bzero((char*) &context->Message_Block[i],
390 sizeof(context->Message_Block[0])*(64-i));
391 context->Message_Block_Index=64;
393 /* This function sets context->Message_Block_Index to zero */
394 SHA1ProcessMessageBlock(context);
396 bzero((char*) &context->Message_Block[0],
397 sizeof(context->Message_Block[0])*56);
398 context->Message_Block_Index=56;
400 else
402 context->Message_Block[i++] = 0x80;
403 bzero((char*) &context->Message_Block[i],
404 sizeof(context->Message_Block[0])*(56-i));
405 context->Message_Block_Index=56;
409 Store the message length as the last 8 octets
412 context->Message_Block[56] = (int8) (context->Length >> 56);
413 context->Message_Block[57] = (int8) (context->Length >> 48);
414 context->Message_Block[58] = (int8) (context->Length >> 40);
415 context->Message_Block[59] = (int8) (context->Length >> 32);
416 context->Message_Block[60] = (int8) (context->Length >> 24);
417 context->Message_Block[61] = (int8) (context->Length >> 16);
418 context->Message_Block[62] = (int8) (context->Length >> 8);
419 context->Message_Block[63] = (int8) (context->Length);
421 SHA1ProcessMessageBlock(context);