~ubuntu-branches/ubuntu/hardy/php5/hardy-updates

« back to all changes in this revision

Viewing changes to ext/standard/sha1.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-10-09 03:14:32 UTC
  • Revision ID: james.westby@ubuntu.com-20051009031432-kspik3lobxstafv9
Tags: upstream-5.0.5
ImportĀ upstreamĀ versionĀ 5.0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   +----------------------------------------------------------------------+
 
3
   | PHP Version 5                                                        |
 
4
   +----------------------------------------------------------------------+
 
5
   | Copyright (c) 1997-2004 The PHP Group                                |
 
6
   +----------------------------------------------------------------------+
 
7
   | This source file is subject to version 3.0 of the PHP license,       |
 
8
   | that is bundled with this package in the file LICENSE, and is        |
 
9
   | available through the world-wide-web at the following url:           |
 
10
   | http://www.php.net/license/3_0.txt.                                  |
 
11
   | If you did not receive a copy of the PHP license and are unable to   |
 
12
   | obtain it through the world-wide-web, please send a note to          |
 
13
   | license@php.net so we can mail you a copy immediately.               |
 
14
   +----------------------------------------------------------------------+
 
15
   | Author: Stefan Esser <sesser@php.net>                                |
 
16
   +----------------------------------------------------------------------+
 
17
*/
 
18
 
 
19
/* $Id: sha1.c,v 1.9.2.2 2005/04/16 09:50:13 thetaphi Exp $ */
 
20
 
 
21
#include "php.h"
 
22
 
 
23
/* This code is heavily based on the PHP md5 implementation */ 
 
24
 
 
25
#include "sha1.h"
 
26
 
 
27
PHPAPI void make_sha1_digest(char *sha1str, unsigned char *digest)
 
28
{
 
29
        int i;
 
30
 
 
31
        for (i = 0; i < 20; i++) {
 
32
                sprintf(sha1str, "%02x", digest[i]);
 
33
                sha1str += 2;
 
34
        }
 
35
 
 
36
        *sha1str = '\0';
 
37
}
 
38
 
 
39
/* {{{ proto string sha1(string str [, bool raw_output])
 
40
   Calculate the sha1 hash of a string */
 
41
PHP_FUNCTION(sha1)
 
42
{
 
43
        char *arg;
 
44
        int arg_len;
 
45
        zend_bool raw_output = 0;
 
46
        char sha1str[41];
 
47
        PHP_SHA1_CTX context;
 
48
        unsigned char digest[20];
 
49
        
 
50
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
 
51
                return;
 
52
        }
 
53
 
 
54
        sha1str[0] = '\0';
 
55
        PHP_SHA1Init(&context);
 
56
        PHP_SHA1Update(&context, arg, arg_len);
 
57
        PHP_SHA1Final(digest, &context);
 
58
        if (raw_output) {
 
59
                RETURN_STRINGL(digest, 20, 1);
 
60
        } else {
 
61
                make_sha1_digest(sha1str, digest);
 
62
                RETVAL_STRING(sha1str, 1);
 
63
        }
 
64
 
 
65
}
 
66
 
 
67
/* }}} */
 
68
 
 
69
 
 
70
/* {{{ proto string sha1_file(string filename [, bool raw_output])
 
71
   Calculate the sha1 hash of given filename */
 
72
PHP_FUNCTION(sha1_file)
 
73
{
 
74
        char          *arg;
 
75
        int           arg_len;
 
76
        zend_bool raw_output = 0;
 
77
        char          sha1str[41];
 
78
        unsigned char buf[1024];
 
79
        unsigned char digest[20];
 
80
        PHP_SHA1_CTX   context;
 
81
        int           n;
 
82
        php_stream    *stream;
 
83
 
 
84
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
 
85
                return;
 
86
        }
 
87
        
 
88
        stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
 
89
        if (!stream) {
 
90
                RETURN_FALSE;
 
91
        }
 
