libyal / libfvde

Library and tools to access FileVault Drive Encryption (FVDE) encrypted volumes
GNU Lesser General Public License v3.0
339 stars 34 forks source link

libfvalue_utf8_string_with_index_copy_to_integer: unsupported character value: 0x78 at index: 1 #36

Closed drogus closed 4 years ago

drogus commented 6 years ago

I'm trying to mount a USB drive encrypted on Mac OSX (unfortunately I don't remember the exact procedure of encrypting it, but I probably used the default time machine setup a few years ago).

I'm using the following command:

sudo fvdemount -o $(( 409640 * 512 )) -p $DRIVE_PASSWORD /dev/sdb mounted-disk

and I get the following output:

fvdemount 20180505

Unable to open: /dev/sdb.
libfvalue_utf8_string_with_index_copy_to_integer: unsupported character value: 0x78 at index: 1.
libfvalue_utf8_string_copy_to_integer: unable to copy UTF-8 string to integer value.
libfplist_property_get_value_integer: unable to convert value to integer.
libfvde_encrypted_metadata_read_type_0x001a: unable to retrieve logical volume size.
libfvde_encrypted_metadata_read: unable to read metadata block type 0x001a.
libfvde_volume_open_read: unable to read primary encrypted metadata.
libfvde_volume_open_file_io_handle: unable to read from file IO handle.
mount_handle_open_input: unable to open input volume.
joachimmetz commented 6 years ago

Could you send me debug output so I can determine what libfvalue_utf8_string_with_index_copy_to_integer might be failing on

Also see: https://github.com/libyal/libfvde/wiki/Troubleshooting#verbose-and-debug-output

drogus commented 6 years ago

Thanks for the response! And yeah, sure, I recompiled with debug options and here's the output: https://gist.github.com/drogus/40ce9cb826f29944a6e91e76ed18aae9

PyBonnetainNesterenko commented 6 years ago

Hello, I have exactly the same issue and same error messages. The debug output is a little too big (41 Mb), and is rejected even when compressed. I will post it elsewhere if you need it.

joachimmetz commented 6 years ago

@PyBonnetainNesterenko feel free to mail the compressed log to me directly.

cirolaferrara commented 6 years ago

Same here with fvdeinfo 20180108 and 20180821

Bob1634854 commented 5 years ago

It looks like some of the plist data integers can be in hex, but libfplist_property_get_value_integer is unable to handle that case.

A quick patch in libfplist/libfplist_property.c at the end of libfplist_property_get_value_integer: Inside:

        if( libfvalue_utf8_string_copy_to_integer(
             internal_property->value_tag->value,
             internal_property->value_tag->value_size - 1,
             (uint64_t *) value_64bit,
             64,
             LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED,
             error ) != 1 )
        {
                libcerror_error_set(
                 error,
                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
                 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
                 "%s: unable to convert value to integer. twice",
                 function );

                return( -1 );
        }

Changing LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED to LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL | LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED seems to do the trick.

Bob1634854 commented 5 years ago

The above does not work (the flags do not compose). Replace the above with the code below, which will attempt to do a hex format copy if the decimal format fails.

        if( libfvalue_utf8_string_copy_to_integer(
             internal_property->value_tag->value,
             internal_property->value_tag->value_size - 1,
             (uint64_t *) value_64bit,
             64,
             LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED,
             error ) != 1 )
        {
                if( libfvalue_utf8_string_copy_to_integer(
                     internal_property->value_tag->value,
                     internal_property->value_tag->value_size - 1,
                     (uint64_t *) value_64bit,
                     64,
                     LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED,
                     error ) != 1 )
                {
                        libcerror_error_set(
                         error,
                         LIBCERROR_ERROR_DOMAIN_RUNTIME,
                         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
                         "%s: unable to convert value to integer.",
                         function );

                        return( -1 );
                }
        }
joachimmetz commented 5 years ago

It looks like some of the plist data integers can be in hex, but libfplist_property_get_value_integer is unable to handle that case.

@Bob1634854 thanks for the suggestion, I'll have a look when time permits to add hexadecimal support.

cirolaferrara commented 5 years ago

