xref: /PHP-8.0/ext/standard/sha1.c (revision 2b5de6f8)
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    | http://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 	zend_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 	zend_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_SHA1Init(PHP_SHA1_CTX * context)155 PHPAPI void PHP_SHA1Init(PHP_SHA1_CTX * context)
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 i, index, partLen;
177 
178 	/* Compute number of bytes mod 64 */
179 	index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
180 
181 	/* Update number of bits */
182 	if ((context->count[0] += ((uint32_t) inputLen << 3))
183 		< ((uint32_t) inputLen << 3))
184 		context->count[1]++;
185 	context->count[1] += ((uint32_t) inputLen >> 29);
186 
187 	partLen = 64 - index;
188 
189 	/* Transform as many times as possible.
190 	 */
191 	if (inputLen >= partLen) {
192 		memcpy
193 			((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
194 		SHA1Transform(context->state, context->buffer);
195 
196 		for (i = partLen; i + 63 < inputLen; i += 64)
197 			SHA1Transform(context->state, &input[i]);
198 
199 		index = 0;
200 	} else
201 		i = 0;
202 
203 	/* Buffer remaining input */
204 	memcpy
205 		((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
206 		 inputLen - i);
207 }
208 /* }}} */
209 
210 /* {{{ PHP_SHA1Final
211    SHA1 finalization. Ends an SHA1 message-digest operation, writing the
212    the message digest and zeroizing the context.
213  */
PHP_SHA1Final(unsigned char digest[20],PHP_SHA1_CTX * context)214 PHPAPI void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context)
215 {
216 	unsigned char bits[8];
217 	unsigned int index, padLen;
218 
219 	/* Save number of bits */
220 	bits[7] = context->count[0] & 0xFF;
221 	bits[6] = (context->count[0] >> 8) & 0xFF;
222 	bits[5] = (context->count[0] >> 16) & 0xFF;
223 	bits[4] = (context->count[0] >> 24) & 0xFF;
224 	bits[3] = context->count[1] & 0xFF;
225 	bits[2] = (context->count[1] >> 8) & 0xFF;
226 	bits[1] = (context->count[1] >> 16) & 0xFF;
227 	bits[0] = (context->count[1] >> 24) & 0xFF;
228 
229 	/* Pad out to 56 mod 64.
230 	 */
231 	index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
232 	padLen = (index < 56) ? (56 - index) : (120 - index);
233 	PHP_SHA1Update(context, PADDING, padLen);
234 
235 	/* Append length (before padding) */
236 	PHP_SHA1Update(context, bits, 8);
237 
238 	/* Store state in digest */
239 	SHA1Encode(digest, context->state, 20);
240 
241 	/* Zeroize sensitive information.
242 	 */
243 	ZEND_SECURE_ZERO((unsigned char*) context, sizeof(*context));
244 }
245 /* }}} */
246 
247 /* {{{ SHA1Transform
248  * SHA1 basic transformation. Transforms state based on block.
249  */
SHA1Transform(state,block)250 static void SHA1Transform(state, block)
251 uint32_t state[5];
252 const unsigned char block[64];
253 {
254 	uint32_t a = state[0], b = state[1], c = state[2];
255 	uint32_t d = state[3], e = state[4], x[16], tmp;
256 
257 	SHA1Decode(x, block, 64);
258 
259 	/* Round 1 */
260 	FF(a, b, c, d, e, x[0]);   /* 1 */
261 	FF(e, a, b, c, d, x[1]);   /* 2 */
262 	FF(d, e, a, b, c, x[2]);   /* 3 */
263 	FF(c, d, e, a, b, x[3]);   /* 4 */
264 	FF(b, c, d, e, a, x[4]);   /* 5 */
265 	FF(a, b, c, d, e, x[5]);   /* 6 */
266 	FF(e, a, b, c, d, x[6]);   /* 7 */
267 	FF(d, e, a, b, c, x[7]);   /* 8 */
268 	FF(c, d, e, a, b, x[8]);   /* 9 */
269 	FF(b, c, d, e, a, x[9]);   /* 10 */
270 	FF(a, b, c, d, e, x[10]);  /* 11 */
271 	FF(e, a, b, c, d, x[11]);  /* 12 */
272 	FF(d, e, a, b, c, x[12]);  /* 13 */
273 	FF(c, d, e, a, b, x[13]);  /* 14 */
274 	FF(b, c, d, e, a, x[14]);  /* 15 */
275 	FF(a, b, c, d, e, x[15]);  /* 16 */
276 	FF(e, a, b, c, d, W(16));  /* 17 */
277 	FF(d, e, a, b, c, W(17));  /* 18 */
278 	FF(c, d, e, a, b, W(18));  /* 19 */
279 	FF(b, c, d, e, a, W(19));  /* 20 */
280 
281 	/* Round 2 */
282 	GG(a, b, c, d, e, W(20));  /* 21 */
283 	GG(e, a, b, c, d, W(21));  /* 22 */
284 	GG(d, e, a, b, c, W(22));  /* 23 */
285 	GG(c, d, e, a, b, W(23));  /* 24 */
286 	GG(b, c, d, e, a, W(24));  /* 25 */
287 	GG(a, b, c, d, e, W(25));  /* 26 */
288 	GG(e, a, b, c, d, W(26));  /* 27 */
289 	GG(d, e, a, b, c, W(27));  /* 28 */
290 	GG(c, d, e, a, b, W(28));  /* 29 */
291 	GG(b, c, d, e, a, W(29));  /* 30 */
292 	GG(a, b, c, d, e, W(30));  /* 31 */
293 	GG(e, a, b, c, d, W(31));  /* 32 */
294 	GG(d, e, a, b, c, W(32));  /* 33 */
295 	GG(c, d, e, a, b, W(33));  /* 34 */
296 	GG(b, c, d, e, a, W(34));  /* 35 */
297 	GG(a, b, c, d, e, W(35));  /* 36 */
298 	GG(e, a, b, c, d, W(36));  /* 37 */
299 	GG(d, e, a, b, c, W(37));  /* 38 */
300 	GG(c, d, e, a, b, W(38));  /* 39 */
301 	GG(b, c, d, e, a, W(39));  /* 40 */
302 
303 	/* Round 3 */
304 	HH(a, b, c, d, e, W(40));  /* 41 */
305 	HH(e, a, b, c, d, W(41));  /* 42 */
306 	HH(d, e, a, b, c, W(42));  /* 43 */
307 	HH(c, d, e, a, b, W(43));  /* 44 */
308 	HH(b, c, d, e, a, W(44));  /* 45 */
309 	HH(a, b, c, d, e, W(45));  /* 46 */
310 	HH(e, a, b, c, d, W(46));  /* 47 */
311 	HH(d, e, a, b, c, W(47));  /* 48 */
312 	HH(c, d, e, a, b, W(48));  /* 49 */
313 	HH(b, c, d, e, a, W(49));  /* 50 */
314 	HH(a, b, c, d, e, W(50));  /* 51 */
315 	HH(e, a, b, c, d, W(51));  /* 52 */
316 	HH(d, e, a, b, c, W(52));  /* 53 */
317 	HH(c, d, e, a, b, W(53));  /* 54 */
318 	HH(b, c, d, e, a, W(54));  /* 55 */
319 	HH(a, b, c, d, e, W(55));  /* 56 */
320 	HH(e, a, b, c, d, W(56));  /* 57 */
321 	HH(d, e, a, b, c, W(57));  /* 58 */
322 	HH(c, d, e, a, b, W(58));  /* 59 */
323 	HH(b, c, d, e, a, W(59));  /* 60 */
324 
325 	/* Round 4 */
326 	II(a, b, c, d, e, W(60));  /* 61 */
327 	II(e, a, b, c, d, W(61));  /* 62 */
328 	II(d, e, a, b, c, W(62));  /* 63 */
329 	II(c, d, e, a, b, W(63));  /* 64 */
330 	II(b, c, d, e, a, W(64));  /* 65 */
331 	II(a, b, c, d, e, W(65));  /* 66 */
332 	II(e, a, b, c, d, W(66));  /* 67 */
333 	II(d, e, a, b, c, W(67));  /* 68 */
334 	II(c, d, e, a, b, W(68));  /* 69 */
335 	II(b, c, d, e, a, W(69));  /* 70 */
336 	II(a, b, c, d, e, W(70));  /* 71 */
337 	II(e, a, b, c, d, W(71));  /* 72 */
338 	II(d, e, a, b, c, W(72));  /* 73 */
339 	II(c, d, e, a, b, W(73));  /* 74 */
340 	II(b, c, d, e, a, W(74));  /* 75 */
341 	II(a, b, c, d, e, W(75));  /* 76 */
342 	II(e, a, b, c, d, W(76));  /* 77 */
343 	II(d, e, a, b, c, W(77));  /* 78 */
344 	II(c, d, e, a, b, W(78));  /* 79 */
345 	II(b, c, d, e, a, W(79));  /* 80 */
346 
347 	state[0] += a;
348 	state[1] += b;
349 	state[2] += c;
350 	state[3] += d;
351 	state[4] += e;
352 
353 	/* Zeroize sensitive information. */
354 	ZEND_SECURE_ZERO((unsigned char*) x, sizeof(x));
355 }
356 /* }}} */
357 
358 /* {{{ SHA1Encode
359    Encodes input (uint32_t) into output (unsigned char). Assumes len is
360    a multiple of 4.
361  */
SHA1Encode(output,input,len)362 static void SHA1Encode(output, input, len)
363 unsigned char *output;
364 uint32_t *input;
365 unsigned int len;
366 {
367 	unsigned int i, j;
368 
369 	for (i = 0, j = 0; j < len; i++, j += 4) {
370 		output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
371 		output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
372 		output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
373 		output[j + 3] = (unsigned char) (input[i] & 0xff);
374 	}
375 }
376 /* }}} */
377 
378 /* {{{ SHA1Decode
379    Decodes input (unsigned char) into output (uint32_t). Assumes len is
380    a multiple of 4.
381  */
SHA1Decode(output,input,len)382 static void SHA1Decode(output, input, len)
383 uint32_t *output;
384 const unsigned char *input;
385 unsigned int len;
386 {
387 	unsigned int i, j;
388 
389 	for (i = 0, j = 0; j < len; i++, j += 4)
390 		output[i] = ((uint32_t) input[j + 3]) | (((uint32_t) input[j + 2]) << 8) |
391 			(((uint32_t) input[j + 1]) << 16) | (((uint32_t) input[j]) << 24);
392 }
393 /* }}} */
394