92
 
 
93
        PHP_SHA1Init(&context);
 
94
 
 
95
        while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
 
96
                PHP_SHA1Update(&context, buf, n);
 
97
        }
 
98
 
 
99
        PHP_SHA1Final(digest, &context);
 
100
 
 
101
        php_stream_close(stream);
 
102
 
 
103
        if (n<0) {
 
104
                RETURN_FALSE;
 
105
        }
 
106
 
 
107
        if (raw_output) {
 
108
                RETURN_STRINGL(digest, 20, 1);
 
109
        } else {
 
110
                make_sha1_digest(sha1str, digest);
 
111
                RETVAL_STRING(sha1str, 1);
 
112
        }
 
113
}
 
114
/* }}} */
 
115
 
 
116
 
 
117
static void SHA1Transform(php_uint32[5], const unsigned char[64]);
 
118
static void SHA1Encode(unsigned char *, php_uint32 *, unsigned int);
 
119
static void SHA1Decode(php_uint32 *, const unsigned char *, unsigned int);
 
120
 
 
121
static unsigned char PADDING[64] =
 
122
{
 
123
        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
124
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
125
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 
126
};
 
127
 
 
128
/* F, G, H and I are basic SHA1 functions.
 
129
 */
 
130
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
 
131
#define G(x, y, z) ((x) ^ (y) ^ (z))
 
132
#define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
 
133
#define I(x, y, z) ((x) ^ (y) ^ (z))
 
134
 
 
135
/* ROTATE_LEFT rotates x left n bits.
 
136
 */
 
137
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
 
138
 
 
139
/* W[i]
 
140
 */
 
141
#define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
 
142
        (x[i&15]=ROTATE_LEFT(tmp, 1)) )  
 
143
 
 
144
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
 
145
 */
 
146
#define FF(a, b, c, d, e, w) { \
 
147
 (e) += F ((b), (c), (d)) + (w) + (php_uint32)(0x5A827999); \
 
148
 (e) += ROTATE_LEFT ((a), 5); \
 
149
 (b) = ROTATE_LEFT((b), 30); \
 
150
  }
 
151
#define GG(a, b, c, d, e, w) { \
 
152
 (e) += G ((b), (c), (d)) + (w) + (php_uint32)(0x6ED9EBA1); \
 
153
 (e) += ROTATE_LEFT ((a), 5); \
 
154
 (b) = ROTATE_LEFT((b), 30); \
 
155
  }
 
156
#define HH(a, b, c, d, e, w) { \
 
157
 (e) += H ((b), (c), (d)) + (w) + (php_uint32)(0x8F1BBCDC); \
 
158
 (e) += ROTATE_LEFT ((a), 5); \
 
159
 (b) = ROTATE_LEFT((b), 30); \
 
160
  }
 
161
#define II(a, b, c, d, e, w) { \
 
162
 (e) += I ((b), (c), (d)) + (w) + (php_uint32)(0xCA62C1D6); \
 
163
 (e) += ROTATE_LEFT ((a), 5); \
 
164
 (b) = ROTATE_LEFT((b), 30); \
 
165
  }
 
166
                                            
 
167
 
 
168
/* {{{ PHP_SHA1Init
 
169
 * SHA1 initialization. Begins an SHA1 operation, writing a new context.
 
170
 */
 
171
PHPAPI void PHP_SHA1Init(PHP_SHA1_CTX * context)
 
172
{
 
173
        context->count[0] = context->count[1] = 0;
 
174
        /* Load magic initialization constants.
 
175
         */
 
176
        context->state[0] = 0x67452301;
 
177
        context->state[1] = 0xefcdab89;
 
178
        context->state[2] = 0x98badcfe;
 
179
        context->state[3] = 0x10325476;
 
180
        context->state[4] = 0xc3d2e1f0;
 
181
}
 
182
/* }}} */
 
183
 
 
184
/* {{{ PHP_SHA1Update
 
185
   SHA1 block update operation. Continues an SHA1 message-digest
 
186
   operation, processing another message block, and updating the
 
187
   context.
 
188
 */
 
