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