Skip to content

Commit 9e209e8

Browse files
author
Scott MacVicar
committed
MFB: Add sha224 support.
1 parent 32842a0 commit 9e209e8

File tree

5 files changed

+144
-3
lines changed

5 files changed

+144
-3
lines changed

ext/hash/hash.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,7 @@ PHP_MINIT_FUNCTION(hash)
745745
php_hash_register_algo("md4", &php_hash_md4_ops);
746746
php_hash_register_algo("md5", &php_hash_md5_ops);
747747
php_hash_register_algo("sha1", &php_hash_sha1_ops);
748+
php_hash_register_algo("sha224", &php_hash_sha224_ops);
748749
php_hash_register_algo("sha256", &php_hash_sha256_ops);
749750
php_hash_register_algo("sha384", &php_hash_sha384_ops);
750751
php_hash_register_algo("sha512", &php_hash_sha512_ops);

ext/hash/hash_sha.c

Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const php_hash_ops php_hash_sha1_ops = {
7676
sizeof(PHP_SHA1_CTX)
7777
};
7878

79-
/* sha256 */
79+
/* sha224/sha256 */
8080

8181
const php_hash_ops php_hash_sha256_ops = {
8282
(php_hash_init_func_t) PHP_SHA256Init,
@@ -88,6 +88,16 @@ const php_hash_ops php_hash_sha256_ops = {
8888
sizeof(PHP_SHA256_CTX)
8989
};
9090

91+
const php_hash_ops php_hash_sha224_ops = {
92+
(php_hash_init_func_t) PHP_SHA224Init,
93+
(php_hash_update_func_t) PHP_SHA224Update,
94+
(php_hash_final_func_t) PHP_SHA224Final,
95+
(php_hash_copy_func_t) php_hash_copy,
96+
28,
97+
64,
98+
sizeof(PHP_SHA224_CTX)
99+
};
100+
91101
#define ROTR32(b,x) ((x >> b) | (x << (32 - b)))
92102
#define ROTR64(b,x) ((x >> b) | (x << (64 - b)))
93103
#define SHR(b, x) (x >> b)
@@ -175,6 +185,102 @@ static void SHA256Transform(php_hash_uint32 state[8], const unsigned char block[
175185
}
176186
/* }}} */
177187

188+
/* {{{ PHP_SHA224Init
189+
* SHA224 initialization. Begins an SHA224 operation, writing a new context.
190+
*/
191+
PHP_HASH_API void PHP_SHA224Init(PHP_SHA224_CTX * context)
192+
{
193+
context->count[0] = context->count[1] = 0;
194+
/* Load magic initialization constants.
195+
*/
196+
context->state[0] = 0xc1059ed8;
197+
context->state[1] = 0x367cd507;
198+
context->state[2] = 0x3070dd17;
199+
context->state[3] = 0xf70e5939;
200+
context->state[4] = 0xffc00b31;
201+
context->state[5] = 0x68581511;
202+
context->state[6] = 0x64f98fa7;
203+
context->state[7] = 0xbefa4fa4;
204+
}
205+
/* }}} */
206+
207+
/* {{{ PHP_SHA224Update
208+
SHA224 block update operation. Continues an SHA224 message-digest
209+
operation, processing another message block, and updating the
210+
context.
211+
*/
212+
PHP_HASH_API void PHP_SHA224Update(PHP_SHA224_CTX * context, const unsigned char *input, unsigned int inputLen)
213+
{
214+
unsigned int i, index, partLen;
215+
216+
/* Compute number of bytes mod 64 */
217+
index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
218+
219+
/* Update number of bits */
220+
if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
221+
context->count[1]++;
222+
}
223+
context->count[1] += ((php_hash_uint32) inputLen >> 29);
224+
225+
partLen = 64 - index;
226+
227+
/* Transform as many times as possible.
228+
*/
229+
if (inputLen >= partLen) {
230+
memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
231+
SHA256Transform(context->state, context->buffer);
232+
233+
for (i = partLen; i + 63 < inputLen; i += 64) {
234+
SHA256Transform(context->state, &input[i]);
235+
}
236+
237+
index = 0;
238+
} else {
239+
i = 0;
240+
}
241+
242+
/* Buffer remaining input */
243+
memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
244+
}
245+
/* }}} */
246+
247+
/* {{{ PHP_SHA224Final
248+
SHA224 finalization. Ends an SHA224 message-digest operation, writing the
249+
the message digest and zeroizing the context.
250+
*/
251+
PHP_HASH_API void PHP_SHA224Final(unsigned char digest[28], PHP_SHA224_CTX * context)
252+
{
253+
unsigned char bits[8];
254+
unsigned int index, padLen;
255+
256+
/* Save number of bits */
257+
bits[7] = (unsigned char) (context->count[0] & 0xFF);
258+
bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
259+
bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
260+
bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
261+
bits[3] = (unsigned char) (context->count[1] & 0xFF);
262+
bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
263+
bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
264+
bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
265+
266+
/* Pad out to 56 mod 64.
267+
*/
268+
index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
269+
padLen = (index < 56) ? (56 - index) : (120 - index);
270+
PHP_SHA224Update(context, PADDING, padLen);
271+
272+
/* Append length (before padding) */
273+
PHP_SHA224Update(context, bits, 8);
274+
275+
/* Store state in digest */
276+
SHAEncode32(digest, context->state, 28);
277+
278+
/* Zeroize sensitive information.
279+
*/
280+
memset((unsigned char*) context, 0, sizeof(*context));
281+
}
282+
/* }}} */
283+
178284
/* {{{ PHP_SHA256Update
179285
SHA256 block update operation. Continues an SHA256 message-digest
180286
operation, processing another message block, and updating the
@@ -544,10 +650,10 @@ PHP_HASH_API void PHP_SHA512Update(PHP_SHA512_CTX * context, const unsigned char
544650
/* }}} */
545651

546652
/* {{{ PHP_SHA512Final
547-
SHA512 finalization. Ends an SHA384 message-digest operation, writing the
653+
SHA512 finalization. Ends an SHA512 message-digest operation, writing the
548654
the message digest and zeroizing the context.
549655
*/
550-
PHP_HASH_API void PHP_SHA512Final(unsigned char digest[48], PHP_SHA512_CTX * context)
656+
PHP_HASH_API void PHP_SHA512Final(unsigned char digest[64], PHP_SHA512_CTX * context)
551657
{
552658
unsigned char bits[16];
553659
unsigned int index, padLen;

ext/hash/php_hash.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ extern const php_hash_ops php_hash_md2_ops;
6262
extern const php_hash_ops php_hash_md4_ops;
6363
extern const php_hash_ops php_hash_md5_ops;
6464
extern const php_hash_ops php_hash_sha1_ops;
65+
extern const php_hash_ops php_hash_sha224_ops;
6566
extern const php_hash_ops php_hash_sha256_ops;
6667
extern const php_hash_ops php_hash_sha384_ops;
6768
extern const php_hash_ops php_hash_sha512_ops;

ext/hash/php_hash_sha.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@
2525
#include "ext/standard/sha1.h"
2626
#include "ext/standard/basic_functions.h"
2727

28+
/* SHA224 context. */
29+
typedef struct {
30+
php_hash_uint32 state[8]; /* state */
31+
php_hash_uint32 count[2]; /* number of bits, modulo 2^64 */
32+
unsigned char buffer[64]; /* input buffer */
33+
} PHP_SHA224_CTX;
34+
35+
PHP_HASH_API void PHP_SHA224Init(PHP_SHA224_CTX *);
36+
PHP_HASH_API void PHP_SHA224Update(PHP_SHA224_CTX *, const unsigned char *, unsigned int);
37+
PHP_HASH_API void PHP_SHA224Final(unsigned char[28], PHP_SHA224_CTX *);
38+
2839
/* SHA256 context. */
2940
typedef struct {
3041
php_hash_uint32 state[8]; /* state */

ext/hash/tests/sha224.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
sha224 algorithm
3+
--SKIPIF--
4+
<?php if(!extension_loaded("hash")) print "skip"; ?>
5+
--FILE--
6+
<?php
7+
echo hash('sha224', '') . "\n";
8+
echo hash('sha224', 'a') . "\n";
9+
echo hash('sha224', '012345678901234567890123456789012345678901234567890123456789') . "\n";
10+
11+
/* FIPS-180 Vectors */
12+
echo hash('sha224', 'abc') . "\n";
13+
echo hash('sha224', 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') . "\n";
14+
echo hash('sha224', str_repeat('a', 1000000)) . "\n";
15+
--EXPECT--
16+
d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
17+
abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5
18+
ae5c0d27fe120752911c994718296a3bccc77000aac07b8810714932
19+
23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7
20+
75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525
21+
20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67
22+

0 commit comments

Comments
 (0)