189
PHPAPI void PHP_SHA1Update(PHP_SHA1_CTX * context, const unsigned char *input,
 
190
                           unsigned int inputLen)
 
191
{
 
192
        unsigned int i, index, partLen;
 
193
 
 
194
        /* Compute number of bytes mod 64 */
 
195
        index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
 
196
 
 
197
        /* Update number of bits */
 
198
        if ((context->count[0] += ((php_uint32) inputLen << 3))
 
199
                < ((php_uint32) inputLen << 3))
 
200
                context->count[1]++;
 
201
        context->count[1] += ((php_uint32) inputLen >> 29);
 
202
 
 
203
        partLen = 64 - index;
 
204
 
 
205
        /* Transform as many times as possible.
 
206
         */
 
207
        if (inputLen >= partLen) {
 
208
                memcpy
 
209
                        ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
 
210
                SHA1Transform(context->state, context->buffer);
 
211
 
 
212
                for (i = partLen; i + 63 < inputLen; i += 64)
 
213
                        SHA1Transform(context->state, &input[i]);
 
214
 
 
215
                index = 0;
 
216
        } else
 
217
                i = 0;
 
218
 
 
219
        /* Buffer remaining input */
 
220
        memcpy
 
221
                ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
 
222
                 inputLen - i);
 
223
}
 
224
/* }}} */
 
225
 
 
226
/* {{{ PHP_SHA1Final
 
227
   SHA1 finalization. Ends an SHA1 message-digest operation, writing the
 
228
   the message digest and zeroizing the context.
 
229
 */
 
230
PHPAPI void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context)
 
231
{
 
232
        unsigned char bits[8];
 
233
        unsigned int index, padLen;
 
234
 
 
235
        /* Save number of bits */
 
236
        bits[7] = context->count[0] & 0xFF;
 
237
        bits[6] = (context->count[0] >> 8) & 0xFF;
 
238
        bits[5] = (context->count[0] >> 16) & 0xFF;
 
239
        bits[4] = (context->count[0] >> 24) & 0xFF;
 
240
        bits[3] = context->count[1] & 0xFF;
 
241
        bits[2] = (context->count[1] >> 8) & 0xFF;
 
242
        bits[1] = (context->count[1] >> 16) & 0xFF;
 
243
        bits[0] = (context->count[1] >> 24) & 0xFF;
 
244
        
 
245
        /* Pad out to 56 mod 64.
 
246
         */
 
247
        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
 
248
        padLen = (index < 56) ? (56 - index) : (120 - index);
 
249
        PHP_SHA1Update(context, PADDING, padLen);
 
250
 
 
251
        /* Append length (before padding) */
 
252
        PHP_SHA1Update(context, bits, 8);
 
253
 
 
254
        /* Store state in digest */
 
255
        SHA1Encode(digest, context->state, 20);
 
256
 
 
257
        /* Zeroize sensitive information.
 
258
         */
 
259
        memset((unsigned char*) context, 0, sizeof(*context));
 
260
}
 
261
/* }}} */
 
262
 
 
263
/* {{{ SHA1Transform
 
264
 * SHA1 basic transformation. Transforms state based on block.
 
265
 */
 
266
static void SHA1Transform(state, block)
 
267
php_uint32 state[5];
 
268
const unsigned char block[64];
 
