All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anderson Briglia <anderson.briglia@indt.org.br>
To: "Linux-omap-open-source@linux.omap.com"
	<linux-omap-open-source@linux.omap.com>
Cc: linux-kernel@vger.kernel.org,
	Pierre Ossman <drzeus-list@drzeus.cx>,
	ext David Brownell <david-b@pacbell.net>,
	Russell King <rmk+lkml@arm.linux.org.uk>,
	Tony Lindgren <tony@atomide.com>,
	"Aguiar Carlos (EXT-INdT/Manaus)" <carlos.aguiar@indt.org.br>,
	"Biris Ilias (EXT-INdT/Manaus)" <Ilias.Biris@indt.org.br>
Subject: [patch 5/6] [RFC] Add MMC Password Protection (lock/unlock) support V6
Date: Fri, 17 Nov 2006 09:12:39 -0400	[thread overview]
Message-ID: <455DB547.5060407@indt.org.br> (raw)

[-- Attachment #1: Type: text/plain, Size: 4804 bytes --]

Implement MMC password force erase, remove password, change password,
unlock card and assign password operations. It uses the sysfs mechanism
to send commands to the MMC subsystem.

Signed-off-by: Carlos Eduardo Aguiar <carlos.aguiar <at> indt.org.br>
Signed-off-by: Anderson Lizardo <anderson.lizardo <at> indt.org.br>
Signed-off-by: Anderson Briglia <anderson.briglia <at> indt.org.br>

Index: linux-omap-2.6.git/drivers/mmc/mmc_sysfs.c
===================================================================
--- linux-omap-2.6.git.orig/drivers/mmc/mmc_sysfs.c	2006-11-16 15:45:20.000000000 -0400
+++ linux-omap-2.6.git/drivers/mmc/mmc_sysfs.c	2006-11-16 15:54:44.000000000 -0400
@@ -17,6 +17,7 @@
  #include <linux/idr.h>
  #include <linux/workqueue.h>
  #include <linux/key.h>
+#include <linux/err.h>

  #include <linux/mmc/card.h>
  #include <linux/mmc/host.h>
@@ -65,6 +66,114 @@ static struct device_attribute mmc_dev_a

  static struct device_attribute mmc_dev_attr_scr = MMC_ATTR_RO(scr);

+#ifdef	CONFIG_MMC_PASSWORDS
+
+static ssize_t
+mmc_lockable_show(struct device *dev, struct device_attribute *att, char *buf)
+{
+	struct mmc_card *card = dev_to_mmc_card(dev);
+
+	if (!mmc_card_lockable(card))
+		return sprintf(buf, "unsupported\n");
+	else
+		return sprintf(buf, "%slocked\n", mmc_card_locked(card) ?
+			"" : "un");
+}
+
+/*
+ * implement MMC password functions: force erase, remove password, change
+ * password, unlock card and assign password.
+ */
+static ssize_t
+mmc_lockable_store(struct device *dev, struct device_attribute *att,
+	const char *data, size_t len)
+{
+	struct mmc_card *card = dev_to_mmc_card(dev);
+	/* Lock to protect the mmc_lock_unlock data */
+	spinlock_t mmc_lock = SPIN_LOCK_UNLOCKED;
+
+	if (!mmc_card_lockable(card))
+		return -EINVAL;
+
+	if (mmc_card_locked(card) && !strncmp(data, "erase", 5)) {
+		/* forced erase only works while card is locked */
+		spin_lock(&mmc_lock);
+		mmc_lock_unlock(card, NULL, MMC_LOCK_MODE_ERASE);
+		spin_unlock(&mmc_lock);
+		return len;
+	} else if (!mmc_card_locked(card) && !strncmp(data, "remove", 6)) {
+		/* remove password only works while card is unlocked */
+		struct key *mmc_key = request_key(&mmc_key_type, "mmc:key", "remove");
+
+		if (!IS_ERR(mmc_key)) {
+			int err = 0;
+
+			spin_lock(&mmc_lock);
+			err = mmc_lock_unlock(card, mmc_key, MMC_LOCK_MODE_CLR_PWD);
+			spin_unlock(&mmc_lock);
+			if (!err)
+				return len;
+		} else
+			dev_dbg(&card->dev, "request_key returned error %ld\n", PTR_ERR(mmc_key));
+	} else if (!mmc_card_locked(card) && !strncmp(data, "change", 6)) {
+			/* change */
+			struct key *mmc_key = request_key(&mmc_key_type, "mmc:key", "change");
+
+			if (!IS_ERR(mmc_key)) {
+				int err = 0;
+				
+				spin_lock(&mmc_lock);
+				err = mmc_lock_unlock(card, mmc_key, MMC_LOCK_MODE_SET_PWD);
+				spin_unlock(&mmc_lock);
+				if (!err)
+					return len;
+			} else
+				dev_dbg(&card->dev, "request_key returned error %ld\n", PTR_ERR(mmc_key));
+	} else if (mmc_card_locked(card) && !strncmp(data, "unlock", 6)) {
+			/* unlock */
+			struct key *mmc_key = request_key(&mmc_key_type, "mmc:key", "unlock");
+
+			if (!IS_ERR(mmc_key)) {
+				int err = 0;
+				
+				spin_lock(&mmc_lock);
+				mmc_lock_unlock(card, mmc_key, MMC_LOCK_MODE_UNLOCK);
+				spin_unlock(&mmc_lock);
+				if (err) {
+					dev_dbg(&card->dev, "Wrong password\n");
+				}
+				else {
+					device_release_driver(dev);
+					device_attach(dev);
+					return len;
+				}
+			} else
+				dev_dbg(&card->dev, "request_key returned error %ld\n", PTR_ERR(mmc_key));
+	} else if (!mmc_card_locked(card) && !strncmp(data, "assign", 6)) {
+			/* assign */
+			struct key *mmc_key = request_key(&mmc_key_type, "mmc:key", "assign");
+
+			if (!IS_ERR(mmc_key)) {
+			int err = 0;
+			
+			spin_lock(&mmc_lock);
+			err = mmc_lock_unlock(card, mmc_key, MMC_LOCK_MODE_SET_PWD);
+			spin_unlock(&mmc_lock);
+			if (!err)
+				return len;
+			} else
+				dev_dbg(&card->dev, "request_key returned error %ld\n", PTR_ERR(mmc_key));
+	}
+
+	return -EINVAL;
+}
+
+static struct device_attribute mmc_dev_attr_lockable =
+	__ATTR(lockable, S_IWUSR | S_IRUGO,
+		 mmc_lockable_show, mmc_lockable_store);
+
+#endif
+

  static void mmc_release_card(struct device *dev)
  {
@@ -234,6 +343,11 @@ int mmc_register_card(struct mmc_card *c
  			if (ret)
  				device_del(&card->dev);
  		}
+#ifdef CONFIG_MMC_PASSWORDS
+		ret = device_create_file(&card->dev, &mmc_dev_attr_lockable);
+		if (ret)
+			device_del(&card->dev);
+#endif
  	}
  	return ret;
  }
