summaryrefslogtreecommitdiff
path: root/sha256.c
diff options
context:
space:
mode:
authorStefan Esser2010-02-21 11:44:54 +0100
committerStefan Esser2010-02-21 11:44:54 +0100
commit36dbfacbe64697d959f524e537b15b73c090d898 (patch)
treef1c7ce1409b0e7765fc72d550546967fcf0f9717 /sha256.c
Inital commit
Diffstat (limited to 'sha256.c')
-rw-r--r--sha256.c432
1 files changed, 432 insertions, 0 deletions
diff --git a/sha256.c b/sha256.c
new file mode 100644
index 0000000..35715e9
--- /dev/null
+++ b/sha256.c
@@ -0,0 +1,432 @@
1/*
2 +----------------------------------------------------------------------+
3 | Suhosin Version 1 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2007 The Hardened-PHP Project |
6 | Copyright (c) 2007 SektionEins GmbH |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
16 | Author: Stefan Esser <sesser@sektioneins.de> |
17 +----------------------------------------------------------------------+
18*/
19
20/* $Id: sha256.c,v 1.1.1.1 2007-11-28 01:15:35 sesser Exp $ */
21
22#include <stdio.h>
23#include "php.h"
24
25/* This code is heavily based on the PHP md5/sha1 implementations */
26
27#include "sha256.h"
28
29static void make_sha256_digest(char *sha256str, unsigned char *digest)
30{
31 int i;
32
33 for (i = 0; i < 32; i++) {
34 sprintf(sha256str, "%02x", digest[i]);
35 sha256str += 2;
36 }
37
38 *sha256str = '\0';
39}
40
41/* {{{ proto string sha256(string str [, bool raw_output])
42 Calculate the sha256 hash of a string */
43static PHP_FUNCTION(suhosin_sha256)
44{
45 char *arg;
46 int arg_len;
47 zend_bool raw_output = 0;
48 char sha256str[65];
49 suhosin_SHA256_CTX context;
50 unsigned char digest[32];
51
52 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
53 return;
54 }
55
56 sha256str[0] = '\0';
57 suhosin_SHA256Init(&context);
58 suhosin_SHA256Update(&context, (unsigned char *)arg, (unsigned int)arg_len);
59 suhosin_SHA256Final(digest, &context);
60 if (raw_output) {
61 RETURN_STRINGL((char *)digest, 32, 1);
62 } else {
63 make_sha256_digest(sha256str, digest);
64 RETVAL_STRING(sha256str, 1);
65 }
66
67}
68
69/* }}} */
70
71/* {{{ proto string sha256_file(string filename [, bool raw_output])
72 Calculate the sha256 hash of given filename */
73static PHP_FUNCTION(suhosin_sha256_file)
74{
75 char *arg;
76 int arg_len;
77 zend_bool raw_output = 0;
78 char sha256str[65];
79 unsigned char buf[1024];
80 unsigned char digest[32];
81 suhosin_SHA256_CTX context;
82 int n;
83 FILE *fp;
84
85 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
86 return;
87 }
88
89 if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
90 RETURN_FALSE;
91 }
92
93 if (php_check_open_basedir(arg TSRMLS_CC)) {
94 RETURN_FALSE;
95 }
96
97 if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
98 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
99 RETURN_FALSE;
100 }
101
102 suhosin_SHA256Init(&context);
103
104 while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
105 suhosin_SHA256Update(&context, buf, n);
106 }
107
108 suhosin_SHA256Final(digest, &context);
109
110 if (ferror(fp)) {
111 fclose(fp);
112 RETURN_FALSE;
113 }
114
115 fclose(fp);
116
117 if (raw_output) {
118 RETURN_STRINGL((char *)digest, 32, 1);
119 } else {
120 make_sha256_digest(sha256str, digest);
121 RETVAL_STRING(sha256str, 1);
122 }
123}
124/* }}} */
125
126
127static void SHA256Transform(php_uint32[8], const unsigned char[64]);
128static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
129static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
130
131static unsigned char PADDING[64] =
132{
133 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
136};
137
138/* F, G, H and I are basic SHA256 functions.
139 */
140#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
141#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
142#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
143#define I(x, y, z) (((x) & (y)) | ((~x) & z))
144
145/* ROTATE_RIGHT rotates x right n bits.
146 */
147#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
148
149/* W[i]
150 */
151#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
152 tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
153 (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
154
155/* ROUND function of sha256
156 */
157
158#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
159 t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
160 (h) = F((a)) + G((a), (b), (c)) + t1; \
161 (d) += t1; \
162 }
163
164
165/* {{{ suhosin_SHA256Init
166 * SHA256 initialization. Begins an SHA256 operation, writing a new context.
167 */
168void suhosin_SHA256Init(suhosin_SHA256_CTX * context)
169{
170 context->count[0] = context->count[1] = 0;
171 /* Load magic initialization constants.
172 */
173 context->state[0] = 0x6a09e667;
174 context->state[1] = 0xbb67ae85;
175 context->state[2] = 0x3c6ef372;
176 context->state[3] = 0xa54ff53a;
177 context->state[4] = 0x510e527f;
178 context->state[5] = 0x9b05688c;
179 context->state[6] = 0x1f83d9ab;
180 context->state[7] = 0x5be0cd19;
181}
182/* }}} */
183
184/* {{{ suhosin_SHA256Update
185 SHA256 block update operation. Continues an SHA256 message-digest
186 operation, processing another message block, and updating the
187 context.
188 */
189void suhosin_SHA256Update(suhosin_SHA256_CTX * context, const unsigned char *input,
190 unsigned int inputLen)
191{
192 unsigned int i, index, partLen;
193
194 /* Compute number of bytes mod 64 */
195 index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
196
197 /* Update number of bits */
198 if ((context->count[0] += ((php_uint32) inputLen << 3))
199 < ((php_uint32) inputLen << 3))
200 context->count[1]++;
201 context->count[1] += ((php_uint32) inputLen >> 29);
202
203 partLen = 64 - index;
204
205 /* Transform as many times as possible.
206 */
207 if (inputLen >= partLen) {
208 memcpy
209 ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
210 SHA256Transform(context->state, context->buffer);
211
212 for (i = partLen; i + 63 < inputLen; i += 64)
213 SHA256Transform(context->state, &input[i]);
214
215 index = 0;
216 } else
217 i = 0;
218
219 /* Buffer remaining input */
220 memcpy
221 ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
222 inputLen - i);
223}
224/* }}} */
225
226/* {{{ suhosin_SHA256Final
227 SHA256 finalization. Ends an SHA256 message-digest operation, writing the
228 the message digest and zeroizing the context.
229 */
230void suhosin_SHA256Final(unsigned char digest[32], suhosin_SHA256_CTX * context)
231{
232 unsigned char bits[8];
233 unsigned int index, padLen;
234
235 /* Save number of bits */
236 bits[7] = context->count[0] & 0xFF;
237 bits[6] = (context->count[0] >> 8) & 0xFF;
238 bits[5] = (context->count[0] >> 16) & 0xFF;
239 bits[4] = (context->count[0] >> 24) & 0xFF;
240 bits[3] = context->count[1] & 0xFF;
241 bits[2] = (context->count[1] >> 8) & 0xFF;
242 bits[1] = (context->count[1] >> 16) & 0xFF;
243 bits[0] = (context->count[1] >> 24) & 0xFF;
244
245 /* Pad out to 56 mod 64.
246 */
247 index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
248 padLen = (index < 56) ? (56 - index) : (120 - index);
249 suhosin_SHA256Update(context, PADDING, padLen);
250
251 /* Append length (before padding) */
252 suhosin_SHA256Update(context, bits, 8);
253
254 /* Store state in digest */
255 SHA256Encode(digest, context->state, 32);
256
257 /* Zeroize sensitive information.
258 */
259 memset((unsigned char*) context, 0, sizeof(*context));
260}
261/* }}} */
262
263/* {{{ SHA256Transform
264 * SHA256 basic transformation. Transforms state based on block.
265 */
266static void SHA256Transform(state, block)
267php_uint32 state[8];
268const unsigned char block[64];
269{
270 php_uint32 a = state[0], b = state[1], c = state[2];
271 php_uint32 d = state[3], e = state[4], f = state[5];
272 php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
273
274 SHA256Decode(x, block, 64);
275
276 ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
277 ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
278 ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
279 ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
280 ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
281 ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
282 ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
283 ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
284 ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
285 ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
286 ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
287 ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
288 ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
289 ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
290 ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
291 ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
292 ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
293 ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
294 ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
295 ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
296 ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
297 ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
298 ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
299 ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
300 ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
301 ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
302 ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
303 ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
304 ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
305 ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
306 ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
307 ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
308 ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
309 ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
310 ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
311 ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
312 ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
313 ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
314 ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
315 ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
316 ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
317 ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
318 ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
319 ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
320 ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
321 ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
322 ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
323 ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
324 ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
325 ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
326 ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
327 ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
328 ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
329 ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
330 ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
331 ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
332 ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
333 ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
334 ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
335 ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
336 ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
337 ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
338 ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
339 ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
340
341 state[0] += a;
342 state[1] += b;
343 state[2] += c;
344 state[3] += d;
345 state[4] += e;
346 state[5] += f;
347 state[6] += g;
348 state[7] += h;
349
350 /* Zeroize sensitive information. */
351 memset((unsigned char*) x, 0, sizeof(x));
352}
353/* }}} */
354
355/* {{{ SHA256Encode
356 Encodes input (php_uint32) into output (unsigned char). Assumes len is
357 a multiple of 4.
358 */
359static void SHA256Encode(output, input, len)
360unsigned char *output;
361php_uint32 *input;
362unsigned int len;
363{
364 unsigned int i, j;
365
366 for (i = 0, j = 0; j < len; i++, j += 4) {
367 output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
368 output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
369 output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
370 output[j + 3] = (unsigned char) (input[i] & 0xff);
371 }
372}
373/* }}} */
374
375/* {{{ SHA256Decode
376 Decodes input (unsigned char) into output (php_uint32). Assumes len is
377 a multiple of 4.
378 */
379static void SHA256Decode(output, input, len)
380php_uint32 *output;
381const unsigned char *input;
382unsigned int len;
383{
384 unsigned int i, j;
385
386 for (i = 0, j = 0; j < len; i++, j += 4)
387 output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
388 (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
389}
390/* }}} */
391
392
393/* {{{ suhosin_sha256_functions[]
394 */
395static function_entry suhosin_sha256_functions[] = {
396 PHP_NAMED_FE(sha256, PHP_FN(suhosin_sha256), NULL)
397 PHP_NAMED_FE(sha256_file, PHP_FN(suhosin_sha256_file), NULL)
398 {NULL, NULL, NULL}
399};
400/* }}} */
401
402
403void suhosin_hook_sha256()
404{
405 TSRMLS_FETCH();
406
407 /* check if we already have sha256 support */
408 if (zend_hash_exists(CG(function_table), "sha256", sizeof("sha256"))) {
409 return;
410 }
411
412 /* add the sha256 functions */
413#ifndef ZEND_ENGINE_2
414 zend_register_functions(suhosin_sha256_functions, NULL, MODULE_PERSISTENT TSRMLS_CC);
415#else
416 zend_register_functions(NULL, suhosin_sha256_functions, NULL, MODULE_PERSISTENT TSRMLS_CC);
417#endif
418
419
420
421
422}
423
424
425/*
426 * Local variables:
427 * tab-width: 4
428 * c-basic-offset: 4
429 * End:
430 * vim600: sw=4 ts=4 fdm=marker
431 * vim<600: sw=4 ts=4
432 */