269
{
 
270
        php_uint32 a = state[0], b = state[1], c = state[2];
 
271
        php_uint32 d = state[3], e = state[4], x[16], tmp;
 
272
 
 
273
        SHA1Decode(x, block, 64);
 
274
 
 
275
        /* Round 1 */
 
276
        FF(a, b, c, d, e, x[0]);   /* 1 */
 
277
        FF(e, a, b, c, d, x[1]);   /* 2 */
 
278
        FF(d, e, a, b, c, x[2]);   /* 3 */
 
279
        FF(c, d, e, a, b, x[3]);   /* 4 */
 
280
        FF(b, c, d, e, a, x[4]);   /* 5 */
 
281
        FF(a, b, c, d, e, x[5]);   /* 6 */
 
282
        FF(e, a, b, c, d, x[6]);   /* 7 */
 
283
        FF(d, e, a, b, c, x[7]);   /* 8 */
 
284
        FF(c, d, e, a, b, x[8]);   /* 9 */
 
285
        FF(b, c, d, e, a, x[9]);   /* 10 */
 
286
        FF(a, b, c, d, e, x[10]);  /* 11 */
 
287
        FF(e, a, b, c, d, x[11]);  /* 12 */
 
288
        FF(d, e, a, b, c, x[12]);  /* 13 */
 
289
        FF(c, d, e, a, b, x[13]);  /* 14 */
 
290
        FF(b, c, d, e, a, x[14]);  /* 15 */
 
291
        FF(a, b, c, d, e, x[15]);  /* 16 */
 
292
        FF(e, a, b, c, d, W(16));  /* 17 */
 
293
        FF(d, e, a, b, c, W(17));  /* 18 */
 
294
        FF(c, d, e, a, b, W(18));  /* 19 */
 
295
        FF(b, c, d, e, a, W(19));  /* 20 */
 
296
 
 
297
        /* Round 2 */
 
298
        GG(a, b, c, d, e, W(20));  /* 21 */
 
299
        GG(e, a, b, c, d, W(21));  /* 22 */
 
300
        GG(d, e, a, b, c, W(22));  /* 23 */
 
301
        GG(c, d, e, a, b, W(23));  /* 24 */
 
302
        GG(b, c, d, e, a, W(24));  /* 25 */
 
303
        GG(a, b, c, d, e, W(25));  /* 26 */
 
304
        GG(e, a, b, c, d, W(26));  /* 27 */
 
305
        GG(d, e, a, b, c, W(27));  /* 28 */
 
306
        GG(c, d, e, a, b, W(28));  /* 29 */
 
307
        GG(b, c, d, e, a, W(29));  /* 30 */
 
308
        GG(a, b, c, d, e, W(30));  /* 31 */
 
309
        GG(e, a, b, c, d, W(31));  /* 32 */
 
310
        GG(d, e, a, b, c, W(32));  /* 33 */
 
311
        GG(c, d, e, a, b, W(33));  /* 34 */
 
312
        GG(b, c, d, e, a, W(34));  /* 35 */
 
313
        GG(a, b, c, d, e, W(35));  /* 36 */
 
314
        GG(e, a, b, c, d, W(36));  /* 37 */
 
315
        GG(d, e, a, b, c, W(37));  /* 38 */
 
316
        GG(c, d, e, a, b, W(38));  /* 39 */
 
317
        GG(b, c, d, e, a, W(39));  /* 40 */
 
318
 
 
319
        /* Round 3 */
 
320
        HH(a, b, c, d, e, W(40));  /* 41 */
 
321
        HH(e, a, b, c, d, W(41));  /* 42 */
 
322
        HH(d, e, a, b, c, W(42));  /* 43 */
 
323
        HH(c, d, e, a, b, W(43));  /* 44 */
 
324
        HH(b, c, d, e, a, W(44));  /* 45 */
 
325
        HH(a, b, c, d, e, W(45));  /* 46 */
 
326
        HH(e, a, b, c, d, W(46));  /* 47 */
 
327
        HH(d, e, a, b, c, W(47));  /* 48 */
 
328
        HH(c, d, e, a, b, W(48));  /* 49 */
 
329
        HH(b, c, d, e, a, W(49));  /* 50 */
 
330
        HH(a, b, c, d, e, W(50));  /* 51 */
 
331
        HH(e, a, b, c, d, W(51));  /* 52 */
 
332
        HH(d, e, a, b, c, W(52));  /* 53 */
 
333
        HH(c, d, e, a, b, W(53));  /* 54 */
 
334
        HH(b, c, d, e, a, W(54));  /* 55 */
 
335
        HH(a, b, c, d, e, W(55));  /* 56 */
 
336
        HH(e, a, b, c, d, W(56));  /* 57 */
 
337
        HH(d, e, a, b, c, W(57));  /* 58 */
 
338
        HH(c, d, e, a, b, W(58));  /* 59 */
 
339
        HH(b, c, d, e, a, W(59));  /* 60 */
 
340
 
 
341
        /* Round 4 */
 
342
        II(a, b, c, d, e, W(60));  /* 61 */
 
343
        II(e, a, b, c, d, W(61));  /* 62 */
 
344
        II(d, e, a, b, c, W(62));  /* 63 */
 
345
        II(c, d, e, a, b, W(63));  /* 64 */
 
346
        II(b, c, d, e, a, W(64));  /* 65 */
 
347
        II(a, b, c, d, e, W(65));  /* 66 */
 
348
        II(e, a, b, c, d, W(66));  /* 67 */
 
349
        II(d, e, a, b, c, W(67));  /* 68 */
 
350
        II(c, d, e, a, b, W(68));  /* 69 */
 
351
        II(b, c, d, e, a, W(69));  /* 70 */
 
352
        II(a, b, c, d, e, W(70));  /* 71 */
 
353
        II(e, a, b, c, d, W(71));  /* 72 */
 
354
        II(d, e, a, b, c, W(72));  /* 73 */
 
355
        II(c, d, e, a, b, W(73));  /* 74 */
 
356
        II(b, c, d, e, a, W(74));  /* 75 */
 
357
        II(a, b, c, d, e, W(75));  /* 76 */
 
358
        II(e, a, b, c, d, W(76));  /* 77 */
 
359
        II(d, e, a, b, c, W(77));  /* 78 */
 
360
        II(c, d, e, a, b, W(78));  /* 79 */
 
361
        II(b, c, d, e, a, W(79));  /* 80 */
 
362
 
 
363
        state[0] += a;
 
364
        state[1] += b;
 
365
        state[2] += c;
 
366
        state[3] += d;
 
367
        state[4] += e;
 
368
 
 
369
        /* Zeroize sensitive information. */
 
370
        memset((unsigned char*) x, 0, sizeof(x));
 
371
}
 
