~ubuntu-branches/ubuntu/trusty/mariadb-5.5/trusty-proposed

« back to all changes in this revision

Viewing changes to mysys/sha1.c

  • Committer: Package Import Robot
  • Author(s): Otto Kekäläinen
  • Date: 2013-12-22 10:27:05 UTC
  • Revision ID: package-import@ubuntu.com-20131222102705-mndw7s12mz0szrcn
Tags: upstream-5.5.32
Import upstream version 5.5.32

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2002, 2004, 2006 MySQL AB
 
2
 
 
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.
 
6
 
 
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.
 
11
 
 
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
 
15
*/
 
16
 
 
17
/*
 
18
  Original Source from: http://www.faqs.org/rfcs/rfc3174.html
 
19
 
 
20
  Copyright (C) The Internet Society (2001).  All Rights Reserved.
 
21
 
 
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.
 
35
 
 
36
  The limited permissions granted above are perpetual and will not be
 
37
  revoked by the Internet Society or its successors or assigns.
 
38
 
 
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.
 
45
 
 
46
  Acknowledgement 
 
47
  Funding for the RFC Editor function is currently provided by the 
 
48
  Internet Society. 
 
49
 
 
50
 DESCRIPTION
 
51
  This file implements the Secure Hashing Algorithm 1 as
 
52
  defined in FIPS PUB 180-1 published April 17, 1995.
 
53
 
 
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.
 
60
 
 
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.
 
66
 
 
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.
 
73
 
 
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
 
80
*/
 
81
 
 
82
#include "my_global.h"
 
83
#include "m_string.h"
 
84
#include "sha1.h"
 
85
 
 
86
/*
 
87
  Define the SHA1 circular left shift macro
 
88
*/
 
89
 
 
90
#define SHA1CircularShift(bits,word) \
 
91
                (((word) << (bits)) | ((word) >> (32-(bits))))
 
92
 
 
93
/* Local Function Prototyptes */
 
94
static void SHA1PadMessage(SHA1_CONTEXT*);
 
95
static void SHA1ProcessMessageBlock(SHA1_CONTEXT*);
 
96
 
 
97
 
 
98
/*
 
99
  Initialize SHA1Context
 
100
 
 
101
  SYNOPSIS
 
102
    mysql_sha1_reset()
 
103
    context [in/out]            The context to reset.
 
104
 
 
105
 DESCRIPTION
 
106
   This function will initialize the SHA1Context in preparation
 
107
   for computing a new SHA1 message digest.
 
108
 
 
109
 RETURN
 
110
   SHA_SUCCESS          ok
 
111
   != SHA_SUCCESS       sha Error Code.
 
112
*/
 
113
 
 
114
 
 
115
const uint32 sha_const_key[5]=
 
116
{
 
117
  0x67452301,
 
118
  0xEFCDAB89,
 
119
  0x98BADCFE,
 
120
  0x10325476,
 
121
  0xC3D2E1F0
 
122
};
 
123
 
 
124
 
 
125
int mysql_sha1_reset(SHA1_CONTEXT *context)
 
126
{
 
127
#ifndef DBUG_OFF
 
128
  if (!context)
 
129
    return SHA_NULL;
 
130
#endif
 
131
 
 
132
  context->Length                 = 0;
 
133
  context->Message_Block_Index    = 0;
 
134
 
 
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];
 
140
 
 
141
  context->Computed   = 0;
 
142
  context->Corrupted  = 0;
 
143
 
 
144
  return SHA_SUCCESS;
 
145
}
 
146
 
 
147
 
 
148
/*
 
149
   Return the 160-bit message digest into the array provided by the caller
 
150
 
 
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.
 
155
 
 
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.
 
159
 
 
160
 RETURN
 
161
   SHA_SUCCESS          ok
 
162
   != SHA_SUCCESS       sha Error Code.
 
163
*/
 
164
 
 
165
int mysql_sha1_result(SHA1_CONTEXT *context,
 
166
                      uint8 Message_Digest[SHA1_HASH_SIZE])
 
167
{
 
168
  int i;
 
169
 
 
170
#ifndef DBUG_OFF
 
171
  if (!context || !Message_Digest)
 
172
    return SHA_NULL;
 
173
 
 
174
  if (context->Corrupted)
 
175
    return context->Corrupted;
 
176
#endif
 
177
 
 
178
  if (!context->Computed)
 
179
  {
 
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;
 
185
  }
 
186
 
 
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;
 
191
}
 
