/* Tests the libevt_file_header_read_file_io_handle function * Returns 1 if successful or 0 if not */ int evt_test_file_header_read_file_io_handle( void ) { libbfio_handle_t *file_io_handle = NULL; libcerror_error_t *error = NULL; libevt_file_header_t *file_header = NULL; int result = 0; /* Initialize test */ result = libevt_file_header_initialize( &file_header, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); EVT_TEST_ASSERT_IS_NOT_NULL( "file_header", file_header ); EVT_TEST_ASSERT_IS_NULL( "error", error ); /* Initialize file IO handle */ result = evt_test_open_file_io_handle( &file_io_handle, evt_test_file_header_data1, 48, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); EVT_TEST_ASSERT_IS_NOT_NULL( "file_io_handle", file_io_handle ); EVT_TEST_ASSERT_IS_NULL( "error", error ); /* Test regular cases */ result = libevt_file_header_read_file_io_handle( file_header, file_io_handle, 0, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); EVT_TEST_ASSERT_IS_NULL( "error", error ); /* Test error cases */ result = libevt_file_header_read_file_io_handle( NULL, file_io_handle, 0, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); EVT_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); result = libevt_file_header_read_file_io_handle( file_header, NULL, 0, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); EVT_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); result = libevt_file_header_read_file_io_handle( file_header, file_io_handle, -1, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); EVT_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); /* Clean up file IO handle */ result = evt_test_close_file_io_handle( &file_io_handle, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, 0 ); EVT_TEST_ASSERT_IS_NULL( "error", error ); /* Test data too small */ result = evt_test_open_file_io_handle( &file_io_handle, evt_test_file_header_data1, 8, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); EVT_TEST_ASSERT_IS_NOT_NULL( "file_io_handle", file_io_handle ); EVT_TEST_ASSERT_IS_NULL( "error", error ); result = libevt_file_header_read_file_io_handle( file_header, file_io_handle, 0, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); EVT_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); result = evt_test_close_file_io_handle( &file_io_handle, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, 0 ); EVT_TEST_ASSERT_IS_NULL( "error", error ); /* Test invalid signature */ result = evt_test_open_file_io_handle( &file_io_handle, evt_test_file_header_data1, 48, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); EVT_TEST_ASSERT_IS_NOT_NULL( "file_io_handle", file_io_handle ); EVT_TEST_ASSERT_IS_NULL( "error", error ); byte_stream_copy_from_uint32_little_endian( &( evt_test_file_header_data1[ 4 ] ), 0xffffffffUL ); result = libevt_file_header_read_file_io_handle( file_header, file_io_handle, 0, &error ); byte_stream_copy_from_uint32_little_endian( &( evt_test_file_header_data1[ 4 ] ), 0x654c664cUL ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); EVT_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); result = evt_test_close_file_io_handle( &file_io_handle, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, 0 ); EVT_TEST_ASSERT_IS_NULL( "error", error ); /* Clean up */ result = libevt_file_header_free( &file_header, &error ); EVT_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); EVT_TEST_ASSERT_IS_NULL( "file_header", file_header ); EVT_TEST_ASSERT_IS_NULL( "error", error ); return( 1 ); on_error: if( error != NULL ) { libcerror_error_free( &error ); } if( file_io_handle != NULL ) { libbfio_handle_free( &file_io_handle, NULL ); } if( file_header != NULL ) { libevt_file_header_free( &file_header, NULL ); } return( 0 ); }
/* Packs the chunk data * This function either adds the checksum or compresses the chunk data * Returns 1 if successful or -1 on error */ int libewf_chunk_data_pack( libewf_chunk_data_t *chunk_data, int8_t compression_level, uint8_t compression_flags, uint8_t ewf_format, size32_t chunk_size, const uint8_t *compressed_zero_byte_empty_block, size_t compressed_zero_byte_empty_block_size, liberror_error_t **error ) { static char *function = "libewf_chunk_data_pack"; void *reallocation = NULL; uint32_t calculated_checksum = 0; int is_empty_zero_block = 0; int result = 0; if( chunk_data == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid chunk data.", function ); return( -1 ); } if( chunk_data->data == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid chunk data - missing data.", function ); return( -1 ); } if( chunk_data->is_packed != 0 ) { return( 1 ); } chunk_data->is_compressed = 0; if( ( ewf_format != EWF_FORMAT_S01 ) && ( compression_flags & LIBEWF_FLAG_COMPRESS_EMPTY_BLOCK ) != 0 ) { result = libewf_empty_block_test( chunk_data->data, chunk_data->data_size, error ); if( result == -1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if chunk data is empty an empty block.", function ); return( -1 ); } else if( result == 1 ) { if( compression_level == EWF_COMPRESSION_NONE ) { compression_level = EWF_COMPRESSION_DEFAULT; } if( ( chunk_data->data )[ 0 ] == 0 ) { is_empty_zero_block = 1; } } else { compression_level = EWF_COMPRESSION_NONE; } } if( ( ewf_format == EWF_FORMAT_S01 ) || ( compression_level != EWF_COMPRESSION_NONE ) ) { chunk_data->compressed_data_size = 2 * chunk_data->data_size; chunk_data->compressed_data = (uint8_t *) memory_allocate( sizeof( uint8_t ) * chunk_data->compressed_data_size ); if( chunk_data->compressed_data == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create compressed data.", function ); return( -1 ); } if( ( is_empty_zero_block != 0 ) && ( chunk_data->data_size == (size_t) chunk_size ) && ( compressed_zero_byte_empty_block != NULL ) ) { if( memory_copy( chunk_data->compressed_data, compressed_zero_byte_empty_block, compressed_zero_byte_empty_block_size ) == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to copy compressed zero byte empty block to compressed chunk buffer.", function ); return( -1 ); } chunk_data->compressed_data_size = compressed_zero_byte_empty_block_size; } else { result = libewf_compress( chunk_data->compressed_data, &( chunk_data->compressed_data_size ), chunk_data->data, chunk_data->data_size, compression_level, error ); /* Check if the compressed buffer was too small * and a new compressed data size buffer was passed back */ if( ( result == -1 ) && ( chunk_data->compressed_data_size > 0 ) ) { liberror_error_free( error ); reallocation = memory_reallocate( chunk_data->compressed_data, sizeof( uint8_t ) * chunk_data->compressed_data_size ); if( reallocation == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_MEMORY, LIBERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize compressed data.", function ); return( -1 ); } chunk_data->compressed_data = (uint8_t *) reallocation; result = libewf_compress( chunk_data->compressed_data, &( chunk_data->compressed_data_size ), chunk_data->data, chunk_data->data_size, compression_level, error ); } if( result != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_COMPRESSION, LIBERROR_COMPRESSION_ERROR_COMPRESS_FAILED, "%s: unable to compress chunk data.", function ); return( -1 ); } } if( ( ewf_format == EWF_FORMAT_S01 ) || ( chunk_data->compressed_data_size < chunk_data->data_size ) ) { memory_free( chunk_data->data ); chunk_data->data = chunk_data->compressed_data; chunk_data->data_size = chunk_data->compressed_data_size; chunk_data->compressed_data = NULL; chunk_data->compressed_data_size = 0; chunk_data->is_compressed = 1; } } if( chunk_data->is_compressed == 0 ) { if( ( chunk_data->data_size + sizeof( uint32_t ) ) > chunk_data->allocated_data_size ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: chunk data size value out of bounds.", function ); return( -1 ); } calculated_checksum = ewf_checksum_calculate( chunk_data->data, chunk_data->data_size, 1 ); byte_stream_copy_from_uint32_little_endian( &( ( chunk_data->data )[ chunk_data->data_size ] ), calculated_checksum ); chunk_data->data_size += sizeof( uint32_t ); } chunk_data->is_packed = 1; return( 1 ); }
/* Copies a base16 stream from a byte stream * Returns 1 if successful or -1 on error */ int libuna_base16_stream_with_index_copy_from_byte_stream( uint8_t *base16_stream, size_t base16_stream_size, size_t *base16_stream_index, const uint8_t *byte_stream, size_t byte_stream_size, uint32_t base16_variant, libcerror_error_t **error ) { static char *function = "libuna_base16_stream_with_index_copy_from_byte_stream"; size_t calculated_base16_stream_size = 0; size_t base16_character_size = 0; size_t stream_index = 0; size_t byte_stream_index = 0; size_t number_of_characters = 0; size_t whitespace_size = 0; uint32_t a_character_value = 0; uint32_t base16_character = 0; uint8_t character_limit = 0; if( base16_stream == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid base16 stream.", function ); return( -1 ); } if( base16_stream_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid base16 stream size value exceeds maximum.", function ); return( -1 ); } if( base16_stream_index == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid base16 stream index.", function ); return( -1 ); } if( *base16_stream_index >= base16_stream_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: base16 stream string too small.", function ); return( -1 ); } if( byte_stream == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid byte stream.", function ); return( -1 ); } if( byte_stream_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid byte stream size value exceeds maximum.", function ); return( -1 ); } switch( base16_variant & 0x000000ffUL ) { case LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_NONE: character_limit = 0; break; case LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_64: character_limit = 64; break; case LIBUNA_BASE16_VARIANT_CHARACTER_LIMIT_76: character_limit = 76; break; default: libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: unsupported base16 variant.", function ); return( -1 ); } switch( base16_variant & 0x000f0000UL ) { case LIBUNA_BASE16_VARIANT_CASE_LOWER: a_character_value = (uint32_t) 'a' - 10; break; case LIBUNA_BASE16_VARIANT_CASE_MIXED: case LIBUNA_BASE16_VARIANT_CASE_UPPER: a_character_value = (uint32_t) 'A' - 10; break; default: libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: unsupported base16 variant.", function ); return( -1 ); } switch( base16_variant & 0xf0000000UL ) { case LIBUNA_BASE16_VARIANT_ENCODING_BYTE_STREAM: base16_character_size = 1; break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN: case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN: base16_character_size = 2; break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN: case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN: base16_character_size = 4; break; default: libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: unsupported base16 variant.", function ); return( -1 ); } stream_index = *base16_stream_index; /* Make sure the base16 stream is able to hold * at least 2 bytes for each byte */ calculated_base16_stream_size = byte_stream_size * 2; if( character_limit != 0 ) { whitespace_size = calculated_base16_stream_size / character_limit; if( ( calculated_base16_stream_size % character_limit ) != 0 ) { whitespace_size += 1; } calculated_base16_stream_size += whitespace_size; } calculated_base16_stream_size *= base16_character_size; if( base16_stream_size < calculated_base16_stream_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: base16 stream is too small.", function ); return( -1 ); } while( byte_stream_index < byte_stream_size ) { base16_character = byte_stream[ byte_stream_index ] >> 4; if( base16_character <= 9 ) { base16_character += (uint32_t) '0'; } else { base16_character += a_character_value; } switch( base16_variant & 0xf0000000UL ) { case LIBUNA_BASE16_VARIANT_ENCODING_BYTE_STREAM: base16_stream[ stream_index ] = (uint8_t) base16_character; break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN: byte_stream_copy_from_uint16_big_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN: byte_stream_copy_from_uint16_little_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN: byte_stream_copy_from_uint32_big_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN: byte_stream_copy_from_uint32_little_endian( &( base16_stream[ stream_index ] ), base16_character ); break; } stream_index += base16_character_size; base16_character = byte_stream[ byte_stream_index ] & 0x0f; if( base16_character <= 9 ) { base16_character += (uint32_t) '0'; } else { base16_character += a_character_value; } switch( base16_variant & 0xf0000000UL ) { case LIBUNA_BASE16_VARIANT_ENCODING_BYTE_STREAM: base16_stream[ stream_index ] = (uint8_t) base16_character; break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN: byte_stream_copy_from_uint16_big_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN: byte_stream_copy_from_uint16_little_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN: byte_stream_copy_from_uint32_big_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN: byte_stream_copy_from_uint32_little_endian( &( base16_stream[ stream_index ] ), base16_character ); break; } stream_index += base16_character_size; if( character_limit != 0 ) { number_of_characters += 2; if( number_of_characters >= (size_t) character_limit ) { base16_character = (uint32_t) '\n'; switch( base16_variant & 0xf0000000UL ) { case LIBUNA_BASE16_VARIANT_ENCODING_BYTE_STREAM: base16_stream[ stream_index ] = (uint8_t) base16_character; break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN: byte_stream_copy_from_uint16_big_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN: byte_stream_copy_from_uint16_little_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN: byte_stream_copy_from_uint32_big_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN: byte_stream_copy_from_uint32_little_endian( &( base16_stream[ stream_index ] ), base16_character ); break; } stream_index += base16_character_size; number_of_characters = 0; } } byte_stream_index++; } if( character_limit != 0 ) { if( number_of_characters != 0 ) { base16_character = (uint32_t) '\n'; switch( base16_variant & 0xf0000000UL ) { case LIBUNA_BASE16_VARIANT_ENCODING_BYTE_STREAM: base16_stream[ stream_index ] = (uint8_t) base16_character; break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_BIG_ENDIAN: byte_stream_copy_from_uint16_big_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF16_LITTLE_ENDIAN: byte_stream_copy_from_uint16_little_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_BIG_ENDIAN: byte_stream_copy_from_uint32_big_endian( &( base16_stream[ stream_index ] ), base16_character ); break; case LIBUNA_BASE16_VARIANT_ENCODING_UTF32_LITTLE_ENDIAN: byte_stream_copy_from_uint32_little_endian( &( base16_stream[ stream_index ] ), base16_character ); break; } stream_index += base16_character_size; } } *base16_stream_index = stream_index; return( 1 ); }
/* Determines the GUID * Returns 1 if successful or -1 on error */ int guid_generate( uint8_t *guid, size_t guid_size, uint8_t guid_type, liberror_error_t **error ) { #if defined( WINAPI ) UUID uuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }; #endif static char *function = "guid_generate"; if( guid == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid GUID.", function ); return( -1 ); } if( guid_size < GUID_SIZE ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: GUID too small.", function ); return( -1 ); } if( guid_size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid GUID size value exceeds maximum.", function ); return( -1 ); } if( ( guid_type != GUID_TYPE_RANDOM ) && ( guid_type != GUID_TYPE_TIME ) ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: unsupported GUID type.", function ); return( -1 ); } if( guid_type == GUID_TYPE_RANDOM ) { #if defined( WINAPI ) UuidCreate( &uuid ); #elif defined( HAVE_UUID_GENERATE_RANDOM ) uuid_generate_random( guid ); #endif } if( guid_type == GUID_TYPE_TIME ) { #if defined( __BORLANDC__ ) && __BORLANDC__ <= 0x0520 /* No support for the time type GUID */ #elif defined( WINAPI ) && _WIN32_WINNT >= 0x0500 UuidCreateSequential( &uuid ); #elif defined( HAVE_UUID_GENERATE_TIME ) uuid_generate_time( guid ); #endif } #if defined( WINAPI ) byte_stream_copy_from_uint32_little_endian( guid, uuid.Data1 ); guid += 4; byte_stream_copy_from_uint16_little_endian( guid, uuid.Data2 ); guid += 2; byte_stream_copy_from_uint16_little_endian( guid, uuid.Data3 ); guid += 2; guid[ 0 ] = uuid.Data4[ 0 ]; guid[ 1 ] = uuid.Data4[ 1 ]; guid[ 2 ] = uuid.Data4[ 2 ]; guid[ 3 ] = uuid.Data4[ 3 ]; guid[ 4 ] = uuid.Data4[ 4 ]; guid[ 5 ] = uuid.Data4[ 5 ]; guid[ 6 ] = uuid.Data4[ 6 ]; guid[ 7 ] = uuid.Data4[ 7 ]; #endif return( 1 ); }
/* Reads a record_values * Returns the number of bytes read if successful or -1 on error */ ssize_t libevt_record_values_read( libevt_record_values_t *record_values, libbfio_handle_t *file_io_handle, libevt_io_handle_t *io_handle, off64_t *file_offset, uint8_t strict_mode, libcerror_error_t **error ) { uint8_t record_size_data[ 4 ]; uint8_t *record_data = NULL; static char *function = "libevt_record_values_read"; size_t read_size = 0; size_t record_data_offset = 0; ssize_t read_count = 0; ssize_t total_read_count = 0; uint32_t record_data_size = 0; if( record_values == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid record values.", function ); return( -1 ); } if( io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid IO handle.", function ); return( -1 ); } if( file_offset == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid file offset.", function ); return( -1 ); } record_values->offset = *file_offset; read_count = libbfio_handle_read_buffer( file_io_handle, record_size_data, sizeof( uint32_t ), error ); if( read_count != (ssize_t) sizeof( uint32_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read record size data.", function ); goto on_error; } *file_offset += read_count; total_read_count = read_count; byte_stream_copy_to_uint32_little_endian( record_size_data, record_data_size ); if( record_data_size < 4 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: record data size value out of bounds.", function ); goto on_error; } #if SIZEOF_SIZE_T <= 4 if( (size_t) record_data_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid record data size value exceeds maximum.", function ); goto on_error; } #endif /* Allocating record data as 4 bytes and then using realloc here * corrupts the memory */ record_data = (uint8_t *) memory_allocate( sizeof( uint8_t ) * record_data_size ); if( record_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create record data.", function ); goto on_error; } byte_stream_copy_from_uint32_little_endian( record_data, record_data_size ); record_data_offset = 4; read_size = record_data_size - record_data_offset; if( ( (size64_t) *file_offset + read_size ) > io_handle->file_size ) { read_size = (size_t) ( io_handle->file_size - *file_offset ); } read_count = libbfio_handle_read_buffer( file_io_handle, &( record_data[ record_data_offset ] ), read_size, error ); if( read_count != (ssize_t) read_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read record data.", function ); goto on_error; } *file_offset += read_count; record_data_offset += read_count; total_read_count += read_count; if( record_data_offset < (size_t) record_data_size ) { if( libbfio_handle_seek_offset( file_io_handle, (off64_t) sizeof( evt_file_header_t ), SEEK_SET, error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_SEEK_FAILED, "%s: unable to seek file header offset: %" PRIzd ".", function, sizeof( evt_file_header_t ) ); goto on_error; } *file_offset = (off64_t) sizeof( evt_file_header_t ); read_size = (size_t) record_data_size - record_data_offset; read_count = libbfio_handle_read_buffer( file_io_handle, &( record_data[ record_data_offset ] ), read_size, error ); if( read_count != (ssize_t) read_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read record data.", function ); goto on_error; } *file_offset += read_count; total_read_count += read_count; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: record data:\n", function ); libcnotify_print_data( record_data, (size_t) record_data_size, LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); } #endif if( memory_compare( &( record_data[ 4 ] ), evt_file_signature, 4 ) == 0 ) { record_values->type = LIBEVT_RECORD_TYPE_EVENT; } else if( memory_compare( &( record_data[ 4 ] ), evt_end_of_file_record_signature1, 4 ) == 0 ) { record_values->type = LIBEVT_RECORD_TYPE_END_OF_FILE; } else { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported record values signature.", function ); goto on_error; } if( record_values->type == LIBEVT_RECORD_TYPE_EVENT ) { if( libevt_record_values_read_event( record_values, record_data, (size_t) record_data_size, strict_mode, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read event record values.", function ); goto on_error; } } else if( record_values->type == LIBEVT_RECORD_TYPE_END_OF_FILE ) { if( libevt_record_values_read_end_of_file( record_values, record_data, (size_t) record_data_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read end of file record values.", function ); goto on_error; } } memory_free( record_data ); return( total_read_count ); on_error: if( record_data != NULL ) { memory_free( record_data ); } return( -1 ); }
/* Encrypts the data using Diffuser-A and B * Returns 1 if successful or -1 on error */ int libbde_diffuser_encrypt( uint8_t *data, size_t data_size, libcerror_error_t **error ) { uint32_t *values_32bit = NULL; static char *function = "libbde_diffuser_encrypt"; size_t data_index = 0; size_t number_of_values = 0; size_t value_32bit_index = 0; if( data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid data.", function ); return( -1 ); } if( data_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid data size value exceeds maximum.", function ); return( -1 ); } if( ( data_size % 4 ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, "%s: unsupported data size - not a multitude of 4.", function ); return( -1 ); } number_of_values = data_size / 4; values_32bit = (uint32_t *) memory_allocate( data_size ); if( values_32bit == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create values 32-bit.", function ); goto on_error; } data_index = 0; for( value_32bit_index = 0; value_32bit_index < number_of_values; value_32bit_index++ ) { byte_stream_copy_to_uint32_little_endian( &( data[ data_index ] ), values_32bit[ value_32bit_index ] ); data_index += sizeof( uint32_t ); } if( libbde_diffuser_a_encrypt( values_32bit, number_of_values, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ENCRYPTION, LIBCERROR_ENCRYPTION_ERROR_ENCRYPT_FAILED, "%s: unable to encrypt data using Diffuser-A.", function ); goto on_error; } if( libbde_diffuser_b_encrypt( values_32bit, number_of_values, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ENCRYPTION, LIBCERROR_ENCRYPTION_ERROR_ENCRYPT_FAILED, "%s: unable to encrypt data using Diffuser-B.", function ); goto on_error; } data_index = 0; for( value_32bit_index = 0; value_32bit_index < number_of_values; value_32bit_index++ ) { byte_stream_copy_from_uint32_little_endian( &( data[ data_index ] ), values_32bit[ value_32bit_index ] ); data_index += sizeof( uint32_t ); } if( memory_set( values_32bit, 0, data_size ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear values 32-bit.", function ); goto on_error; } memory_free( values_32bit ); return( 1 ); on_error: if( values_32bit != NULL ) { memory_set( values_32bit, 0, data_size ); memory_free( values_32bit ); } return( -1 ); }