2005-12-13 22:27:06

by Anderson Briglia

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

[resending summary because our first attempt failed]

Hi,

These series of patches add support for MultiMediaCard (MMC) password
protection, as described in the MMC Specification v4.1. This feature is
supported by all compliant MMC cards, and used by some devices such as Symbian
OS cell phones to optionally protect MMC cards with a password. Password length
is limited to 16 bytes.

By default, a MMC card with no password assigned is always in "unlocked" state.
After password assignement, 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 the
card can be normally used for operations like block I/O.

Password management and caching is done through the "Kernel Key Retention
Service" mechanism and the sysfs filesystem. The Key Retention Service is used
for (1) unlocking the card, (2) assigning a password to an unlocked card and
(3) change a card's password. To remove the password and check locked/unlocked
status, a new sysfs attribute was added to the MMC driver.

Along with this thread will be sent a script that tests all possible user
scenarios described above. Also will be attached a tarball containing a simple
text-only reference UI to demonstrate how to manipulate the password.

TODO:

- MMC hotplugging needs to be extended to properly call probe() for the
different MMC drivers (currently only mmc_block). Currently, the block driver
is not notified in any way that the card was unlocked.

- Password caching: when inserting a locked card, the driver should try to
unlock it with the currently stored password (if any), and if it fails,
revoke the key containing it and fallback to the normal "no password present"
situation.

- Currently, some host drivers assume the block length will always be a power
of 2. This is not true for the MMC_LOCK_UNLOCK command, which is a block
command that accepts arbitratry block lengths. We have made the necessary
changes to the omap.c driver (present on the linux-omap tree), but the same
needs to be done for other hosts' drivers.

Known Issue:

- Some cards have an incorrect behaviour (hardware bug?) regarding password
acceptance: if an affected card has password <pwd>, it accepts <pwd><xxx> as
the correct password too, where <xxx> is any sequence of characters, of any
length. In other words, on these cards only the first <password length> bytes
need to match the correct password.

Comments or suggestions are welcome.

--
Anderson Briglia,
Anderson Lizardo,
Carlos Eduardo Aguiar

Embedded Linux Lab - 10LE
Nokia Institute of Technology - INdT
Manaus - Brazil


2005-12-14 07:07:27

by Pierre Ossman

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

Anderson Briglia wrote:
> [resending summary because our first attempt failed]
>
>
> - Password caching: when inserting a locked card, the driver should try to
> unlock it with the currently stored password (if any), and if it fails,
> revoke the key containing it and fallback to the normal "no password present"
> situation.
>

Would it be possible to use the id of the card as a search key for the
password? That way several passwords can coexist.

> - Currently, some host drivers assume the block length will always be a power
> of 2. This is not true for the MMC_LOCK_UNLOCK command, which is a block
> command that accepts arbitratry block lengths. We have made the necessary
> changes to the omap.c driver (present on the linux-omap tree), but the same
> needs to be done for other hosts' drivers.
>

The MMC layer is designed that way, so it's hardly surprising that
drivers have been coded for it. I'm assuming you've removed blksz_bits
in favor of something in bytes?

Rgds
Pierre

2005-12-14 23:51:09

by Anderson Lizardo

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

On 12/14/05, Pierre Ossman <[email protected]> wrote:
> Anderson Briglia wrote:
> > - Password caching: when inserting a locked card, the driver should try to
> > unlock it with the currently stored password (if any), and if it fails,
> > revoke the key containing it and fallback to the normal "no password present"
> > situation.
> >
>
> Would it be possible to use the id of the card as a search key for the
> password? That way several passwords can coexist.

Yes, we have plans for that. The keys managed by the key retention
service have a description field that can be used to uniquely identify
keys and allows searching for specific keys. For this first version of
the code, we are using simply "mmc:key" as the description, which does
not allow more than one MMC password to be stored at a time.

Probably using the entire 128-bit CID for the key description would
waste too much space though, so we are thinking about using just some
CID fields to build a smaller unique ID. The key retention service has
quotas for how much space a keyring can use for payload and key
description, so we should try to keep the description as short as
possible. If a collision occurs and the password is wrong, we can
simply invalidate the key and ask for the password again.

> > - Currently, some host drivers assume the block length will always be a power
> > of 2. This is not true for the MMC_LOCK_UNLOCK command, which is a block
> > command that accepts arbitratry block lengths. We have made the necessary
> > changes to the omap.c driver (present on the linux-omap tree), but the same
> > needs to be done for other hosts' drivers.
> >
>
> The MMC layer is designed that way, so it's hardly surprising that
> drivers have been coded for it. I'm assuming you've removed blksz_bits
> in favor of something in bytes?

