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 272374 2008-12-31 11:17: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 100 : {
167 100 : context->count[0] = context->count[1] = 0;
168 : /* Load magic initialization constants.
169 : */
170 100 : context->state[0] = 0x67452301;
171 100 : context->state[1] = 0xefcdab89;
172 100 : context->state[2] = 0x98badcfe;
173 100 : context->state[3] = 0x10325476;
174 100 : context->state[4] = 0xc3d2e1f0;
175 100 : }
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 301 : {
186 : unsigned int i, index, partLen;
187 :
188 : /* Compute number of bytes mod 64 */
189 301 : index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
190 :
191 : /* Update number of bits */
192 301 : if ((context->count[0] += ((php_uint32) inputLen << 3))
193 : < ((php_uint32) inputLen << 3))
194 0 : context->count[1]++;
195 301 : context->count[1] += ((php_uint32) inputLen >> 29);
196 :
197 301 : partLen = 64 - index;
198 :
199 : /* Transform as many times as possible.
200 : */
201 301 : if (inputLen >= partLen) {
202 124 : memcpy
203 : ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
204 124 : SHA1Transform(context->state, context->buffer);
205 :
206 15748 : for (i = partLen; i + 63 < inputLen; i += 64)
207 15624 : SHA1Transform(context->state, &input[i]);
208 :
209 124 : index = 0;
210 : } else
211 177 : i = 0;
212 :
213 : /* Buffer remaining input */
214 301 : memcpy
215 : ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
216 : inputLen - i);
217 301 : }
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 100 : {
226 : unsigned char bits[8];
227 : unsigned int index, padLen;
228 :
229 : /* Save number of bits */
230 100 : bits[7] = context->count[0] & 0xFF;
231 100 : bits[6] = (context->count[0] >> 8) & 0xFF;
232 100 : bits[5] = (context->count[0] >> 16) & 0xFF;
233 100 : bits[4] = (context->count[0] >> 24) & 0xFF;
234 100 : bits[3] = context->count[1] & 0xFF;
235 100 : bits[2] = (context->count[1] >> 8) & 0xFF;
236 100 : bits[1] = (context->count[1] >> 16) & 0xFF;
237 100 : bits[0] = (context->count[1] >> 24) & 0xFF;
238 :
239 : /* Pad out to 56 mod 64.
240 : */
241 100 : index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
242 100 : padLen = (index < 56) ? (56 - index) : (120 - index);
243 100 : PHP_SHA1Update(context, PADDING, padLen);
244 :
245 : /* Append length (before padding) */
246 100 : PHP_SHA1Update(context, bits, 8);
247 :
248 : /* Store state in digest */
249 100 : SHA1Encode(digest, context->state, 20);
250 :
251 : /* Zeroize sensitive information.
252 : */
253 100 : memset((unsigned char*) context, 0, sizeof(*context));
254 100 : }
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 15748 : {
264 15748 : php_uint32 a = state[0], b = state[1], c = state[2];
265 15748 : php_uint32 d = state[3], e = state[4], x[16], tmp;
266 :
267 15748 : SHA1Decode(x, block, 64);
268 :
269 : /* Round 1 */
270 15748 : FF(a, b, c, d, e, x[0]); /* 1 */
271 15748 : FF(e, a, b, c, d, x[1]); /* 2 */
272 15748 : FF(d, e, a, b, c, x[2]); /* 3 */
273 15748 : FF(c, d, e, a, b, x[3]); /* 4 */
274 15748 : FF(b, c, d, e, a, x[4]); /* 5 */
275 15748 : FF(a, b, c, d, e, x[5]); /* 6 */
276 15748 : FF(e, a, b, c, d, x[6]); /* 7 */
277 15748 : FF(d, e, a, b, c, x[7]); /* 8 */
278 15748 : FF(c, d, e, a, b, x[8]); /* 9 */
279 15748 : FF(b, c, d, e, a, x[9]); /* 10 */
280 15748 : FF(a, b, c, d, e, x[10]); /* 11 */
281 15748 : FF(e, a, b, c, d, x[11]); /* 12 */
282 15748 : FF(d, e, a, b, c, x[12]); /* 13 */
283 15748 : FF(c, d, e, a, b, x[13]); /* 14 */
284 15748 : FF(b, c, d, e, a, x[14]); /* 15 */
285 15748 : FF(a, b, c, d, e, x[15]); /* 16 */
286 15748 : FF(e, a, b, c, d, W(16)); /* 17 */
287 15748 : FF(d, e, a, b, c, W(17)); /* 18 */
288 15748 : FF(c, d, e, a, b, W(18)); /* 19 */
289 15748 : FF(b, c, d, e, a, W(19)); /* 20 */
290 :
291 : /* Round 2 */
292 15748 : GG(a, b, c, d, e, W(20)); /* 21 */
293 15748 : GG(e, a, b, c, d, W(21)); /* 22 */
294 15748 : GG(d, e, a, b, c, W(22)); /* 23 */
295 15748 : GG(c, d, e, a, b, W(23)); /* 24 */
296 15748 : GG(b, c, d, e, a, W(24)); /* 25 */
297 15748 : GG(a, b, c, d, e, W(25)); /* 26 */
298 15748 : GG(e, a, b, c, d, W(26)); /* 27 */
299 15748 : GG(d, e, a, b, c, W(27)); /* 28 */
300 15748 : GG(c, d, e, a, b, W(28)); /* 29 */
301 15748 : GG(b, c, d, e, a, W(29)); /* 30 */
302 15748 : GG(a, b, c, d, e, W(30)); /* 31 */
303 15748 : GG(e, a, b, c, d, W(31)); /* 32 */
304 15748 : GG(d, e, a, b, c, W(32)); /* 33 */
305 15748 : GG(c, d, e, a, b, W(33)); /* 34 */
306 15748 : GG(b, c, d, e, a, W(34)); /* 35 */
307 15748 : GG(a, b, c, d, e, W(35)); /* 36 */
308 15748 : GG(e, a, b, c, d, W(36)); /* 37 */
309 15748 : GG(d, e, a, b, c, W(37)); /* 38 */
310 15748 : GG(c, d, e, a, b, W(38)); /* 39 */
311 15748 : GG(b, c, d, e, a, W(39)); /* 40 */
312 :
313 : /* Round 3 */
314 15748 : HH(a, b, c, d, e, W(40)); /* 41 */
315 15748 : HH(e, a, b, c, d, W(41)); /* 42 */
316 15748 : HH(d, e, a, b, c, W(42)); /* 43 */
317 15748 : HH(c, d, e, a, b, W(43)); /* 44 */
318 15748 : HH(b, c, d, e, a, W(44)); /* 45 */
319 15748 : HH(a, b, c, d, e, W(45)); /* 46 */
320 15748 : HH(e, a, b, c, d, W(46)); /* 47 */
321 15748 : HH(d, e, a, b, c, W(47)); /* 48 */
322 15748 : HH(c, d, e, a, b, W(48)); /* 49 */
323 15748 : HH(b, c, d, e, a, W(49)); /* 50 */
324 15748 : HH(a, b, c, d, e, W(50)); /* 51 */
325 15748 : HH(e, a, b, c, d, W(51)); /* 52 */
326 15748 : HH(d, e, a, b, c, W(52)); /* 53 */
327 15748 : HH(c, d, e, a, b, W(53)); /* 54 */
328 15748 : HH(b, c, d, e, a, W(54)); /* 55 */
329 15748 : HH(a, b, c, d, e, W(55)); /* 56 */
330 15748 : HH(e, a, b, c, d, W(56)); /* 57 */
331 15748 : HH(d, e, a, b, c, W(57)); /* 58 */
332 15748 : HH(c, d, e, a, b, W(58)); /* 59 */
333 15748 : HH(b, c, d, e, a, W(59)); /* 60 */
334 :
335 : /* Round 4 */
336 15748 : II(a, b, c, d, e, W(60)); /* 61 */
337 15748 : II(e, a, b, c, d, W(61)); /* 62 */
338 15748 : II(d, e, a, b, c, W(62)); /* 63 */
339 15748 : II(c, d, e, a, b, W(63)); /* 64 */
340 15748 : II(b, c, d, e, a, W(64)); /* 65 */
341 15748 : II(a, b, c, d, e, W(65)); /* 66 */
342 15748 : II(e, a, b, c, d, W(66)); /* 67 */
343 15748 : II(d, e, a, b, c, W(67)); /* 68 */
344 15748 : II(c, d, e, a, b, W(68)); /* 69 */
345 15748 : II(b, c, d, e, a, W(69)); /* 70 */
346 15748 : II(a, b, c, d, e, W(70)); /* 71 */
347 15748 : II(e, a, b, c, d, W(71)); /* 72 */
348 15748 : II(d, e, a, b, c, W(72)); /* 73 */
349 15748 : II(c, d, e, a, b, W(73)); /* 74 */
350 15748 : II(b, c, d, e, a, W(74)); /* 75 */
351 15748 : II(a, b, c, d, e, W(75)); /* 76 */
352 15748 : II(e, a, b, c, d, W(76)); /* 77 */
353 15748 : II(d, e, a, b, c, W(77)); /* 78 */
354 15748 : II(c, d, e, a, b, W(78)); /* 79 */
355 15748 : II(b, c, d, e, a, W(79)); /* 80 */
356 :
357 15748 : state[0] += a;
358 15748 : state[1] += b;
359 15748 : state[2] += c;
360 15748 : state[3] += d;
361 15748 : state[4] += e;
362 :
363 : /* Zeroize sensitive information. */
364 15748 : memset((unsigned char*) x, 0, sizeof(x));
365 15748 : }
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 100 : {
377 : unsigned int i, j;
378 :
379 600 : for (i = 0, j = 0; j < len; i++, j += 4) {
380 500 : output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
381 500 : output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
382 500 : output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
383 500 : output[j + 3] = (unsigned char) (input[i] & 0xff);
384 : }
385 100 : }
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 15748 : {
397 : unsigned int i, j;
398 :
399 267716 : for (i = 0, j = 0; j < len; i++, j += 4)
400 251968 : 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 15748 : }
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 : */
|