From 3b7d690912ad3947cbf3cb842846b2ae09c53b95 Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Tue, 21 Feb 2006 20:37:12 +0000 Subject: [PATCH] Add md2 algo support --- ext/hash/hash.c | 1 + ext/hash/hash_md.c | 98 +++++++++++++++++++++++++++++++++++++++++ ext/hash/package.xml | 2 + ext/hash/php_hash.h | 1 + ext/hash/php_hash_md.h | 12 +++++ ext/hash/tests/md2.phpt | 21 +++++++++ 6 files changed, 135 insertions(+) create mode 100644 ext/hash/tests/md2.phpt diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 21f2f5a13e..a03890e377 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -516,6 +516,7 @@ PHP_MINIT_FUNCTION(hash) zend_hash_init(&php_hash_hashtable, 35, NULL, NULL, 1); + php_hash_register_algo("md2", &php_hash_md2_ops); php_hash_register_algo("md4", &php_hash_md4_ops); php_hash_register_algo("md5", &php_hash_md5_ops); php_hash_register_algo("sha1", &php_hash_sha1_ops); diff --git a/ext/hash/hash_md.c b/ext/hash/hash_md.c index 1ff0eba63a..8c43845cde 100644 --- a/ext/hash/hash_md.c +++ b/ext/hash/hash_md.c @@ -39,6 +39,15 @@ php_hash_ops php_hash_md4_ops = { sizeof(PHP_MD4_CTX) }; +php_hash_ops php_hash_md2_ops = { + (php_hash_init_func_t) PHP_MD2Init, + (php_hash_update_func_t) PHP_MD2Update, + (php_hash_final_func_t) PHP_MD2Final, + 16, + 16, + sizeof(PHP_MD2_CTX) +}; + /* MD common stuff */ static unsigned char PADDING[64] = @@ -579,6 +588,95 @@ PHP_HASH_API void PHP_MD4Final(unsigned char digest[16], PHP_MD4_CTX * context) } /* }}} */ +/* MD2 */ + +static unsigned char MD2_S[256] = { + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 19, + 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76, 130, 202, + 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138, 23, 229, 18, + 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142, 187, 47, 238, 122, + 169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16, 137, 11, 34, 95, 33, + 128, 127, 93, 154, 90, 144, 50, 39, 53, 62, 204, 231, 191, 247, 151, 3, + 255, 25, 48, 179, 72, 165, 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, + 79, 184, 56, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, + 69, 157, 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, + 27, 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38, + 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82, + 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74, + 120, 136, 149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57, + 242, 239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10, + 49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 }; + +PHP_HASH_API void PHP_MD2Init(PHP_MD2_CTX *context) +{ + memset(context, 0, sizeof(PHP_MD2_CTX)); +} + +static void MD2_Transform(PHP_MD2_CTX *context, const unsigned char *block) +{ + unsigned char i,j,t = 0; + + for(i = 0; i < 16; i++) { + context->state[16+i] = block[i]; + context->state[32+i] = (context->state[16+i] ^ context->state[i]); + } + + for(i = 0; i < 18; i++) { + for(j = 0; j < 48; j++) { + t = context->state[j] = context->state[j] ^ MD2_S[t]; + } + t += i; + } + + /* Update checksum -- must be after transform to avoid fouling up last message block */ + t = context->checksum[15]; + for(i = 0; i < 16; i++) { + t = context->checksum[i] ^= MD2_S[block[i] ^ t]; + } +} + +PHP_HASH_API void PHP_MD2Update(PHP_MD2_CTX *context, const unsigned char *buf, unsigned int len) +{ + const unsigned char *p = buf, *e = buf + len; + + if (context->in_buffer) { + if (context->in_buffer + len < 16) { + /* Not enough for block, just pass into buffer */ + memcpy(context->buffer + context->in_buffer, p, len); + context->in_buffer += len; + return; + } + /* Put buffered data together with inbound for a single block */ + memcpy(context->buffer + context->in_buffer, p, 16 - context->in_buffer); + MD2_Transform(context, context->buffer); + p += 16 - context->in_buffer; + context->in_buffer = 0; + } + + /* Process as many whole blocks as remain */ + while ((p + 16) <= e) { + MD2_Transform(context, p); + p += 16; + } + + /* Copy remaining data to buffer */ + if (p < e) { + memcpy(context->buffer, p, e - p); + context->in_buffer = e - p; + } +} + +PHP_HASH_API void PHP_MD2Final(unsigned char output[16], PHP_MD2_CTX *context) +{ + memset(context->buffer + context->in_buffer, 16 - context->in_buffer, 16 - context->in_buffer); + MD2_Transform(context, context->buffer); + MD2_Transform(context, context->checksum); + + memcpy(output, context->state, 16); +} + + /* * Local variables: * tab-width: 4 diff --git a/ext/hash/package.xml b/ext/hash/package.xml index 7aaf7ff027..2ff444a8fa 100644 --- a/ext/hash/package.xml +++ b/ext/hash/package.xml @@ -26,6 +26,7 @@ 2006-02-00 Fixed tiger algorithm generating wrong results on big endian platforms. +Add md2 support @@ -82,6 +83,7 @@ Supported Algorithms: + diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h index 4587f2b518..524b2b7551 100644 --- a/ext/hash/php_hash.h +++ b/ext/hash/php_hash.h @@ -52,6 +52,7 @@ typedef struct _php_hash_data { unsigned char *key; } php_hash_data; +extern php_hash_ops php_hash_md2_ops; extern php_hash_ops php_hash_md4_ops; extern php_hash_ops php_hash_md5_ops; extern php_hash_ops php_hash_sha1_ops; diff --git a/ext/hash/php_hash_md.h b/ext/hash/php_hash_md.h index 30bf6a1602..66a0c88ef5 100644 --- a/ext/hash/php_hash_md.h +++ b/ext/hash/php_hash_md.h @@ -85,4 +85,16 @@ typedef struct { PHP_HASH_API void PHP_MD4Update(PHP_MD4_CTX *context, const unsigned char *, unsigned int); PHP_HASH_API void PHP_MD4Final(unsigned char[16], PHP_MD4_CTX *); +/* MD2 context */ +typedef struct { + unsigned char state[48]; + unsigned char checksum[16]; + unsigned char buffer[16]; + char in_buffer; +} PHP_MD2_CTX; + +PHP_HASH_API void PHP_MD2Init(PHP_MD2_CTX *context); +PHP_HASH_API void PHP_MD2Update(PHP_MD2_CTX *context, const unsigned char *, unsigned int); +PHP_HASH_API void PHP_MD2Final(unsigned char[16], PHP_MD2_CTX *); + #endif diff --git a/ext/hash/tests/md2.phpt b/ext/hash/tests/md2.phpt new file mode 100644 index 0000000000..c98ad34054 --- /dev/null +++ b/ext/hash/tests/md2.phpt @@ -0,0 +1,21 @@ +--TEST-- +md2 algorithm +--SKIPIF-- + +--FILE-- +