Changeset beb9336 in mainline for uspace/lib/ext4/libext4_hash.c


Ignore:
Timestamp:
2012-08-24T14:07:52Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
041ab64
Parents:
bd29f9c9 (diff), db81577 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge with mainline

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ext4/libext4_hash.c

    rbd29f9c9 rbeb9336  
    2929/** @addtogroup libext4
    3030 * @{
    31  */
    32 
     31 */
    3332/**
    34  * @file        libext4_hash.c
    35  * @brief       Hashing algorithms for ext4 HTree.
     33 * @file  libext4_hash.c
     34 * @brief Hashing algorithms for ext4 HTree.
    3635 */
    3736
    3837#include <errno.h>
    3938#include <mem.h>
    40 
    4139#include "libext4.h"
    4240
    43 #define TEA_DELTA 0x9E3779B9
    44 
     41#define TEA_DELTA  0x9E3779B9
    4542
    4643/* F, G and H are basic MD4 functions: selection, majority, parity */
    47 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
    48 #define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
    49 #define H(x, y, z) ((x) ^ (y) ^ (z))
    50 
     44#define F(x, y, z)  ((z) ^ ((x) & ((y) ^ (z))))
     45#define G(x, y, z)  (((x) & (y)) + (((x) ^ (y)) & (z)))
     46#define H(x, y, z)  ((x) ^ (y) ^ (z))
    5147
    5248/*
     
    5652 * Rotation is separate from addition to prevent recomputation
    5753 */
    58 #define ROUND(f, a, b, c, d, x, s)      \
    59         (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s)))
    60 #define K1 0
    61 #define K2 013240474631UL
    62 #define K3 015666365641UL
    63 
     54#define ROUND(f, a, b, c, d, x, s) \
     55        (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s)))
     56
     57#define K1  0
     58#define K2  013240474631UL
     59#define K3  015666365641UL
    6460
    6561static void tea_transform(uint32_t buf[4], uint32_t const in[])
    6662{
    6763        uint32_t sum = 0;
    68         uint32_t b0 = buf[0], b1 = buf[1];
    69         uint32_t a = in[0], b = in[1], c = in[2], d = in[3];
     64        uint32_t b0 = buf[0];
     65        uint32_t b1 = buf[1];
     66        uint32_t a = in[0];
     67        uint32_t b = in[1];
     68        uint32_t c = in[2];
     69        uint32_t d = in[3];
     70       
    7071        int n = 16;
    71 
     72       
    7273        do {
    7374                sum += TEA_DELTA;
    74                 b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
    75                 b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
     75                b0 += ((b1 << 4) + a) ^ (b1 + sum) ^ ((b1 >> 5) + b);
     76                b1 += ((b0 << 4) + c) ^ (b0 + sum) ^ ((b0 >> 5) + d);
    7677        } while (--n);
    77 
     78       
    7879        buf[0] += b0;
    7980        buf[1] += b1;
     
    8485{
    8586        uint32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3];
    86 
     87       
    8788        /* Round 1 */
    8889        ROUND(F, a, b, c, d, in[0] + K1,  3);
     
    9495        ROUND(F, c, d, a, b, in[6] + K1, 11);
    9596        ROUND(F, b, c, d, a, in[7] + K1, 19);
    96 
     97       
    9798        /* Round 2 */
    9899        ROUND(G, a, b, c, d, in[1] + K2,  3);
     
    104105        ROUND(G, c, d, a, b, in[4] + K2,  9);
    105106        ROUND(G, b, c, d, a, in[6] + K2, 13);
    106 
     107       
    107108        /* Round 3 */
    108109        ROUND(H, a, b, c, d, in[3] + K3,  3);
     
    114115        ROUND(H, c, d, a, b, in[0] + K3, 11);
    115116        ROUND(H, b, c, d, a, in[4] + K3, 15);
    116 
     117       
    117118        buf[0] += a;
    118119        buf[1] += b;
    119120        buf[2] += c;
    120121        buf[3] += d;
    121 
    122122}
    123123
    124124static uint32_t hash_unsigned(const char *name, int len)
    125125{
    126         uint32_t hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
     126        uint32_t hash;
     127        uint32_t hash0 = 0x12a3fe2d;
     128        uint32_t hash1 = 0x37abe8f9;
    127129        const unsigned char *ucp = (const unsigned char *) name;
    128 
     130       
    129131        while (len--) {
    130132                hash = hash1 + (hash0 ^ (((int) *ucp++) * 7152373));
    131 
    132                 if (hash & 0x80000000) {
     133               
     134                if (hash & 0x80000000)
    133135                        hash -= 0x7fffffff;
    134                 }
     136               
    135137                hash1 = hash0;
    136138                hash0 = hash;
    137139        }
     140       
    138141        return hash0 << 1;
    139142}
     
    141144static uint32_t hash_signed(const char *name, int len)
    142145{
    143         uint32_t hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
     146        uint32_t hash;
     147        uint32_t hash0 = 0x12a3fe2d;
     148        uint32_t hash1 = 0x37abe8f9;
    144149        const signed char *scp = (const signed char *) name;
    145 
     150       
    146151        while (len--) {
    147152                hash = hash1 + (hash0 ^ (((int) *scp++) * 7152373));
    148 
    149                 if (hash & 0x80000000) {
     153               
     154                if (hash & 0x80000000)
    150155                        hash -= 0x7fffffff;
    151                 }
     156               
    152157                hash1 = hash0;
    153158                hash0 = hash;
    154159        }
     160       
    155161        return hash0 << 1;
    156162}
     
    161167        int i;
    162168        const signed char *scp = (const signed char *) msg;
    163 
    164         pad = (uint32_t)len | ((uint32_t)len << 8);
     169       
     170        pad = (uint32_t) len | ((uint32_t) len << 8);
    165171        pad |= pad << 16;
    166 
     172       
    167173        val = pad;
    168         if (len > num*4) {
     174        if (len > num * 4)
    169175                len = num * 4;
    170         }
    171 
     176       
    172177        for (i = 0; i < len; i++) {
    173                 if ((i % 4) == 0) {
     178                if ((i % 4) == 0)
    174179                        val = pad;
    175                 }
     180               
    176181                val = ((int) scp[i]) + (val << 8);
    177182                if ((i % 4) == 3) {
     
    181186                }
    182187        }
    183 
    184         if (--num >= 0) {
     188       
     189        if (--num >= 0)
    185190                *buf++ = val;
    186         }
    187 
    188         while (--num >= 0) {
     191       
     192        while (--num >= 0)
    189193                *buf++ = pad;
    190         }
    191 }
    192 
    193 
    194 static void str2hashbuf_unsigned(const char *msg, int len, uint32_t *buf, int num)
     194}
     195
     196static void str2hashbuf_unsigned(const char *msg, int len, uint32_t *buf,
     197    int num)
    195198{
    196199        uint32_t pad, val;
    197200        int i;
    198201        const unsigned char *ucp = (const unsigned char *) msg;
    199 
    200         pad = (uint32_t)len | ((uint32_t)len << 8);
     202       
     203        pad = (uint32_t) len | ((uint32_t) len << 8);
    201204        pad |= pad << 16;
    202 
     205       
    203206        val = pad;
    204         if (len > num*4) {
    205         len = num * 4;
    206         }
    207 
     207        if (len > num * 4)
     208                len = num * 4;
     209       
    208210        for (i = 0; i < len; i++) {
    209                 if ((i % 4) == 0) {
     211                if ((i % 4) == 0)
    210212                        val = pad;
    211                 }
     213               
    212214                val = ((int) ucp[i]) + (val << 8);
    213215                if ((i % 4) == 3) {
     
    217219                }
    218220        }
    219 
    220         if (--num >= 0) {
     221       
     222        if (--num >= 0)
    221223                *buf++ = val;
    222         }
    223 
    224         while (--num >= 0) {
     224       
     225        while (--num >= 0)
    225226                *buf++ = pad;
    226         }
    227 }
    228 
     227}
    229228
    230229/** Compute hash value of the string.
    231230 *
    232  * @param hinfo         hash info structure with information about
    233  *                                      the algorithm, hash seed and with the place
    234  *                                      for the output hash value
    235  * @param len           length of the name
    236  * @param name          name to be hashed
    237  * @return                      error code
     231 * @param hinfo Hash info structure with information about
     232 *              the algorithm, hash seed and with the place
     233 *              for the output hash value
     234 * @param len  Length of the name
     235 * @param name Name to be hashed
     236 *
     237 * @return Error code
     238 *
    238239 */
    239240int ext4_hash_string(ext4_hash_info_t *hinfo, int len, const char *name)
     
    242243        uint32_t minor_hash = 0;
    243244        const char *p;
    244     int i;
    245     uint32_t in[8], buf[4];
    246     void (*str2hashbuf)(const char *, int, uint32_t *, int) = str2hashbuf_signed;
    247 
    248     /* Initialize the default seed for the hash checksum functions */
     245        int i;
     246        uint32_t in[8], buf[4];
     247        void (*str2hashbuf)(const char *, int, uint32_t *, int) =
     248            str2hashbuf_signed;
     249       
     250        /* Initialize the default seed for the hash checksum functions */
    249251        buf[0] = 0x67452301;
    250252        buf[1] = 0xefcdab89;
    251253        buf[2] = 0x98badcfe;
    252254        buf[3] = 0x10325476;
    253 
    254     /* Check if the seed is all zero's */
     255       
     256        /* Check if the seed is all zero's */
    255257        if (hinfo->seed) {
    256258                for (i = 0; i < 4; i++) {
    257                         if (hinfo->seed[i] != 0) {
    258                 break;
    259                         }
    260                 }
    261                 if (i < 4) {
     259                        if (hinfo->seed[i] != 0)
     260                                break;
     261                       
     262                }
     263               
     264                if (i < 4)
    262265                        memcpy(buf, hinfo->seed, sizeof(buf));
    263                 }
    264     }
    265 
     266        }
     267       
    266268        switch (hinfo->hash_version) {
    267                 case EXT4_HASH_VERSION_LEGACY_UNSIGNED:
    268                         hash = hash_unsigned(name, len);
    269                         break;
    270 
    271                 case EXT4_HASH_VERSION_LEGACY:
    272                         hash = hash_signed(name, len);
    273                         break;
    274 
    275 
    276                 case EXT4_HASH_VERSION_HALF_MD4_UNSIGNED:
    277                         str2hashbuf = str2hashbuf_unsigned;
    278 
    279                 case EXT4_HASH_VERSION_HALF_MD4:
    280                         p = name;
    281                         while (len > 0) {
    282                                 (*str2hashbuf)(p, len, in, 8);
    283                                 half_md4_transform(buf, in);
    284                                 len -= 32;
    285                                 p += 32;
    286                         }
    287                         minor_hash = buf[2];
    288                         hash = buf[1];
    289                         break;
    290 
    291 
    292                 case EXT4_HASH_VERSION_TEA_UNSIGNED:
    293                         str2hashbuf = str2hashbuf_unsigned;
    294 
    295                 case EXT4_HASH_VERSION_TEA:
    296                         p = name;
    297                         while (len > 0) {
    298                                 (*str2hashbuf)(p, len, in, 4);
    299                                 tea_transform(buf, in);
    300                                 len -= 16;
    301                                 p += 16;
    302                         }
    303                         hash = buf[0];
    304                         minor_hash = buf[1];
    305                         break;
    306 
    307                 default:
    308                         hinfo->hash = 0;
    309                         return EINVAL;
    310         }
    311 
     269        case EXT4_HASH_VERSION_LEGACY_UNSIGNED:
     270                hash = hash_unsigned(name, len);
     271                break;
     272        case EXT4_HASH_VERSION_LEGACY:
     273                hash = hash_signed(name, len);
     274                break;
     275        case EXT4_HASH_VERSION_HALF_MD4_UNSIGNED:
     276                str2hashbuf = str2hashbuf_unsigned;
     277        case EXT4_HASH_VERSION_HALF_MD4:
     278                p = name;
     279               
     280                while (len > 0) {
     281                        (*str2hashbuf)(p, len, in, 8);
     282                        half_md4_transform(buf, in);
     283                        len -= 32;
     284                        p += 32;
     285                }
     286               
     287                minor_hash = buf[2];
     288                hash = buf[1];
     289                break;
     290        case EXT4_HASH_VERSION_TEA_UNSIGNED:
     291                str2hashbuf = str2hashbuf_unsigned;
     292        case EXT4_HASH_VERSION_TEA:
     293                p = name;
     294               
     295                while (len > 0) {
     296                        (*str2hashbuf)(p, len, in, 4);
     297                        tea_transform(buf, in);
     298                        len -= 16;
     299                        p += 16;
     300                }
     301               
     302                hash = buf[0];
     303                minor_hash = buf[1];
     304                break;
     305        default:
     306                hinfo->hash = 0;
     307                return EINVAL;
     308        }
     309       
    312310        hash = hash & ~1;
    313         if (hash == (EXT4_DIRECTORY_HTREE_EOF << 1)) {
    314                 hash = (EXT4_DIRECTORY_HTREE_EOF-1) << 1;
    315         }
    316 
     311        if (hash == (EXT4_DIRECTORY_HTREE_EOF << 1))
     312                hash = (EXT4_DIRECTORY_HTREE_EOF - 1) << 1;
     313       
    317314        hinfo->hash = hash;
    318315        hinfo->minor_hash = minor_hash;
    319 
     316       
    320317        return EOK;
    321318}
     
    323320/**
    324321 * @}
    325  */ 
     322 */
Note: See TracChangeset for help on using the changeset viewer.