xref: /PHP-7.1/ext/standard/sha1.c (revision 588db7ce)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2018 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(uint32_t[5], const unsigned char[64]);
107 static void SHA1Encode(unsigned char *, uint32_t *, unsigned int);
108 static void SHA1Decode(uint32_t *, 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) + (uint32_t)(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) + (uint32_t)(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) + (uint32_t)(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) + (uint32_t)(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] += ((uint32_t) inputLen << 3))
188 		< ((uint32_t) inputLen << 3))
189 		context->count[1]++;
190 	context->count[1] += ((uint32_t) 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 	ZEND_SECURE_ZERO((unsigned char*) context, 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 uint32_t state[5];
257 const unsigned char block[64];
258 {
259 	uint32_t a = state[0], b = state[1], c = state[2];
260 	uint32_t 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 	ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
360 }
361 /* }}} */
362 
363 /* {{{ SHA1Encode
364    Encodes input (uint32_t) 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 uint32_t *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 (uint32_t). Assumes len is
385    a multiple of 4.
386  */
SHA1Decode(output,input,len)387 static void SHA1Decode(output, input, len)
388 uint32_t *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] = ((uint32_t) input[j + 3]) | (((uint32_t) input[j + 2]) << 8) |
396 			(((uint32_t) input[j + 1]) << 16) | (((uint32_t) 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