I actually just did the following change to the OMAP code (drivers/mmc/omap.c):

-
- block_size = 1 << data->blksz_bits;
+ /* password protection: we need to send the exact block size to the
+ * card (password + 2), not a 2-exponent. */
+ if (req->cmd->opcode == MMC_LOCK_UNLOCK)
+ block_size = data->sg[0].length;
+ else
+ block_size = 1 << data->blksz_bits;

Given that for the LOCK_UNLOCK command the sg_len will always be 1, we
can get the block size directly from the first entry of the
scatterlist. For other block operations, the blksz_bits value is used
as usual.

Maybe removing blksz_bits and using the block size directly would be
better? Is there any host/card which expects to always receive a
power-of-2 block size for block operations?
--
Anderson Lizardo
Embedded Linux Lab - 10LE
Nokia Institute of Technology - INdT
Manaus - Brazil

2005-12-15 06:49:49

by Pierre Ossman

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

Anderson Lizardo wrote:

>Probably using the entire 128-bit CID for the key description would
>waste too much space though, so we are thinking about using just some
>CID fields to build a smaller unique ID. The key retention service has
>quotas for how much space a keyring can use for payload and key
>description, so we should try to keep the description as short as
>possible. If a collision occurs and the password is wrong, we can
>simply invalidate the key and ask for the password again.
>
>
>

For SD cards we can also use the RCA, which tends to be a bit random.
Perhaps a generic hash function so that we can extend and tweak this
algorithm in one place?

>I actually just did the following change to the OMAP code (drivers/mmc/omap.c):
>
>-
>- block_size = 1 << data->blksz_bits;
>+ /* password protection: we need to send the exact block size to the
>+ * card (password + 2), not a 2-exponent. */
>+ if (req->cmd->opcode == MMC_LOCK_UNLOCK)
>+ block_size = data->sg[0].length;
>+ else
>+ block_size = 1 << data->blksz_bits;
>
>Given that for the LOCK_UNLOCK command the sg_len will always be 1, we
>can get the block size directly from the first entry of the
>scatterlist. For other block operations, the blksz_bits value is used
>as usual.
>
>
>

I can't say that I approve of this code. It's my firm belief that
drivers that are protocol aware are horribly broken.

>Maybe removing blksz_bits and using the block size directly would be
>better? Is there any host/card which expects to always receive a
>power-of-2 block size for block operations?
>
>

Sounds like a much better solution. Hacking around problems instead of
solving them usually lead to even more problems.

I haven't studied all drivers in detail, but I believe all of them
should be able to handle the transistion.

Rgds
Pierre

2005-12-15 09:12:43

by Russell King

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

On Thu, Dec 15, 2005 at 07:49:40AM +0100, Pierre Ossman wrote:
> Sounds like a much better solution. Hacking around problems instead of
> solving them usually lead to even more problems.

No, that's not possible.

> I haven't studied all drivers in detail, but I believe all of them
> should be able to handle the transistion.

You seem to have ignored my message on why this is required. The MMCI
driver requires that all transfers be a multiple of 1 << blksz_bits.
So, if you want to transfer (eg) 9 bytes, it must be transferred as 9
one byte blocks. So set blksz_bits to 0 and blocks to 9.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-15 09:28:09

by Pierre Ossman

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

Russell King wrote:
>
> You seem to have ignored my message on why this is required. The MMCI
> driver requires that all transfers be a multiple of 1 << blksz_bits.
> So, if you want to transfer (eg) 9 bytes, it must be transferred as 9
> one byte blocks. So set blksz_bits to 0 and blocks to 9.
>
>

I haven't seen any such comments from you, so I haven't ignored anything.

The spec I have says that this is a single block command. So such
trickery would not work. It isn't explicit about padding so it might be
possible to pad the data (since password length is specified in the
data). If not, then we either ignore this function or have a system
where we can detect limited hosts and print warnings.

Rgds
Pierre

2005-12-15 10:07:10

by Russell King

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

On Thu, Dec 15, 2005 at 10:27:13AM +0100, Pierre Ossman wrote:
> The spec I have says that this is a single block command. So such
> trickery would not work. It isn't explicit about padding so it might be
> possible to pad the data (since password length is specified in the
> data). If not, then we either ignore this function or have a system
> where we can detect limited hosts and print warnings.

What we need is someone with the real MMC spec to tell us about the
requirements here.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-15 13:44:52

by Russell King

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