372
/* }}} */
 
373
 
 
374
/* {{{ SHA1Encode
 
375
   Encodes input (php_uint32) into output (unsigned char). Assumes len is
 
376
   a multiple of 4.
 
377
 */
 
378
static void SHA1Encode(output, input, len)
 
379
unsigned char *output;
 
380
php_uint32 *input;
 
381
unsigned int len;
 
382
{
 
383
        unsigned int i, j;
 
384
 
 
385
        for (i = 0, j = 0; j < len; i++, j += 4) {
 
386
                output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
 
387
                output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
 
388
                output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
 
389
                output[j + 3] = (unsigned char) (input[i] & 0xff);
 
390
        }
 
391
}
 
392
/* }}} */
 
393
 
 
394
/* {{{ SHA1Decode
 
395
   Decodes input (unsigned char) into output (php_uint32). Assumes len is
 
396
   a multiple of 4.
 
397
 */
 
398
static void SHA1Decode(output, input, len)
 
399
php_uint32 *output;
 
400
const unsigned char *input;
 
401
unsigned int len;
 
402
{
 
403
        unsigned int i, j;
 
404
 
 
405
        for (i = 0, j = 0; j < len; i++, j += 4)
 
406
                output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
 
407
                        (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
 
408
}
 
409
/* }}} */
 
410
 
 
411
/*
 
412
 * Local variables:
 
413
 * tab-width: 4
 
414
 * c-basic-offset: 4
 
415
 * End:
 
416
 * vim600: sw=4 ts=4 fdm=marker
 
417
 * vim<600: sw=4 ts=4
 
418
 */