From: Alex Elder Date: Fri, 18 Feb 2011 21:21:02 +0000 (+0000) Subject: xfsprogs: metadump: move obfuscation algorithm into its own function X-Git-Tag: v3.1.5~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da7daaf2c7056baa6acfe532c34cb238132708eb;p=thirdparty%2Fxfsprogs-dev.git xfsprogs: metadump: move obfuscation algorithm into its own function Pull the name obfuscation algorithm into a separate function. This separates it from the checking for duplicates and recording of names that are found to be acceptable. Signed-off-by: Alex Elder Reviewed-by: Dave Chinner --- diff --git a/db/metadump.c b/db/metadump.c index d75b17df9..5665abdcc 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -475,16 +475,24 @@ in_lost_found( return slen == namelen && !memcmp(name, s, namelen); } +/* + * Given a name and its hash value, massage the name in such a way + * that the result is another name of equal length which shares the + * same hash value. + */ static void -generate_obfuscated_name( - xfs_ino_t ino, - int namelen, - uchar_t *name) +obfuscate_name( + xfs_dahash_t hash, + size_t name_len, + uchar_t *name) { - xfs_dahash_t hash; - int dup = 0; - uchar_t newname[NAME_MAX]; - uchar_t *newp; + uchar_t newname[NAME_MAX]; + uchar_t *newp = newname; + int i; + xfs_dahash_t new_hash = 0; + uchar_t *first; + uchar_t high_bit; + int shift; /* * Our obfuscation algorithm requires at least 5-character @@ -493,9 +501,72 @@ generate_obfuscated_name( * five bytes in a name required to produce a new name * with the same hash. */ - if (namelen < 5) + if (name_len < 5) return; + /* + * The beginning of the obfuscated name can be pretty much + * anything, so fill it in with random characters. + * Accumulate its new hash value as we go. + */ + for (i = 0; i < name_len - 5; i++) { + *newp = random_filename_char(); + new_hash = *newp ^ rol32(new_hash, 7); + newp++; + } + + /* + * Compute which five bytes need to be used at the end of + * the name so the hash of the obfuscated name is the same + * as the hash of the original. If any result in an invalid + * character, flip a bit and arrange for a corresponding bit + * in a neighboring byte to be flipped as well. For the + * last byte, the "neighbor" to change is the first byte + * we're computing here. + */ + new_hash = rol32(new_hash, 3) ^ hash; + + first = newp; + high_bit = 0; + for (shift = 28; shift >= 0; shift -= 7) { + *newp = (new_hash >> shift & 0x7f) ^ high_bit; + if (is_invalid_char(*newp)) { + *newp ^= 1; + high_bit = 0x80; + } else + high_bit = 0; + ASSERT(!is_invalid_char(*newp)); + newp++; + } + + /* + * If we flipped a bit on the last byte, we need to fix up + * the matching bit in the first byte. The result will + * be a valid character, because we know that first byte + * has 0's in its upper four bits (it was produced by a + * 28-bit right-shift of a 32-bit unsigned value). + */ + if (high_bit) { + *first ^= 0x10; + ASSERT(!is_invalid_char(*first)); + } + ASSERT(libxfs_da_hashname(newname, name_len) == hash); + + /* Copy the fully obfuscated name back to the caller's buffer */ + + memcpy(name, newname, name_len); +} + +static void +generate_obfuscated_name( + xfs_ino_t ino, + int namelen, + uchar_t *name) +{ + xfs_dahash_t hash; + int dup = 0; + uchar_t newname[NAME_MAX]; + /* * We don't obfuscate "lost+found" or any orphan files * therein. When the name table is used for extended @@ -518,65 +589,7 @@ generate_obfuscated_name( hash = libxfs_da_hashname(name, namelen); do { - int i; - xfs_dahash_t newhash = 0; - uchar_t *first; - uchar_t high_bit; - int shift; - - /* - * The beginning of the obfuscated name can be - * pretty much anything, so fill it in with random - * characters. Accumulate its new hash value as we - * go. - */ - newp = &newname[0]; - for (i = 0; i < namelen - 5; i++) { - *newp = random_filename_char(); - newhash = *newp ^ rol32(newhash, 7); - newp++; - } - - /* - * Compute which five bytes need to be used at the - * end of the name so the hash of the obfuscated - * name is the same as the hash of the original. If - * any result in an invalid character, flip a bit - * and arrange for a corresponding bit in a - * neighboring byte to be flipped as well. For the - * last byte, the "neighbor" to change is the first - * byte we're computing here. - */ - newhash = rol32(newhash, 3) ^ hash; - - first = newp; - high_bit = 0; - for (shift = 28; shift >= 0; shift -= 7) { - *newp = ((newhash >> shift) & 0x7f) ^ high_bit; - if (is_invalid_char(*newp)) { - *newp ^= 1; - high_bit = 0x80; - } else - high_bit = 0; - ASSERT(!is_invalid_char(*newp)); - newp++; - } - - /* - * If we flipped a bit on the last byte, we need to - * fix up the first one we computed. - * - * That first byte had 0's in its upper four bits - * (it's the result of shifting a 32-bit unsigned - * value Right by 28 bits), so we don't need to - * worry about it becoming invalid as a result. - */ - if (high_bit) { - *first ^= 0x10; - ASSERT(!is_invalid_char(*first)); - } - - ASSERT(libxfs_da_hashname(newname, namelen) == hash); + obfuscate_name(hash, namelen, newname); /* * Search the name table to be sure we don't produce