Example #1
0
/*
 * Prevent security lock state changes to the dimm until the next reboot
 */
int nvm_freezelock_device(const NVM_UID device_uid)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;
	struct device_discovery discovery;

	// check user has permission to make changes
	if (check_caller_permissions() != COMMON_SUCCESS)
	{
		rc = NVM_ERR_INVALIDPERMISSIONS;
	}
	else if (!is_supported_driver_available())
	{
		rc = NVM_ERR_BADDRIVER;
	}
	else if ((rc = IS_NVM_FEATURE_SUPPORTED(modify_device_security)) != NVM_SUCCESS)
	{
		COMMON_LOG_ERROR("Modifying "NVM_DIMM_NAME" security is not supported.");
	}
	else if (device_uid == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, device_uid is NULL");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	else if ((rc = exists_and_manageable(device_uid, &discovery, 1)) == NVM_SUCCESS)
	{
		if ((rc = check_lock_state(&discovery)) == NVM_SUCCESS)
		{
			rc = freeze_security(&discovery);
		}
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Example #2
0
/*
 * Clear an injected error into the device specified.
 */
int nvm_clear_injected_device_error(const NVM_UID device_uid,
		const struct device_error *p_error)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;
	struct device_discovery discovery;

	if (device_uid == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, device_uid is NULL");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	else if (p_error == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, p_error is NULL");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	else if (check_caller_permissions() != NVM_SUCCESS)
	{
		rc = NVM_ERR_INVALIDPERMISSIONS;
	}
	else if (!is_supported_driver_available())
	{
		rc = NVM_ERR_BADDRIVER;
	}
	else if ((rc = IS_NVM_FEATURE_SUPPORTED(error_injection)) != NVM_SUCCESS)
	{
		COMMON_LOG_ERROR("Error injection is not supported.");
	}
	else if ((rc = exists_and_manageable(device_uid, &discovery, 1)) == NVM_SUCCESS)
	{
		if ((rc = enable_error_injection_functionality(discovery.device_handle.handle)) ==
				NVM_SUCCESS)
		{
			switch (p_error->type)
			{
			case ERROR_TYPE_TEMPERATURE:
				rc = inject_temperature_error(discovery.device_handle.handle,
						0, 0);
				break;
			case ERROR_TYPE_POISON:
				rc = inject_poison_error(&discovery, p_error->dpa, 0);
				break;
			case ERROR_TYPE_DIE_SPARING:
				rc = inject_software_trigger(&discovery, p_error->type, 0);
				break;
			case ERROR_TYPE_SPARE_ALARM:
			case ERROR_TYPE_MEDIA_FATAL_ERROR:
				rc = NVM_ERR_NOTSUPPORTED;
				break;
			default:
				break;
			}
		}
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Example #3
0
/*
 * Unlocks the device with the passphrase specified.
 */
int nvm_unlock_device(const NVM_UID device_uid,
		const NVM_PASSPHRASE passphrase, const NVM_SIZE passphrase_len)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;
	struct device_discovery discovery;

	// check user has permission to make changes
	if (check_caller_permissions() != COMMON_SUCCESS)
	{
		rc = NVM_ERR_INVALIDPERMISSIONS;
	}
	else if (!is_supported_driver_available())
	{
		rc = NVM_ERR_BADDRIVER;
	}
	else if ((rc = IS_NVM_FEATURE_SUPPORTED(modify_device_security)) != NVM_SUCCESS)
	{
		COMMON_LOG_ERROR("Modifying " NVM_DIMM_NAME " security is not supported.");
	}
	else if (device_uid == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, device_uid is NULL");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	else if (((rc = check_passphrase(passphrase, passphrase_len)) == NVM_SUCCESS) &&
			((rc = exists_and_manageable(device_uid, &discovery, 1)) == NVM_SUCCESS) &&
			((rc = check_unlock_device_capable(device_uid)) == NVM_SUCCESS))
	{
		if ((rc = security_change_prepare(&discovery, passphrase,
				passphrase_len)) == NVM_SUCCESS)
		{
			// send a pass through command to unlock the device
			struct pt_payload_passphrase input_payload;
			memset(&input_payload, 0, sizeof (input_payload));
			s_strncpy(input_payload.passphrase_current, NVM_PASSPHRASE_LEN,
					passphrase, passphrase_len);

			struct fw_cmd cmd;
			memset(&cmd, 0, sizeof (struct fw_cmd));
			cmd.device_handle = discovery.device_handle.handle;
			cmd.opcode = PT_SET_SEC_INFO;
			cmd.sub_opcode = SUBOP_UNLOCK_UNIT;
			cmd.input_payload_size = sizeof (input_payload);
			cmd.input_payload = &input_payload;
			rc = ioctl_passthrough_cmd(&cmd);
			s_memset(&input_payload, sizeof (input_payload));

			// clear any device context - security state has likely changed
			invalidate_devices();
		}
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Example #4
0
/*
 * Erases the data on the device specified.
 */
int nvm_erase_device(const NVM_UID device_uid,
		const NVM_PASSPHRASE passphrase, const NVM_SIZE passphrase_len)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;
	struct device_discovery discovery;

	// check user has permission to make changes
	if (check_caller_permissions() != COMMON_SUCCESS)
	{
		rc = NVM_ERR_INVALIDPERMISSIONS;
	}
	else if (!is_supported_driver_available())
	{
		rc = NVM_ERR_BADDRIVER;
	}
	else if ((rc = IS_NVM_FEATURE_SUPPORTED(modify_device_security)) != NVM_SUCCESS)
	{
		COMMON_LOG_ERROR("Modifying " NVM_DIMM_NAME " security is not supported.");
	}
	else if (device_uid == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, device_uid is NULL");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	else if ((rc = exists_and_manageable(device_uid, &discovery, 1)) == NVM_SUCCESS)
	{
		if (discovery.security_capabilities.passphrase_capable)
		{
			// check passphrase length
			if (check_passphrase(passphrase, passphrase_len) != NVM_SUCCESS)
			{
				rc = NVM_ERR_BADPASSPHRASE;
			}
			// verify device is in the right state to accept a secure erase
			else if ((rc =
					security_change_prepare(&discovery, passphrase, passphrase_len))
					== NVM_SUCCESS)
			{
				rc = secure_erase(passphrase, passphrase_len, &discovery);
				// clear any device context - security state has likely changed
				invalidate_devices();
			}
		}
		else
		{
			COMMON_LOG_ERROR("Invalid parameter. "
					"Crypto scramble erase is not valid in the current security state");
			rc = NVM_ERR_INVALIDPARAMETER;
		}
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Example #5
0
int nvm_get_job_count()
{
	COMMON_LOG_ENTRY();
	int rc = NVM_ERR_UNKNOWN;

	if (check_caller_permissions() != NVM_SUCCESS)
	{
		rc = NVM_ERR_INVALIDPERMISSIONS;
	}
	else
	{
		rc = get_job_count();
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Example #6
0
/*
 * Run a diagnostic test on the device specified.
 */
int nvm_run_diagnostic(const NVM_GUID device_guid,
		const struct diagnostic *p_diagnostic, NVM_UINT32 *p_results)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;

	if (p_diagnostic == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, p_diagnostic is NULL");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	else if (p_results == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, p_results is NULL");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	else if (check_caller_permissions() != NVM_SUCCESS)
	{
		rc = NVM_ERR_INVALIDPERMISSIONS;
	}
	else
	{
		switch (p_diagnostic->test)
		{
			case DIAG_TYPE_QUICK:
				rc = diag_quick_health_check(device_guid, p_diagnostic, p_results);
				break;
			case DIAG_TYPE_PLATFORM_CONFIG:
				rc = diag_platform_config_check(p_diagnostic, p_results);
				break;
			case DIAG_TYPE_PM_META:
				rc = diag_pm_metadata_check(p_results);
				break;
			case DIAG_TYPE_FW_CONSISTENCY:
				rc = diag_firmware_check(p_diagnostic, p_results);
				break;
			case DIAG_TYPE_SECURITY:
				rc = diag_security_check(p_diagnostic, p_results);
				break;
		}
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Example #7
0
int nvm_get_job_count()
{
	COMMON_LOG_ENTRY();
	int rc = NVM_ERR_UNKNOWN;

	if (check_caller_permissions() != NVM_SUCCESS)
	{
		rc = NVM_ERR_INVALIDPERMISSIONS;
	}
	else if (!is_supported_driver_available())
	{
		rc = NVM_ERR_BADDRIVER;
	}
	else
	{
		rc = get_job_count();
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Example #8
0
/*
 * Disables data at rest security and removes the passphrase.
 * The device will be unlocked if it is currently locked.
 */
int nvm_remove_passphrase(const NVM_UID device_uid,
		const NVM_PASSPHRASE passphrase, const NVM_SIZE passphrase_len)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;
	struct device_discovery discovery;

	// check user has permission to make changes
	if (check_caller_permissions() != COMMON_SUCCESS)
	{
		rc = NVM_ERR_INVALIDPERMISSIONS;
	}
	else if (!is_supported_driver_available())
	{
		rc = NVM_ERR_BADDRIVER;
	}
	else if ((rc = IS_NVM_FEATURE_SUPPORTED(modify_device_security)) != NVM_SUCCESS)
	{
		COMMON_LOG_ERROR("Modifying " NVM_DIMM_NAME " security is not supported.");
	}
	else if (device_uid == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, device_uid is NULL");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	else if (((rc = check_passphrase(passphrase, passphrase_len)) == NVM_SUCCESS) &&
			((rc = exists_and_manageable(device_uid, &discovery, 1)) == NVM_SUCCESS) &&
			((rc = check_passphrase_capable(device_uid)) == NVM_SUCCESS) &&
			((rc = security_change_prepare(&discovery, passphrase, passphrase_len))
					== NVM_SUCCESS))
	{
		// send a pass through command to disable security
		struct pt_payload_passphrase input_payload;
		memset(&input_payload, 0, sizeof (input_payload));
		s_strncpy(input_payload.passphrase_current, NVM_PASSPHRASE_LEN,
				passphrase, passphrase_len);

		struct fw_cmd cmd;
		memset(&cmd, 0, sizeof (struct fw_cmd));
		cmd.device_handle = discovery.device_handle.handle;
		cmd.opcode = PT_SET_SEC_INFO;
		cmd.sub_opcode = SUBOP_DISABLE_PASS;
		cmd.input_payload_size = sizeof (input_payload);
		cmd.input_payload = &input_payload;
		rc = ioctl_passthrough_cmd(&cmd);
		if (rc == NVM_SUCCESS)
		{
			// Log an event indicating we successfully removed the passphrase
			NVM_EVENT_ARG uid_arg;
			uid_to_event_arg(device_uid, uid_arg);
			log_mgmt_event(EVENT_SEVERITY_INFO,
					EVENT_CODE_MGMT_SECURITY_PASSWORD_REMOVED,
					device_uid,
					0, // no action required
					uid_arg, NULL, NULL);
		}
		s_memset(&input_payload, sizeof (input_payload));

		// clear any device context - security state has likely changed
		invalidate_devices();
	}

	COMMON_LOG_EXIT_RETURN_I(rc);
	return rc;
}
Example #9
0
int nvm_get_jobs(struct job *p_jobs, const NVM_UINT32 count)
{
	COMMON_LOG_ENTRY();
	int rc = NVM_SUCCESS;
	int job_index = 0;

	if (check_caller_permissions() != NVM_SUCCESS)
	{
		rc = NVM_ERR_INVALIDPERMISSIONS;
	}
	else if (!is_supported_driver_available())
	{
		rc = NVM_ERR_BADDRIVER;
	}
	else if (p_jobs == NULL)
	{
		COMMON_LOG_ERROR("Invalid parameter, p_jobs is NULL");
		rc = NVM_ERR_INVALIDPARAMETER;
	}
	else if ((rc = get_job_count()) < 0)
	{
		COMMON_LOG_ERROR("Failed to retrieve job count.");
	}
	else if (rc > 0)
	{
		// clear the structure
		memset(p_jobs, 0, sizeof (struct job) * count);

		if ((rc = nvm_get_device_count()) >= 0)
		{
			int device_count = rc;
			struct device_discovery devices[rc];
			if ((rc = nvm_get_devices(devices, device_count)) > 0)
			{
				// iterate through all devices and add up the capacities
				for (int i = 0; i < device_count; i++)
				{
					if (job_index >= count)
					{
						rc = NVM_ERR_ARRAYTOOSMALL;
						COMMON_LOG_ERROR("Invalid parameter, "
								"count is smaller than number of jobs");
						break;
					}

					if (devices[i].manageability == MANAGEMENT_VALIDCONFIG)
					{
						struct pt_payload_sanitize_dimm_status sanitize_status;
						struct fw_cmd cmd;
						memset(&cmd, 0, sizeof (struct fw_cmd));
						cmd.device_handle = devices[i].device_handle.handle;
						cmd.opcode = PT_GET_SEC_INFO;
						cmd.sub_opcode = SUBOP_GET_SAN_STATE;
						cmd.output_payload_size = sizeof (sanitize_status);
						cmd.output_payload = &sanitize_status;
						if (NVM_SUCCESS != ioctl_passthrough_cmd(&cmd))
						{
							COMMON_LOG_ERROR_F(
									"Unable to get sanitize status for handle: [%d]",
									devices[i].device_handle.handle);
						}
						else
						{
							if (sanitize_status.state != SAN_IDLE)
							{
								if (sanitize_status.state == SAN_INPROGRESS)
								{
									p_jobs[job_index].status = NVM_JOB_STATUS_RUNNING;
								}
								else if (sanitize_status.state ==  SAN_COMPLETED)
								{
									p_jobs[job_index].status = NVM_JOB_STATUS_COMPLETE;
								}
								else
								{
									p_jobs[job_index].status = NVM_JOB_STATUS_UNKNOWN;
								}

								p_jobs[job_index].type = NVM_JOB_TYPE_SANITIZE;
								p_jobs[job_index].percent_complete = sanitize_status.progress;
								memmove(p_jobs[job_index].uid, devices[i].uid, NVM_MAX_UID_LEN);
								memmove(p_jobs[job_index].affected_element,
									devices[i].uid, NVM_MAX_UID_LEN);
								p_jobs[job_index].result = NULL;
								job_index++;
							}
						}
					}
					rc = job_index;
				}
			}
			else
			{
				COMMON_LOG_ERROR_F("Unable to get device discovery: rc = %d", rc);
			}
		}
		else
		{
			COMMON_LOG_ERROR_F("Unable to get device count: rc = %d", rc);
		}
	}
	return rc;
}