docs: def _CallPlugin(self, cmd, input_json):
      """Calls the plugin and validates the response."""
      # Calculate length of input
      input_length = len(input_json)
      length_bytes_le = struct.pack('<I', input_length)
      request = length_bytes_le + input_json.encode()
  
      # Call plugin
      sign_process = subprocess.Popen(cmd,
                                      stdin=subprocess.PIPE,
                                      stdout=subprocess.PIPE)
  
      stdout = sign_process.communicate(request)[0]
      exit_status = sign_process.wait()
  
      # Parse and validate response size
      response_len_le = stdout[:4]
      response_len = struct.unpack('<I', response_len_le)[0]
      response = stdout[4:]
      if response_len != len(response):
        raise errors.PluginError(
            'Plugin response length {} does not match data {} (exit_status={})'
            .format(response_len, len(response), exit_status))
  
      # Ensure valid json
      try:
        json_response = json.loads(response.decode())
      except ValueError:
        raise errors.PluginError('Plugin returned invalid output (exit_status={})'
                                 .format(exit_status))
  
      # Ensure response type
      if json_response.get('type') != 'sign_helper_reply':
        raise errors.PluginError('Plugin returned invalid response type '
                                 '(exit_status={})'
                                 .format(exit_status))
  
      # Parse response codes
      result_code = json_response.get('code')
      if result_code is None:
        raise errors.PluginError('Plugin missing result code (exit_status={})'
                                 .format(exit_status))
  
      # Handle errors
      if result_code == SK_SIGNING_PLUGIN_TOUCH_REQUIRED:
        raise errors.U2FError(errors.U2FError.TIMEOUT)
      elif result_code == SK_SIGNING_PLUGIN_WRONG_DATA:
        raise errors.U2FError(errors.U2FError.DEVICE_INELIGIBLE)
      elif result_code != SK_SIGNING_PLUGIN_NO_ERROR:
        raise errors.PluginError(
            'Plugin failed with error {} - {} (exit_status={})'
            .format(result_code,
                    json_response.get('errorDetail'),
                    exit_status))
  
      # Ensure response data is present
      response_data = json_response.get('responseData')
      if response_data is None:
        raise errors.PluginErrors(
            'Plugin returned output with missing responseData (exit_status={})'
            .format(exit_status))
  
      return response_data