Back to index

php5  5.3.10
hash_haval.c
Go to the documentation of this file.
00001 /*
00002   +----------------------------------------------------------------------+
00003   | PHP Version 5                                                        |
00004   +----------------------------------------------------------------------+
00005   | Copyright (c) 1997-2012 The PHP Group                                |
00006   +----------------------------------------------------------------------+
00007   | This source file is subject to version 3.01 of the PHP license,      |
00008   | that is bundled with this package in the file LICENSE, and is        |
00009   | available through the world-wide-web at the following url:           |
00010   | http://www.php.net/license/3_01.txt                                  |
00011   | If you did not receive a copy of the PHP license and are unable to   |
00012   | obtain it through the world-wide-web, please send a note to          |
00013   | license@php.net so we can mail you a copy immediately.               |
00014   +----------------------------------------------------------------------+
00015   | Author: Sara Golemon <pollita@php.net>                               |
00016   +----------------------------------------------------------------------+
00017 */
00018 
00019 /* $Id: hash_haval.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #include "php_hash.h"
00022 #include "php_hash_haval.h"
00023 
00024 static const unsigned char PADDING[128] ={
00025        1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00026        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00027        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00028        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00029        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00030        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00031        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00032        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
00033 
00034 static const php_hash_uint32 D0[8] = {
00035        0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89 };
00036 
00037 static const php_hash_uint32 K2[32] = {
00038        0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
00039        0x9216D5D9, 0x8979FB1B, 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96,
00040        0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69,
00041        0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5 };
00042 
00043 static const php_hash_uint32 K3[32] = {
00044        0x9C30D539, 0x2AF26013, 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E,
00045        0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, 0xE65525F3, 0xAA55AB94,
00046        0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993,
00047        0xB3EE1411, 0x636FBC2A, 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C };
00048 
00049 static const php_hash_uint32 K4[32] = {
00050        0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991,
00051        0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5,
00052        0x0F6D6FF3, 0x83F44239, 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A,
00053        0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4 };
00054 
00055 static const php_hash_uint32 K5[32] = {
00056        0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4,
00057        0x7D84A5C3, 0x3B8B5EBE, 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706,
00058        0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, 0x075372C9, 0x80991B7B,
00059        0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4 };
00060 
00061 static const short I2[32] = {       5, 14, 26, 18, 11, 28,  7, 16,  0, 23, 20, 22,  1, 10,  4,  8,
00062                                           30,  3, 21,  9, 17, 24, 29,  6, 19, 12, 15, 13,  2, 25, 31, 27 };
00063 
00064 static const short I3[32] = {      19,  9,  4, 20, 28, 17,  8, 22, 29, 14, 25, 12, 24, 30, 16, 26,
00065                                           31, 15,  7,  3,  1,  0, 18, 27, 13,  6, 21, 10, 23, 11,  5,  2 };
00066 
00067 static const short I4[32] = {      24,  4,  0, 14,  2,  7, 28, 23, 26,  6, 30, 20, 18, 25, 19,  3,
00068                                           22, 11, 31, 21,  8, 27, 12,  9,  1, 29,  5, 15, 17, 10, 16, 13 };
00069 
00070 static const short I5[32] = {      27,  3, 21, 26, 17, 11, 20, 29, 19,  0, 12,  7, 13,  8, 31, 10,
00071                                            5,  9, 14, 30, 18,  6, 28, 24,  2, 23, 16, 22,  4,  1, 25, 15 };
00072 
00073 static const short M0[32] = {      0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1,
00074                                           0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1 };
00075 
00076 static const short M1[32] = {      1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2,
00077                                           1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2 };
00078 
00079 static const short M2[32] = {      2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3,
00080                                           2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3 };
00081 
00082 static const short M3[32] = {      3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4,
00083                                           3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4 };
00084 
00085 static const short M4[32] = {      4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5,
00086                                           4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5 };
00087 
00088 static const short M5[32] = {      5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6,
00089                                           5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6 };
00090 
00091 static const short M6[32] = {      6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7,
00092                                           6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 7 };
00093 
00094 static const short M7[32] = {      7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0,
00095                                           7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0 };
00096 
00097 /* {{{ Encode
00098    Encodes input (php_hash_uint32) into output (unsigned char). Assumes len is
00099    a multiple of 4.
00100  */
00101 static void Encode(unsigned char *output, php_hash_uint32 *input, unsigned int len)
00102 {
00103        unsigned int i, j;
00104 
00105        for (i = 0, j = 0; j < len; i++, j += 4) {
00106               output[j] = (unsigned char) (input[i] & 0xff);
00107               output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
00108               output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
00109               output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
00110        }
00111 }
00112 /* }}} */
00113 
00114 /* {{{ Decode
00115    Decodes input (unsigned char) into output (php_hash_uint32). Assumes len is
00116    a multiple of 4.
00117  */
00118 static void Decode(php_hash_uint32 *output, const unsigned char *input, unsigned int len)
00119 {
00120        unsigned int i, j;
00121 
00122        for (i = 0, j = 0; j < len; i++, j += 4) {
00123               output[i] = ((php_hash_uint32) input[j]) | (((php_hash_uint32) input[j + 1]) << 8) |
00124                      (((php_hash_uint32) input[j + 2]) << 16) | (((php_hash_uint32) input[j + 3]) << 24);
00125        }
00126 }
00127 /* }}} */
00128 
00129 #define F1(x6,x5,x4,x3,x2,x1,x0)   ( ((x1) & (x4)) ^ ((x2) & (x5)) ^ ((x3) & (x6)) ^ ((x0) & (x1)) ^ (x0) )
00130 #define F2(x6,x5,x4,x3,x2,x1,x0)   ( ((x1) & (x2) & (x3)) ^ ((x2) & (x4) & (x5)) ^ ((x1) & (x2)) ^ ((x1) & (x4)) ^ \
00131                                                                  ((x2) & (x6)) ^ ((x3) & (x5)) ^ ((x4) & (x5)) ^ ((x0) & (x2)) ^ (x0) )
00132 #define F3(x6,x5,x4,x3,x2,x1,x0)   ( ((x1) & (x2) & (x3)) ^ ((x1) & (x4)) ^ ((x2) & (x5)) ^ ((x3) & (x6)) ^ ((x0) & (x3)) ^ (x0) )
00133 #define F4(x6,x5,x4,x3,x2,x1,x0)   ( ((x1) & (x2) & (x3)) ^ ((x2) & (x4) & (x5)) ^ ((x3) & (x4) & (x6)) ^ \
00134                                                                  ((x1) & (x4)) ^ ((x2) & (x6)) ^ ((x3) & (x4)) ^ ((x3) & (x5)) ^ \
00135                                                                  ((x3) & (x6)) ^ ((x4) & (x5)) ^ ((x4) & (x6)) ^ ((x0) & (x4)) ^ (x0) )
00136 #define F5(x6,x5,x4,x3,x2,x1,x0)   ( ((x1) & (x4)) ^ ((x2) & (x5)) ^ ((x3) & (x6)) ^ \
00137                                                                  ((x0) & (x1) & (x2) & (x3)) ^ ((x0) & (x5)) ^ (x0) )
00138 
00139 #define ROTR(x,n)    (((x) >> (n)) | ((x) << (32 - (n))))
00140 
00141 
00142 /* {{{ PHP_3HAVALTransform
00143  */
00144 static void PHP_3HAVALTransform(php_hash_uint32 state[8], const unsigned char block[128])
00145 {
00146        php_hash_uint32 E[8];
00147        php_hash_uint32 x[32];
00148        int i;
00149 
00150        Decode(x, block, 128);
00151 
00152        for(i = 0; i < 8; i++) {
00153               E[i] = state[i];
00154        }
00155 
00156        for(i = 0; i < 32; i++) {
00157               E[7 - (i % 8)] = ROTR(F1(E[M1[i]],E[M0[i]],E[M3[i]],E[M5[i]],E[M6[i]],E[M2[i]],E[M4[i]]),7) + ROTR(E[M7[i]],11) + x[i];
00158        }
00159        for(i = 0; i < 32; i++) {
00160               E[7 - (i % 8)] = ROTR(F2(E[M4[i]],E[M2[i]],E[M1[i]],E[M0[i]],E[M5[i]],E[M3[i]],E[M6[i]]),7) + ROTR(E[M7[i]],11) + x[I2[i]] + K2[i];
00161        }
00162        for(i = 0; i < 32; i++) {
00163               E[7 - (i % 8)] = ROTR(F3(E[M6[i]],E[M1[i]],E[M2[i]],E[M3[i]],E[M4[i]],E[M5[i]],E[M0[i]]),7) + ROTR(E[M7[i]],11) + x[I3[i]] + K3[i];
00164        }
00165 
00166        /* Update digest */
00167        for(i = 0; i < 8; i++) {
00168               state[i] += E[i];
00169        }
00170 
00171        /* Zeroize sensitive information. */
00172        memset((unsigned char*) x, 0, sizeof(x));
00173 }
00174 /* }}} */
00175 
00176 /* {{{ PHP_4HAVALTransform
00177  */
00178 static void PHP_4HAVALTransform(php_hash_uint32 state[8], const unsigned char block[128])
00179 {
00180        php_hash_uint32 E[8];
00181        php_hash_uint32 x[32];
00182        int i;
00183 
00184        Decode(x, block, 128);
00185 
00186        for(i = 0; i < 8; i++) {
00187               E[i] = state[i];
00188        }
00189 
00190        for(i = 0; i < 32; i++) {
00191               E[7 - (i % 8)] = ROTR(F1(E[M2[i]],E[M6[i]],E[M1[i]],E[M4[i]],E[M5[i]],E[M3[i]],E[M0[i]]),7) + ROTR(E[M7[i]],11) + x[i];
00192        }
00193        for(i = 0; i < 32; i++) {
00194               E[7 - (i % 8)] = ROTR(F2(E[M3[i]],E[M5[i]],E[M2[i]],E[M0[i]],E[M1[i]],E[M6[i]],E[M4[i]]),7) + ROTR(E[M7[i]],11) + x[I2[i]] + K2[i];
00195        }
00196        for(i = 0; i < 32; i++) {
00197               E[7 - (i % 8)] = ROTR(F3(E[M1[i]],E[M4[i]],E[M3[i]],E[M6[i]],E[M0[i]],E[M2[i]],E[M5[i]]),7) + ROTR(E[M7[i]],11) + x[I3[i]] + K3[i];
00198        }
00199        for(i = 0; i < 32; i++) {
00200               E[7 - (i % 8)] = ROTR(F4(E[M6[i]],E[M4[i]],E[M0[i]],E[M5[i]],E[M2[i]],E[M1[i]],E[M3[i]]),7) + ROTR(E[M7[i]],11) + x[I4[i]] + K4[i];
00201        }
00202 
00203        /* Update digest */
00204        for(i = 0; i < 8; i++) {
00205               state[i] += E[i];
00206        }
00207 
00208        /* Zeroize sensitive information. */
00209        memset((unsigned char*) x, 0, sizeof(x));
00210 }
00211 /* }}} */
00212 
00213 /* {{{ PHP_5HAVALTransform
00214  */
00215 static void PHP_5HAVALTransform(php_hash_uint32 state[8], const unsigned char block[128])
00216 {
00217        php_hash_uint32 E[8];
00218        php_hash_uint32 x[32];
00219        int i;
00220 
00221        Decode(x, block, 128);
00222 
00223        for(i = 0; i < 8; i++) {
00224               E[i] = state[i];
00225        }
00226        for(i = 0; i < 32; i++) {
00227               E[7 - (i % 8)] = ROTR(F1(E[M3[i]],E[M4[i]],E[M1[i]],E[M0[i]],E[M5[i]],E[M2[i]],E[M6[i]]),7) + ROTR(E[M7[i]],11) + x[i];
00228        }
00229        for(i = 0; i < 32; i++) {
00230               E[7 - (i % 8)] = ROTR(F2(E[M6[i]],E[M2[i]],E[M1[i]],E[M0[i]],E[M3[i]],E[M4[i]],E[M5[i]]),7) + ROTR(E[M7[i]],11) + x[I2[i]] + K2[i];
00231        }
00232        for(i = 0; i < 32; i++) {
00233               E[7 - (i % 8)] = ROTR(F3(E[M2[i]],E[M6[i]],E[M0[i]],E[M4[i]],E[M3[i]],E[M1[i]],E[M5[i]]),7) + ROTR(E[M7[i]],11) + x[I3[i]] + K3[i];
00234        }
00235        for(i = 0; i < 32; i++) {
00236               E[7 - (i % 8)] = ROTR(F4(E[M1[i]],E[M5[i]],E[M3[i]],E[M2[i]],E[M0[i]],E[M4[i]],E[M6[i]]),7) + ROTR(E[M7[i]],11) + x[I4[i]] + K4[i];
00237        }
00238        for(i = 0; i < 32; i++) {
00239               E[7 - (i % 8)] = ROTR(F5(E[M2[i]],E[M5[i]],E[M0[i]],E[M6[i]],E[M4[i]],E[M3[i]],E[M1[i]]),7) + ROTR(E[M7[i]],11) + x[I5[i]] + K5[i];
00240        }
00241 
00242        /* Update digest */
00243        for(i = 0; i < 8; i++) {
00244               state[i] += E[i];
00245        }
00246 
00247        /* Zeroize sensitive information. */
00248        memset((unsigned char*) x, 0, sizeof(x));
00249 }
00250 /* }}} */
00251 
00252 #define PHP_HASH_HAVAL_INIT(p,b) \
00253 const php_hash_ops php_hash_##p##haval##b##_ops = { \
00254        (php_hash_init_func_t) PHP_##p##HAVAL##b##Init, \
00255        (php_hash_update_func_t) PHP_HAVALUpdate, \
00256        (php_hash_final_func_t) PHP_HAVAL##b##Final, \
00257        (php_hash_copy_func_t) php_hash_copy, \
00258        ((b) / 8), 128, sizeof(PHP_HAVAL_CTX) }; \
00259 PHP_HASH_API void PHP_##p##HAVAL##b##Init(PHP_HAVAL_CTX *context) \
00260 {      int i; context->count[0] =  context->count[1] =  0; \
00261        for(i = 0; i < 8; i++) context->state[i] = D0[i]; \
00262        context->passes = p; context->output = b; \
00263        context->Transform = PHP_##p##HAVALTransform; }
00264 
00265 PHP_HASH_HAVAL_INIT(3,128)
00266 PHP_HASH_HAVAL_INIT(3,160)
00267 PHP_HASH_HAVAL_INIT(3,192)
00268 PHP_HASH_HAVAL_INIT(3,224)
00269 PHP_HASH_HAVAL_INIT(3,256)
00270 
00271 PHP_HASH_HAVAL_INIT(4,128)
00272 PHP_HASH_HAVAL_INIT(4,160)
00273 PHP_HASH_HAVAL_INIT(4,192)
00274 PHP_HASH_HAVAL_INIT(4,224)
00275 PHP_HASH_HAVAL_INIT(4,256)
00276 
00277 PHP_HASH_HAVAL_INIT(5,128)
00278 PHP_HASH_HAVAL_INIT(5,160)
00279 PHP_HASH_HAVAL_INIT(5,192)
00280 PHP_HASH_HAVAL_INIT(5,224)
00281 PHP_HASH_HAVAL_INIT(5,256)
00282 
00283 /* {{{ PHP_HAVALUpdate
00284  */
00285 PHP_HASH_API void PHP_HAVALUpdate(PHP_HAVAL_CTX *context, const unsigned char *input, unsigned int inputLen)
00286 {
00287        unsigned int i, index, partLen;
00288 
00289        /* Compute number of bytes mod 128 */
00290        index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
00291        /* Update number of bits */
00292        if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
00293               context->count[1]++;
00294        }
00295        context->count[1] += ((php_hash_uint32) inputLen >> 29);
00296 
00297        partLen = 128 - index;
00298 
00299        /* Transform as many times as possible.
00300         */
00301        if (inputLen >= partLen) {
00302               memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
00303               context->Transform(context->state, context->buffer);
00304 
00305               for (i = partLen; i + 127 < inputLen; i += 128) {
00306                      context->Transform(context->state, &input[i]);
00307               }
00308 
00309               index = 0;
00310        } else {
00311               i = 0;
00312        }
00313 
00314        /* Buffer remaining input */
00315        memcpy((unsigned char*) &context->buffer[index], (unsigned char*) &input[i], inputLen - i);
00316 }
00317 /* }}} */
00318 
00319 #define PHP_HASH_HAVAL_VERSION     0x01
00320 
00321 /* {{{ PHP_HAVAL128Final
00322  */
00323 PHP_HASH_API void PHP_HAVAL128Final(unsigned char *digest, PHP_HAVAL_CTX * context)
00324 {
00325        unsigned char bits[10];
00326        unsigned int index, padLen;
00327 
00328        /* Version, Passes, and Digest Length */
00329        bits[0] =     (PHP_HASH_HAVAL_VERSION & 0x07) |
00330                             ((context->passes & 0x07) << 3) |
00331                             ((context->output & 0x03) << 6);
00332        bits[1] = (context->output >> 2);
00333 
00334        /* Save number of bits */
00335        Encode(bits + 2, context->count, 8);
00336 
00337        /* Pad out to 118 mod 128.
00338         */
00339        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00340        padLen = (index < 118) ? (118 - index) : (246 - index);
00341        PHP_HAVALUpdate(context, PADDING, padLen);
00342 
00343        /* Append version, passes, digest length, and message length */
00344        PHP_HAVALUpdate(context, bits, 10);
00345 
00346        /* Store state in digest */
00347        context->state[3] += (context->state[7] & 0xFF000000) |
00348                                            (context->state[6] & 0x00FF0000) |
00349                                            (context->state[5] & 0x0000FF00) |
00350                                            (context->state[4] & 0x000000FF);
00351 
00352        context->state[2] += (((context->state[7] & 0x00FF0000) |
00353                                              (context->state[6] & 0x0000FF00) |
00354                                              (context->state[5] & 0x000000FF)) << 8) |
00355                                             ((context->state[4] & 0xFF000000) >> 24);
00356 
00357        context->state[1] += (((context->state[7] & 0x0000FF00) |
00358                                              (context->state[6] & 0x000000FF)) << 16) |
00359                                            (((context->state[5] & 0xFF000000) |
00360                                              (context->state[4] & 0x00FF0000)) >> 16);
00361 
00362        context->state[0] +=  ((context->state[7] & 0x000000FF) << 24) |
00363                                            (((context->state[6] & 0xFF000000) |
00364                                              (context->state[5] & 0x00FF0000) |
00365                                              (context->state[4] & 0x0000FF00)) >> 8);
00366 
00367        Encode(digest, context->state, 16);
00368 
00369        /* Zeroize sensitive information.
00370         */
00371        memset((unsigned char*) context, 0, sizeof(*context));
00372 }
00373 /* }}} */
00374 
00375 /* {{{ PHP_HAVAL160Final
00376  */
00377 PHP_HASH_API void PHP_HAVAL160Final(unsigned char *digest, PHP_HAVAL_CTX * context)
00378 {
00379        unsigned char bits[10];
00380        unsigned int index, padLen;
00381 
00382        /* Version, Passes, and Digest Length */
00383        bits[0] =     (PHP_HASH_HAVAL_VERSION & 0x07) |
00384                             ((context->passes & 0x07) << 3) |
00385                             ((context->output & 0x03) << 6);
00386        bits[1] = (context->output >> 2);
00387 
00388        /* Save number of bits */
00389        Encode(bits + 2, context->count, 8);
00390 
00391        /* Pad out to 118 mod 128.
00392         */
00393        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00394        padLen = (index < 118) ? (118 - index) : (246 - index);
00395        PHP_HAVALUpdate(context, PADDING, padLen);
00396 
00397        /* Append version, passes, digest length, and message length */
00398        PHP_HAVALUpdate(context, bits, 10);
00399 
00400        /* Store state in digest */
00401        context->state[4] += ((context->state[7] & 0xFE000000) |
00402                                             (context->state[6] & 0x01F80000) |
00403                                             (context->state[5] & 0x0007F000)) >> 12;
00404 
00405        context->state[3] += ((context->state[7] & 0x01F80000) |
00406                                             (context->state[6] & 0x0007F000) |
00407                                             (context->state[5] & 0x00000FC0)) >> 6;
00408 
00409        context->state[2] +=  (context->state[7] & 0x0007F000) |
00410                                             (context->state[6] & 0x00000FC0) |
00411                                             (context->state[5] & 0x0000003F);
00412 
00413        context->state[1] += ROTR((context->state[7] & 0x00000FC0) |
00414                                                    (context->state[6] & 0x0000003F) |
00415                                                    (context->state[5] & 0xFE000000), 25);
00416 
00417        context->state[0] += ROTR((context->state[7] & 0x0000003F) |
00418                                                    (context->state[6] & 0xFE000000) |
00419                                                    (context->state[5] & 0x01F80000), 19);
00420 
00421        Encode(digest, context->state, 20);
00422 
00423        /* Zeroize sensitive information.
00424         */
00425        memset((unsigned char*) context, 0, sizeof(*context));
00426 }
00427 /* }}} */
00428 
00429 /* {{{ PHP_HAVAL192Final
00430  */
00431 PHP_HASH_API void PHP_HAVAL192Final(unsigned char *digest, PHP_HAVAL_CTX * context)
00432 {
00433        unsigned char bits[10];
00434        unsigned int index, padLen;
00435 
00436        /* Version, Passes, and Digest Length */
00437        bits[0] =     (PHP_HASH_HAVAL_VERSION & 0x07) |
00438                             ((context->passes & 0x07) << 3) |
00439                             ((context->output & 0x03) << 6);
00440        bits[1] = (context->output >> 2);
00441 
00442        /* Save number of bits */
00443        Encode(bits + 2, context->count, 8);
00444 
00445        /* Pad out to 118 mod 128.
00446         */
00447        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00448        padLen = (index < 118) ? (118 - index) : (246 - index);
00449        PHP_HAVALUpdate(context, PADDING, padLen);
00450 
00451        /* Append version, passes, digest length, and message length */
00452        PHP_HAVALUpdate(context, bits, 10);
00453 
00454        /* Store state in digest */
00455        context->state[5] += ((context->state[7] & 0xFC000000) | (context->state[6] & 0x03E00000)) >> 21;
00456        context->state[4] += ((context->state[7] & 0x03E00000) | (context->state[6] & 0x001F0000)) >> 16;
00457        context->state[3] += ((context->state[7] & 0x001F0000) | (context->state[6] & 0x0000FC00)) >> 10;
00458        context->state[2] += ((context->state[7] & 0x0000FC00) | (context->state[6] & 0x000003E0)) >>  5;
00459        context->state[1] +=  (context->state[7] & 0x000003E0) | (context->state[6] & 0x0000001F);
00460        context->state[0] += ROTR((context->state[7] & 0x0000001F) | (context->state[6] & 0xFC000000), 26);
00461        Encode(digest, context->state, 24);
00462 
00463        /* Zeroize sensitive information.
00464         */
00465        memset((unsigned char*) context, 0, sizeof(*context));
00466 }
00467 /* }}} */
00468 
00469 /* {{{ PHP_HAVAL224Final
00470  */
00471 PHP_HASH_API void PHP_HAVAL224Final(unsigned char *digest, PHP_HAVAL_CTX * context)
00472 {
00473        unsigned char bits[10];
00474        unsigned int index, padLen;
00475 
00476        /* Version, Passes, and Digest Length */
00477        bits[0] =     (PHP_HASH_HAVAL_VERSION & 0x07) |
00478                             ((context->passes & 0x07) << 3) |
00479                             ((context->output & 0x03) << 6);
00480        bits[1] = (context->output >> 2);
00481 
00482        /* Save number of bits */
00483        Encode(bits + 2, context->count, 8);
00484 
00485        /* Pad out to 118 mod 128.
00486         */
00487        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00488        padLen = (index < 118) ? (118 - index) : (246 - index);
00489        PHP_HAVALUpdate(context, PADDING, padLen);
00490 
00491        /* Append version, passes, digest length, and message length */
00492        PHP_HAVALUpdate(context, bits, 10);
00493 
00494        /* Store state in digest */
00495        context->state[6] +=  context->state[7]        & 0x0000000F;
00496        context->state[5] += (context->state[7] >>  4) & 0x0000001F;
00497        context->state[4] += (context->state[7] >>  9) & 0x0000000F;
00498        context->state[3] += (context->state[7] >> 13) & 0x0000001F;
00499        context->state[2] += (context->state[7] >> 18) & 0x0000000F;
00500        context->state[1] += (context->state[7] >> 22) & 0x0000001F;
00501        context->state[0] += (context->state[7] >> 27) & 0x0000001F;
00502        Encode(digest, context->state, 28);
00503 
00504        /* Zeroize sensitive information.
00505         */
00506        memset((unsigned char*) context, 0, sizeof(*context));
00507 }
00508 /* }}} */
00509 
00510 /* {{{ PHP_HAVAL256Final
00511  */
00512 PHP_HASH_API void PHP_HAVAL256Final(unsigned char *digest, PHP_HAVAL_CTX * context)
00513 {
00514        unsigned char bits[10];
00515        unsigned int index, padLen;
00516 
00517        /* Version, Passes, and Digest Length */
00518        bits[0] =     (PHP_HASH_HAVAL_VERSION & 0x07) |
00519                             ((context->passes & 0x07) << 3) |
00520                             ((context->output & 0x03) << 6);
00521        bits[1] = (context->output >> 2);
00522 
00523        /* Save number of bits */
00524        Encode(bits + 2, context->count, 8);
00525 
00526        /* Pad out to 118 mod 128.
00527         */
00528        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00529        padLen = (index < 118) ? (118 - index) : (246 - index);
00530        PHP_HAVALUpdate(context, PADDING, padLen);
00531 
00532        /* Append version, passes, digest length, and message length */
00533        PHP_HAVALUpdate(context, bits, 10);
00534 
00535        /* Store state in digest */
00536        Encode(digest, context->state, 32);
00537 
00538        /* Zeroize sensitive information.
00539         */
00540        memset((unsigned char*) context, 0, sizeof(*context));
00541 }
00542 /* }}} */
00543 
00544 /*
00545  * Local variables:
00546  * tab-width: 4
00547  * c-basic-offset: 4
00548  * End:
00549  * vim600: sw=4 ts=4 fdm=marker
00550  * vim<600: sw=4 ts=4
00551  */