Add password protected lock/unlock support for SD/MMC
v3 cover Add password protected lock/unlock support for SD/MMC
This set of patches adds support for password protected locking and unlocking of MMC and SD devices. It uses the LOCK/UNLOCK command (CMD42) available in both the MMC and SD command sets.
Some of this code was based on a patch set submitted in 2006 by Anderson Briglia "Add MMC Password Protection (lock/unlock)". This patch set never made it into mainline.
By default, a card with no password assigned is always in "unlocked" state. After password assignment, in the next power cycle the card switches to a "locked" state where only the "basic" and "lock card" command classes are accepted by the card. Only after unlocking it with the correct password can the card be used for normal operations like block I/O.
Password management and caching is done through the "Kernel Key Retention Service" mechanism and the sysfs filesystem. Two new sysfs attributes were added. The "lock" attribute is used to lock, unlock, assign a password, clear a password and force erase a card. The "unlock_retry" attribute is used to retry an unlock that failed during boot because the rootfs was not yet available with the password.
The user space software needed to test this new feature is available on GitHub at:
https://github.com/alcooper/mmc-password-utils
See the README for a detailed description of the user space layer and how to use this feature.
Changed for V3:
- Ported the V2 patch set submitted Aug. 2013 to the latest mainline
(v4.1-rc4).
- Created a GitHub project for the user space layer.
- Change the lock command (CMD42) to round up the data buffer size to 512 for SD but leave exact size for eMMC based on the SD and eMMC specs.
Changed for V2:
The V2 changes were not functional and were just general cleanup.
- Use stub functions to reduce the number of CONFIG ifdefs.
- Add static to a few functions that were local.
- Use pr_warn instead of pr_warning.
- Improve a few variable names and messages.
Abbas Raza (1):
According to SD Physical Layer Specifications: Locked cards respond to
(and execute) all commands in the "basic" command class (class 0), ACMD41, CMD16 and "lock card" command class. Thus, the host is allowed to reset, initialize, select, query for status, etc., but not to access data on the card.
Al Cooper (7):
mmc: lock: Use the kernel "KEYS" subsystem to get a card's password
mmc: lock: Add low level LOCK_UNLOCK command
mmc: lock: Add function to unlock a password locked card
mmc: lock: Add card lock/unlock maintenance commands
mmc: lock: Change SD init functionality to handle locked SD cards
mmc: lock: Prevent partition table read for locked cards.
mmc: lock: Change MMC init to handle locked cards.
drivers/mmc/card/block.c | 14 ++++ drivers/mmc/core/Kconfig | 8 +++ drivers/mmc/core/core.c | 120 +++++++++++++++++++++++++++++++++ drivers/mmc/core/core.h | 14 +++- drivers/mmc/core/mmc.c | 123 ++++++++++++++++++++++++++++++++++ drivers/mmc/core/mmc_ops.c | 150 +++++++++++++++++++++++++++++++++++++++++ drivers/mmc/core/mmc_ops.h | 13 ++++ drivers/mmc/core/sd.c | 161 +++++++++++++++++++++++++++++++-------------- include/linux/mmc/card.h | 6 ++ 9 files changed, 560 insertions(+), 49 deletions(-)
Signature · 1 line
1.9.0.138.g2de3478
PATCH v3 1/8 mmc: lock: Use the kernel "KEYS" subsystem to get a card's password
Use the kernel "KEYS" subsystem to get a password for a card based on the card's CID. This code was based on a patch set submitted by Anderson Briglia in 2006.
--- drivers/mmc/core/Kconfig | 8 ++++ drivers/mmc/core/core.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/core/core.h | 10 ++++- 3 files changed, 114 insertions(+), 1 deletion(-)
drivers/mmc/core/Kconfig +8 -0
@@ -11,3 +11,11 @@ config MMC_CLKGATE support handling this in order for it to be of any use. If unsure, say N. + +config MMC_LOCK + bool "MMC/SD password based card lock/unlock" + select KEYS + help + This will add the ability to lock/unlock SD and MMC cards. + + If unsure, say N.
drivers/mmc/core/core.c +97 -0
123 lines not on this page · raw message
drivers/mmc/core/core.h +9 -1
@@ -89,5 +89,13 @@ void mmc_init_context_info(struct mmc_host *host);int mmc_execute_tuning (struct mmc_card *card); -#endif +/* Lock/Unlock functionality */ +#define MMC_PASSWORD_MAX 16 +struct mmc_password { +char password[MMC_PASSWORD_MAX ]; +int length; +}; +int mmc_unlock_card (struct mmc_card *card); +int mmc_get_password (struct mmc_card *card,struct mmc_password *password); +#endif
Signature · 1 line
1.9.0.138.g2de3478
PATCH v3 2/8 mmc: lock: Add low level LOCK_UNLOCK command
In reply to Al CooperAdd support for the LOCK_UNLOCK command. This command can lock, unlock, set password, clear password and force erase SD and MMC cards.
--- drivers/mmc/core/core.c | 5 +- drivers/mmc/core/mmc_ops.c | 150 +++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/core/mmc_ops.h | 13 ++++ include/linux/mmc/card.h | 5 ++ 4 files changed, 169 insertions(+), 4 deletions(-)
drivers/mmc/core/core.c +1 -4
@@ -2716,11 +2716,8 @@ static int mmc_key_instantiate(struct key *key,char *payload;if (prep->datalen <=0 || prep->datalen >MMC_PASSWORD_MAX || - !prep->data) { -pr_warn ("Invalid data\n" ); + !prep->data)return -EINVAL ; - } - payload =kmalloc (prep->datalen,GFP_KERNEL );if (!payload)return -ENOMEM ;
drivers/mmc/core/mmc_ops.c +150 -0
159 lines not on this page · raw message
drivers/mmc/core/mmc_ops.h +13 -0
@@ -12,6 +12,15 @@#ifndef _MMC_MMC_OPS_H#define _MMC_MMC_OPS_H +/* +* MMC_LOCK_UNLOCK modes +*/ +#define MMC_LOCK_MODE_ERASE (1<<3) +#define MMC_LOCK_MODE_LOCK (1<<2) +#define MMC_LOCK_MODE_UNLOCK (0<<2) +#define MMC_LOCK_MODE_CLR_PWD (1<<1) +#define MMC_LOCK_MODE_SET_PWD (1<<0) +int mmc_select_card (struct mmc_card *card);int mmc_deselect_cards (struct mmc_host *host);int mmc_set_dsr (struct mmc_host *host);
@@ -27,6 +36,10 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc);int mmc_bus_test (struct mmc_card *card,u8 bus_width);int mmc_send_hpi_cmd (struct mmc_card *card,u32 *status);int mmc_can_ext_csd (struct mmc_card *card); +#ifdef CONFIG_MMC_LOCK +int mmc_lock_unlock (struct mmc_card *card,struct mmc_password *password, +int mode); +#endif #endif
include/linux/mmc/card.h +5 -0
@@ -262,6 +262,7 @@ struct mmc_card {#define MMC_CARD_REMOVED (1<<4)/* card has been removed */ #define MMC_STATE_DOING_BKOPS (1<<5)/* card is doing BKOPS */ #define MMC_STATE_SUSPENDED (1<<6)/* card is suspended */ +#define MMC_STATE_LOCKED (1<<7)/* card is currently locked */ unsigned int quirks;/* card quirks */ #define MMC_QUIRK_LENIENT_FN0 (1<<0)/* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)/* use func->cur_blksize */
@@ -427,6 +428,8 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)#define mmc_card_removed (c) ((c) && ((c)->state & MMC_CARD_REMOVED))#define mmc_card_doing_bkops (c) ((c)->state & MMC_STATE_DOING_BKOPS)#define mmc_card_suspended (c) ((c)->state & MMC_STATE_SUSPENDED) +#define mmc_card_locked (c) ((c)->state & MMC_STATE_LOCKED) +#define mmc_card_lockable (c) ((c)->csd.cmdclass & CCC_LOCK_CARD)#define mmc_card_set_present (c) ((c)->state |= MMC_STATE_PRESENT)#define mmc_card_set_readonly (c) ((c)->state |= MMC_STATE_READONLY)
@@ -437,6 +440,8 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)#define mmc_card_clr_doing_bkops (c) ((c)->state &= ~MMC_STATE_DOING_BKOPS)#define mmc_card_set_suspended (c) ((c)->state |= MMC_STATE_SUSPENDED)#define mmc_card_clr_suspended (c) ((c)->state &= ~MMC_STATE_SUSPENDED) +#define mmc_card_set_locked (c) ((c)->state |= MMC_STATE_LOCKED) +#define mmc_card_clear_locked (c) ((c)->state &= ~MMC_STATE_LOCKED)/* * Quirk add/remove for MMC products.
Signature · 1 line
1.9.0.138.g2de3478
PATCH v3 3/8 mmc: lock: Add function to unlock a password locked card
In reply to Al CooperThis function will try to get a password for the card and use the password to unlock it. It will leave the card state flag set appropriately.
--- drivers/mmc/core/core.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
drivers/mmc/core/core.c +26 -0
@@ -2777,6 +2777,27 @@ static inline void mmc_unregister_key_type(void) unregister_key_type(&key_type_mmc); } +int mmc_unlock_card (struct mmc_card *card) +{ +int stat; +struct mmc_password password; + +mmc_card_set_locked (card); + stat =mmc_get_password (card, &password); +if (stat) { +pr_warn ("%s: Cannot find matching key\n" , +mmc_hostname (card->host)); +return stat; + } + stat =mmc_lock_unlock (card, &password,MMC_LOCK_MODE_UNLOCK ); +if (stat) +pr_warn ("%s: Password failed to unlock card\n" , +mmc_hostname (card->host)); +else +mmc_card_clear_locked (card); +return stat; +} +#else /* CONFIG_MMC_LOCK */ int mmc_get_password (struct mmc_card *card,struct mmc_password *password)
@@ -2793,6 +2814,11 @@ static inline void mmc_unregister_key_type(void) { } +int mmc_unlock_card (struct mmc_card *card) +{ +return -ENOKEY ; +} +#endif /* CONFIG_MMC_LOCK */ static int __init mmc_init (void )
Signature · 1 line
1.9.0.138.g2de3478
PATCH v3 4/8 mmc: lock: Add card lock/unlock maintenance commands
In reply to Al CooperCreate a sysfs interface that allows a user to manage an inserted cards lock state. The sysfs attribute "lock" will be added to the device's sysfs directory. The following commands are supported:
"setpw" - Set the cards password
"clearpw" - Clear the cards password
"lock" - Lock the card "unlock" - Unlock the card "erase" - Force erase the card, clear the password and unlock it
Commands that require a password will request the password through the kernels KEYS subsystem.
--- drivers/mmc/core/mmc.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+)
drivers/mmc/core/mmc.c +81 -0
@@ -697,6 +697,84 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width)return err; } +#ifdef CONFIG_MMC_LOCK + +ssize_t mmc_lock_show (struct device *dev,struct device_attribute *att, +char *buf) +{ +struct mmc_card *card =mmc_dev_to_card (dev); + +if (!mmc_card_lockable (card)) +return sprintf (buf,"unsupported\n" ); +else +return sprintf (buf,"%slocked\n" ,mmc_card_locked (card) ? +"" :"un" ); +} + + +static struct lock_cmd { +const char *name; +int io_cmd; +int locked_required; +int need_pw; +} lock_cmds[] = { + {"erase" ,MMC_LOCK_MODE_ERASE , true, false }, + {"clrpw" ,MMC_LOCK_MODE_CLR_PWD , false, true }, + {"setpw" ,MMC_LOCK_MODE_SET_PWD , false, true }, + {"lock" ,MMC_LOCK_MODE_LOCK , false, true }, + {"unlock" ,MMC_LOCK_MODE_UNLOCK , true, true }, +}; + +/* +* implement MMC password functions: force erase, set password, +* clear password, lock and unlock. +*/ +ssize_t mmc_lock_store (struct device *dev,struct device_attribute *att, +const char *data,size_t len) +{ +struct mmc_card *card =mmc_dev_to_card (dev); +int res = -EINVAL ; +int x; +struct mmc_password password; + +mmc_claim_host (card->host); +if (!mmc_card_lockable (card)) + goto out; +for (x =0 ; x <ARRAY_SIZE (lock_cmds); x++) { +if (sysfs_streq (data, lock_cmds[x].name)) +break ; + } +if (x >=ARRAY_SIZE (lock_cmds)) + goto out; + +if ((lock_cmds[x].locked_required && !mmc_card_locked (card)) || + (!lock_cmds[x].locked_required &&mmc_card_locked (card))) { +dev_warn (dev,"%s requires %slocked card\n" , + lock_cmds[x].name, + lock_cmds[x].locked_required ?"" :"un" ); + goto out; + } +if (lock_cmds[x].need_pw) { + res =mmc_get_password (card, &password); +if (res) + goto out; + } + res =mmc_lock_unlock (card, &password, lock_cmds[x].io_cmd); +out: +mmc_release_host (card->host); +if (res ==0 ) +return len; +else +return res; +} + +static DEVICE_ATTR(lock, S_IWUSR | S_IRUGO, + mmc_lock_show, mmc_lock_store); + + +#endif /* CONFIG_MMC_LOCK */ + +MMC_DEV_ATTR (cid,"%08x%08x%08x%08x\n" , card->raw_cid[0 ], card->raw_cid[1 ], card->raw_cid[2 ], card->raw_cid[3 ]); MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
@@ -751,6 +829,9 @@ static struct attribute *mmc_std_attrs[] = { &dev_attr_enhanced_area_size.attr, &dev_attr_raw_rpmb_size_mult.attr, &dev_attr_rel_sectors.attr, +#ifdef CONFIG_MMC_LOCK + &dev_attr_lock.attr, +#endif /* CONFIG_MMC_LOCK */NULL , };ATTRIBUTE_GROUPS (mmc_std);
Signature · 1 line
1.9.0.138.g2de3478
PATCH v3 5/8 mmc: lock: Change SD init functionality to handle locked SD cards
In reply to Al Cooper- Change mmc_sd_init_card() to check for a locked card and, if found, try to get a password using the kernel KEYS subsystem, unlock the card and continue. The unlock can fail due to a bad password, no password or during boot when the rootfs that holds the password is not yet available. To handle this, mmc_sd_init_card() will send just the early init commands before trying to unlock and, on unlock failure, skip the later init commands (which would fail on a locked card). mmc_sd_init_card() will also handle the retry case, trigger via sysfs, where it will skip the already issued early init commands, try again to unlock the card and if successful issue the previously skipped later init commands. These changes allow a card that failed unlock to still come up to the point that the block device and sysfs for the device is created. This allows the sysfs to be used to issue LOCK maintenance commands or to trigger a retry, presumably after the password has be made available by user space.
- Add sysfs attribute "unlock_retry" that will try again to unlock and fully init the card.
- Add sysfs attribute "lock" to enable sysfs LOCK maintenance commands
--- drivers/mmc/core/core.h | 4 ++ drivers/mmc/core/sd.c | 161 +++++++++++++++++++++++++++++++++-------------- include/linux/mmc/card.h | 1 + 3 files changed, 118 insertions(+), 48 deletions(-)
drivers/mmc/core/core.h +4 -0
@@ -97,5 +97,9 @@ struct mmc_password { };int mmc_unlock_card (struct mmc_card *card);int mmc_get_password (struct mmc_card *card,struct mmc_password *password); +ssize_t mmc_lock_show (struct device *dev,struct device_attribute *att, +char *buf); +ssize_t mmc_lock_store (struct device *dev,struct device_attribute *att, +const char *data,size_t len);#endif
drivers/mmc/core/sd.c +113 -48
206 lines not on this page · raw message
include/linux/mmc/card.h +1 -0
@@ -288,6 +288,7 @@ struct mmc_card {u32 raw_cid[4 ];/* raw card CID */ u32 raw_csd[4 ];/* raw card CSD */ u32 raw_scr[2 ];/* raw card SCR */ +u32 raw_ocr;/* raw card OCR */ struct mmc_cid cid;/* card identification */ struct mmc_csd csd;/* card specific */ struct mmc_ext_csd ext_csd;/* mmc v4 extended card specific */
Signature · 1 line
1.9.0.138.g2de3478
PATCH v3 6/8 mmc: lock: Prevent partition table read for locked cards.
In reply to Al CooperChange the MMC block layer to avoid reading the partition table when the card is locked because read commands will fail.
--- drivers/mmc/card/block.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/mmc/card/block.c +7 -0
@@ -2147,6 +2147,13 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, md->disk->flags |=GENHD_FL_NO_PART_SCAN ;/* +* If the card is locked, reads will fail so prevent partition +* table scan +*/ +if (mmc_card_locked (card)) + md->disk->flags |=GENHD_FL_NO_PART_SCAN ; + +/* * As discussed on lkml, GENHD_FL_REMOVABLE should: * * - be set for removable media with permanent block devices
Signature · 1 line
1.9.0.138.g2de3478
PATCH v3 7/8 mmc: lock: Change MMC init to handle locked cards.
In reply to Al Cooper- Change mmc_init_card() to check for a locked card and, if found, try to get a password using the kernel KEYS subsystem, unlock the card and continue. Unlike SD cards, MMC cards support all initialization commands when locked so the init sequence can be completed on a locked card and the card can be used without further init after being unlocked. If the unlock fails, the card state will be marked as "locked" which will prevent the block layer from reading the partition table.
- Add sysfs attribute "unlock_retry" that will try again to unlock the card. If the unlock succeeds, the cards "locked" state will be cleared and the block layer restarted which will now read the partition table.
--- drivers/mmc/core/mmc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-)
drivers/mmc/core/mmc.c +44 -2
@@ -768,10 +768,37 @@ out:return res; } -static DEVICE_ATTR(lock, S_IWUSR | S_IRUGO, - mmc_lock_show, mmc_lock_store); +static ssize_t mmc_unlock_retry_store (struct device *dev, +struct device_attribute *att, +const char *data,size_t len) +{ +struct mmc_card *card =mmc_dev_to_card (dev); +struct mmc_host *host = card->host; +int err; +BUG_ON (!card); +BUG_ON (!host); +mmc_claim_host (host); +if (!mmc_card_locked (card)) { +mmc_release_host (host); +return len; + } + err =mmc_unlock_card (card); +mmc_release_host (host); +if (err <0 ) +return err; +device_release_driver (dev); + err =device_attach (dev); +if (err <0 ) +return err; +return len; +} + +static DEVICE_ATTR(lock, S_IWUSR | S_IRUGO, + mmc_lock_show, mmc_lock_store); +static DEVICE_ATTR(unlock_retry, S_IWUSR, + NULL, mmc_unlock_retry_store);#endif /* CONFIG_MMC_LOCK */
@@ -831,6 +858,7 @@ static struct attribute *mmc_std_attrs[] = { &dev_attr_rel_sectors.attr, #ifdef CONFIG_MMC_LOCK &dev_attr_lock.attr, + &dev_attr_unlock_retry.attr, #endif /* CONFIG_MMC_LOCK */ NULL, };
@@ -1279,6 +1307,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,int err;u32 cid[4 ];u32 rocr; +u32 status;BUG_ON (!host);WARN_ON (!host->claimed);
@@ -1568,6 +1597,19 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, } } +/* If card is locked, try to unlock it */ + err =mmc_send_status (card, &status); +if (err) + goto free_card; +if (status &R1_CARD_IS_LOCKED ) { +pr_info ("%s: card is locked.\n" ,mmc_hostname (card->host)); + err =mmc_unlock_card (card); +if (err !=0 ) { +pr_warn ("%s: Card unlock failed.\n" , +mmc_hostname (card->host)); + } + } +if (!oldcard) host->card = card;
Signature · 1 line
1.9.0.138.g2de3478
PATCH v3 8/8 According to SD Physical Layer Specifications: Locked cards respond to (and execute) all commands in the "basic" command class (class 0), ACMD41, CMD16 and "lock card" command class. Thus, the host is allowed to reset, initialize, select, query for status, etc., but not to access data on the card.
In reply to Al CooperFrom: Abbas Raza <[email protected]>
But when a locked card is inserted into system having no key added for this card, following errors are observed until the card is removed
[ 36.955193] mmc0: card is locked. [ 36.959746] mmc (null): Error, request_key -2 [ 36.964622] mmc0: Cannot find matching key [ 36.968765] mmc0: Card unlock failed. [ 36.972717] mmc0: new SDHC card at address 0002 [ 36.977747] mmcblk0: mmc0:0002 00000 7.41 GiB [ 36.989596] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 36.999630] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.009604] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.019574] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.029548] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.039514] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.046729] end_request: I/O error, dev mmcblk0, sector 15556480 [ 37.052813] Buffer I/O error on device mmcblk0, logical block 1944560 [ 37.062139] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.072106] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 37.082072] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 ............. [ 46.249273] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 46.259247] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 46.269215] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 46.279183] mmcblk0: timed out sending r/w cmd command, card status 0x2400900 [ 46.289151] mmcblk0: timed out sending r/w cmd command, card status 0x2400900
As a workaround, skip all the regular block io operations if the card is locked. One can unlock the card after system boot by following below steps
1) Add key for this card.
2) Unlock the card using sysfs attribute 'unlock_retry' for this card.
--- drivers/mmc/card/block.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/mmc/card/block.c +7 -0
@@ -2026,6 +2026,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)/* claim host only for the first request */ mmc_get_card (card); +if (mmc_card_locked (card)) { +if (req) +blk_end_request_all (req,0 ); + ret =0 ; + goto out; + } + ret =mmc_blk_part_switch (card, md);if (ret) {if (req) {
Signature · 1 line
1.9.0.138.g2de3478
Hi Al,
Let me start by apologizing for the long delay in feedback.
Quoted 7 lines · Al Cooper
This set of patches adds support for password protected locking and unlocking of MMC and SD devices. It uses the LOCK/UNLOCK command (CMD42) available in both the MMC and SD command sets.
Some of this code was based on a patch set submitted in 2006 by Anderson Briglia "Add MMC Password Protection (lock/unlock)". This patch set never made it into mainline.
I lot have happened since 2006 and I don't know the history to why this was rejected. Was it just that nobody cares to review it or something else?
Quoted 8 lines
By default, a card with no password assigned is always in "unlocked" state. After password assignment, in the next power cycle the card switches to a "locked" state where only the "basic" and "lock card" command classes are accepted by the card. Only after unlocking it with the correct password can the card be used for normal operations like block I/O.
Quoted 6 lines
Password management and caching is done through the "Kernel Key Retention Service" mechanism and the sysfs filesystem. Two new sysfs attributes were added. The "lock" attribute is used to lock, unlock, assign a password, clear a password and force erase a card. The "
unlock_retry" attribute is used to retry an unlock that failed during boot because the rootfs was not yet available with the password.
The rootfs issue makes this a bit complicated to handle. I think this can be simplified, perhaps by allowing user-space to trigger a mmc_rescan() to be run for a particular mmc host.
Quoted 1 line
From a power management point of view I think that would be preferred,
as else you might be leaving a locked card powered forever.
Quoted 6 lines
The user space software needed to test this new feature is available on GitHub at:
https://github.com/alcooper/mmc-password-utils
See the README for a detailed description of the user space layer and how to use this feature.
Really nice that you maintain such utility. If this feature enters mainline, it would nice to merge this into Chris' mmc-utils.
Quoted 45 lines
Changed for V3:
- Ported the V2 patch set submitted Aug. 2013 to the latest mainline(v4.1-rc4).- Created a GitHub project for the user space layer.
- Change the lock command (CMD42) to round up the data buffer size to 512 for SD but leave exact size for eMMC based on the SD and eMMC specs.Changed for V2:
The V2 changes were not functional and were just general cleanup.
- Use stub functions to reduce the number of CONFIG ifdefs.
- Add static to a few functions that were local.
- Usepr_warninstead ofpr_warning.
- Improve a few variable names and messages.Abbas Raza (1):
According to SD Physical Layer Specifications: Locked cards respond to
(and execute) all commands in the "basic" command class (class 0), ACMD41, CMD16 and "lock card" command class. Thus, the host is allowed to reset, initialize, select, query for status, etc., but not to access data on the card.Al Cooper (7):
mmc: lock: Use the kernel "KEYS" subsystem to get a card's password
mmc: lock: Add low levelLOCK_UNLOCKcommand
mmc: lock: Add function to unlock a password locked card
mmc: lock: Add card lock/unlock maintenance commands
mmc: lock: Change SD init functionality to handle locked SD cards
mmc: lock: Prevent partition table read for locked cards.
mmc: lock: Change MMC init to handle locked cards.drivers/mmc/card/block.c | 14 ++++ drivers/mmc/core/Kconfig | 8 +++ drivers/mmc/core/core.c | 120 +++++++++++++++++++++++++++++++++ drivers/mmc/core/core.h | 14 +++- drivers/mmc/core/mmc.c | 123 ++++++++++++++++++++++++++++++++++ drivers/mmc/core/mmc_ops.c | 150 +++++++++++++++++++++++++++++++++++++++++ drivers/mmc/core/mmc_ops.h | 13 ++++ drivers/mmc/core/sd.c | 161 +++++++++++++++++++++++++++++++-------------- include/linux/mmc/card.h | 6 ++ 9 files changed, 560 insertions(+), 49 deletions(-)
Quoted 3 lines
--
1.9.0.138.g2de3478
This is just an initial review and before I spend more time going into the details, I want to understand *why* we want this feature. Could you elaborate on what use cases you see and whether you already know someone actively using this?
Quoted 1 line
From a code quality point of view, it overall looks okay, but let me
get back to the details once we discussed the above a bit.
Moreover, I would like to encourage other MMC developers to give there overall opinion about this feature.
Kind regards
Uffe
Hi Ulf Hansson,
One use case is whenever any host controller tries for specification compliance or certification, there are defined test cases for each spec version.
If mmc/sd subsystem can validate most of them, if not all, out of tree, it would be of great advantage for users.
I have performed recently this compliance testing for v3.0 host spec and found some features missing like lock/unlock, register programming, erase etc.
These patches should defintely help linux get compliant atleast for SD Host Spec.
Defined Host Controller Test Specification is available from SD Card Association. www.sdcard.org
Hope this helps,
Regards,
Suneel
Quoted 115 lines · Ulf Hansson
Hi Al,
Let me start by apologizing for the long delay in feedback.
Quoted 7 lines · Al Cooper
This set of patches adds support for password protected locking and unlocking of MMC and SD devices. It uses the LOCK/UNLOCK command (CMD42) available in both the MMC and SD command sets.
Some of this code was based on a patch set submitted in 2006 by Anderson Briglia "Add MMC Password Protection (lock/unlock)". This patch set never made it into mainline.
I lot have happened since 2006 and I don't know the history to why this was rejected. Was it just that nobody cares to review it or something else?
Quoted 8 lines
By default, a card with no password assigned is always in "unlocked" state. After password assignment, in the next power cycle the card switches to a "locked" state where only the "basic" and "lock card" command classes are accepted by the card. Only after unlocking it with the correct password can the card be used for normal operations like block I/O.
Quoted 6 lines
Password management and caching is done through the "Kernel Key Retention Service" mechanism and the sysfs filesystem. Two new sysfs attributes were added. The "lock" attribute is used to lock, unlock, assign a password, clear a password and force erase a card. The "
unlock_retry" attribute is used to retry an unlock that failed during boot because the rootfs was not yet available with the password.The rootfs issue makes this a bit complicated to handle. I think this can be simplified, perhaps by allowing user-space to trigger a
mmc_rescan()to be run for a particular mmc host.From a power management point of view I think that would be preferred, as else you might be leaving a locked card powered forever.
Quoted 6 lines
The user space software needed to test this new feature is available on GitHub at:
https://github.com/alcooper/mmc-password-utils
See the README for a detailed description of the user space layer and how to use this feature.Really nice that you maintain such utility. If this feature enters mainline, it would nice to merge this into Chris' mmc-utils.
Quoted 45 lines
Changed for V3:
- Ported the V2 patch set submitted Aug. 2013 to the latest mainline(v4.1-rc4).- Created a GitHub project for the user space layer.
- Change the lock command (CMD42) to round up the data buffer size to 512 for SD but leave exact size for eMMC based on the SD and eMMC specs.Changed for V2:
The V2 changes were not functional and were just general cleanup.
- Use stub functions to reduce the number of CONFIG ifdefs.
- Add static to a few functions that were local.
- Usepr_warninstead ofpr_warning.
- Improve a few variable names and messages.Abbas Raza (1):
According to SD Physical Layer Specifications: Locked cards respond to
(and execute) all commands in the "basic" command class (class 0), ACMD41, CMD16 and "lock card" command class. Thus, the host is allowed to reset, initialize, select, query for status, etc., but not to access data on the card.Al Cooper (7):
mmc: lock: Use the kernel "KEYS" subsystem to get a card's password
mmc: lock: Add low levelLOCK_UNLOCKcommand
mmc: lock: Add function to unlock a password locked card
mmc: lock: Add card lock/unlock maintenance commands
mmc: lock: Change SD init functionality to handle locked SD cards
mmc: lock: Prevent partition table read for locked cards.
mmc: lock: Change MMC init to handle locked cards.drivers/mmc/card/block.c | 14 ++++ drivers/mmc/core/Kconfig | 8 +++ drivers/mmc/core/core.c | 120 +++++++++++++++++++++++++++++++++ drivers/mmc/core/core.h | 14 +++- drivers/mmc/core/mmc.c | 123 ++++++++++++++++++++++++++++++++++ drivers/mmc/core/mmc_ops.c | 150 +++++++++++++++++++++++++++++++++++++++++ drivers/mmc/core/mmc_ops.h | 13 ++++ drivers/mmc/core/sd.c | 161 +++++++++++++++++++++++++++++++-------------- include/linux/mmc/card.h | 6 ++ 9 files changed, 560 insertions(+), 49 deletions(-)Quoted 3 lines
--
1.9.0.138.g2de3478This is just an initial review and before I spend more time going into the details, I want to understand *why* we want this feature. Could you elaborate on what use cases you see and whether you already know someone actively using this?
From a code quality point of view, it overall looks okay, but let me get back to the details once we discussed the above a bit.
Moreover, I would like to encourage other MMC developers to give there overall opinion about this feature.
Kind regards
Uffe
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 9 lines · Ulf Hansson
Hi Al,
Let me start by apologizing for the long delay in feedback.
Quoted 4 lines · Al Cooper
This set of patches adds support for password protected locking and unlocking of MMC and SD devices. It uses the LOCK/UNLOCK command (CMD42) available in both the MMC and SD command sets.
Quoted 7 lines
Quoted 3 lines
Some of this code was based on a patch set submitted in 2006 by Anderson Briglia "Add MMC Password Protection (lock/unlock)". This patch set never made it into mainline.
I lot have happened since 2006 and I don't know the history to why this was rejected. Was it just that nobody cares to review it or something else?
It was never rejected, it just didn't get enough review interest.
Quoted 15 lines
Quoted 8 lines
By default, a card with no password assigned is always in "unlocked" state. After password assignment, in the next power cycle the card switches to a "locked" state where only the "basic" and "lock card" command classes are accepted by the card. Only after unlocking it with the correct password can the card be used for normal operations like block I/O.
Quoted 6 lines
Password management and caching is done through the "Kernel Key Retention Service" mechanism and the sysfs filesystem. Two new sysfs attributes were added. The "lock" attribute is used to lock, unlock, assign a password, clear a password and force erase a card. The "
unlock_retry" attribute is used to retry an unlock that failed during boot because the rootfs was not yet available with the password.
Quoted 3 lines
The rootfs issue makes this a bit complicated to handle. I think this can be simplified, perhaps by allowing user-space to trigger a
mmc_rescan()to be run for a particular mmc host.
The "unlock_retry" attribute in sysfs allows user-space to trigger an unlock retry
for a locked card.
Quoted 4 lines
From a power management point of view I think that would be preferred, as else you might be leaving a locked card powered forever.
Since a locked device is allowed to come up partially, all the power management seems to work correctly. I tested suspend and verified that the power to the SD card was turned off. This should also allow the eMMC SLEEP_AWAKE command (CMD5) to work on locked eMMC devices.
Quoted 9 lines
Quoted 6 lines
The user space software needed to test this new feature is available on GitHub at:
https://github.com/alcooper/mmc-password-utils
See the README for a detailed description of the user space layer and how to use this feature.Really nice that you maintain such utility. If this feature enters mainline, it would nice to merge this into Chris' mmc-utils.
I agree and Chris has recently accepted other features I've added to mmc-utils.
Quoted 5 lines
This is just an initial review and before I spend more time going into the details, I want to understand *why* we want this feature. Could you elaborate on what use cases you see and whether you already know someone actively using this?
The reason I added this functionality is for the Settop Box industry. There's a trend to use SD cards for Time-Shift-Buffering of video and it's nice to be able to
lock the card to prevent the SD card and it's video from being used in another system. There are a few very big Settop Box companies interested in doing this. SanDisk is now creating a special class of SD card, called a Video Buffer Card, with extended write cycles just for this purpose. SanDisk is also extending the CMD42 (LOCK_UNLOCK) command and expects to have the extensions in the next version of the SD Physical Layer Specification.
The other use would be to allow a user to password protect their SD card to keep sensitive information safe.
As far as others currently using the patches, I got the following email last year:
| Y Garcia <[email protected]> | | 6/19/14 | to me | | Hi Alan, | | I successful built the kernel with SD/MMC lock support and I also
included keyutils package in rootfs but now I need
|
| a user space script or helper example to deal with password and "keyutil" utility.
| | Can you be so kind to once again give me a hint on this regard? | | I've been study/searching without any luck. | | | Regards, | | Thanks in advance for your support. | | Yamil.
I also got an email about 2 years ago asking if it was OK to use the my first version of the patchset, but I can't find the email.
Also, the last patch in the set I submitted was from from Abbas Raza <[email protected]> who must be doing something with the patches to have found the issue.
Quoted 9 lines
From a code quality point of view, it overall looks okay, but let me get back to the details once we discussed the above a bit.
Moreover, I would like to encourage other MMC developers to give there overall opinion about this feature.
Kind regards
Uffe
Thanks.
Al
[...]
Quoted 6 lines
Quoted 4 lines
I lot have happened since 2006 and I don't know the history to why this was rejected. Was it just that nobody cares to review it or something else?
It was never rejected, it just didn't get enough review interest.
Okay, I will do my best to make sure we get consensus in how to proceed then.
[...]
Quoted 10 lines
Quoted 4 lines
The rootfs issue makes this a bit complicated to handle. I think this can be simplified, perhaps by allowing user-space to trigger a
mmc_rescan()to be run for a particular mmc host.The "
unlock_retry" attribute in sysfs allows user-space to trigger an unlock retry
for a locked card.Quoted 1 line
Quoted 8 lines
Quoted 3 lines
From a power management point of view I think that would be preferred, as else you might be leaving a locked card powered forever.
Since a locked device is allowed to come up partially, all the power management seems to work correctly. I tested suspend and verified that the power to the SD card was turned off. This should also allow the eMMC
SLEEP_AWAKEcommand (CMD5) to work on locked eMMC devices.
I see your point, I just feel it's becoming complex and fragile. Still, it seems this feature is important also for non-removable cards and these are only enumerated once during the boot.
I need to think a bit more on this.
[...]
Quoted 47 lines
Quoted 5 lines
This is just an initial review and before I spend more time going into the details, I want to understand *why* we want this feature. Could you elaborate on what use cases you see and whether you already know someone actively using this?
The reason I added this functionality is for the Settop Box industry. There's a trend to use SD cards for Time-Shift-Buffering of video and it's nice to be able to
lock the card to prevent the SD card and it's video from being used in another system. There are a few very big Settop Box companies interested in doing this. SanDisk is now creating a special class of SD card, called a Video Buffer Card, with extended write cycles just for this purpose. SanDisk is also extending the CMD42 (LOCK_UNLOCK) command and expects to have the extensions in the next version of the SD Physical Layer Specification.The other use would be to allow a user to password protect their SD card to keep sensitive information safe.
As far as others currently using the patches, I got the following email last year:
| Y Garcia <[email protected]> | | 6/19/14 | to me | | Hi Alan, | | I successful built the kernel with SD/MMC lock support and I alsoincluded keyutils package in rootfs but now I need
|
| a user space script or helper example to deal with password and "keyutil" utility.| | Can you be so kind to once again give me a hint on this regard? | | I've been study/searching without any luck. | | | Regards, | | Thanks in advance for your support. | | Yamil.
Quoted 7 lines
I also got an email about 2 years ago asking if it was OK to use the my first version of the patchset, but I can't find the email.
Also, the last patch in the set I submitted was from from Abbas Raza <[email protected]> who must be doing something with the patches to have found the issue.
Thanks for the info. I am okay going forward with this patchset, though I think it's a bit late (my fault) for 4.3. Could you perhaps repost once 4.3 rc1 is out!?
Kind regards
Uffe
Quoted 3 lines · Ulf Hansson
Thanks for the info. I am okay going forward with this patchset, though I think it's a bit late (my fault) for 4.3. Could you perhaps repost once 4.3 rc1 is out!?
Thanks!
I'll re-post after 4.3 rc1.
Al