On Thu, Dec 15, 2005 at 10:06:57AM +0000, Russell King wrote:
> On Thu, Dec 15, 2005 at 10:27:13AM +0100, Pierre Ossman wrote:
> > The spec I have says that this is a single block command. So such
> > trickery would not work. It isn't explicit about padding so it might be
> > possible to pad the data (since password length is specified in the
> > data). If not, then we either ignore this function or have a system
> > where we can detect limited hosts and print warnings.
>
> What we need is someone with the real MMC spec to tell us about the
> requirements here.

Reading through the specs I have here, block sizes seem to be all over
the place. The MMC card specs seem to imply that any block size can
be set, from 0 bytes to 2^32-1 bytes.

The PXA MMC interface specification allows the block size to be anything
from 1 to 1023 bytes, excluding CRC. It is unclear whether a value of 0
means 1024.

The MMCI specification allows the block size to be specified as a power
of two, from 1 to 2048 bytes, excluding CRC.

Pierre - can you comment on wbsd's capabilities please?

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-15 16:01:37

by Pierre Ossman

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

Russell King wrote:
> Reading through the specs I have here, block sizes seem to be all over
> the place. The MMC card specs seem to imply that any block size can
> be set, from 0 bytes to 2^32-1 bytes.
>
> The PXA MMC interface specification allows the block size to be anything
> from 1 to 1023 bytes, excluding CRC. It is unclear whether a value of 0
> means 1024.
>
> The MMCI specification allows the block size to be specified as a power
> of two, from 1 to 2048 bytes, excluding CRC.
>
> Pierre - can you comment on wbsd's capabilities please?
>
>

wbsd can do 1 to 4087 (it wants CRC bytes in the size so it goes to 4095
including those). Which means I probably set incorrect sg limits... I
guess I should fix that.

sdhci, which I'm currently developing, can do up to 0x7FFF. The register
is 16-bits, but the upper bit never sticks so I assume it cannot be used.

Rgds
Pierre

2005-12-29 19:06:17

by Anderson Lizardo

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

On 12/15/05, Russell King <[email protected]> wrote:
> Reading through the specs I have here, block sizes seem to be all over
> the place. The MMC card specs seem to imply that any block size can
> be set, from 0 bytes to 2^32-1 bytes.
>
> The PXA MMC interface specification allows the block size to be anything
> from 1 to 1023 bytes, excluding CRC. It is unclear whether a value of 0
> means 1024.
>
> The MMCI specification allows the block size to be specified as a power
> of two, from 1 to 2048 bytes, excluding CRC.

By "allows" do you mean we can set the block size to arbitrary values
on MMCI too?

The MMC specification v4.1 is clear in one thing: the SET_BLOCKLEN
command should be issued prior to the actual LOCK_UNLOCK command with
*exactly* the password length + 2 bytes (which contains the operation
mode bits and the password length in bytes). The MMC password
unlocking (and other password operations, FWIW) doesn't work on the
OMAP host if the SET_BLOCKLEN command argument and the block size of
the data transfer itself do not match.

--
Anderson Lizardo
Embedded Linux Lab - 10LE
Nokia Institute of Technology - INdT
Manaus - Brazil

2005-12-29 19:17:21

by Anderson Lizardo

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

On 12/15/05, Russell King <[email protected]> wrote:
> Reading through the specs I have here, block sizes seem to be all over
> the place. The MMC card specs seem to imply that any block size can
> be set, from 0 bytes to 2^32-1 bytes.
>
> The PXA MMC interface specification allows the block size to be anything
> from 1 to 1023 bytes, excluding CRC. It is unclear whether a value of 0
> means 1024.
>
> The MMCI specification allows the block size to be specified as a power
> of two, from 1 to 2048 bytes, excluding CRC.

By "allows" do you mean we can set the block size to arbitrary values
on MMCI too?

The MMC specification v4.1 is clear in one thing: the SET_BLOCKLEN
command should be issued prior to the actual LOCK_UNLOCK command with
*exactly* the password length + 2 bytes (which contains the operation
mode bits and the password length in bytes). The MMC password
unlocking (and other password operations, FWIW) doesn't work on the
OMAP host if the SET_BLOCKLEN command argument and the block size of
the data transfer itself do not match.

--
Anderson Lizardo
Embedded Linux Lab - 10LE
Nokia Institute of Technology - INdT
Manaus - Brazil

2005-12-29 20:10:08

by Russell King

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

On Thu, Dec 29, 2005 at 03:06:15PM -0400, Anderson Lizardo wrote:
> On 12/15/05, Russell King <[email protected]> wrote:
> > Reading through the specs I have here, block sizes seem to be all over
> > the place. The MMC card specs seem to imply that any block size can
> > be set, from 0 bytes to 2^32-1 bytes.
> >
> > The PXA MMC interface specification allows the block size to be anything
> > from 1 to 1023 bytes, excluding CRC. It is unclear whether a value of 0
> > means 1024.
> >
> > The MMCI specification allows the block size to be specified as a power
> > of two, from 1 to 2048 bytes, excluding CRC.
>
> By "allows" do you mean we can set the block size to arbitrary values
> on MMCI too?

