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