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