No - that's not what I said. I said "power of two, from 1 to 2048
bytes excluding CRC."

To expand on that to make it crystal clear (I feel like I'm teaching
grandmother to suck eggs, but what the hell) that means 1, 2, 4, 8,
16, 32, 64, 128, 256, 512, 1024, and 2048 are the only possible block
sizes with MMCI. All other block sizes can not be configured with
MMCI.

> The MMC specification v4.1 is clear in one thing: the SET_BLOCKLEN
> command should be issued prior to the actual LOCK_UNLOCK command with
> *exactly* the password length + 2 bytes (which contains the operation
> mode bits and the password length in bytes). The MMC password
> unlocking (and other password operations, FWIW) doesn't work on the
> OMAP host if the SET_BLOCKLEN command argument and the block size of
> the data transfer itself do not match.

Since passwords are limited to a maximum of 16 characters, this means
that only passwords of length 2, 6, and 14 are possible with MMCI.
All other passwords are invalid and/or impossible with this host.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2005-12-29 21:23:54

by Anderson Lizardo

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

On 12/29/05, Russell King <[email protected]> wrote:
> On Thu, Dec 29, 2005 at 03:06:15PM -0400, Anderson Lizardo wrote:
> > On 12/15/05, Russell King <[email protected]> wrote:
> > > Reading through the specs I have here, block sizes seem to be all over
> > > the place. The MMC card specs seem to imply that any block size can
> > > be set, from 0 bytes to 2^32-1 bytes.
> > >
> > > The PXA MMC interface specification allows the block size to be anything
> > > from 1 to 1023 bytes, excluding CRC. It is unclear whether a value of 0
> > > means 1024.
> > >
> > > The MMCI specification allows the block size to be specified as a power
> > > of two, from 1 to 2048 bytes, excluding CRC.
> >
> > By "allows" do you mean we can set the block size to arbitrary values
> > on MMCI too?
>
> No - that's not what I said. I said "power of two, from 1 to 2048
> bytes excluding CRC."

Ah, so you meant "only allows", sorry for the confusion.

> > The MMC specification v4.1 is clear in one thing: the SET_BLOCKLEN
> > command should be issued prior to the actual LOCK_UNLOCK command with
> > *exactly* the password length + 2 bytes (which contains the operation
> > mode bits and the password length in bytes). The MMC password
> > unlocking (and other password operations, FWIW) doesn't work on the
> > OMAP host if the SET_BLOCKLEN command argument and the block size of
> > the data transfer itself do not match.
>
> Since passwords are limited to a maximum of 16 characters, this means
> that only passwords of length 2, 6, and 14 are possible with MMCI.
> All other passwords are invalid and/or impossible with this host.

What do you suggest in this case? So far the MMCI host seems the only
one (from those supported by mainline tree) that has such limitation.

--
Anderson Lizardo
Embedded Linux Lab - 10LE
Nokia Institute of Technology - INdT
Manaus - Brazil

2005-12-29 21:38:06

by Russell King

[permalink] [raw]
Subject: Re: [patch 0/5] Add MMC password protection (lock/unlock) support

On Thu, Dec 29, 2005 at 05:23:52PM -0400, Anderson Lizardo wrote:
> On 12/29/05, Russell King <[email protected]> wrote:
> > On Thu, Dec 29, 2005 at 03:06:15PM -0400, Anderson Lizardo wrote:
> > > The MMC specification v4.1 is clear in one thing: the SET_BLOCKLEN
> > > command should be issued prior to the actual LOCK_UNLOCK command with
> > > *exactly* the password length + 2 bytes (which contains the operation
> > > mode bits and the password length in bytes). The MMC password
> > > unlocking (and other password operations, FWIW) doesn't work on the
> > > OMAP host if the SET_BLOCKLEN command argument and the block size of
> > > the data transfer itself do not match.
> >
> > Since passwords are limited to a maximum of 16 characters, this means
> > that only passwords of length 2, 6, and 14 are possible with MMCI.
> > All other passwords are invalid and/or impossible with this host.
>
> What do you suggest in this case?

Well, we seem to have an increasing number of silly limitations in
MMC host implementations. In this particular case, I guess the
easiest solution would be to supply a capability flag from the host
to say "only supports power of two block sizes" - and disable
password support if this flag is set.

Yes, this means that password-locked cards become non-functional
with such restricted hosts, but I think that's realistically
unavoidable.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core