The above does not work (the flags do not compose). Replace the above with the code below, which will attempt to do a hex format copy if the decimal format fails.

        if( libfvalue_utf8_string_copy_to_integer(
             internal_property->value_tag->value,
             internal_property->value_tag->value_size - 1,
             (uint64_t *) value_64bit,
             64,
             LIBFVALUE_INTEGER_FORMAT_TYPE_DECIMAL | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED,
             error ) != 1 )
        {
                if( libfvalue_utf8_string_copy_to_integer(
                     internal_property->value_tag->value,
                     internal_property->value_tag->value_size - 1,
                     (uint64_t *) value_64bit,
                     64,
                     LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL | LIBFVALUE_INTEGER_FORMAT_FLAG_UNSIGNED,
                     error ) != 1 )
                {
                        libcerror_error_set(
                         error,
                         LIBCERROR_ERROR_DOMAIN_RUNTIME,
                         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
                         "%s: unable to convert value to integer.",
                         function );

                        return( -1 );
                }
        }

Same.

$ fdisk -l /media/hard-disk/1A.raw
Disk /media/hard-disk/1A.raw: 233.8 GiB, 251000193024 bytes, 490234752 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: XXXX-XXX-XXX-XXX-XXX

Device                              Start       End   Sectors   Size Type
/media/hard-disk/1A.raw1        40    409639    409600   200M EFI System
/media/hard-disk/1A.raw2    409640 488965175 488555536   233G Apple Core storage
/media/hard-disk/1A.raw3 488965176 490234711   1269536 619.9M Apple boot
$ ./fvdemount -e /media/hard-disk/EncryptedRoot.plist.wipekey -o $(( 409640 * 512 )) -p mypwd /media/hard-disk/1A.raw /mnt/fvdevolume/

fvdemount 20180821

Unable to open: /media/hard-disk/1A.raw.
libfvalue_utf8_string_with_index_copy_to_integer: unsupported character value: 0x78 at index: 1.
libfvalue_utf8_string_copy_to_integer: unable to copy UTF-8 string to integer value.
libfvalue_utf8_string_with_index_copy_to_integer: unsupported character value: 0x78 at index: 1.
libfvalue_utf8_string_copy_to_integer: unable to copy UTF-8 string to integer value.
libfvalue_utf8_string_with_index_copy_to_integer: unsupported character value: 0x78 at index: 1.
libfvalue_utf8_string_copy_to_integer: unable to copy UTF-8 string to integer value.
libfvalue_utf8_string_with_index_copy_to_integer: unsupported character value: 0x78 at index: 1.
libfvalue_utf8_string_copy_to_integer: unable to copy UTF-8 string to integer value.
libfvde_encryption_context_plist_get_passphrase_wrapped_kek: unable to retrieve PassphraseWrappedKEKStruct sub property.
libfvde_encrypted_metadata_get_volume_master_key: unable to retrieve passphrase wrapped KEK: 1 from encryption context plist.
libfvde_volume_open_read_keys_from_encrypted_metadata: unable to retrieve volume master key from encrypted metadata.
libfvde_volume_open_read: unable to read keys from primary encrypted metadata.
libfvde_volume_open_file_io_handle: unable to read from file IO handle.
mount_handle_open_input: unable to open input volume.
elerch commented 5 years ago

libfvalue_integer.c also needs to be modified as it's verifying input. libfvalue is used in this repository but the code lives in another repo, pulled in via synclibs.sh. I modified this if statement: https://github.com/libyal/libfvalue/blob/master/libfvalue/libfvalue_integer.c#L1525

to the following:

  if( ( character_value < (uint8_t) '0' )
  || (( character_value > (uint8_t) '9' ) &&
              character_value != (uint8_t) 'x') &&
              ( character_value < (uint8_t) 'a' || character_value > (uint8_t) 'f' )
     )

This got me past the error message, though I'm having other issues so I'm not sure that would complete the support for hex values here.

cirolaferrara commented 5 years ago

libfvalue_integer.c also needs to be modified as it's verifying input. libfvalue is used in this repository but the code lives in another repo, pulled in via synclibs.sh. I modified this if statement: https://github.com/libyal/libfvalue/blob/master/libfvalue/libfvalue_integer.c#L1525

to the following:

  if( ( character_value < (uint8_t) '0' )
  || (( character_value > (uint8_t) '9' ) &&
              character_value != (uint8_t) 'x') &&
              ( character_value < (uint8_t) 'a' || character_value > (uint8_t) 'f' )
     )

This got me past the error message, though I'm having other issues so I'm not sure that would complete the support for hex values here.

Yeah. It works 👍

joachimmetz commented 5 years ago

made changes to libfplist to support hexadecimal integer properties https://github.com/libyal/libfplist/commit/70ccbb889fe11f80c72a6f88f35bd43297a48797

joachimmetz commented 5 years ago

Integer issue should be addressed in libfvde 20190104