Opal: Add support for erase locking range
Change-Id: Ie40ea642bc266f84ad5a3dbad8012b9eac178360 Signed-off-by: Chunyang Hui <chunyang.hui@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/465244 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
parent
a1d0f799c2
commit
0fae4f64c4
@ -962,13 +962,14 @@ opal_usage(void)
|
||||
printf("\n");
|
||||
printf("\t[1: scan device]\n");
|
||||
printf("\t[2: init - take ownership and activate locking]\n");
|
||||
printf("\t[3: setup locking range]\n");
|
||||
printf("\t[4: list locking ranges]\n");
|
||||
printf("\t[5: enable user]\n");
|
||||
printf("\t[6: set new password]\n");
|
||||
printf("\t[7: add user to locking range]\n");
|
||||
printf("\t[8: lock/unlock range]\n");
|
||||
printf("\t[9: revert tper]\n");
|
||||
printf("\t[3: revert tper]\n");
|
||||
printf("\t[4: setup locking range]\n");
|
||||
printf("\t[5: list locking ranges]\n");
|
||||
printf("\t[6: enable user]\n");
|
||||
printf("\t[7: set new password]\n");
|
||||
printf("\t[8: add user to locking range]\n");
|
||||
printf("\t[9: lock/unlock range]\n");
|
||||
printf("\t[10: erase locking range]\n");
|
||||
printf("\t[0: quit]\n");
|
||||
}
|
||||
|
||||
@ -1493,6 +1494,51 @@ opal_revert_tper(struct dev *iter)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
opal_erase_locking_range(struct dev *iter)
|
||||
{
|
||||
char passwd[MAX_PASSWORD_SIZE] = {0};
|
||||
char *passwd_p;
|
||||
int ret;
|
||||
int ch;
|
||||
int locking_range_id;
|
||||
|
||||
if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) {
|
||||
iter->opal_dev = spdk_opal_init_dev(iter->ctrlr);
|
||||
if (iter->opal_dev == NULL) {
|
||||
return;
|
||||
}
|
||||
if (spdk_opal_supported(iter->opal_dev)) {
|
||||
printf("Please be noted this operation will erase ALL DATA on this range\n");
|
||||
printf("Please input password for erase locking range:");
|
||||
while ((ch = getchar()) != '\n' && ch != EOF);
|
||||
passwd_p = get_line(passwd, MAX_PASSWORD_SIZE, stdin, true);
|
||||
if (passwd_p) {
|
||||
printf("\nSpecify locking range id:\n");
|
||||
if (!scanf("%d", &locking_range_id)) {
|
||||
printf("Invalid locking range id\n");
|
||||
spdk_opal_close(iter->opal_dev);
|
||||
return;
|
||||
}
|
||||
printf("\n...\n");
|
||||
ret = spdk_opal_cmd_erase_locking_range(iter->opal_dev, OPAL_ADMIN1, locking_range_id, passwd_p);
|
||||
if (ret) {
|
||||
printf("Erase locking range failure: %d\n", ret);
|
||||
spdk_opal_close(iter->opal_dev);
|
||||
return;
|
||||
}
|
||||
printf("...\nErase locking range Success\n");
|
||||
} else {
|
||||
printf("Input password invalid. Erase locking range failure\n");
|
||||
}
|
||||
}
|
||||
spdk_opal_close(iter->opal_dev);
|
||||
} else {
|
||||
printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n",
|
||||
iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_opal(void)
|
||||
{
|
||||
@ -1526,25 +1572,28 @@ test_opal(void)
|
||||
opal_init(ctrlr); /* Take ownership, Activate Locking SP */
|
||||
break;
|
||||
case 3:
|
||||
opal_setup_lockingrange(ctrlr);
|
||||
opal_revert_tper(ctrlr);
|
||||
break;
|
||||
case 4:
|
||||
opal_list_locking_ranges(ctrlr);
|
||||
opal_setup_lockingrange(ctrlr);
|
||||
break;
|
||||
case 5:
|
||||
opal_new_user_enable(ctrlr);
|
||||
opal_list_locking_ranges(ctrlr);
|
||||
break;
|
||||
case 6:
|
||||
opal_change_password(ctrlr);
|
||||
opal_new_user_enable(ctrlr);
|
||||
break;
|
||||
case 7:
|
||||
opal_add_user_to_locking_range(ctrlr);
|
||||
opal_change_password(ctrlr);
|
||||
break;
|
||||
case 8:
|
||||
opal_user_lock_unlock_range(ctrlr);
|
||||
opal_add_user_to_locking_range(ctrlr);
|
||||
break;
|
||||
case 9:
|
||||
opal_revert_tper(ctrlr);
|
||||
opal_user_lock_unlock_range(ctrlr);
|
||||
break;
|
||||
case 10:
|
||||
opal_erase_locking_range(ctrlr);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -193,7 +193,8 @@ 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);
|
||||
|
||||
struct spdk_opal_locking_range_info *spdk_opal_get_locking_range_info(struct spdk_opal_dev *dev,
|
||||
enum spdk_opal_locking_range id);
|
||||
|
@ -1927,6 +1927,113 @@ opal_revert_tper(struct spdk_opal_dev *dev)
|
||||
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
opal_gen_new_active_key(struct spdk_opal_dev *dev)
|
||||
{
|
||||
uint8_t uid_data[OPAL_UID_LENGTH] = {0};
|
||||
int err = 0;
|
||||
int length;
|
||||
|
||||
opal_clear_cmd(dev);
|
||||
opal_set_comid(dev, dev->comid);
|
||||
|
||||
if (dev->prev_data == NULL || dev->prev_d_len == 0) {
|
||||
SPDK_ERRLOG("Error finding previous data to generate new active key\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
length = spdk_min(dev->prev_d_len, OPAL_UID_LENGTH);
|
||||
memcpy(uid_data, dev->prev_data, length);
|
||||
free(dev->prev_data);
|
||||
dev->prev_data = NULL;
|
||||
|
||||
opal_add_token_u8(&err, dev, SPDK_OPAL_CALL);
|
||||
opal_add_token_bytestring(&err, dev, uid_data, OPAL_UID_LENGTH);
|
||||
opal_add_token_bytestring(&err, dev, spdk_opal_method[GENKEY_METHOD],
|
||||
OPAL_UID_LENGTH);
|
||||
|
||||
opal_add_tokens(&err, dev, 2, SPDK_OPAL_STARTLIST, SPDK_OPAL_ENDLIST);
|
||||
|
||||
if (err) {
|
||||
SPDK_ERRLOG("Error building new key generation command.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
opal_get_active_key_cb(struct spdk_opal_dev *dev, void *data)
|
||||
{
|
||||
const char *active_key;
|
||||
size_t str_len;
|
||||
int error = 0;
|
||||
|
||||
error = opal_parse_and_check_status(dev, NULL);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
str_len = opal_response_get_string(&dev->parsed_resp, 4, &active_key);
|
||||
if (!active_key) {
|
||||
SPDK_ERRLOG("Couldn't extract active key from response\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev->prev_d_len = str_len;
|
||||
dev->prev_data = calloc(1, str_len);
|
||||
if (!dev->prev_data) {
|
||||
SPDK_ERRLOG("memory allocation error\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(dev->prev_data, active_key, str_len);
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_OPAL, "active key = %p\n", dev->prev_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opal_get_active_key(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[GET_METHOD],
|
||||
OPAL_UID_LENGTH);
|
||||
opal_add_tokens(&err, dev, 12,
|
||||
SPDK_OPAL_STARTLIST,
|
||||
SPDK_OPAL_STARTLIST,
|
||||
SPDK_OPAL_STARTNAME,
|
||||
SPDK_OPAL_STARTCOLUMN,
|
||||
SPDK_OPAL_ACTIVEKEY,
|
||||
SPDK_OPAL_ENDNAME,
|
||||
SPDK_OPAL_STARTNAME,
|
||||
SPDK_OPAL_ENDCOLUMN,
|
||||
SPDK_OPAL_ACTIVEKEY,
|
||||
SPDK_OPAL_ENDNAME,
|
||||
SPDK_OPAL_ENDLIST,
|
||||
SPDK_OPAL_ENDLIST);
|
||||
|
||||
if (err) {
|
||||
SPDK_ERRLOG("Error building get active key command.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
return opal_finalize_and_send(dev, 1, opal_get_active_key_cb, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
spdk_opal_cmd_revert_tper(struct spdk_opal_dev *dev, const char *passwd)
|
||||
{
|
||||
@ -2347,6 +2454,56 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
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 = {};
|
||||
struct spdk_opal_key opal_key;
|
||||
int ret;
|
||||
|
||||
if (!dev || dev->supported == false) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = opal_init_key(&opal_key, password, locking_range_id);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
session.opal_key = &opal_key;
|
||||
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: %s\n", ret, opal_error_to_human(ret));
|
||||
pthread_mutex_unlock(&dev->mutex_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = opal_get_active_key(dev, &session);
|
||||
if (ret) {
|
||||
SPDK_ERRLOG("get active key error %d: %s\n", ret, opal_error_to_human(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = opal_gen_new_active_key(dev);
|
||||
if (ret) {
|
||||
SPDK_ERRLOG("generate new active key error %d: %s\n", ret, opal_error_to_human(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
ret += opal_end_session(dev);
|
||||
if (ret) {
|
||||
SPDK_ERRLOG("end session error %d: %s\n", ret, opal_error_to_human(ret));
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&dev->mutex_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct spdk_opal_info *
|
||||
spdk_opal_get_info(struct spdk_opal_dev *dev)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user