1/*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2015 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$ */
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
28PHPAPI void make_sha1_digest(char *sha1str, unsigned char *digest)
29{
30 make_digest_ex(sha1str, digest, 20);
31}
32
33/* {{{ proto string sha1(string str [, bool raw_output])
34 Calculate the sha1 hash of a string */
35PHP_FUNCTION(sha1)
36{
37 char *arg;
38 int arg_len;
39 zend_bool raw_output = 0;
40 char sha1str[41];
41 PHP_SHA1_CTX context;
42 unsigned char digest[20];
43
44 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
45 return;
46 }
47
48 sha1str[0] = '\0';
49 PHP_SHA1Init(&context);
50 PHP_SHA1Update(&context, arg, arg_len);
51 PHP_SHA1Final(digest, &context);
52 if (raw_output) {
53 RETURN_STRINGL(digest, 20, 1);
54 } else {
55 make_digest_ex(sha1str, digest, 20);
56 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 */
66PHP_FUNCTION(sha1_file)
67{
68 char *arg;
69 int arg_len;
70 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 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|b", &arg, &arg_len, &raw_output) == FAILURE) {
79 return;
80 }
81
82 stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS, NULL);
83 if (!stream) {
84 RETURN_FALSE;
85 }
86
87 PHP_SHA1Init(&context);
88
89 while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
90 PHP_SHA1Update(&context, buf, n);
91 }
92
93 PHP_SHA1Final(digest, &context);
94
95 php_stream_close(stream);
96
97 if (n<0) {
98 RETURN_FALSE;
99 }
100
101 if (raw_output) {
102 RETURN_STRINGL(digest, 20, 1);
103 } else {
104 make_digest_ex(sha1str, digest, 20);
105 RETVAL_STRING(sha1str, 1);
106 }
107}
108/* }}} */
109
110
111static void SHA1Transform(php_uint32[5], const unsigned char[64]);
112static void SHA1Encode(unsigned char *, php_uint32 *, unsigned int);
113static void SHA1Decode(php_uint32 *, const unsigned char *, unsigned int);
114
115static 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 */
165PHPAPI void PHP_SHA1Init(PHP_SHA1_CTX * context)
166{
167 context->count[0] = context->count[1] = 0;
168 /* Load magic initialization constants.
169 */
170 context->state[0] = 0x67452301;
171 context->state[1] = 0xefcdab89;
172 context->state[2] = 0x98badcfe;
173 context->state[3] = 0x10325476;
174 context->state[4] = 0xc3d2e1f0;
175}
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 */
183PHPAPI void PHP_SHA1Update(PHP_SHA1_CTX * context, const unsigned char *input,
184 unsigned int inputLen)
185{
186 unsigned int i, index, partLen;
187
188 /* Compute number of bytes mod 64 */
189 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
190
191 /* Update number of bits */
192 if ((context->count[0] += ((php_uint32) inputLen << 3))
193 < ((php_uint32) inputLen << 3))
194 context->count[1]++;
195 context->count[1] += ((php_uint32) inputLen >> 29);
196
197 partLen = 64 - index;
198
199 /* Transform as many times as possible.
200 */
201 if (inputLen >= partLen) {
202 memcpy
203 ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
204 SHA1Transform(context->state, context->buffer);
205
206 for (i = partLen; i + 63 < inputLen; i += 64)
207 SHA1Transform(context->state, &input[i]);
208
209 index = 0;
210 } else
211 i = 0;
212
213 /* Buffer remaining input */
214 memcpy
215 ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
216 inputLen - i);
217}
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 */
224PHPAPI void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context)
225{
226 unsigned char bits[8];
227 unsigned int index, padLen;
228
229 /* Save number of bits */
230 bits[7] = context->count[0] & 0xFF;
231 bits[6] = (context->count[0] >> 8) & 0xFF;
232 bits[5] = (context->count[0] >> 16) & 0xFF;
233 bits[4] = (context->count[0] >> 24) & 0xFF;
234 bits[3] = context->count[1] & 0xFF;
235 bits[2] = (context->count[1] >> 8) & 0xFF;
236 bits[1] = (context->count[1] >> 16) & 0xFF;
237 bits[0] = (context->count[1] >> 24) & 0xFF;
238
239 /* Pad out to 56 mod 64.
240 */
241 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
242 padLen = (index < 56) ? (56 - index) : (120 - index);
243 PHP_SHA1Update(context, PADDING, padLen);
244
245 /* Append length (before padding) */
246 PHP_SHA1Update(context, bits, 8);
247
248 /* Store state in digest */
249 SHA1Encode(digest, context->state, 20);
250
251 /* Zeroize sensitive information.
252 */
253 memset((unsigned char*) context, 0, sizeof(*context));
254}
255/* }}} */
256
257/* {{{ SHA1Transform
258 * SHA1 basic transformation. Transforms state based on block.
259 */
260static void SHA1Transform(state, block)
261php_uint32 state[5];
262const unsigned char block[64];
263{
264 php_uint32 a = state[0], b = state[1], c = state[2];
265 php_uint32 d = state[3], e = state[4], x[16], tmp;
266
267 SHA1Decode(x, block, 64);
268
269 /* Round 1 */
270 FF(a, b, c, d, e, x[0]); /* 1 */
271 FF(e, a, b, c, d, x[1]); /* 2 */
272 FF(d, e, a, b, c, x[2]); /* 3 */
273 FF(c, d, e, a, b, x[3]); /* 4 */
274 FF(b, c, d, e, a, x[4]); /* 5 */
275 FF(a, b, c, d, e, x[5]); /* 6 */
276 FF(e, a, b, c, d, x[6]); /* 7 */
277 FF(d, e, a, b, c, x[7]); /* 8 */
278 FF(c, d, e, a, b, x[8]); /* 9 */
279 FF(b, c, d, e, a, x[9]); /* 10 */
280 FF(a, b, c, d, e, x[10]); /* 11 */
281 FF(e, a, b, c, d, x[11]); /* 12 */
282 FF(d, e, a, b, c, x[12]); /* 13 */
283 FF(c, d, e, a, b, x[13]); /* 14 */
284 FF(b, c, d, e, a, x[14]); /* 15 */
285 FF(a, b, c, d, e, x[15]); /* 16 */
286 FF(e, a, b, c, d, W(16)); /* 17 */
287 FF(d, e, a, b, c, W(17)); /* 18 */
288 FF(c, d, e, a, b, W(18)); /* 19 */
289 FF(b, c, d, e, a, W(19)); /* 20 */
290
291 /* Round 2 */
292 GG(a, b, c, d, e, W(20)); /* 21 */
293 GG(e, a, b, c, d, W(21)); /* 22 */
294 GG(d, e, a, b, c, W(22)); /* 23 */
295 GG(c, d, e, a, b, W(23)); /* 24 */
296 GG(b, c, d, e, a, W(24)); /* 25 */
297 GG(a, b, c, d, e, W(25)); /* 26 */
298 GG(e, a, b, c, d, W(26)); /* 27 */
299 GG(d, e, a, b, c, W(27)); /* 28 */
300 GG(c, d, e, a, b, W(28)); /* 29 */
301 GG(b, c, d, e, a, W(29)); /* 30 */
302 GG(a, b, c, d, e, W(30)); /* 31 */
303 GG(e, a, b, c, d, W(31)); /* 32 */
304 GG(d, e, a, b, c, W(32)); /* 33 */
305 GG(c, d, e, a, b, W(33)); /* 34 */
306 GG(b, c, d, e, a, W(34)); /* 35 */
307 GG(a, b, c, d, e, W(35)); /* 36 */
308 GG(e, a, b, c, d, W(36)); /* 37 */
309 GG(d, e, a, b, c, W(37)); /* 38 */
310 GG(c, d, e, a, b, W(38)); /* 39 */
311 GG(b, c, d, e, a, W(39)); /* 40 */
312
313 /* Round 3 */
314 HH(a, b, c, d, e, W(40)); /* 41 */
315 HH(e, a, b, c, d, W(41)); /* 42 */
316 HH(d, e, a, b, c, W(42)); /* 43 */
317 HH(c, d, e, a, b, W(43)); /* 44 */
318 HH(b, c, d, e, a, W(44)); /* 45 */
319 HH(a, b, c, d, e, W(45)); /* 46 */
320 HH(e, a, b, c, d, W(46)); /* 47 */
321 HH(d, e, a, b, c, W(47)); /* 48 */
322 HH(c, d, e, a, b, W(48)); /* 49 */
323 HH(b, c, d, e, a, W(49)); /* 50 */
324 HH(a, b, c, d, e, W(50)); /* 51 */
325 HH(e, a, b, c, d, W(51)); /* 52 */
326 HH(d, e, a, b, c, W(52)); /* 53 */
327 HH(c, d, e, a, b, W(53)); /* 54 */
328 HH(b, c, d, e, a, W(54)); /* 55 */
329 HH(a, b, c, d, e, W(55)); /* 56 */
330 HH(e, a, b, c, d, W(56)); /* 57 */
331 HH(d, e, a, b, c, W(57)); /* 58 */
332 HH(c, d, e, a, b, W(58)); /* 59 */
333 HH(b, c, d, e, a, W(59)); /* 60 */
334
335 /* Round 4 */
336 II(a, b, c, d, e, W(60)); /* 61 */
337 II(e, a, b, c, d, W(61)); /* 62 */
338 II(d, e, a, b, c, W(62)); /* 63 */
339 II(c, d, e, a, b, W(63)); /* 64 */
340 II(b, c, d, e, a, W(64)); /* 65 */
341 II(a, b, c, d, e, W(65)); /* 66 */
342 II(e, a, b, c, d, W(66)); /* 67 */
343 II(d, e, a, b, c, W(67)); /* 68 */
344 II(c, d, e, a, b, W(68)); /* 69 */
345 II(b, c, d, e, a, W(69)); /* 70 */
346 II(a, b, c, d, e, W(70)); /* 71 */
347 II(e, a, b, c, d, W(71)); /* 72 */
348 II(d, e, a, b, c, W(72)); /* 73 */
349 II(c, d, e, a, b, W(73)); /* 74 */
350 II(b, c, d, e, a, W(74)); /* 75 */
351 II(a, b, c, d, e, W(75)); /* 76 */
352 II(e, a, b, c, d, W(76)); /* 77 */
353 II(d, e, a, b, c, W(77)); /* 78 */
354 II(c, d, e, a, b, W(78)); /* 79 */
355 II(b, c, d, e, a, W(79)); /* 80 */
356
357 state[0] += a;
358 state[1] += b;
359 state[2] += c;
360 state[3] += d;
361 state[4] += e;
362
363 /* Zeroize sensitive information. */
364 memset((unsigned char*) x, 0, sizeof(x));
365}
366/* }}} */
367
368/* {{{ SHA1Encode
369 Encodes input (php_uint32) into output (unsigned char). Assumes len is
370 a multiple of 4.
371 */
372static void SHA1Encode(output, input, len)
373unsigned char *output;
374php_uint32 *input;
375unsigned int len;
376{
377 unsigned int i, j;
378
379 for (i = 0, j = 0; j < len; i++, j += 4) {
380 output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
381 output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
382 output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
383 output[j + 3] = (unsigned char) (input[i] & 0xff);
384 }
385}
386/* }}} */
387
388/* {{{ SHA1Decode
389 Decodes input (unsigned char) into output (php_uint32). Assumes len is
390 a multiple of 4.
391 */
392static void SHA1Decode(output, input, len)
393php_uint32 *output;
394const unsigned char *input;
395unsigned int len;
396{
397 unsigned int i, j;
398
399 for (i = 0, j = 0; j < len; i++, j += 4)
400 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}
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 */
413