@@ -248,6 +362,9 @@ void mmc_remove_card(struct mmc_card *ca
  		if (mmc_card_sd(card))
  			device_remove_file(&card->dev, &mmc_dev_attr_scr);

+#ifdef CONFIG_MMC_PASSWORDS
+		device_remove_file(&card->dev, &mmc_dev_attr_lockable);
+#endif
  		device_del(&card->dev);
  	}



[-- Attachment #2: mmc_sysfs.diff --]
[-- Type: text/x-patch, Size: 4792 bytes --]

Implement MMC password force erase, remove password, change password,
unlock card and assign password operations. It uses the sysfs mechanism
to send commands to the MMC subsystem. 

Signed-off-by: Carlos Eduardo Aguiar <carlos.aguiar <at> indt.org.br>
Signed-off-by: Anderson Lizardo <anderson.lizardo <at> indt.org.br>
Signed-off-by: Anderson Briglia <anderson.briglia <at> indt.org.br>

Index: linux-omap-2.6.git/drivers/mmc/mmc_sysfs.c
===================================================================
--- linux-omap-2.6.git.orig/drivers/mmc/mmc_sysfs.c	2006-11-16 15:45:20.000000000 -0400
+++ linux-omap-2.6.git/drivers/mmc/mmc_sysfs.c	2006-11-16 15:54:44.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/idr.h>
 #include <linux/workqueue.h>
 #include <linux/key.h>
+#include <linux/err.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -65,6 +66,114 @@ static struct device_attribute mmc_dev_a
 
 static struct device_attribute mmc_dev_attr_scr = MMC_ATTR_RO(scr);
 
+#ifdef	CONFIG_MMC_PASSWORDS
+
+static ssize_t
+mmc_lockable_show(struct device *dev, struct device_attribute *att, char *buf)
+{
+	struct mmc_card *card = dev_to_mmc_card(dev);
+
+	if (!mmc_card_lockable(card))
+		return sprintf(buf, "unsupported\n");
+	else
+		return sprintf(buf, "%slocked\n", mmc_card_locked(card) ?
+			"" : "un");
+}
+
+/*
+ * implement MMC password functions: force erase, remove password, change
+ * password, unlock card and assign password.
+ */
+static ssize_t
+mmc_lockable_store(struct device *dev, struct device_attribute *att,
+	const char *data, size_t len)
+{
+	struct mmc_card *card = dev_to_mmc_card(dev);
+	/* Lock to protect the mmc_lock_unlock data */
+	spinlock_t mmc_lock = SPIN_LOCK_UNLOCKED;
+
+	if (!mmc_card_lockable(card))
+		return -EINVAL;
+
+	if (mmc_card_locked(card) && !strncmp(data, "erase", 5)) {
+		/* forced erase only works while card is locked */
+		spin_lock(&mmc_lock);
+		mmc_lock_unlock(card, NULL, MMC_LOCK_MODE_ERASE);
+		spin_unlock(&mmc_lock);
+		return len;
+	} else if (!mmc_card_locked(card) && !strncmp(data, "remove", 6)) {
+		/* remove password only works while card is unlocked */
+		struct key *mmc_key = request_key(&mmc_key_type, "mmc:key", "remove");
+
+		if (!IS_ERR(mmc_key)) {
+			int err = 0;
+
+			spin_lock(&mmc_lock);
+			err = mmc_lock_unlock(card, mmc_key, MMC_LOCK_MODE_CLR_PWD);
+			spin_unlock(&mmc_lock);
+			if (!err)
+				return len;
+		} else
+			dev_dbg(&card->dev, "request_key returned error %ld\n", PTR_ERR(mmc_key));
+	} else if (!mmc_card_locked(card) && !strncmp(data, "change", 6)) {
+			/* change */
+			struct key *mmc_key = request_key(&mmc_key_type, "mmc:key", "change");
+
+			if (!IS_ERR(mmc_key)) {
+				int err = 0;
+				
+				spin_lock(&mmc_lock);
+				err = mmc_lock_unlock(card, mmc_key, MMC_LOCK_MODE_SET_PWD);
+				spin_unlock(&mmc_lock);
+				if (!err)
+					return len;
+			} else
+				dev_dbg(&card->dev, "request_key returned error %ld\n", PTR_ERR(mmc_key));
+	} else if (mmc_card_locked(card) && !strncmp(data, "unlock", 6)) {
+			/* unlock */
+			struct key *mmc_key = request_key(&mmc_key_type, "mmc:key", "unlock");
+
+			if (!IS_ERR(mmc_key)) {
+				int err = 0;
+				
+				spin_lock(&mmc_lock);
+				mmc_lock_unlock(card, mmc_key, MMC_LOCK_MODE_UNLOCK);
+				spin_unlock(&mmc_lock);
+				if (err) {
+					dev_dbg(&card->dev, "Wrong password\n");
+				}
+				else {
+					device_release_driver(dev);
+					device_attach(dev);
+					return len;
+				}
+			} else
+				dev_dbg(&card->dev, "request_key returned error %ld\n", PTR_ERR(mmc_key));
+	} else if (!mmc_card_locked(card) && !strncmp(data, "assign", 6)) {
+			/* assign */
+			struct key *mmc_key = request_key(&mmc_key_type, "mmc:key", "assign");
+
+			if (!IS_ERR(mmc_key)) {
+			int err = 0;
+			
+			spin_lock(&mmc_lock);
+			err = mmc_lock_unlock(card, mmc_key, MMC_LOCK_MODE_SET_PWD);
+			spin_unlock(&mmc_lock);
+			if (!err)
+				return len;
+			} else
+				dev_dbg(&card->dev, "request_key returned error %ld\n", PTR_ERR(mmc_key));
+	}
+
+	return -EINVAL;
+}
+
+static struct device_attribute mmc_dev_attr_lockable =
+	__ATTR(lockable, S_IWUSR | S_IRUGO,
+		 mmc_lockable_show, mmc_lockable_store);
+
+#endif
+
 
 static void mmc_release_card(struct device *dev)
 {
@@ -234,6 +343,11 @@ int mmc_register_card(struct mmc_card *c
 			if (ret)
 				device_del(&card->dev);
 		}
+#ifdef CONFIG_MMC_PASSWORDS
+		ret = device_create_file(&card->dev, &mmc_dev_attr_lockable);
+		if (ret)
+			device_del(&card->dev);
+#endif
 	}
 	return ret;
 }
@@ -248,6 +362,9 @@ void mmc_remove_card(struct mmc_card *ca
 		if (mmc_card_sd(card))
 			device_remove_file(&card->dev, &mmc_dev_attr_scr);
 
+#ifdef CONFIG_MMC_PASSWORDS
+		device_remove_file(&card->dev, &mmc_dev_attr_lockable);
+#endif
 		device_del(&card->dev);
 	}
 

             reply	other threads:[~2006-11-17 13:12 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-11-17 13:12 Anderson Briglia [this message]
2006-11-17 16:13 ` [patch 5/6] [RFC] Add MMC Password Protection (lock/unlock) support V6 Russell King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=455DB547.5060407@indt.org.br \
    --to=anderson.briglia@indt.org.br \
    --cc=Ilias.Biris@indt.org.br \
    --cc=carlos.aguiar@indt.org.br \
    --cc=david-b@pacbell.net \
    --cc=drzeus-list@drzeus.cx \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap-open-source@linux.omap.com \
    --cc=rmk+lkml@arm.linux.org.uk \
    --cc=tony@atomide.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.