nvme/opal: add erase locking range method support

The previous erase locking range API didn't take the real
erase action, it's kind of secure erase, so rename it with
another name and add the real erase support.

This method is used to cryptographically erase user data within
a specific LBA Range and to reset the access control Locking
of that LBA Range.

The TPer SHALL reset the ReadLockEnabled, WriteLockEnabled,
ReadLocked, and WriteLocked column values to False for the
Locking object on which the method is invoked.

Change-Id: I0c83df589382b0a2f189642d8119e389aa4bc559
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1210
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Changpeng Liu 2020-03-10 23:20:04 +08:00 committed by Tomasz Zawadzki
parent 3020a6fb30
commit 8c1d107487
3 changed files with 78 additions and 0 deletions

View File

@ -153,9 +153,13 @@ int spdk_opal_cmd_add_user_to_locking_range(struct spdk_opal_dev *dev, enum spdk
enum spdk_opal_lock_state lock_flag, const char *passwd);
int spdk_opal_cmd_set_new_passwd(struct spdk_opal_dev *dev, enum spdk_opal_user user_id,
const char *new_passwd, const char *old_passwd, bool new_user);
int spdk_opal_cmd_erase_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user_id,
enum spdk_opal_locking_range locking_range_id, const char *password);
int spdk_opal_cmd_secure_erase_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user_id,
enum spdk_opal_locking_range locking_range_id, const char *password);
struct spdk_opal_locking_range_info *spdk_opal_get_locking_range_info(struct spdk_opal_dev *dev,
enum spdk_opal_locking_range id);
void spdk_opal_free_locking_range_info(struct spdk_opal_dev *dev, enum spdk_opal_locking_range id);

View File

@ -1907,6 +1907,36 @@ opal_get_active_key(struct spdk_opal_dev *dev, struct opal_common_session *sessi
return opal_finalize_and_send(dev, 1, opal_get_active_key_cb, (void *)active_key);
}
static int
opal_erase_locking_range(struct spdk_opal_dev *dev, struct opal_common_session *session)
{
uint8_t uid_locking_range[OPAL_UID_LENGTH];
uint8_t locking_range_id;
int err = 0;
opal_clear_cmd(dev);
opal_set_comid(dev, dev->comid);
locking_range_id = session->opal_key.locking_range;
err = opal_build_locking_range(uid_locking_range, OPAL_UID_LENGTH, locking_range_id);
if (err) {
return err;
}
opal_add_token_u8(&err, dev, SPDK_OPAL_CALL);
opal_add_token_bytestring(&err, dev, uid_locking_range, OPAL_UID_LENGTH);
opal_add_token_bytestring(&err, dev, spdk_opal_method[ERASE_METHOD],
OPAL_UID_LENGTH);
opal_add_tokens(&err, dev, 2, SPDK_OPAL_STARTLIST, SPDK_OPAL_ENDLIST);
if (err) {
SPDK_ERRLOG("Error building erase locking range.\n");
return err;
}
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status, NULL);
}
int
spdk_opal_cmd_revert_tper(struct spdk_opal_dev *dev, const char *passwd)
{
@ -2403,6 +2433,47 @@ end:
int
spdk_opal_cmd_erase_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user_id,
enum spdk_opal_locking_range locking_range_id, const char *password)
{
struct opal_common_session session = {};
int ret;
if (dev->supported == false) {
return -ENODEV;
}
ret = opal_init_key(&session.opal_key, password, locking_range_id);
if (ret != 0) {
return ret;
}
session.who = user_id;
pthread_mutex_lock(&dev->mutex_lock);
ret = opal_start_auth_session(dev, &session);
if (ret) {
SPDK_ERRLOG("start authenticate session error %d\n", ret);
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
ret = opal_erase_locking_range(dev, &session);
if (ret) {
SPDK_ERRLOG("get active key error %d\n", ret);
goto end;
}
end:
ret += opal_end_session(dev);
if (ret) {
SPDK_ERRLOG("end session error %d\n", ret);
}
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
int
spdk_opal_cmd_secure_erase_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user_id,
enum spdk_opal_locking_range locking_range_id, const char *password)
{
struct opal_common_session session = {};
struct spdk_opal_key active_key = {};

View File

@ -115,6 +115,7 @@ enum opal_method_enum {
SET_METHOD,
AUTHENTICATE_METHOD,
RANDOM_METHOD,
ERASE_METHOD,
};
struct spdk_opal_key {
@ -226,6 +227,8 @@ const uint8_t spdk_opal_method[][OPAL_UID_LENGTH] = {
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c },
[RANDOM_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x01 },
[ERASE_METHOD] =
{ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x08, 0x03 },
};
/*