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