1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2017 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
make_sha1_digest(char * sha1str,unsigned char * digest)28 PHPAPI 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 */
PHP_FUNCTION(sha1)35 PHP_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 *) ZSTR_VAL(arg), ZSTR_LEN(arg));
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 */
PHP_FUNCTION(sha1_file)65 PHP_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
106 static void SHA1Transform(php_uint32[5], const unsigned char[64]);
107 static void SHA1Encode(unsigned char *, php_uint32 *, unsigned int);
108 static void SHA1Decode(php_uint32 *, const unsigned char *, unsigned int);
109
110 static 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 */
PHP_SHA1Init(PHP_SHA1_CTX * context)160 PHPAPI 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 */
PHP_SHA1Update(PHP_SHA1_CTX * context,const unsigned char * input,size_t inputLen)178 PHPAPI 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 */
PHP_SHA1Final(unsigned char digest[20],PHP_SHA1_CTX * context)219 PHPAPI 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 */
SHA1Transform(state,block)255 static void SHA1Transform(state, block)
256 php_uint32 state[5];
257 const 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 */
SHA1Encode(output,input,len)367 static void SHA1Encode(output, input, len)
368 unsigned char *output;
369 php_uint32 *input;
370 unsigned 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 */
SHA1Decode(output,input,len)387 static void SHA1Decode(output, input, len)
388 php_uint32 *output;
389 const unsigned char *input;
390 unsigned 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