/* Frees an external key * Returns 1 if successful or -1 on error */ int libbde_external_key_free( libbde_external_key_t **external_key, libcerror_error_t **error ) { static char *function = "libbde_external_key_free"; int result = 1; if( external_key == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid external key.", function ); return( -1 ); } if( *external_key != NULL ) { if( ( *external_key )->key != NULL ) { if( libbde_key_free( &( ( *external_key )->key ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free key.", function ); result = -1; } } if( libcdata_array_free( &( ( *external_key )->entries_array ), (int(*)(intptr_t **, libcerror_error_t **)) &libbde_metadata_entry_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free entries array.", function ); result = -1; } memory_free( *external_key ); *external_key = NULL; } return( result ); }
/* Reads a external key from the metadata entry * Returns 1 if successful or -1 on error */ int libbde_external_key_read( libbde_external_key_t *external_key, libbde_metadata_entry_t *metadata_entry, libcerror_error_t **error ) { libbde_key_t *key = NULL; libbde_metadata_entry_t *property_metadata_entry = NULL; uint8_t *value_data = NULL; static char *function = "libbde_external_key_read"; size_t value_data_size = 0; ssize_t read_count = 0; int property_metadata_entry_index = 0; #if defined( HAVE_DEBUG_OUTPUT ) libcstring_system_character_t filetime_string[ 32 ]; libcstring_system_character_t guid_string[ 48 ]; libfdatetime_filetime_t *filetime = NULL; libfguid_identifier_t *guid = NULL; int result = 0; #endif if( external_key == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid external key.", function ); return( -1 ); } if( metadata_entry == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid metadata entry.", function ); return( -1 ); } if( metadata_entry->value_type != LIBBDE_VALUE_TYPE_EXTERNAL_KEY ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: invalid metadata entry - unsupported value type: 0x%04" PRIx16 ".", function, metadata_entry->value_type ); return( -1 ); } value_data = metadata_entry->value_data; value_data_size = metadata_entry->value_data_size; if( value_data_size < sizeof( bde_metadata_entry_external_key_header_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: value data size value out of bounds.", function ); return( -1 ); } if( memory_copy( external_key->identifier, ( (bde_metadata_entry_external_key_header_t *) value_data )->identifier, 16 ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to copy volume identifier.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( libfguid_identifier_initialize( &guid, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create GUID.", function ); goto on_error; } if( libfguid_identifier_copy_from_byte_stream( guid, ( (bde_metadata_entry_external_key_header_t *) value_data )->identifier, 16, LIBFGUID_ENDIAN_LITTLE, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy byte stream to GUID.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libfguid_identifier_copy_to_utf16_string( guid, (uint16_t *) guid_string, 48, LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE, error ); #else result = libfguid_identifier_copy_to_utf8_string( guid, (uint8_t *) guid_string, 48, LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy GUID to string.", function ); goto on_error; } libcnotify_printf( "%s: identifier\t\t\t\t\t: %" PRIs_LIBCSTRING_SYSTEM "\n", function, guid_string ); if( libfguid_identifier_free( &guid, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free GUID.", function ); goto on_error; } if( libfdatetime_filetime_initialize( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create filetime.", function ); goto on_error; } if( libfdatetime_filetime_copy_from_byte_stream( filetime, ( (bde_metadata_entry_external_key_header_t *) value_data )->modification_time, 8, LIBFDATETIME_ENDIAN_LITTLE, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime from byte stream.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) result = libfdatetime_filetime_copy_to_utf16_string( filetime, (uint16_t *) filetime_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #else result = libfdatetime_filetime_copy_to_utf8_string( filetime, (uint8_t *) filetime_string, 32, LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, error ); #endif if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to copy filetime to string.", function ); goto on_error; } libcnotify_printf( "%s: modification time\t\t\t\t: %" PRIs_LIBCSTRING_SYSTEM " UTC\n", function, filetime_string ); if( libfdatetime_filetime_free( &filetime, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free filetime.", function ); goto on_error; } libcnotify_printf( "\n" ); } #endif value_data += sizeof( bde_metadata_entry_external_key_header_t ); value_data_size -= sizeof( bde_metadata_entry_external_key_header_t ); while( value_data_size >= sizeof( bde_metadata_entry_v1_t ) ) { if( memory_compare( value_data, libbde_metadata_entry_empty, sizeof( bde_metadata_entry_v1_t ) ) == 0 ) { break; } if( libbde_metadata_entry_initialize( &property_metadata_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create property metadata entry.", function ); goto on_error; } read_count = libbde_metadata_entry_read( property_metadata_entry, value_data, value_data_size, error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read property metadata entry.", function ); goto on_error; } value_data += read_count; value_data_size -= read_count; if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_KEY ) { if( libbde_key_initialize( &key, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create key.", function ); goto on_error; } if( libbde_key_read( key, property_metadata_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read key metadata entry.", function ); goto on_error; } if( external_key->key == NULL ) { external_key->key = key; key = NULL; } if( key != NULL ) { if( libbde_key_free( &key, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free key.", function ); goto on_error; } } } else if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_UNICODE_STRING ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libbde_metadata_entry_read_string( property_metadata_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read string from property metadata entry.", function ); goto on_error; } #endif if( external_key->string_entry == NULL ) { external_key->string_entry = property_metadata_entry; } } if( libcdata_array_append_entry( external_key->entries_array, &property_metadata_entry_index, (intptr_t *) property_metadata_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to append property metadata entry to entries array.", function ); goto on_error; } property_metadata_entry = NULL; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( value_data_size > 0 ) { libcnotify_printf( "%s: trailing data:\n", function ); libcnotify_print_data( value_data, value_data_size, LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); } } #endif return( 1 ); on_error: #if defined( HAVE_DEBUG_OUTPUT ) if( guid != NULL ) { libfguid_identifier_free( &guid, NULL ); } if( filetime != NULL ) { libfdatetime_filetime_free( &filetime, NULL ); } #endif if( key != NULL ) { libbde_key_free( &key, NULL ); } if( property_metadata_entry != NULL ) { libbde_metadata_entry_free( &property_metadata_entry, NULL ); } return( -1 ); }
/* Frees a volume master key * Returns 1 if successful or -1 on error */ int libbde_volume_master_key_free( libbde_volume_master_key_t **volume_master_key, libcerror_error_t **error ) { static char *function = "libbde_volume_master_key_free"; int result = 1; if( volume_master_key == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid volume master key.", function ); return( -1 ); } if( *volume_master_key != NULL ) { if( ( *volume_master_key )->key != NULL ) { if( libbde_key_free( &( ( *volume_master_key )->key ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free key.", function ); result = -1; } } if( ( *volume_master_key )->stretch_key != NULL ) { if( libbde_stretch_key_free( &( ( *volume_master_key )->stretch_key ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free stretch key.", function ); result = -1; } } if( ( *volume_master_key )->aes_ccm_encrypted_key != NULL ) { if( libbde_aes_ccm_encrypted_key_free( &( ( *volume_master_key )->aes_ccm_encrypted_key ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free AES-CCM encrypted key.", function ); result = -1; } } if( libcdata_array_free( &( ( *volume_master_key )->entries_array ), (int(*)(intptr_t **, libcerror_error_t **)) &libbde_metadata_entry_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free entries array.", function ); result = -1; } memory_free( *volume_master_key ); *volume_master_key = NULL; } return( result ); }