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