192
 
 
193
 
 
194
/*
 
195
  Accepts an array of octets as the next portion of the message.
 
196
 
 
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
 
203
 
 
204
 RETURN
 
205
   SHA_SUCCESS          ok
 
206
   != SHA_SUCCESS       sha Error Code.
 
207
*/
 
208
 
 
209
int mysql_sha1_input(SHA1_CONTEXT *context, const uint8 *message_array,
 
210
                     unsigned length)
 
211
{
 
212
  if (!length)
 
213
    return SHA_SUCCESS;
 
214
 
 
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
 
224
 
 
225
  while (length--)
 
226
  {
 
227
    context->Message_Block[context->Message_Block_Index++]=
 
228
      (*message_array & 0xFF);
 
229
    context->Length  += 8;  /* Length is in bits */
 
230
 
 
231
#ifndef DBUG_OFF
 
232
    /*
 
233
      Then we're not debugging we assume we never will get message longer
 
234
      2^64 bits.
 
235
    */
 
236
    if (context->Length == 0)
 
237
      return (context->Corrupted= 1);      /* Message is too long */
 
238
#endif
 
239
 
 
240
    if (context->Message_Block_Index == 64)
 
241
    {
 
242
      SHA1ProcessMessageBlock(context);
 
243
    }
 
244
    message_array++;
 
245
  }
 
246
  return SHA_SUCCESS;
 
247
}
 
248
 
 
249
 
 
250
/*
 
251
  Process the next 512 bits of the message stored in the Message_Block array.
 
252
 
 
253
  SYNOPSIS
 
254
    SHA1ProcessMessageBlock()
 
255
 
 
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.
 
260
*/
 
261
 
 
262
/* Constants defined in SHA-1   */
 
263
static const uint32  K[]=
 
264
{
 
265
  0x5A827999,
 
266
  0x6ED9EBA1,
 
267
  0x8F1BBCDC,
 
268
  0xCA62C1D6
 
269
};
 
270
 
 
271
 
 
272
static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context)
 
273
{
 
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;
 
279
 
 
280
  /*
 
281
    Initialize the first 16 words in the array W
 
282
  */
 
283
 
 
284
  for (t = 0; t < 16; t++)
 
285
  {
 
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];
 
291
  }
 
292
 
 
293
 
 
294
  for (t = 16; t < 80; t++)
 
295
  {
 
296
    W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
 
297
  }
 
298
 
 
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];
 
304
 
 
305
  for (t = 0; t < 20; t++)
 
306
  {
 
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;
 
313
  }
 
314
 
 
315
  for (t = 20; t < 40; t++)
 
316
  {
 
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;
 
323
  }
 
324
 
 
325
  for (t = 40; t < 60; t++)
 
326
  {
 
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;
 
334
  }
 
335
 
 
336
  for (t = 60; t < 80; t++)
 
337
  {
 
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;
 
344
  }
 
345
 
 
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;
 
351
 
 
352
  context->Message_Block_Index = 0;
 
353
}
 
354
 
 
355
 
 
356
/*
 
357
  Pad message
 
358
 
 
359
  SYNOPSIS
 
360
    SHA1PadMessage()
 
361
    context: [in/out]           The context to pad
 
362
 
 
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.
 
372
 
 
373
*/
 
374
 
 
375
static void SHA1PadMessage(SHA1_CONTEXT *context)
 
376
{
 
377
  /*
 
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.
 
382
  */
 
383
 
 
384
  int i=context->Message_Block_Index;
 
385
 
 
386
  if (i > 55)
 
387
  {
 
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;
 
392
 
 
393
    /* This function sets context->Message_Block_Index to zero  */
 
394
    SHA1ProcessMessageBlock(context);
 
395
 
 
396
    bzero((char*) &context->Message_Block[0],
 
397
          sizeof(context->Message_Block[0])*56);
 
398
    context->Message_Block_Index=56;
 
399
  }
 
400
  else
 
401
  {
 
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;
 
406
  }
 
407
 
 
408
  /*
 
409
    Store the message length as the last 8 octets
 
410
  */
 
411
 
 
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);
 
420
 
 
421
  SHA1ProcessMessageBlock(context);
 
422
}