Re: [PATCH] block: sed-opal: Implement RevertSP IOCTL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Revanth,


On Mon, 2020-04-13 at 17:11 -0600, Revanth Rajashekar wrote:
> This patch implements an ioctl for Reverting SP functionality.
> RevertSP fucntionality
*functionality

> can be used under scenarios where user
> data shall not be erased after TPer reverting.
> 
> The pacth
*patch

> adds a new optional parameter 'keep_glbl_rn_key' to opal_key struct.
> If the optional parameter,
> keep_glbl_rn_key(KeepGlobalRangeKey),is provided
space after comma

> with a value of TRUE, then the media encryption key associated with
> Locking_GlobalRange is preserved. Else, all user data is cryptographically
> erased.
> 
> Test Scenarios:
> RevertSP(keep_glbl_rn_key = true)  + RevertTper => Data is retained
> RevertSP(keep_glbl_rn_key = false) + RevertTper => Data is erased
> RevertSP(no keep_glbl_rn_key)      + RevertTper => Data is erased
> 
> Reference:
> 1. Section 5.1.3 of https://trustedcomputinggroup.org/wp-content/uploads/TCG_Storage-Opal_SSC_v2.01_rev1.00.pdf
> 2. Section 3.2.12.2 of https://trustedcomputinggroup.org/wp-content/uploads/TCG_Storage_Opal_SSC_Application_Note_1-00_1-00-Final.pdf
> 
> Signed-off-by: Revanth Rajashekar <revanth.rajashekar@xxxxxxxxx>
> ---
>  block/opal_proto.h            |  6 ++++
>  block/sed-opal.c              | 52 +++++++++++++++++++++++++++++++----
>  include/linux/sed-opal.h      |  1 +
>  include/uapi/linux/sed-opal.h |  4 ++-
>  4 files changed, 57 insertions(+), 6 deletions(-)
> 
> diff --git a/block/opal_proto.h b/block/opal_proto.h
> index b486b3ec7dc4..8c6faa418ab4 100644
> --- a/block/opal_proto.h
> +++ b/block/opal_proto.h
> @@ -140,6 +140,12 @@ enum opal_method {
>  	OPAL_ERASE,
>  };
> 
> +enum opal_revert_method {
> +	OPAL_REVERT_TPER,
> +	OPAL_REVERT_PSID,
> +	OPAL_REVERT_SP,
> +};
> +
>  enum opal_token {
>  	/* Boolean */
>  	OPAL_TRUE = 0x01,
> diff --git a/block/sed-opal.c b/block/sed-opal.c
> index daafadbb88ca..1939df83c45e 100644
> --- a/block/sed-opal.c
> +++ b/block/sed-opal.c
> @@ -1552,6 +1552,28 @@ static int revert_tper(struct opal_dev *dev, void *data)
>  	return finalize_and_send(dev, parse_and_check_status);
>  }
> 
> +static int revert_sp(struct opal_dev *dev, void *data)
> +{
> +	int err;
> +	struct opal_key *key = data;
> +
> +	err = cmd_start(dev, opaluid[OPAL_THISSP_UID],
> +			opalmethod[OPAL_REVERTSP]);
> +
> +	add_token_u8(&err, dev, OPAL_STARTNAME);
> +	add_token_u64(&err, dev, OPAL_SUM_SET_LIST);
> +
> +	/*
> +	 * If KeepGlobalRangeKey is true, then the media encryption key
> +	 * associated with Locking_GlobalRange is preserved.
> +	 * If not true, then all user data is cryptographically erased.
> +	 */
> +	add_token_u8(&err, dev, key->keep_glbl_rn_key ? OPAL_TRUE : OPAL_FALSE);
> +	add_token_u8(&err, dev, OPAL_ENDNAME);
> +
> +	return finalize_and_send(dev, parse_and_check_status);
> +}
> +
>  static int internal_activate_user(struct opal_dev *dev, void *data)
>  {
>  	struct opal_session_info *session = data;
> @@ -2327,7 +2349,8 @@ static int opal_add_user_to_lr(struct opal_dev *dev,
>  	return ret;
>  }
> 
> -static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal, bool psid)
> +static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal,
> +			   enum opal_revert_method revert_type)
>  {
>  	/* controller will terminate session */
>  	const struct opal_step revert_steps[] = {
> @@ -2338,17 +2361,33 @@ static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal, bool psi
>  		{ start_PSID_opal_session, opal },
>  		{ revert_tper, }
>  	};
> +	const struct opal_step revertsp_steps[] = {
> +		{ start_admin1LSP_opal_session, opal },
> +		{ revert_sp, opal }
> +	};
> 
>  	int ret;
> 
>  	mutex_lock(&dev->dev_lock);
>  	setup_opal_dev(dev);
> -	if (psid)
> +	switch (revert_type) {
> +	case OPAL_REVERT_PSID:
>  		ret = execute_steps(dev, psid_revert_steps,
>  				    ARRAY_SIZE(psid_revert_steps));
> -	else
> +		break;
> +	case OPAL_REVERT_TPER:
>  		ret = execute_steps(dev, revert_steps,
>  				    ARRAY_SIZE(revert_steps));
> +		break;
> +	case OPAL_REVERT_SP:
> +		ret = execute_steps(dev, revertsp_steps,
> +				    ARRAY_SIZE(revertsp_steps));
> +		break;
> +	default:
> +		pr_debug("Invalid revert type\n");
> +		ret = -EINVAL;
> +		break;
> +	}
>  	mutex_unlock(&dev->dev_lock);
> 
>  	/*
> @@ -2656,7 +2695,7 @@ int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
>  		ret = opal_activate_user(dev, p);
>  		break;
>  	case IOC_OPAL_REVERT_TPR:
> -		ret = opal_reverttper(dev, p, false);
> +		ret = opal_reverttper(dev, p, OPAL_REVERT_TPER);
>  		break;
>  	case IOC_OPAL_LR_SETUP:
>  		ret = opal_setup_locking_range(dev, p);
> @@ -2680,11 +2719,14 @@ int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg)
>  		ret = opal_secure_erase_locking_range(dev, p);
>  		break;
>  	case IOC_OPAL_PSID_REVERT_TPR:
> -		ret = opal_reverttper(dev, p, true);
> +		ret = opal_reverttper(dev, p, OPAL_REVERT_PSID);
>  		break;
>  	case IOC_OPAL_GENERIC_TABLE_RW:
>  		ret = opal_generic_read_write_table(dev, p);
>  		break;
> +	case IOC_OPAL_REVERT_SP:
> +		ret = opal_reverttper(dev, p, OPAL_REVERT_SP);
> +		break;
>  	default:
>  		break;
>  	}
> diff --git a/include/linux/sed-opal.h b/include/linux/sed-opal.h
> index 1ac0d712a9c3..85ad7bb7da41 100644
> --- a/include/linux/sed-opal.h
> +++ b/include/linux/sed-opal.h
> @@ -43,6 +43,7 @@ static inline bool is_sed_ioctl(unsigned int cmd)
>  	case IOC_OPAL_MBR_DONE:
>  	case IOC_OPAL_WRITE_SHADOW_MBR:
>  	case IOC_OPAL_GENERIC_TABLE_RW:
> +	case IOC_OPAL_REVERT_SP:
>  		return true;
>  	}
>  	return false;
> diff --git a/include/uapi/linux/sed-opal.h b/include/uapi/linux/sed-opal.h
> index 6f5af1a84213..ac59fbc1d06b 100644
> --- a/include/uapi/linux/sed-opal.h
> +++ b/include/uapi/linux/sed-opal.h
> @@ -47,7 +47,8 @@ enum opal_lock_state {
>  struct opal_key {
>  	__u8 lr;
>  	__u8 key_len;
> -	__u8 __align[6];
> +	__u8 keep_glbl_rn_key;
> +	__u8 __align[5];
> 
This is mostly fine, except that we're changing the definition of bits
in an existing ioctl structure. We're not using those bits for any
other ioctl so I wouldn't expect issues.

I think instead you should take 4 bytes of __align and change it to a
__u32 'flags', and #define a bitwise flag for your purposes. Eg,
similar to the flags param in opal_read_write_table.

Please update the commit message if you do that.

>  	__u8 key[OPAL_KEY_MAX];
>  };
> 
> @@ -148,5 +149,6 @@ struct opal_read_write_table {
>  #define IOC_OPAL_MBR_DONE           _IOW('p', 233, struct opal_mbr_done)
>  #define IOC_OPAL_WRITE_SHADOW_MBR   _IOW('p', 234, struct opal_shadow_mbr)
>  #define IOC_OPAL_GENERIC_TABLE_RW   _IOW('p', 235, struct opal_read_write_table)
> +#define IOC_OPAL_REVERT_SP          _IOW('p', 236, struct opal_key)
> 
>  #endif /* _UAPI_SED_OPAL_H */
> --
> 2.17.1
> 




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux