* [PATCH 0/7] Add password protected lock/unlock support for SD/MMC
@ 2013-08-13 15:21 Al Cooper
2013-08-13 15:21 ` [PATCH 1/7] mmc: lock: Use the kernel "KEYS" subsystem to get a card's password Al Cooper
` (6 more replies)
0 siblings, 7 replies; 10+ messages in thread
From: Al Cooper @ 2013-08-13 15:21 UTC (permalink / raw)
To: cjb, linux-mmc; +Cc: 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.
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.
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 funtion 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 | 7 +++
drivers/mmc/core/Kconfig | 8 +++
drivers/mmc/core/core.c | 114 +++++++++++++++++++++++++++++++++++++
drivers/mmc/core/core.h | 20 ++++++-
drivers/mmc/core/mmc.c | 124 ++++++++++++++++++++++++++++++++++++++++
drivers/mmc/core/mmc_ops.c | 112 ++++++++++++++++++++++++++++++++++++
drivers/mmc/core/mmc_ops.h | 13 +++++
drivers/mmc/core/sd.c | 138 +++++++++++++++++++++++++++++++++------------
include/linux/mmc/card.h | 6 ++
9 files changed, 505 insertions(+), 37 deletions(-)
--
1.8.1.3
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/7] mmc: lock: Use the kernel "KEYS" subsystem to get a card's password
2013-08-13 15:21 [PATCH 0/7] Add password protected lock/unlock support for SD/MMC Al Cooper
@ 2013-08-13 15:21 ` Al Cooper
2013-08-15 1:16 ` Brian Norris
2013-08-23 10:34 ` Ulf Hansson
2013-08-13 15:21 ` [PATCH 2/7] mmc: lock: Add low level LOCK_UNLOCK command Al Cooper
` (5 subsequent siblings)
6 siblings, 2 replies; 10+ messages in thread
From: Al Cooper @ 2013-08-13 15:21 UTC (permalink / raw)
To: cjb, linux-mmc; +Cc: Al Cooper
From: Al Cooper <acooper@broadcom.com>
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.
refs #SWLINUX-2545
Signed-off-by: Al Cooper <acooper@broadcom.com>
---
drivers/mmc/core/Kconfig | 8 +++++
drivers/mmc/core/core.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++
drivers/mmc/core/core.h | 16 ++++++++-
3 files changed, 109 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
index 269d072..b0ba79d 100644
--- a/drivers/mmc/core/Kconfig
+++ b/drivers/mmc/core/Kconfig
@@ -26,3 +26,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.
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 49a5bca..510927f 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -27,6 +27,7 @@
#include <linux/fault-inject.h>
#include <linux/random.h>
#include <linux/slab.h>
+#include <linux/key-type.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -2705,6 +2706,78 @@ void mmc_init_context_info(struct mmc_host *host)
init_waitqueue_head(&host->context_info.wait);
}
+#ifdef CONFIG_MMC_LOCK
+
+int mmc_get_password(struct mmc_card *card, struct mmc_password *password)
+{
+ struct key *mmc_key;
+ char key_desc[(sizeof(card->raw_cid) * 2) + 1];
+
+ /* Use the CID to uniquely identify the card */
+ snprintf(key_desc, sizeof(key_desc), "%08x%08x%08x%08x",
+ card->raw_cid[0], card->raw_cid[1],
+ card->raw_cid[2], card->raw_cid[3]);
+
+ mmc_key = request_key(&mmc_key_type, key_desc,
+ "password");
+ if (IS_ERR(mmc_key)) {
+ dev_warn(&card->dev, "Error, request_key %ld\n",
+ PTR_ERR(mmc_key));
+ return PTR_ERR(mmc_key);
+ }
+ dev_dbg(&card->dev, "Found matching key\n");
+ memcpy(&password->password, mmc_key->payload.data,
+ mmc_key->datalen);
+ password->length = mmc_key->datalen;
+ key_put(mmc_key);
+
+ return 0;
+}
+
+
+static int mmc_key_instantiate(struct key *key,
+ struct key_preparsed_payload *prep)
+{
+ char *payload;
+
+ if (prep->datalen <= 0 || prep->datalen > MMC_PASSWORD_MAX ||
+ !prep->data) {
+ pr_warn("Invalid data\n");
+ return -EINVAL;
+ }
+
+ payload = kmalloc(prep->datalen, GFP_KERNEL);
+ if (!payload)
+ return -ENOMEM;
+ memcpy(payload, prep->data, prep->datalen);
+ key->payload.data = payload;
+ key->datalen = prep->datalen;
+ return 0;
+}
+
+static int mmc_key_match(const struct key *key, const void *description)
+{
+ pr_debug("mmc_key_match: %s, %s\n",
+ key->description, (char *)description);
+ return strcmp(key->description, description) == 0;
+}
+
+/*
+ * dispose of the data dangling from the corpse of a mmc key
+ */
+static void mmc_key_destroy(struct key *key)
+{
+ kfree(key->payload.data);
+}
+
+struct key_type mmc_key_type = {
+ .name = "mmc",
+ .instantiate = mmc_key_instantiate,
+ .match = mmc_key_match,
+ .destroy = mmc_key_destroy,
+};
+#endif /* CONFIG_MMC_LOCK */
+
static int __init mmc_init(void)
{
int ret;
@@ -2725,8 +2798,18 @@ static int __init mmc_init(void)
if (ret)
goto unregister_host_class;
+#ifdef CONFIG_MMC_LOCK
+ ret = register_key_type(&mmc_key_type);
+ if (ret)
+ goto unregister_sdio_bus;
+#endif /* CONFIG_MMC_LOCK */
+
return 0;
+#ifdef CONFIG_MMC_LOCK
+unregister_sdio_bus:
+ sdio_unregister_bus();
+#endif /* CONFIG_MMC_LOCK */
unregister_host_class:
mmc_unregister_host_class();
unregister_bus:
@@ -2739,6 +2822,9 @@ destroy_workqueue:
static void __exit mmc_exit(void)
{
+#ifdef CONFIG_MMC_LOCK
+ unregister_key_type(&mmc_key_type);
+#endif /* CONFIG_MMC_LOCK */
sdio_unregister_bus();
mmc_unregister_host_class();
mmc_unregister_bus();
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 5345d15..dcf516d 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -81,5 +81,19 @@ void mmc_add_card_debugfs(struct mmc_card *card);
void mmc_remove_card_debugfs(struct mmc_card *card);
void mmc_init_context_info(struct mmc_host *host);
-#endif
+/* Lock/Unlock functionality */
+int mmc_unlock_card(struct mmc_card *card);
+
+#ifdef CONFIG_MMC_LOCK
+#define MMC_PASSWORD_MAX 16
+struct mmc_password {
+ char password[MMC_PASSWORD_MAX];
+ int length;
+};
+extern struct key_type mmc_key_type;
+
+int mmc_get_password(struct mmc_card *card, struct mmc_password *password);
+#endif /* CONFIG_MMC_LOCK */
+
+#endif
--
1.8.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/7] mmc: lock: Add low level LOCK_UNLOCK command
2013-08-13 15:21 [PATCH 0/7] Add password protected lock/unlock support for SD/MMC Al Cooper
2013-08-13 15:21 ` [PATCH 1/7] mmc: lock: Use the kernel "KEYS" subsystem to get a card's password Al Cooper
@ 2013-08-13 15:21 ` Al Cooper
2013-08-13 15:21 ` [PATCH 3/7] mmc: lock: Add funtion to unlock a password locked card Al Cooper
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Al Cooper @ 2013-08-13 15:21 UTC (permalink / raw)
To: cjb, linux-mmc; +Cc: Al Cooper
From: Al Cooper <acooper@broadcom.com>
Add support for the LOCK_UNLOCK command. This command can lock,
unlock, set password, clear password and force erase SD and
MMC cards.
refs #SWLINUX-2545
Signed-off-by: Al Cooper <acooper@broadcom.com>
---
drivers/mmc/core/mmc_ops.c | 112 +++++++++++++++++++++++++++++++++++++++++++++
drivers/mmc/core/mmc_ops.h | 13 ++++++
include/linux/mmc/card.h | 5 ++
3 files changed, 130 insertions(+)
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 837fc73..26e37a1 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -13,6 +13,8 @@
#include <linux/export.h>
#include <linux/types.h>
#include <linux/scatterlist.h>
+#include <linux/key.h>
+#include <linux/err.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
@@ -606,3 +608,113 @@ int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status)
return 0;
}
+
+#ifdef CONFIG_MMC_LOCK
+/**
+ * mmc_lock_unlock - send LOCK_UNLOCK command to a specific card.
+ * @card: card to which the LOCK_UNLOCK command should be sent
+ * @key: key containing the MMC password
+ * @mode: LOCK_UNLOCK mode
+ *
+ */
+int mmc_lock_unlock(struct mmc_card *card, struct mmc_password *password,
+ int mode)
+{
+ struct mmc_request mrq;
+ struct mmc_command cmd;
+ struct mmc_data data;
+ struct scatterlist sg;
+ unsigned long erase_timeout;
+ int err, data_size;
+ u8 *data_buf;
+
+ data_size = 4;
+ if (!(mode & MMC_LOCK_MODE_ERASE))
+ data_size = 2 + password->length;
+
+ data_buf = kzalloc(data_size, GFP_KERNEL);
+ if (!data_buf)
+ return -ENOMEM;
+ data_buf[0] |= mode;
+ if (!(mode & MMC_LOCK_MODE_ERASE)) {
+ data_buf[1] = password->length;
+ memcpy(data_buf + 2, password->password, password->length);
+ }
+
+ memset(&cmd, 0, sizeof(struct mmc_command));
+ cmd.opcode = MMC_SET_BLOCKLEN;
+ cmd.arg = data_size;
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+ err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
+ if (err)
+ goto out;
+
+ memset(&cmd, 0, sizeof(struct mmc_command));
+ cmd.opcode = MMC_LOCK_UNLOCK;
+ cmd.arg = 0;
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+
+ memset(&data, 0, sizeof(struct mmc_data));
+ mmc_set_data_timeout(&data, card);
+ data.blksz = data_size;
+ data.blocks = 1;
+ data.flags = MMC_DATA_WRITE;
+ data.sg = &sg;
+ data.sg_len = 1;
+
+ memset(&mrq, 0, sizeof(struct mmc_request));
+ mrq.cmd = &cmd;
+ mrq.data = &data;
+
+ sg_init_one(&sg, data_buf, data_size);
+ mmc_wait_for_req(card->host, &mrq);
+ if (cmd.error) {
+ err = cmd.error;
+ goto out;
+ }
+ if (data.error) {
+ err = data.error;
+ goto out;
+ }
+
+ memset(&cmd, 0, sizeof(struct mmc_command));
+ cmd.opcode = MMC_SEND_STATUS;
+ cmd.arg = card->rca << 16;
+ cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+
+ /* set timeout for forced erase operation to 3 min. (see MMC spec) */
+ erase_timeout = jiffies + 180 * HZ;
+ do {
+ /*
+ * we cannot use "retries" here because the
+ * R1_LOCK_UNLOCK_FAILED bit is cleared by subsequent reads to
+ * the status register, hiding the error condition
+ */
+ err = mmc_wait_for_cmd(card->host, &cmd, 0);
+ if (err)
+ break;
+ /* the other modes don't need timeout checking */
+ if (!(mode & MMC_LOCK_MODE_ERASE))
+ continue;
+ if (time_after(jiffies, erase_timeout) &&
+ !(cmd.resp[0] & R1_READY_FOR_DATA)) {
+ dev_err(&card->dev, "forced erase timed out\n");
+ err = -ETIMEDOUT;
+ break;
+ }
+ } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
+ if (cmd.resp[0] & R1_LOCK_UNLOCK_FAILED) {
+ dev_dbg(&card->dev, "LOCK_UNLOCK operation failed\n");
+ err = -EIO;
+ }
+ if (cmd.resp[0] & R1_CARD_IS_LOCKED)
+ mmc_card_set_locked(card);
+ else
+ mmc_card_clear_locked(card);
+
+out:
+ kfree(data_buf);
+
+ return err;
+}
+#endif /* CONFIG_MMC_LOCK */
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h
index 80ae9f4..5fe50e0 100644
--- a/drivers/mmc/core/mmc_ops.h
+++ b/drivers/mmc/core/mmc_ops.h
@@ -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_go_idle(struct mmc_host *host);
@@ -26,6 +35,10 @@ int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp);
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);
+#ifdef CONFIG_MMC_LOCK
+int mmc_lock_unlock(struct mmc_card *card, struct mmc_password *password,
+ int mode);
+#endif
#endif
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 842de3e..af92c44 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -257,6 +257,7 @@ struct mmc_card {
#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
#define MMC_STATE_DOING_BKOPS (1<<10) /* card is doing BKOPS */
+#define MMC_STATE_LOCKED (1<<11) /* 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 */
@@ -424,6 +425,8 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
#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_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_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
#define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS)
#define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS)
+#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.
--
1.8.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/7] mmc: lock: Add funtion to unlock a password locked card
2013-08-13 15:21 [PATCH 0/7] Add password protected lock/unlock support for SD/MMC Al Cooper
2013-08-13 15:21 ` [PATCH 1/7] mmc: lock: Use the kernel "KEYS" subsystem to get a card's password Al Cooper
2013-08-13 15:21 ` [PATCH 2/7] mmc: lock: Add low level LOCK_UNLOCK command Al Cooper
@ 2013-08-13 15:21 ` Al Cooper
2013-08-13 15:21 ` [PATCH 4/7] mmc: lock: Add card lock/unlock maintenance commands Al Cooper
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Al Cooper @ 2013-08-13 15:21 UTC (permalink / raw)
To: cjb, linux-mmc; +Cc: Al Cooper
From: Al Cooper <acooper@broadcom.com>
This 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.
refs #SWLINUX-2545
Signed-off-by: Al Cooper <acooper@broadcom.com>
---
drivers/mmc/core/core.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 510927f..7dd6a33 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2776,6 +2776,34 @@ struct key_type mmc_key_type = {
.match = mmc_key_match,
.destroy = mmc_key_destroy,
};
+
+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: Wrong password\n", mmc_hostname(card->host));
+ else
+ mmc_card_clear_locked(card);
+ return stat;
+}
+
+#else /* CONFIG_MMC_LOCK */
+
+int mmc_unlock_card(struct mmc_card *card)
+{
+ return -ENOKEY;
+}
+
#endif /* CONFIG_MMC_LOCK */
static int __init mmc_init(void)
--
1.8.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/7] mmc: lock: Add card lock/unlock maintenance commands
2013-08-13 15:21 [PATCH 0/7] Add password protected lock/unlock support for SD/MMC Al Cooper
` (2 preceding siblings ...)
2013-08-13 15:21 ` [PATCH 3/7] mmc: lock: Add funtion to unlock a password locked card Al Cooper
@ 2013-08-13 15:21 ` Al Cooper
2013-08-13 15:21 ` [PATCH 5/7] mmc: lock: Change SD init functionality to handle locked SD cards Al Cooper
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Al Cooper @ 2013-08-13 15:21 UTC (permalink / raw)
To: cjb, linux-mmc; +Cc: Al Cooper
From: Al Cooper <acooper@broadcom.com>
Create 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.
refs #SWLINUX-2545
Signed-off-by: Al Cooper <acooper@broadcom.com>
---
drivers/mmc/core/mmc.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 6d02012..1ad33ca 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -654,6 +654,85 @@ out:
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");
+}
+
+
+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 },
+};
+
+#define LOCK_CMD_CNT (sizeof(lock_cmds) / sizeof(struct lock_cmd))
+
+/*
+ * 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 < LOCK_CMD_CNT; x++) {
+ if (sysfs_streq(data, lock_cmds[x].name))
+ break;
+ }
+ if (x >= LOCK_CMD_CNT)
+ goto out;
+ if (lock_cmds[x].locked_required ^
+ (mmc_card_locked(card) ? true : false)) {
+ pr_warning("%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],
@@ -691,6 +770,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,
};
--
1.8.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/7] mmc: lock: Change SD init functionality to handle locked SD cards
2013-08-13 15:21 [PATCH 0/7] Add password protected lock/unlock support for SD/MMC Al Cooper
` (3 preceding siblings ...)
2013-08-13 15:21 ` [PATCH 4/7] mmc: lock: Add card lock/unlock maintenance commands Al Cooper
@ 2013-08-13 15:21 ` Al Cooper
2013-08-13 15:21 ` [PATCH 6/7] mmc: lock: Prevent partition table read for locked cards Al Cooper
2013-08-13 15:21 ` [PATCH 7/7] mmc: lock: Change MMC init to handle " Al Cooper
6 siblings, 0 replies; 10+ messages in thread
From: Al Cooper @ 2013-08-13 15:21 UTC (permalink / raw)
To: cjb, linux-mmc; +Cc: Al Cooper
From: Al Cooper <acooper@broadcom.com>
- 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
refs #SWLINUX-2545
Signed-off-by: Al Cooper <acooper@broadcom.com>
---
drivers/mmc/core/core.h | 4 ++
drivers/mmc/core/sd.c | 138 ++++++++++++++++++++++++++++++++++-------------
include/linux/mmc/card.h | 1 +
3 files changed, 107 insertions(+), 36 deletions(-)
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index dcf516d..def5d71 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -94,6 +94,10 @@ struct mmc_password {
extern struct key_type mmc_key_type;
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 /* CONFIG_MMC_LOCK */
#endif
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 176d125..ee81d27 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -25,6 +25,10 @@
#include "sd.h"
#include "sd_ops.h"
+ssize_t mmc_sd_unlock_retry_store(struct device *dev,
+ struct device_attribute *att,
+ const char *data, size_t len);
+
static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000,
0, 0, 0, 0
@@ -665,6 +669,8 @@ out:
return err;
}
+
+
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],
@@ -680,6 +686,13 @@ MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
+#ifdef CONFIG_MMC_LOCK
+static DEVICE_ATTR(lock, S_IWUSR | S_IRUGO,
+ mmc_lock_show, mmc_lock_store);
+static DEVICE_ATTR(unlock_retry, S_IWUSR,
+ NULL, mmc_sd_unlock_retry_store);
+#endif /* CONFIG_MMC_LOCK */
+
static struct attribute *sd_std_attrs[] = {
&dev_attr_cid.attr,
@@ -694,6 +707,10 @@ static struct attribute *sd_std_attrs[] = {
&dev_attr_name.attr,
&dev_attr_oemid.attr,
&dev_attr_serial.attr,
+#ifdef CONFIG_MMC_LOCK
+ &dev_attr_lock.attr,
+ &dev_attr_unlock_retry.attr,
+#endif /* CONFIG_MMC_LOCK */
NULL,
};
@@ -911,55 +928,78 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
int err;
u32 cid[4];
u32 rocr = 0;
+ u32 status;
BUG_ON(!host);
WARN_ON(!host->claimed);
- err = mmc_sd_get_cid(host, ocr, cid, &rocr);
- if (err)
- return err;
-
- if (oldcard) {
- if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)
- return -ENOENT;
-
+ /* Retry init of locked card */
+ if (oldcard && mmc_card_locked(oldcard)) {
card = oldcard;
+ oldcard = NULL;
+ rocr = card->raw_ocr;
} else {
+ err = mmc_sd_get_cid(host, ocr, cid, &rocr);
+ if (err)
+ return err;
+
+ if (oldcard) {
+ if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)
+ return -ENOENT;
+
+ card = oldcard;
+ } else {
+ /*
+ * Allocate card structure.
+ */
+ card = mmc_alloc_card(host, &sd_type);
+ if (IS_ERR(card))
+ return PTR_ERR(card);
+
+ card->type = MMC_TYPE_SD;
+ memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
+ }
+
/*
- * Allocate card structure.
+ * For native busses: get card RCA and quit open drain mode.
*/
- card = mmc_alloc_card(host, &sd_type);
- if (IS_ERR(card))
- return PTR_ERR(card);
-
- card->type = MMC_TYPE_SD;
- memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
- }
+ if (!mmc_host_is_spi(host)) {
+ err = mmc_send_relative_addr(host, &card->rca);
+ if (err)
+ return err;
+ }
- /*
- * For native busses: get card RCA and quit open drain mode.
- */
- if (!mmc_host_is_spi(host)) {
- err = mmc_send_relative_addr(host, &card->rca);
- if (err)
- return err;
- }
+ if (!oldcard) {
+ err = mmc_sd_get_csd(host, card);
+ if (err)
+ return err;
- if (!oldcard) {
- err = mmc_sd_get_csd(host, card);
- if (err)
- return err;
+ mmc_decode_cid(card);
+ }
- mmc_decode_cid(card);
+ /*
+ * Select card, as all following commands rely on that.
+ */
+ if (!mmc_host_is_spi(host)) {
+ err = mmc_select_card(card);
+ if (err)
+ return err;
+ }
}
- /*
- * Select card, as all following commands rely on that.
- */
- if (!mmc_host_is_spi(host)) {
- err = mmc_select_card(card);
- if (err)
- return err;
+ /* If card is locked, skip the rest of the init */
+ 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_warning("%s: Card unlock failed.\n",
+ mmc_hostname(card->host));
+ card->raw_ocr = rocr;
+ goto locked_return;
+ }
}
err = mmc_sd_setup_card(host, card, oldcard != NULL);
@@ -1002,6 +1042,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
}
}
+locked_return:
host->card = card;
return 0;
@@ -1284,3 +1325,28 @@ err:
return err;
}
+ssize_t mmc_sd_unlock_retry_store(struct device *dev,
+ struct device_attribute *att,
+ const char *data, size_t len)
+{
+ int err;
+ struct mmc_card *card = mmc_dev_to_card(dev);
+ struct mmc_host *host = card->host;
+ BUG_ON(!card);
+ BUG_ON(!host);
+
+ mmc_claim_host(host);
+ if (!mmc_card_locked(card)) {
+ mmc_release_host(host);
+ return len;
+ }
+ err = mmc_sd_init_card(host, host->ocr, 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;
+}
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index af92c44..593b854 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -282,6 +282,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 */
--
1.8.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/7] mmc: lock: Prevent partition table read for locked cards.
2013-08-13 15:21 [PATCH 0/7] Add password protected lock/unlock support for SD/MMC Al Cooper
` (4 preceding siblings ...)
2013-08-13 15:21 ` [PATCH 5/7] mmc: lock: Change SD init functionality to handle locked SD cards Al Cooper
@ 2013-08-13 15:21 ` Al Cooper
2013-08-13 15:21 ` [PATCH 7/7] mmc: lock: Change MMC init to handle " Al Cooper
6 siblings, 0 replies; 10+ messages in thread
From: Al Cooper @ 2013-08-13 15:21 UTC (permalink / raw)
To: cjb, linux-mmc; +Cc: Al Cooper
From: Al Cooper <acooper@broadcom.com>
Change the MMC block layer to avoid reading the partition table
when the card is locked because read commands will fail.
refs #SWLINUX-2545
Signed-off-by: Al Cooper <acooper@broadcom.com>
---
drivers/mmc/card/block.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index cd0b7f4..8eb254f 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -2047,6 +2047,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
--
1.8.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/7] mmc: lock: Change MMC init to handle locked cards.
2013-08-13 15:21 [PATCH 0/7] Add password protected lock/unlock support for SD/MMC Al Cooper
` (5 preceding siblings ...)
2013-08-13 15:21 ` [PATCH 6/7] mmc: lock: Prevent partition table read for locked cards Al Cooper
@ 2013-08-13 15:21 ` Al Cooper
6 siblings, 0 replies; 10+ messages in thread
From: Al Cooper @ 2013-08-13 15:21 UTC (permalink / raw)
To: cjb, linux-mmc; +Cc: Al Cooper
From: Al Cooper <acooper@broadcom.com>
- 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.
refs #SWLINUX-2545
Signed-off-by: Al Cooper <acooper@broadcom.com>
---
drivers/mmc/core/mmc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 1ad33ca..bec1914 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -726,10 +726,37 @@ out:
return res;
}
-static DEVICE_ATTR(lock, S_IWUSR | S_IRUGO,
- mmc_lock_show, mmc_lock_store);
+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 */
@@ -772,6 +799,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,
};
@@ -958,6 +986,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
unsigned int max_dtr;
u32 rocr;
u8 *ext_csd = NULL;
+ u32 status;
BUG_ON(!host);
WARN_ON(!host->claimed);
@@ -1416,6 +1445,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_warning("%s: Card unlock failed.\n",
+ mmc_hostname(card->host));
+ }
+ }
+
if (!oldcard)
host->card = card;
--
1.8.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/7] mmc: lock: Use the kernel "KEYS" subsystem to get a card's password
2013-08-13 15:21 ` [PATCH 1/7] mmc: lock: Use the kernel "KEYS" subsystem to get a card's password Al Cooper
@ 2013-08-15 1:16 ` Brian Norris
2013-08-23 10:34 ` Ulf Hansson
1 sibling, 0 replies; 10+ messages in thread
From: Brian Norris @ 2013-08-15 1:16 UTC (permalink / raw)
To: linux-mmc
Al Cooper <alcooperx@gmail.com> writes:
> From: Al Cooper <acooper@broadcom.com>
>
> 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.
>
> refs #SWLINUX-2545
You'll want to drop these tags, as they don't have any use in Linus' git logs.
Brian
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/7] mmc: lock: Use the kernel "KEYS" subsystem to get a card's password
2013-08-13 15:21 ` [PATCH 1/7] mmc: lock: Use the kernel "KEYS" subsystem to get a card's password Al Cooper
2013-08-15 1:16 ` Brian Norris
@ 2013-08-23 10:34 ` Ulf Hansson
1 sibling, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2013-08-23 10:34 UTC (permalink / raw)
To: Al Cooper; +Cc: Chris Ball, linux-mmc, Al Cooper
Hi Al,
On 13 August 2013 17:21, Al Cooper <alcooperx@gmail.com> wrote:
> From: Al Cooper <acooper@broadcom.com>
>
> 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.
>
> refs #SWLINUX-2545
>
> Signed-off-by: Al Cooper <acooper@broadcom.com>
> ---
> drivers/mmc/core/Kconfig | 8 +++++
> drivers/mmc/core/core.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++
> drivers/mmc/core/core.h | 16 ++++++++-
> 3 files changed, 109 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
> index 269d072..b0ba79d 100644
> --- a/drivers/mmc/core/Kconfig
> +++ b/drivers/mmc/core/Kconfig
> @@ -26,3 +26,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.
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 49a5bca..510927f 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -27,6 +27,7 @@
> #include <linux/fault-inject.h>
> #include <linux/random.h>
> #include <linux/slab.h>
> +#include <linux/key-type.h>
>
> #include <linux/mmc/card.h>
> #include <linux/mmc/host.h>
> @@ -2705,6 +2706,78 @@ void mmc_init_context_info(struct mmc_host *host)
> init_waitqueue_head(&host->context_info.wait);
> }
>
> +#ifdef CONFIG_MMC_LOCK
> +
> +int mmc_get_password(struct mmc_card *card, struct mmc_password *password)
> +{
> + struct key *mmc_key;
> + char key_desc[(sizeof(card->raw_cid) * 2) + 1];
> +
> + /* Use the CID to uniquely identify the card */
> + snprintf(key_desc, sizeof(key_desc), "%08x%08x%08x%08x",
> + card->raw_cid[0], card->raw_cid[1],
> + card->raw_cid[2], card->raw_cid[3]);
> +
> + mmc_key = request_key(&mmc_key_type, key_desc,
> + "password");
> + if (IS_ERR(mmc_key)) {
> + dev_warn(&card->dev, "Error, request_key %ld\n",
> + PTR_ERR(mmc_key));
> + return PTR_ERR(mmc_key);
> + }
> + dev_dbg(&card->dev, "Found matching key\n");
> + memcpy(&password->password, mmc_key->payload.data,
> + mmc_key->datalen);
> + password->length = mmc_key->datalen;
> + key_put(mmc_key);
> +
> + return 0;
> +}
> +
> +
> +static int mmc_key_instantiate(struct key *key,
> + struct key_preparsed_payload *prep)
> +{
> + char *payload;
> +
> + if (prep->datalen <= 0 || prep->datalen > MMC_PASSWORD_MAX ||
> + !prep->data) {
> + pr_warn("Invalid data\n");
> + return -EINVAL;
> + }
> +
> + payload = kmalloc(prep->datalen, GFP_KERNEL);
> + if (!payload)
> + return -ENOMEM;
> + memcpy(payload, prep->data, prep->datalen);
> + key->payload.data = payload;
> + key->datalen = prep->datalen;
> + return 0;
> +}
> +
> +static int mmc_key_match(const struct key *key, const void *description)
> +{
> + pr_debug("mmc_key_match: %s, %s\n",
> + key->description, (char *)description);
> + return strcmp(key->description, description) == 0;
> +}
> +
> +/*
> + * dispose of the data dangling from the corpse of a mmc key
> + */
> +static void mmc_key_destroy(struct key *key)
> +{
> + kfree(key->payload.data);
> +}
> +
> +struct key_type mmc_key_type = {
> + .name = "mmc",
> + .instantiate = mmc_key_instantiate,
> + .match = mmc_key_match,
> + .destroy = mmc_key_destroy,
> +};
> +#endif /* CONFIG_MMC_LOCK */
> +
> static int __init mmc_init(void)
> {
> int ret;
> @@ -2725,8 +2798,18 @@ static int __init mmc_init(void)
> if (ret)
> goto unregister_host_class;
>
> +#ifdef CONFIG_MMC_LOCK
> + ret = register_key_type(&mmc_key_type);
> + if (ret)
> + goto unregister_sdio_bus;
> +#endif /* CONFIG_MMC_LOCK */
> +
Please don't add "#ifdefs" around the code like this. Instead add
stubbed versions of the functions in case !CONFIG_MMC_LOCK.
> return 0;
>
> +#ifdef CONFIG_MMC_LOCK
dito
> +unregister_sdio_bus:
> + sdio_unregister_bus();
> +#endif /* CONFIG_MMC_LOCK */
> unregister_host_class:
> mmc_unregister_host_class();
> unregister_bus:
> @@ -2739,6 +2822,9 @@ destroy_workqueue:
>
> static void __exit mmc_exit(void)
> {
> +#ifdef CONFIG_MMC_LOCK
> + unregister_key_type(&mmc_key_type);
> +#endif /* CONFIG_MMC_LOCK */
dito
> sdio_unregister_bus();
> mmc_unregister_host_class();
> mmc_unregister_bus();
> diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
> index 5345d15..dcf516d 100644
> --- a/drivers/mmc/core/core.h
> +++ b/drivers/mmc/core/core.h
> @@ -81,5 +81,19 @@ void mmc_add_card_debugfs(struct mmc_card *card);
> void mmc_remove_card_debugfs(struct mmc_card *card);
>
> void mmc_init_context_info(struct mmc_host *host);
> -#endif
>
> +/* Lock/Unlock functionality */
> +int mmc_unlock_card(struct mmc_card *card);
> +
> +#ifdef CONFIG_MMC_LOCK
> +#define MMC_PASSWORD_MAX 16
> +struct mmc_password {
> + char password[MMC_PASSWORD_MAX];
> + int length;
> +};
> +extern struct key_type mmc_key_type;
> +
> +int mmc_get_password(struct mmc_card *card, struct mmc_password *password);
> +#endif /* CONFIG_MMC_LOCK */
> +
> +#endif
> --
> 1.8.1.3
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Kind regards
Ulf Hansson
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2013-08-23 10:34 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-13 15:21 [PATCH 0/7] Add password protected lock/unlock support for SD/MMC Al Cooper
2013-08-13 15:21 ` [PATCH 1/7] mmc: lock: Use the kernel "KEYS" subsystem to get a card's password Al Cooper
2013-08-15 1:16 ` Brian Norris
2013-08-23 10:34 ` Ulf Hansson
2013-08-13 15:21 ` [PATCH 2/7] mmc: lock: Add low level LOCK_UNLOCK command Al Cooper
2013-08-13 15:21 ` [PATCH 3/7] mmc: lock: Add funtion to unlock a password locked card Al Cooper
2013-08-13 15:21 ` [PATCH 4/7] mmc: lock: Add card lock/unlock maintenance commands Al Cooper
2013-08-13 15:21 ` [PATCH 5/7] mmc: lock: Change SD init functionality to handle locked SD cards Al Cooper
2013-08-13 15:21 ` [PATCH 6/7] mmc: lock: Prevent partition table read for locked cards Al Cooper
2013-08-13 15:21 ` [PATCH 7/7] mmc: lock: Change MMC init to handle " Al Cooper
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).