Message ID | 20200413231121.8207-1-revanth.rajashekar@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | block: sed-opal: Implement RevertSP IOCTL | expand |
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@intel.com> > --- > 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 >
Hi Jon, Thanks for the feedback. On 4/14/2020 10:14 AM, Derrick, Jonathan wrote: > 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 Will fix it. > >> can be used under scenarios where user >> data shall not be erased after TPer reverting. >> >> The pacth > *patch Will fix it. > >> 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 Will fix it. > >> 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@intel.com> >> --- >> 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. Changing to __u32 flag is a very good idea. This can be used for any future implementations as well. How about having an enumeration "opal_key_flags", instead of #define for the flag. > > Please update the commit message if you do that. Sure... will do it. > >> __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 >>
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]; __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 */
This patch implements an ioctl for Reverting SP functionality. RevertSP fucntionality can be used under scenarios where user data shall not be erased after TPer reverting. The pacth adds a new optional parameter 'keep_glbl_rn_key' to opal_key struct. If the optional parameter, keep_glbl_rn_key(KeepGlobalRangeKey),is provided 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@intel.com> --- 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(-) -- 2.17.1