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