/* Calculates the SHA256 hash of an UTF-8 formatted password * Returns 1 if successful or -1 on error */ int libbde_utf8_password_calculate_hash( const uint8_t *utf8_string, size_t utf8_string_length, uint8_t *password_hash, size_t password_hash_size, libcerror_error_t **error ) { uint8_t *utf16_stream = NULL; static char *function = "libbde_utf8_password_calculate_hash"; size_t utf16_stream_size = 0; if( password_hash == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid password hash.", function ); return( -1 ); } if( password_hash_size != 32 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: password hash size value out of bounds.", function ); return( -1 ); } if( libuna_utf16_stream_size_from_utf8( utf8_string, utf8_string_length, &utf16_stream_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine UTF-16 stream size.", function ); goto on_error; } utf16_stream = (uint8_t *) memory_allocate( sizeof( uint8_t ) * utf16_stream_size ); if( utf16_stream == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create UTF-16 stream.", function ); goto on_error; } if( libuna_utf16_stream_copy_from_utf8( utf16_stream, utf16_stream_size, LIBUNA_ENDIAN_LITTLE, utf8_string, utf8_string_length, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy UTF-8 string to UTF-16 stream size.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: password:\n", function ); libcnotify_print_data( utf16_stream, utf16_stream_size, 0 ); } #endif /* Ignore the byte-order mark in the UTF16 stream */ if( libhmac_sha256_calculate( &( utf16_stream[ 2 ] ), utf16_stream_size - 2, password_hash, password_hash_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to calculate password hash.", function ); goto on_error; } if( libhmac_sha256_calculate( password_hash, password_hash_size, password_hash, password_hash_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to calculate password hash.", function ); goto on_error; } if( memory_set( utf16_stream, 0, utf16_stream_size ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear UTF-16 stream.", function ); goto on_error; } memory_free( utf16_stream ); return( 1 ); on_error: if( utf16_stream != NULL ) { memory_set( utf16_stream, 0, utf16_stream_size ); memory_free( utf16_stream ); } return( -1 ); }
/* Tests the libuna_utf16_stream_size_from_utf8 function * Returns 1 if successful or 0 if not */ int una_test_utf16_stream_size_from_utf8( void ) { libuna_error_t *error = NULL; size_t utf16_stream_size = 0; int result = 0; /* Test regular cases */ result = libuna_utf16_stream_size_from_utf8( una_test_utf16_stream_utf8_string, 17, &utf16_stream_size, &error ); UNA_TEST_ASSERT_EQUAL_INT( "result", result, 1 ); UNA_TEST_ASSERT_EQUAL_SIZE( "utf16_stream_size", utf16_stream_size, (size_t) 34 ); UNA_TEST_ASSERT_IS_NULL( "error", error ); /* Test error cases */ result = libuna_utf16_stream_size_from_utf8( NULL, 17, &utf16_stream_size, &error ); UNA_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); UNA_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); result = libuna_utf16_stream_size_from_utf8( una_test_utf16_stream_utf8_string, (size_t) SSIZE_MAX + 1, &utf16_stream_size, &error ); UNA_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); UNA_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); result = libuna_utf16_stream_size_from_utf8( una_test_utf16_stream_utf8_string, 17, NULL, &error ); UNA_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); UNA_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); result = libuna_utf16_stream_size_from_utf8( una_test_utf16_stream_error_utf8_string, 17, &utf16_stream_size, &error ); UNA_TEST_ASSERT_EQUAL_INT( "result", result, -1 ); UNA_TEST_ASSERT_IS_NOT_NULL( "error", error ); libcerror_error_free( &error ); return( 1 ); on_error: if( error != NULL ) { libcerror_error_free( &error ); } return( 0 ); }